diff options
author | John Firebaugh <john.firebaugh@gmail.com> | 2017-04-25 18:20:26 -0700 |
---|---|---|
committer | John Firebaugh <john.firebaugh@gmail.com> | 2017-05-12 11:26:27 -0700 |
commit | c2a5894f2dbe9982830066ab9347b059e6e7d845 (patch) | |
tree | c09363c2025b80265de195969ee56cc64e567e70 /src/mbgl/style/sources | |
parent | d3f23b83d42de8ef23ea1dbd8abfc6276009531f (diff) | |
download | qtlocation-mapboxgl-c2a5894f2dbe9982830066ab9347b059e6e7d845.tar.gz |
[core] Immutable Impls
Diffstat (limited to 'src/mbgl/style/sources')
-rw-r--r-- | src/mbgl/style/sources/geojson_source.cpp | 69 | ||||
-rw-r--r-- | src/mbgl/style/sources/geojson_source_impl.cpp | 87 | ||||
-rw-r--r-- | src/mbgl/style/sources/geojson_source_impl.hpp | 15 | ||||
-rw-r--r-- | src/mbgl/style/sources/raster_source.cpp | 74 | ||||
-rw-r--r-- | src/mbgl/style/sources/raster_source_impl.cpp | 30 | ||||
-rw-r--r-- | src/mbgl/style/sources/raster_source_impl.hpp | 15 | ||||
-rw-r--r-- | src/mbgl/style/sources/vector_source.cpp | 71 | ||||
-rw-r--r-- | src/mbgl/style/sources/vector_source_impl.cpp | 23 | ||||
-rw-r--r-- | src/mbgl/style/sources/vector_source_impl.hpp | 13 |
9 files changed, 278 insertions, 119 deletions
diff --git a/src/mbgl/style/sources/geojson_source.cpp b/src/mbgl/style/sources/geojson_source.cpp index 110c1cd63c..d04c8ffce4 100644 --- a/src/mbgl/style/sources/geojson_source.cpp +++ b/src/mbgl/style/sources/geojson_source.cpp @@ -1,25 +1,80 @@ #include <mbgl/style/sources/geojson_source.hpp> #include <mbgl/style/sources/geojson_source_impl.hpp> +#include <mbgl/style/source_observer.hpp> +#include <mbgl/style/conversion/json.hpp> +#include <mbgl/style/conversion/geojson.hpp> +#include <mbgl/storage/file_source.hpp> +#include <mbgl/util/logging.hpp> namespace mbgl { namespace style { GeoJSONSource::GeoJSONSource(const std::string& id, const GeoJSONOptions& options) - : Source(SourceType::GeoJSON, - std::make_unique<GeoJSONSource::Impl>(std::move(id), *this, options)), - impl(static_cast<Impl*>(baseImpl.get())) { + : Source(makeMutable<Impl>(std::move(id), options)) { } -void GeoJSONSource::setURL(const std::string& url) { - impl->setURL(url); +GeoJSONSource::~GeoJSONSource() = default; + +const GeoJSONSource::Impl& GeoJSONSource::impl() const { + return static_cast<const Impl&>(*baseImpl); +} + +void GeoJSONSource::setURL(const std::string& url_) { + url = std::move(url_); + + // Signal that the source description needs a reload + if (loaded || req) { + loaded = false; + req.reset(); + observer->onSourceDescriptionChanged(*this); + } } void GeoJSONSource::setGeoJSON(const mapbox::geojson::geojson& geoJSON) { - impl->setGeoJSON(geoJSON); + req.reset(); + baseImpl = makeMutable<Impl>(impl(), geoJSON); } optional<std::string> GeoJSONSource::getURL() const { - return impl->getURL(); + return url; +} + +void GeoJSONSource::loadDescription(FileSource& fileSource) { + if (!url) { + loaded = true; + return; + } + + if (req) { + return; + } + + req = fileSource.request(Resource::source(*url), [this](Response res) { + if (res.error) { + observer->onSourceError( + *this, std::make_exception_ptr(std::runtime_error(res.error->message))); + } else if (res.notModified) { + return; + } else if (res.noContent) { + observer->onSourceError( + *this, std::make_exception_ptr(std::runtime_error("unexpectedly empty GeoJSON"))); + } else { + conversion::Error error; + optional<GeoJSON> geoJSON = conversion::convertJSON<GeoJSON>(*res.data, error); + if (!geoJSON) { + Log::Error(Event::ParseStyle, "Failed to parse GeoJSON data: %s", + error.message.c_str()); + // Create an empty GeoJSON VT object to make sure we're not infinitely waiting for + // tiles to load. + baseImpl = makeMutable<Impl>(impl(), GeoJSON{ FeatureCollection{} }); + } else { + baseImpl = makeMutable<Impl>(impl(), *geoJSON); + } + + loaded = true; + observer->onSourceLoaded(*this); + } + }); } } // namespace style diff --git a/src/mbgl/style/sources/geojson_source_impl.cpp b/src/mbgl/style/sources/geojson_source_impl.cpp index 1a686ff9bc..17d05aaa5a 100644 --- a/src/mbgl/style/sources/geojson_source_impl.cpp +++ b/src/mbgl/style/sources/geojson_source_impl.cpp @@ -1,12 +1,6 @@ #include <mbgl/style/sources/geojson_source_impl.hpp> -#include <mbgl/style/conversion/json.hpp> -#include <mbgl/style/conversion/geojson.hpp> -#include <mbgl/style/source_observer.hpp> -#include <mbgl/tile/tile_id.hpp> -#include <mbgl/storage/file_source.hpp> #include <mbgl/renderer/sources/render_geojson_source.hpp> #include <mbgl/util/constants.cpp> -#include <mbgl/util/logging.hpp> #include <mapbox/geojsonvt.hpp> #include <supercluster.hpp> @@ -42,33 +36,14 @@ private: mapbox::supercluster::Supercluster impl; }; -GeoJSONSource::Impl::Impl(std::string id_, Source& base_, const GeoJSONOptions options_) - : Source::Impl(SourceType::GeoJSON, std::move(id_), base_), options(options_) { +GeoJSONSource::Impl::Impl(std::string id_, GeoJSONOptions options_) + : Source::Impl(SourceType::GeoJSON, std::move(id_)), + options(std::move(options_)) { } -GeoJSONSource::Impl::~Impl() = default; - -void GeoJSONSource::Impl::setURL(std::string url_) { - url = std::move(url_); - - // Signal that the source description needs a reload - if (loaded || req) { - loaded = false; - req.reset(); - observer->onSourceDescriptionChanged(base); - } -} - -optional<std::string> GeoJSONSource::Impl::getURL() const { - return url; -} - -void GeoJSONSource::Impl::setGeoJSON(const GeoJSON& geoJSON) { - req.reset(); - _setGeoJSON(geoJSON); -} - -void GeoJSONSource::Impl::_setGeoJSON(const GeoJSON& geoJSON) { +GeoJSONSource::Impl::Impl(const Impl& other, const GeoJSON& geoJSON) + : Source::Impl(other), + options(other.options) { double scale = util::EXTENT / util::tileSize; if (options.cluster @@ -90,47 +65,7 @@ void GeoJSONSource::Impl::_setGeoJSON(const GeoJSON& geoJSON) { } } -void GeoJSONSource::Impl::loadDescription(FileSource& fileSource) { - if (!url) { - loaded = true; - return; - } - - if (req) { - return; - } - - req = fileSource.request(Resource::source(*url), [this](Response res) { - if (res.error) { - observer->onSourceError( - base, std::make_exception_ptr(std::runtime_error(res.error->message))); - } else if (res.notModified) { - return; - } else if (res.noContent) { - observer->onSourceError( - base, std::make_exception_ptr(std::runtime_error("unexpectedly empty GeoJSON"))); - } else { - conversion::Error error; - optional<GeoJSON> geoJSON = conversion::convertJSON<GeoJSON>(*res.data, error); - if (!geoJSON) { - Log::Error(Event::ParseStyle, "Failed to parse GeoJSON data: %s", - error.message.c_str()); - // Create an empty GeoJSON VT object to make sure we're not infinitely waiting for - // tiles to load. - _setGeoJSON(GeoJSON{ FeatureCollection{} }); - } else { - _setGeoJSON(*geoJSON); - } - - loaded = true; - observer->onSourceLoaded(base); - } - }); -} - -std::unique_ptr<RenderSource> GeoJSONSource::Impl::createRenderSource() const { - return std::make_unique<RenderGeoJSONSource>(*this); -} +GeoJSONSource::Impl::~Impl() = default; Range<uint8_t> GeoJSONSource::Impl::getZoomRange() const { return { 0, options.maxzoom }; @@ -140,5 +75,13 @@ GeoJSONData* GeoJSONSource::Impl::getData() const { return data.get(); } +optional<std::string> GeoJSONSource::Impl::getAttribution() const { + return {}; +} + +std::unique_ptr<RenderSource> GeoJSONSource::Impl::createRenderSource() const { + return std::make_unique<RenderGeoJSONSource>(staticImmutableCast<GeoJSONSource::Impl>(immutableFromThis())); +} + } // namespace style } // namespace mbgl diff --git a/src/mbgl/style/sources/geojson_source_impl.hpp b/src/mbgl/style/sources/geojson_source_impl.hpp index e8b881d05e..65580700e7 100644 --- a/src/mbgl/style/sources/geojson_source_impl.hpp +++ b/src/mbgl/style/sources/geojson_source_impl.hpp @@ -2,7 +2,7 @@ #include <mbgl/style/source_impl.hpp> #include <mbgl/style/sources/geojson_source.hpp> -#include <mbgl/util/variant.hpp> +#include <mbgl/util/range.hpp> namespace mbgl { @@ -18,25 +18,18 @@ public: class GeoJSONSource::Impl : public Source::Impl { public: - Impl(std::string id, Source&, const GeoJSONOptions); + Impl(std::string id, GeoJSONOptions); + Impl(const GeoJSONSource::Impl&, const GeoJSON&); ~Impl() final; - void setURL(std::string); - optional<std::string> getURL() const; Range<uint8_t> getZoomRange() const; - - void setGeoJSON(const GeoJSON&); GeoJSONData* getData() const; - void loadDescription(FileSource&) final; + optional<std::string> getAttribution() const final; std::unique_ptr<RenderSource> createRenderSource() const final; private: - void _setGeoJSON(const GeoJSON&); - GeoJSONOptions options; - optional<std::string> url; - std::unique_ptr<AsyncRequest> req; std::unique_ptr<GeoJSONData> data; }; diff --git a/src/mbgl/style/sources/raster_source.cpp b/src/mbgl/style/sources/raster_source.cpp index 94fdbcef12..0a0412a4ed 100644 --- a/src/mbgl/style/sources/raster_source.cpp +++ b/src/mbgl/style/sources/raster_source.cpp @@ -1,21 +1,81 @@ #include <mbgl/style/sources/raster_source.hpp> #include <mbgl/style/sources/raster_source_impl.hpp> +#include <mbgl/style/source_observer.hpp> +#include <mbgl/style/conversion/json.hpp> +#include <mbgl/style/conversion/tileset.hpp> +#include <mbgl/storage/file_source.hpp> +#include <mbgl/util/mapbox.hpp> namespace mbgl { namespace style { -RasterSource::RasterSource(std::string id, variant<std::string, Tileset> urlOrTileset, uint16_t tileSize) - : Source(SourceType::Raster, std::make_unique<RasterSource::Impl>(std::move(id), *this, std::move(urlOrTileset), tileSize)), - impl(static_cast<Impl*>(baseImpl.get())) { +RasterSource::RasterSource(std::string id, variant<std::string, Tileset> urlOrTileset_, uint16_t tileSize) + : Source(makeMutable<Impl>(std::move(id), tileSize)), + urlOrTileset(std::move(urlOrTileset_)) { +} + +RasterSource::~RasterSource() = default; + +const RasterSource::Impl& RasterSource::impl() const { + return static_cast<const Impl&>(*baseImpl); +} + +const variant<std::string, Tileset>& RasterSource::getURLOrTileset() const { + return urlOrTileset; } optional<std::string> RasterSource::getURL() const { - auto urlOrTileset = impl->getURLOrTileset(); - if (urlOrTileset.is<std::string>()) { - return urlOrTileset.get<std::string>(); - } else { + if (urlOrTileset.is<Tileset>()) { return {}; } + + return urlOrTileset.get<std::string>(); +} + +uint16_t RasterSource::getTileSize() const { + return impl().getTileSize(); +} + +void RasterSource::loadDescription(FileSource& fileSource) { + if (urlOrTileset.is<Tileset>()) { + baseImpl = makeMutable<Impl>(impl(), urlOrTileset.get<Tileset>()); + loaded = true; + return; + } + + if (req) { + return; + } + + const std::string& url = urlOrTileset.get<std::string>(); + req = fileSource.request(Resource::source(url), [this, url](Response res) { + if (res.error) { + observer->onSourceError(*this, std::make_exception_ptr(std::runtime_error(res.error->message))); + } else if (res.notModified) { + return; + } else if (res.noContent) { + observer->onSourceError(*this, std::make_exception_ptr(std::runtime_error("unexpectedly empty TileJSON"))); + } else { + conversion::Error error; + optional<Tileset> tileset = conversion::convertJSON<Tileset>(*res.data, error); + if (!tileset) { + observer->onSourceError(*this, std::make_exception_ptr(std::runtime_error(error.message))); + return; + } + + util::mapbox::canonicalizeTileset(*tileset, url, getType(), getTileSize()); + bool changed = impl().getTileset() != *tileset; + + baseImpl = makeMutable<Impl>(impl(), *tileset); + loaded = true; + + observer->onSourceLoaded(*this); + + if (changed) { + observer->onSourceChanged(*this); + } + } + }); } } // namespace style diff --git a/src/mbgl/style/sources/raster_source_impl.cpp b/src/mbgl/style/sources/raster_source_impl.cpp index b85d221f2e..1d684524c7 100644 --- a/src/mbgl/style/sources/raster_source_impl.cpp +++ b/src/mbgl/style/sources/raster_source_impl.cpp @@ -4,14 +4,34 @@ namespace mbgl { namespace style { -RasterSource::Impl::Impl(std::string id_, Source& base_, - variant<std::string, Tileset> urlOrTileset_, - uint16_t tileSize_) - : TileSourceImpl(SourceType::Raster, std::move(id_), base_, std::move(urlOrTileset_), tileSize_) { +RasterSource::Impl::Impl(std::string id_, uint16_t tileSize_) + : Source::Impl(SourceType::Raster, std::move(id_)), + tileSize(tileSize_) { +} + +RasterSource::Impl::Impl(const Impl& other, Tileset tileset_) + : Source::Impl(other), + tileSize(other.tileSize), + tileset(std::move(tileset_)) { +} + +uint16_t RasterSource::Impl::getTileSize() const { + return tileSize; +} + +optional<Tileset> RasterSource::Impl::getTileset() const { + return tileset; +} + +optional<std::string> RasterSource::Impl::getAttribution() const { + if (!tileset) { + return {}; + } + return tileset->attribution; } std::unique_ptr<RenderSource> RasterSource::Impl::createRenderSource() const { - return std::make_unique<RenderRasterSource>(*this); + return std::make_unique<RenderRasterSource>(staticImmutableCast<RasterSource::Impl>(immutableFromThis())); } } // namespace style diff --git a/src/mbgl/style/sources/raster_source_impl.hpp b/src/mbgl/style/sources/raster_source_impl.hpp index 4bc76560f8..0a58953ab7 100644 --- a/src/mbgl/style/sources/raster_source_impl.hpp +++ b/src/mbgl/style/sources/raster_source_impl.hpp @@ -1,16 +1,25 @@ #pragma once #include <mbgl/style/sources/raster_source.hpp> -#include <mbgl/style/tile_source_impl.hpp> +#include <mbgl/style/source_impl.hpp> namespace mbgl { namespace style { -class RasterSource::Impl : public TileSourceImpl { +class RasterSource::Impl : public Source::Impl { public: - Impl(std::string id, Source&, variant<std::string, Tileset>, uint16_t tileSize); + Impl(std::string id, uint16_t tileSize); + Impl(const Impl&, Tileset); + optional<Tileset> getTileset() const; + uint16_t getTileSize() const; + + optional<std::string> getAttribution() const final; std::unique_ptr<RenderSource> createRenderSource() const final; + +private: + uint16_t tileSize; + optional<Tileset> tileset; }; } // namespace style diff --git a/src/mbgl/style/sources/vector_source.cpp b/src/mbgl/style/sources/vector_source.cpp index 4bcd3b8985..ccdd453c75 100644 --- a/src/mbgl/style/sources/vector_source.cpp +++ b/src/mbgl/style/sources/vector_source.cpp @@ -1,21 +1,78 @@ #include <mbgl/style/sources/vector_source.hpp> #include <mbgl/style/sources/vector_source_impl.hpp> +#include <mbgl/style/source_observer.hpp> +#include <mbgl/style/conversion/json.hpp> +#include <mbgl/style/conversion/tileset.hpp> +#include <mbgl/storage/file_source.hpp> +#include <mbgl/util/mapbox.hpp> +#include <mbgl/util/constants.hpp> namespace mbgl { namespace style { -VectorSource::VectorSource(std::string id, variant<std::string, Tileset> urlOrTileset) - : Source(SourceType::Vector, std::make_unique<VectorSource::Impl>(std::move(id), *this, std::move(urlOrTileset))), - impl(static_cast<Impl*>(baseImpl.get())) { +VectorSource::VectorSource(std::string id, variant<std::string, Tileset> urlOrTileset_) + : Source(makeMutable<Impl>(std::move(id))), + urlOrTileset(std::move(urlOrTileset_)) { +} + +VectorSource::~VectorSource() = default; + +const VectorSource::Impl& VectorSource::impl() const { + return static_cast<const Impl&>(*baseImpl); +} + +const variant<std::string, Tileset>& VectorSource::getURLOrTileset() const { + return urlOrTileset; } optional<std::string> VectorSource::getURL() const { - auto urlOrTileset = impl->getURLOrTileset(); - if (urlOrTileset.is<std::string>()) { - return urlOrTileset.get<std::string>(); - } else { + if (urlOrTileset.is<Tileset>()) { return {}; } + + return urlOrTileset.get<std::string>(); +} + +void VectorSource::loadDescription(FileSource& fileSource) { + if (urlOrTileset.is<Tileset>()) { + baseImpl = makeMutable<Impl>(impl(), urlOrTileset.get<Tileset>()); + loaded = true; + return; + } + + if (req) { + return; + } + + const std::string& url = urlOrTileset.get<std::string>(); + req = fileSource.request(Resource::source(url), [this, url](Response res) { + if (res.error) { + observer->onSourceError(*this, std::make_exception_ptr(std::runtime_error(res.error->message))); + } else if (res.notModified) { + return; + } else if (res.noContent) { + observer->onSourceError(*this, std::make_exception_ptr(std::runtime_error("unexpectedly empty TileJSON"))); + } else { + conversion::Error error; + optional<Tileset> tileset = conversion::convertJSON<Tileset>(*res.data, error); + if (!tileset) { + observer->onSourceError(*this, std::make_exception_ptr(std::runtime_error(error.message))); + return; + } + + util::mapbox::canonicalizeTileset(*tileset, url, getType(), util::tileSize); + bool changed = impl().getTileset() != *tileset; + + baseImpl = makeMutable<Impl>(impl(), *tileset); + loaded = true; + + observer->onSourceLoaded(*this); + + if (changed) { + observer->onSourceChanged(*this); + } + } + }); } } // namespace style diff --git a/src/mbgl/style/sources/vector_source_impl.cpp b/src/mbgl/style/sources/vector_source_impl.cpp index 158abf8575..aab62acf3f 100644 --- a/src/mbgl/style/sources/vector_source_impl.cpp +++ b/src/mbgl/style/sources/vector_source_impl.cpp @@ -1,16 +1,31 @@ #include <mbgl/style/sources/vector_source_impl.hpp> #include <mbgl/renderer/sources/render_vector_source.hpp> -#include <mbgl/util/constants.hpp> namespace mbgl { namespace style { -VectorSource::Impl::Impl(std::string id_, Source& base_, variant<std::string, Tileset> urlOrTileset_) - : TileSourceImpl(SourceType::Vector, std::move(id_), base_, std::move(urlOrTileset_), util::tileSize) { +VectorSource::Impl::Impl(std::string id_) + : Source::Impl(SourceType::Vector, std::move(id_)) { +} + +VectorSource::Impl::Impl(const Impl& other, Tileset tileset_) + : Source::Impl(other), + tileset(std::move(tileset_)) { +} + +optional<Tileset> VectorSource::Impl::getTileset() const { + return tileset; +} + +optional<std::string> VectorSource::Impl::getAttribution() const { + if (!tileset) { + return {}; + } + return tileset->attribution; } std::unique_ptr<RenderSource> VectorSource::Impl::createRenderSource() const { - return std::make_unique<RenderVectorSource>(*this); + return std::make_unique<RenderVectorSource>(staticImmutableCast<VectorSource::Impl>(immutableFromThis())); } } // namespace style diff --git a/src/mbgl/style/sources/vector_source_impl.hpp b/src/mbgl/style/sources/vector_source_impl.hpp index 844739948c..602d0e5bbb 100644 --- a/src/mbgl/style/sources/vector_source_impl.hpp +++ b/src/mbgl/style/sources/vector_source_impl.hpp @@ -1,16 +1,23 @@ #pragma once #include <mbgl/style/sources/vector_source.hpp> -#include <mbgl/style/tile_source_impl.hpp> +#include <mbgl/style/source_impl.hpp> namespace mbgl { namespace style { -class VectorSource::Impl : public TileSourceImpl { +class VectorSource::Impl : public Source::Impl { public: - Impl(std::string id, Source&, variant<std::string, Tileset>); + Impl(std::string id); + Impl(const Impl&, Tileset); + optional<Tileset> getTileset() const; + + optional<std::string> getAttribution() const final; std::unique_ptr<RenderSource> createRenderSource() const final; + +private: + optional<Tileset> tileset; }; } // namespace style |