diff options
author | Konstantin Käfer <mail@kkaefer.com> | 2016-05-20 16:12:22 +0200 |
---|---|---|
committer | Konstantin Käfer <mail@kkaefer.com> | 2016-06-10 12:42:14 +0200 |
commit | 2b6d0751cf3495c9246af27fdff6f565186bb2f8 (patch) | |
tree | 8c21aea06e2bd19c37b01156ea882038069b85dc /src/mbgl | |
parent | 6b729ccb4680e41fd6346aeb5a5e55027ca49052 (diff) | |
download | qtlocation-mapboxgl-2b6d0751cf3495c9246af27fdff6f565186bb2f8.tar.gz |
[core] restructure TileSource construction and callbacks
Diffstat (limited to 'src/mbgl')
-rw-r--r-- | src/mbgl/style/source.cpp | 46 | ||||
-rw-r--r-- | src/mbgl/tile/annotation_tile_source.cpp | 18 | ||||
-rw-r--r-- | src/mbgl/tile/annotation_tile_source.hpp | 5 | ||||
-rw-r--r-- | src/mbgl/tile/geojson_tile_source.cpp | 16 | ||||
-rw-r--r-- | src/mbgl/tile/geojson_tile_source.hpp | 5 | ||||
-rw-r--r-- | src/mbgl/tile/geometry_tile_data.cpp | 136 | ||||
-rw-r--r-- | src/mbgl/tile/geometry_tile_data.hpp | 20 | ||||
-rw-r--r-- | src/mbgl/tile/image_tile_source.cpp | 25 | ||||
-rw-r--r-- | src/mbgl/tile/image_tile_source.hpp | 23 | ||||
-rw-r--r-- | src/mbgl/tile/raster_tile_data.cpp | 72 | ||||
-rw-r--r-- | src/mbgl/tile/raster_tile_data.hpp | 9 | ||||
-rw-r--r-- | src/mbgl/tile/raster_tile_source.cpp | 25 | ||||
-rw-r--r-- | src/mbgl/tile/raster_tile_source.hpp | 36 | ||||
-rw-r--r-- | src/mbgl/tile/tile_data.cpp | 10 | ||||
-rw-r--r-- | src/mbgl/tile/tile_data.hpp | 10 | ||||
-rw-r--r-- | src/mbgl/tile/tile_source.cpp | 7 | ||||
-rw-r--r-- | src/mbgl/tile/tile_source.hpp | 40 | ||||
-rw-r--r-- | src/mbgl/tile/vector_tile_source.cpp | 21 | ||||
-rw-r--r-- | src/mbgl/tile/vector_tile_source.hpp | 6 |
19 files changed, 264 insertions, 266 deletions
diff --git a/src/mbgl/style/source.cpp b/src/mbgl/style/source.cpp index 1b5ae05f50..51e6334440 100644 --- a/src/mbgl/style/source.cpp +++ b/src/mbgl/style/source.cpp @@ -25,7 +25,7 @@ #include <mbgl/tile/vector_tile_source.hpp> #include <mbgl/tile/geojson_tile_source.hpp> #include <mbgl/tile/annotation_tile_source.hpp> -#include <mbgl/tile/raster_tile_source.hpp> +#include <mbgl/tile/image_tile_source.hpp> #include <mbgl/tile/geometry_tile_data.hpp> #include <mbgl/tile/raster_tile_data.hpp> @@ -193,8 +193,7 @@ const std::map<UnwrappedTileID, Tile>& Source::getTiles() const { std::unique_ptr<TileData> Source::createTile(const OverscaledTileID& overscaledTileID, const UpdateParameters& parameters) { - std::unique_ptr<TileData> data = cache.get(overscaledTileID); - if (data) { + if (auto data = cache.get(overscaledTileID)) { return data; } @@ -207,33 +206,40 @@ std::unique_ptr<TileData> Source::createTile(const OverscaledTileID& overscaledT const auto resource = Resource::tile( tileset->tiles.at(0), parameters.pixelRatio, overscaledTileID.canonical.x, overscaledTileID.canonical.y, overscaledTileID.canonical.z); - auto monitor = std::make_unique<RasterTileSource>(resource, parameters.fileSource); - data = - std::make_unique<RasterTileData>(overscaledTileID, std::move(monitor), - parameters.texturePool, parameters.worker, callback); + auto data = std::make_unique<RasterTileData>(overscaledTileID, parameters.texturePool, + parameters.worker, callback); + data->setTileSource( + std::make_unique<ImageTileSource>(*data, resource, parameters.fileSource)); + + // Need a std::move here to create a std::unique_ptr<TileData> from + // std::unique_ptr<GeometryTileData>. + return std::move(data); } else { - std::unique_ptr<GeometryTileSource> monitor; - + auto data = std::make_unique<GeometryTileData>(overscaledTileID, id, parameters.style, + parameters.mode, callback); if (type == SourceType::Vector) { assert(!tileset->tiles.empty()); const auto resource = Resource::tile( tileset->tiles.at(0), parameters.pixelRatio, overscaledTileID.canonical.x, overscaledTileID.canonical.y, overscaledTileID.canonical.z); - monitor = std::make_unique<VectorTileSource>(resource, parameters.fileSource); + data->setTileSource( + std::make_unique<VectorTileSource>(*data, resource, parameters.fileSource)); } else if (type == SourceType::Annotations) { - monitor = std::make_unique<AnnotationTileSource>(overscaledTileID, parameters.annotationManager); + data->setTileSource(std::make_unique<AnnotationTileSource>( + *data, overscaledTileID, parameters.annotationManager)); } else if (type == SourceType::GeoJSON) { - monitor = std::make_unique<GeoJSONTileSource>(geojsonvt.get(), overscaledTileID); + data->setTileSource( + std::make_unique<GeoJSONTileSource>(*data, geojsonvt.get(), overscaledTileID)); } else { - Log::Warning(Event::Style, "Source type '%s' is not implemented", SourceTypeClass(type).c_str()); + Log::Warning(Event::Style, "Source type '%s' is not implemented", + SourceTypeClass(type).c_str()); return nullptr; } - data = std::make_unique<GeometryTileData>(overscaledTileID, std::move(monitor), id, - parameters.style, parameters.mode, callback); + // Need a std::move here to create a std::unique_ptr<TileData> from + // std::unique_ptr<GeometryTileData>. + return std::move(data); } - - return data; } TileData* Source::getTileData(const OverscaledTileID& overscaledTileID) const { @@ -322,13 +328,9 @@ bool Source::update(const UpdateParameters& parameters) { } for (auto& pair : tileDataMap) { - const auto& dataTileID = pair.first; auto tileData = pair.second.get(); if (parameters.shouldReparsePartialTiles && tileData->isIncomplete()) { - auto callback = std::bind(&Source::tileLoadingCallback, this, dataTileID, - std::placeholders::_1, false); - - if (!tileData->parsePending(callback)) { + if (!tileData->parsePending()) { allTilesUpdated = false; } } else { diff --git a/src/mbgl/tile/annotation_tile_source.cpp b/src/mbgl/tile/annotation_tile_source.cpp index a89b62f66f..143bcc23f5 100644 --- a/src/mbgl/tile/annotation_tile_source.cpp +++ b/src/mbgl/tile/annotation_tile_source.cpp @@ -1,28 +1,24 @@ #include <mbgl/tile/annotation_tile_source.hpp> #include <mbgl/tile/geometry_tile.hpp> +#include <mbgl/tile/geometry_tile_data.hpp> #include <mbgl/annotation/annotation_manager.hpp> #include <mbgl/util/async_request.hpp> namespace mbgl { -AnnotationTileSource::AnnotationTileSource(const OverscaledTileID& tileID_, - AnnotationManager& annotationManager_) - : tileID(tileID_), annotationManager(annotationManager_) { +AnnotationTileSource::AnnotationTileSource(GeometryTileData& tileData_, + const OverscaledTileID& tileID_, + AnnotationManager& annotationManager_) + : GeometryTileSource(tileData_), tileID(tileID_), annotationManager(annotationManager_) { + annotationManager.addTileSource(*this); } AnnotationTileSource::~AnnotationTileSource() { annotationManager.removeTileSource(*this); } -std::unique_ptr<AsyncRequest> -AnnotationTileSource::monitorTile(const GeometryTileSource::Callback& callback_) { - callback = callback_; - annotationManager.addTileSource(*this); - return nullptr; -} - void AnnotationTileSource::update(std::unique_ptr<GeometryTile> tile) { - callback(nullptr, std::move(tile), {}, {}); + tileData.setData(nullptr, std::move(tile), {}, {}); } } // namespace mbgl diff --git a/src/mbgl/tile/annotation_tile_source.hpp b/src/mbgl/tile/annotation_tile_source.hpp index 8626791e1a..8d7a1d8a1f 100644 --- a/src/mbgl/tile/annotation_tile_source.hpp +++ b/src/mbgl/tile/annotation_tile_source.hpp @@ -8,20 +8,19 @@ namespace mbgl { class AnnotationManager; +class GeometryTile; class AnnotationTileSource : public GeometryTileSource { public: - AnnotationTileSource(const OverscaledTileID&, AnnotationManager&); + AnnotationTileSource(GeometryTileData&, const OverscaledTileID&, AnnotationManager&); ~AnnotationTileSource(); void update(std::unique_ptr<GeometryTile>); - std::unique_ptr<AsyncRequest> monitorTile(const GeometryTileSource::Callback&) override; OverscaledTileID tileID; private: AnnotationManager& annotationManager; - GeometryTileSource::Callback callback; }; } // namespace mbgl diff --git a/src/mbgl/tile/geojson_tile_source.cpp b/src/mbgl/tile/geojson_tile_source.cpp index 824df4bd49..3daf7cd02e 100644 --- a/src/mbgl/tile/geojson_tile_source.cpp +++ b/src/mbgl/tile/geojson_tile_source.cpp @@ -1,5 +1,6 @@ #include <mbgl/tile/geojson_tile_source.hpp> #include <mbgl/tile/geojson_tile.hpp> +#include <mbgl/tile/geometry_tile_data.hpp> #include <mbgl/util/async_request.hpp> @@ -7,9 +8,11 @@ namespace mbgl { -GeoJSONTileSource::GeoJSONTileSource(mapbox::geojsonvt::GeoJSONVT* geojsonvt_, +GeoJSONTileSource::GeoJSONTileSource(GeometryTileData& tileData_, + mapbox::geojsonvt::GeoJSONVT* geojsonvt_, const OverscaledTileID& id) - : tileID(id), geojsonvt(geojsonvt_) { + : GeometryTileSource(tileData_), tileID(id), geojsonvt(geojsonvt_) { + update(); } GeoJSONTileSource::~GeoJSONTileSource() = default; @@ -89,15 +92,8 @@ void GeoJSONTileSource::update() { if (geojsonvt) { auto tile = convertTile( geojsonvt->getTile(tileID.canonical.z, tileID.canonical.x, tileID.canonical.y)); - callback(nullptr, std::move(tile), {}, {}); + tileData.setData(nullptr, std::move(tile), {}, {}); } } -std::unique_ptr<AsyncRequest> -GeoJSONTileSource::monitorTile(const GeometryTileSource::Callback& cb) { - callback = cb; - update(); - return nullptr; -} - } // namespace mbgl diff --git a/src/mbgl/tile/geojson_tile_source.hpp b/src/mbgl/tile/geojson_tile_source.hpp index d37f3cf617..bfa5f87252 100644 --- a/src/mbgl/tile/geojson_tile_source.hpp +++ b/src/mbgl/tile/geojson_tile_source.hpp @@ -16,11 +16,9 @@ namespace mbgl { class GeoJSONTileSource : public GeometryTileSource { public: - GeoJSONTileSource(mapbox::geojsonvt::GeoJSONVT*, const OverscaledTileID&); + GeoJSONTileSource(GeometryTileData&, mapbox::geojsonvt::GeoJSONVT*, const OverscaledTileID&); virtual ~GeoJSONTileSource(); - std::unique_ptr<AsyncRequest> monitorTile(const GeometryTileSource::Callback&) override; - void setGeoJSONVT(mapbox::geojsonvt::GeoJSONVT*); private: @@ -31,7 +29,6 @@ public: private: mapbox::geojsonvt::GeoJSONVT* geojsonvt = nullptr; - GeometryTileSource::Callback callback; }; } // namespace mbgl diff --git a/src/mbgl/tile/geometry_tile_data.cpp b/src/mbgl/tile/geometry_tile_data.cpp index 8797976ed1..9e813a8633 100644 --- a/src/mbgl/tile/geometry_tile_data.cpp +++ b/src/mbgl/tile/geometry_tile_data.cpp @@ -13,12 +13,11 @@ namespace mbgl { GeometryTileData::GeometryTileData(const OverscaledTileID& id_, - std::unique_ptr<GeometryTileSource> tileSource_, std::string sourceID, style::Style& style_, const MapMode mode_, - const std::function<void(std::exception_ptr)>& callback) - : TileData(id_, std::move(tileSource_)), + const std::function<void(std::exception_ptr)>& callback_) + : TileData(id_), style(style_), worker(style_.workers), tileWorker(id_, @@ -27,69 +26,68 @@ GeometryTileData::GeometryTileData(const OverscaledTileID& id_, *style_.glyphAtlas, *style_.glyphStore, obsolete, - mode_) { - auto geometryTileSource = reinterpret_cast<GeometryTileSource*>(tileSource.get()); - tileRequest = geometryTileSource->monitorTile([callback, this](std::exception_ptr err, - std::unique_ptr<GeometryTile> tile, - optional<Timestamp> modified_, - optional<Timestamp> expires_) { - if (err) { - callback(err); - return; - } + mode_), + callback(callback_) { +} - modified = modified_; - expires = expires_; +void GeometryTileData::setData(std::exception_ptr err, + std::unique_ptr<GeometryTile> tile, + optional<Timestamp> modified_, + optional<Timestamp> expires_) { + if (err) { + callback(err); + return; + } - if (!tile) { - // This is a 404 response. We're treating these as empty tiles. - workRequest.reset(); - availableData = DataAvailability::All; - buckets.clear(); - callback(err); - return; - } + modified = modified_; + expires = expires_; - // Mark the tile as pending again if it was complete before to prevent signaling a complete - // state despite pending parse operations. - if (availableData == DataAvailability::All) { - availableData = DataAvailability::Some; - } + if (!tile) { + // This is a 404 response. We're treating these as empty tiles. + workRequest.reset(); + availableData = DataAvailability::All; + buckets.clear(); + callback(err); + return; + } - // Kick off a fresh parse of this tile. This happens when the tile is new, or - // when tile data changed. Replacing the workdRequest will cancel a pending work - // request in case there is one. + // Mark the tile as pending again if it was complete before to prevent signaling a complete + // state despite pending parse operations. + if (availableData == DataAvailability::All) { + availableData = DataAvailability::Some; + } + + // Kick off a fresh parse of this tile. This happens when the tile is new, or + // when tile data changed. Replacing the workdRequest will cancel a pending work + // request in case there is one. + workRequest.reset(); + workRequest = worker.parseGeometryTile(tileWorker, style.getLayers(), std::move(tile), targetConfig, [this, config = targetConfig] (TileParseResult result) { workRequest.reset(); - workRequest = worker.parseGeometryTile(tileWorker, style.getLayers(), std::move(tile), targetConfig, [callback, this, config = targetConfig] (TileParseResult result) { - workRequest.reset(); - - std::exception_ptr error; - if (result.is<TileParseResultData>()) { - auto& resultBuckets = result.get<TileParseResultData>(); - availableData = - resultBuckets.complete ? DataAvailability::All : DataAvailability::Some; - - // Persist the configuration we just placed so that we can later check whether we need to - // place again in case the configuration has changed. - placedConfig = config; - - // Move over all buckets we received in this parse request, potentially overwriting - // existing buckets in case we got a refresh parse. - buckets = std::move(resultBuckets.buckets); - - if (isComplete()) { - featureIndex = std::move(resultBuckets.featureIndex); - geometryTile = std::move(resultBuckets.geometryTile); - } - - } else { - // This is triggered when parsing fails (e.g. due to an invalid vector tile) - error = result.get<std::exception_ptr>(); - availableData = DataAvailability::All; + + std::exception_ptr error; + if (result.is<TileParseResultData>()) { + auto& resultBuckets = result.get<TileParseResultData>(); + availableData = resultBuckets.complete ? DataAvailability::All : DataAvailability::Some; + + // Persist the configuration we just placed so that we can later check whether we need to + // place again in case the configuration has changed. + placedConfig = config; + + // Move over all buckets we received in this parse request, potentially overwriting + // existing buckets in case we got a refresh parse. + buckets = std::move(resultBuckets.buckets); + + if (isComplete()) { + featureIndex = std::move(resultBuckets.featureIndex); + geometryTile = std::move(resultBuckets.geometryTile); } - callback(error); - }); + } else { + error = result.get<std::exception_ptr>(); + availableData = DataAvailability::All; + } + + callback(error); }); } @@ -97,21 +95,20 @@ GeometryTileData::~GeometryTileData() { cancel(); } -bool GeometryTileData::parsePending(std::function<void(std::exception_ptr)> callback) { +bool GeometryTileData::parsePending() { if (workRequest) { // There's already parsing or placement going on. return false; } workRequest.reset(); - workRequest = worker.parsePendingGeometryTileLayers(tileWorker, targetConfig, [this, callback, config = targetConfig] (TileParseResult result) { + workRequest = worker.parsePendingGeometryTileLayers(tileWorker, targetConfig, [this, config = targetConfig] (TileParseResult result) { workRequest.reset(); std::exception_ptr error; if (result.is<TileParseResultData>()) { auto& resultBuckets = result.get<TileParseResultData>(); - availableData = - resultBuckets.complete ? DataAvailability::All : DataAvailability::Some; + availableData = resultBuckets.complete ? DataAvailability::All : DataAvailability::Some; // Move over all buckets we received in this parse request, potentially overwriting // existing buckets in case we got a refresh parse. @@ -149,20 +146,20 @@ Bucket* GeometryTileData::getBucket(const style::Layer& layer) { return it->second.get(); } -void GeometryTileData::redoPlacement(const PlacementConfig newConfig, const std::function<void()>& callback) { +void GeometryTileData::redoPlacement(const PlacementConfig newConfig, const std::function<void()>& cb) { if (newConfig != placedConfig) { targetConfig = newConfig; - redoPlacement(callback); + redoPlacement(cb); } } -void GeometryTileData::redoPlacement(const std::function<void()>& callback) { +void GeometryTileData::redoPlacement(const std::function<void()>& cb) { // Don't start a new placement request when the current one hasn't completed yet, or when // we are parsing buckets. if (workRequest) return; - workRequest = worker.redoPlacement(tileWorker, buckets, targetConfig, [this, callback, config = targetConfig](std::unique_ptr<CollisionTile> collisionTile) { + workRequest = worker.redoPlacement(tileWorker, buckets, targetConfig, [this, cb, config = targetConfig](std::unique_ptr<CollisionTile> collisionTile) { workRequest.reset(); // Persist the configuration we just placed so that we can later check whether we need to @@ -180,9 +177,9 @@ void GeometryTileData::redoPlacement(const std::function<void()>& callback) { // The target configuration could have changed since we started placement. In this case, // we're starting another placement run. if (placedConfig != targetConfig) { - redoPlacement(callback); + redoPlacement(cb); } else { - callback(); + cb(); } }); } @@ -208,7 +205,6 @@ void GeometryTileData::queryRenderedFeatures( void GeometryTileData::cancel() { obsolete = true; - tileRequest.reset(); workRequest.reset(); } diff --git a/src/mbgl/tile/geometry_tile_data.hpp b/src/mbgl/tile/geometry_tile_data.hpp index 00d919a8a6..8a16a32958 100644 --- a/src/mbgl/tile/geometry_tile_data.hpp +++ b/src/mbgl/tile/geometry_tile_data.hpp @@ -12,6 +12,7 @@ namespace mbgl { class AsyncRequest; +class GeometryTile; class GeometryTileSource; class FeatureIndex; @@ -22,17 +23,21 @@ class Style; class GeometryTileData : public TileData { public: GeometryTileData(const OverscaledTileID&, - std::unique_ptr<GeometryTileSource> tileSource, - std::string sourceID, - style::Style&, - const MapMode, - const std::function<void(std::exception_ptr)>& callback); + std::string sourceID, + style::Style&, + const MapMode, + const std::function<void(std::exception_ptr)>& callback); ~GeometryTileData(); + void setData(std::exception_ptr err, + std::unique_ptr<GeometryTile> tile, + optional<Timestamp> modified_, + optional<Timestamp> expires_); + Bucket* getBucket(const style::Layer&) override; - bool parsePending(std::function<void(std::exception_ptr)> callback) override; + bool parsePending() override; void redoPlacement(PlacementConfig config, const std::function<void()>&) override; void redoPlacement(const std::function<void()>&) override; @@ -50,7 +55,6 @@ private: Worker& worker; TileWorker tileWorker; - std::unique_ptr<AsyncRequest> tileRequest; std::unique_ptr<AsyncRequest> workRequest; // Contains all the Bucket objects for the tile. Buckets are render @@ -69,6 +73,8 @@ private: // Used to signal the worker that it should abandon parsing this tile as soon as possible. util::Atomic<bool> obsolete { false }; + + const std::function<void(std::exception_ptr)> callback; }; } // namespace mbgl diff --git a/src/mbgl/tile/image_tile_source.cpp b/src/mbgl/tile/image_tile_source.cpp new file mode 100644 index 0000000000..e552c0e315 --- /dev/null +++ b/src/mbgl/tile/image_tile_source.cpp @@ -0,0 +1,25 @@ +#include <mbgl/tile/image_tile_source.hpp> +#include <mbgl/tile/raster_tile_data.hpp> +#include <mbgl/storage/file_source.hpp> + +namespace mbgl { + +ImageTileSource::ImageTileSource(RasterTileData& tileData_, + const Resource& resource_, + FileSource& fileSource_) + : RasterTileSource(tileData_), resource(resource_), fileSource(fileSource_) { + request = fileSource.request(resource, [this](Response res) { + if (res.error) { + tileData.setData(std::make_exception_ptr(std::runtime_error(res.error->message)), + nullptr, res.modified, res.expires); + } else if (res.notModified) { + return; + } else if (res.noContent) { + tileData.setData(nullptr, nullptr, res.modified, res.expires); + } else { + tileData.setData(nullptr, res.data, res.modified, res.expires); + } + }); +} + +} // namespace mbgl diff --git a/src/mbgl/tile/image_tile_source.hpp b/src/mbgl/tile/image_tile_source.hpp new file mode 100644 index 0000000000..8b4e9c0980 --- /dev/null +++ b/src/mbgl/tile/image_tile_source.hpp @@ -0,0 +1,23 @@ +#pragma once + +#include <mbgl/tile/tile_source.hpp> +#include <mbgl/tile/tile_id.hpp> +#include <mbgl/storage/resource.hpp> + +namespace mbgl { + +class FileSource; +class AsyncRequest; + +class ImageTileSource : public RasterTileSource { +public: + ImageTileSource(RasterTileData&, const Resource&, FileSource&); + virtual ~ImageTileSource() = default; + +private: + const Resource resource; + FileSource& fileSource; + std::unique_ptr<AsyncRequest> request; +}; + +} // namespace mbgl diff --git a/src/mbgl/tile/raster_tile_data.cpp b/src/mbgl/tile/raster_tile_data.cpp index 1a5b78d7ff..5e1948101b 100644 --- a/src/mbgl/tile/raster_tile_data.cpp +++ b/src/mbgl/tile/raster_tile_data.cpp @@ -1,6 +1,5 @@ #include <mbgl/tile/raster_tile_data.hpp> #include <mbgl/style/source.hpp> -#include <mbgl/tile/raster_tile_source.hpp> #include <mbgl/storage/resource.hpp> #include <mbgl/storage/response.hpp> #include <mbgl/storage/file_source.hpp> @@ -10,51 +9,51 @@ using namespace mbgl; RasterTileData::RasterTileData(const OverscaledTileID& id_, - std::unique_ptr<RasterTileSource> tileSource_, gl::TexturePool& texturePool_, Worker& worker_, - const std::function<void(std::exception_ptr)>& callback) - : TileData(id_, std::move(tileSource_)), + const std::function<void(std::exception_ptr)>& callback_) + : TileData(id_), texturePool(texturePool_), - worker(worker_) { - auto rasterTileSource = reinterpret_cast<RasterTileSource*>(tileSource.get()); - tileRequest = rasterTileSource->monitorTile([callback, this](std::exception_ptr err, - std::shared_ptr<const std::string> data, - optional<Timestamp> modified_, - optional<Timestamp> expires_) { - if (err) { - callback(err); - return; - } + worker(worker_), + callback(callback_) { +} - modified = modified_; - expires = expires_; +void RasterTileData::setData(std::exception_ptr err, + std::shared_ptr<const std::string> data, + optional<Timestamp> modified_, + optional<Timestamp> expires_) { + if (err) { + callback(err); + return; + } - if (!data) { - // This is a 404 response. We're treating these as empty tiles. - workRequest.reset(); - availableData = DataAvailability::All; - bucket.reset(); - callback(err); - return; - } + modified = modified_; + expires = expires_; + if (!data) { + // This is a 404 response. We're treating these as empty tiles. workRequest.reset(); - workRequest = worker.parseRasterTile(std::make_unique<RasterBucket>(texturePool), data, [this, callback] (RasterTileParseResult result) { - workRequest.reset(); + availableData = DataAvailability::All; + bucket.reset(); + callback(err); + return; + } - std::exception_ptr error; - if (result.is<std::unique_ptr<Bucket>>()) { - bucket = std::move(result.get<std::unique_ptr<Bucket>>()); - } else { - error = result.get<std::exception_ptr>(); - bucket.reset(); - } + workRequest.reset(); + workRequest = worker.parseRasterTile(std::make_unique<RasterBucket>(texturePool), data, [this] (RasterTileParseResult result) { + workRequest.reset(); + + std::exception_ptr error; + if (result.is<std::unique_ptr<Bucket>>()) { + bucket = std::move(result.get<std::unique_ptr<Bucket>>()); + } else { + error = result.get<std::exception_ptr>(); + bucket.reset(); + } - availableData = DataAvailability::All; + availableData = DataAvailability::All; - callback(error); - }); + callback(error); }); } @@ -67,6 +66,5 @@ Bucket* RasterTileData::getBucket(const style::Layer&) { } void RasterTileData::cancel() { - tileRequest.reset(); workRequest.reset(); } diff --git a/src/mbgl/tile/raster_tile_data.hpp b/src/mbgl/tile/raster_tile_data.hpp index 5c522e6c75..9480292131 100644 --- a/src/mbgl/tile/raster_tile_data.hpp +++ b/src/mbgl/tile/raster_tile_data.hpp @@ -17,12 +17,16 @@ class Layer; class RasterTileData : public TileData { public: RasterTileData(const OverscaledTileID&, - std::unique_ptr<RasterTileSource>, gl::TexturePool&, Worker&, const std::function<void(std::exception_ptr)>& callback); ~RasterTileData(); + void setData(std::exception_ptr err, + std::shared_ptr<const std::string> data, + optional<Timestamp> modified_, + optional<Timestamp> expires_); + void cancel() override; Bucket* getBucket(const style::Layer&) override; @@ -30,12 +34,13 @@ private: gl::TexturePool& texturePool; Worker& worker; - std::unique_ptr<AsyncRequest> tileRequest; std::unique_ptr<AsyncRequest> workRequest; // Contains the Bucket object for the tile. Buckets are render // objects and they get added by tile parsing operations. std::unique_ptr<Bucket> bucket; + + const std::function<void(std::exception_ptr)> callback; }; } // namespace mbgl diff --git a/src/mbgl/tile/raster_tile_source.cpp b/src/mbgl/tile/raster_tile_source.cpp deleted file mode 100644 index 8d07bad07a..0000000000 --- a/src/mbgl/tile/raster_tile_source.cpp +++ /dev/null @@ -1,25 +0,0 @@ -#include <mbgl/tile/raster_tile_source.hpp> -#include <mbgl/storage/file_source.hpp> - -namespace mbgl { - -RasterTileSource::RasterTileSource(const Resource& resource_, FileSource& fileSource_) - : resource(resource_), fileSource(fileSource_) { -} - -std::unique_ptr<AsyncRequest> RasterTileSource::monitorTile(const Callback& callback) { - return fileSource.request(resource, [callback, this](Response res) { - if (res.error) { - callback(std::make_exception_ptr(std::runtime_error(res.error->message)), nullptr, - res.modified, res.expires); - } else if (res.notModified) { - return; - } else if (res.noContent) { - callback(nullptr, nullptr, res.modified, res.expires); - } else { - callback(nullptr, res.data, res.modified, res.expires); - } - }); -} - -} // namespace mbgl diff --git a/src/mbgl/tile/raster_tile_source.hpp b/src/mbgl/tile/raster_tile_source.hpp deleted file mode 100644 index 800f31fefb..0000000000 --- a/src/mbgl/tile/raster_tile_source.hpp +++ /dev/null @@ -1,36 +0,0 @@ -#pragma once - -#include <mbgl/tile/tile_source.hpp> -#include <mbgl/tile/tile_id.hpp> -#include <mbgl/storage/resource.hpp> - -namespace mbgl { - -class FileSource; - -class RasterTileSource : public TileSource { -public: - RasterTileSource(const Resource&, FileSource&); - virtual ~RasterTileSource() = default; - - using Callback = std::function<void(std::exception_ptr, - std::shared_ptr<const std::string>, - optional<Timestamp> modified, - optional<Timestamp> expires)>; - - /* - * Monitor the tile held by this object for changes. When the tile is loaded for the first time, - * or updates, the callback is executed. If an error occurs, the first parameter will be set. - * Otherwise it will be null. If there is no data for the requested tile, the second parameter - * will be null. - * - * To cease monitoring, release the returned Request. - */ - std::unique_ptr<AsyncRequest> monitorTile(const Callback&); - -private: - const Resource resource; - FileSource& fileSource; -}; - -} // namespace mbgl diff --git a/src/mbgl/tile/tile_data.cpp b/src/mbgl/tile/tile_data.cpp index 9214bf98ee..34866c84ca 100644 --- a/src/mbgl/tile/tile_data.cpp +++ b/src/mbgl/tile/tile_data.cpp @@ -5,12 +5,18 @@ namespace mbgl { -TileData::TileData(const OverscaledTileID& id_, std::unique_ptr<TileSource> tileSource_) - : id(id_), tileSource(std::move(tileSource_)) { +TileData::TileData(const OverscaledTileID& id_) + : id(id_) { } TileData::~TileData() = default; +void TileData::setTileSource(std::unique_ptr<TileSource> tileSource_) { + assert(!tileSource); + assert(tileSource_); + tileSource = std::move(tileSource_); +} + void TileData::dumpDebugLogs() const { Log::Info(Event::General, "TileData::id: %s", util::toString(id).c_str()); Log::Info(Event::General, "TileData::renderable: %s", isRenderable() ? "yes" : "no"); diff --git a/src/mbgl/tile/tile_data.hpp b/src/mbgl/tile/tile_data.hpp index d5b178fd24..c7b878879d 100644 --- a/src/mbgl/tile/tile_data.hpp +++ b/src/mbgl/tile/tile_data.hpp @@ -27,15 +27,17 @@ class Layer; class TileData : private util::noncopyable { public: - TileData(const OverscaledTileID&, std::unique_ptr<TileSource>); + TileData(const OverscaledTileID&); virtual ~TileData(); + void setTileSource(std::unique_ptr<TileSource>); + // Mark this tile as no longer needed and cancel any pending work. virtual void cancel() = 0; virtual Bucket* getBucket(const style::Layer&) = 0; - virtual bool parsePending(std::function<void (std::exception_ptr)>) { return true; } + virtual bool parsePending() { return true; } virtual void redoPlacement(PlacementConfig, const std::function<void()>&) {} virtual void redoPlacement(const std::function<void()>&) {} @@ -59,12 +61,12 @@ public: return availableData == DataAvailability::Some; } + void dumpDebugLogs() const; const OverscaledTileID id; optional<Timestamp> modified; optional<Timestamp> expires; - const std::unique_ptr<TileSource> tileSource; // Contains the tile ID string for painting debug information. std::unique_ptr<DebugBucket> debugBucket; @@ -84,6 +86,8 @@ protected: }; DataAvailability availableData = DataAvailability::None; + + std::unique_ptr<TileSource> tileSource; }; } // namespace mbgl diff --git a/src/mbgl/tile/tile_source.cpp b/src/mbgl/tile/tile_source.cpp index e69de29bb2..c45da0c779 100644 --- a/src/mbgl/tile/tile_source.cpp +++ b/src/mbgl/tile/tile_source.cpp @@ -0,0 +1,7 @@ +#include <mbgl/tile/tile_source.hpp> + +#include <cassert> + +namespace mbgl { + +} // namespace mbgl diff --git a/src/mbgl/tile/tile_source.hpp b/src/mbgl/tile/tile_source.hpp index 52601e9b5e..294ddd0d6b 100644 --- a/src/mbgl/tile/tile_source.hpp +++ b/src/mbgl/tile/tile_source.hpp @@ -1,39 +1,37 @@ #pragma once #include <mbgl/util/noncopyable.hpp> -#include <mbgl/util/optional.hpp> -#include <mbgl/util/chrono.hpp> - -#include <memory> -#include <functional> namespace mbgl { -class GeometryTile; -class AsyncRequest; - class TileSource : private util::noncopyable { public: virtual ~TileSource() = default; }; +class GeometryTileData; +class RasterTileData; + class GeometryTileSource : public TileSource { +protected: + GeometryTileSource(GeometryTileData& tileData_) : tileData(tileData_) {} + public: virtual ~GeometryTileSource() = default; - using Callback = std::function<void (std::exception_ptr, - std::unique_ptr<GeometryTile>, - optional<Timestamp> modified, - optional<Timestamp> expires)>; - /* - * Monitor the tile held by this object for changes. When the tile is loaded for the first time, - * or updates, the callback is executed. If an error occurs, the first parameter will be set. - * Otherwise it will be null. If there is no data for the requested tile, the second parameter - * will be null. - * - * To cease monitoring, release the returned Request. - */ - virtual std::unique_ptr<AsyncRequest> monitorTile(const Callback&) = 0; +protected: + GeometryTileData& tileData; +}; + +class RasterTileSource : public TileSource { +protected: + RasterTileSource(RasterTileData& tileData_) : tileData(tileData_) {}; + +public: + virtual ~RasterTileSource() = default; + +protected: + RasterTileData& tileData; }; } // namespace mbgl diff --git a/src/mbgl/tile/vector_tile_source.cpp b/src/mbgl/tile/vector_tile_source.cpp index cfff47f598..2ee0827b14 100644 --- a/src/mbgl/tile/vector_tile_source.cpp +++ b/src/mbgl/tile/vector_tile_source.cpp @@ -1,24 +1,25 @@ #include <mbgl/tile/vector_tile_source.hpp> #include <mbgl/tile/vector_tile.hpp> +#include <mbgl/tile/geometry_tile_data.hpp> #include <mbgl/storage/file_source.hpp> namespace mbgl { -VectorTileSource::VectorTileSource(const Resource& resource_, FileSource& fileSource_) - : resource(resource_), fileSource(fileSource_) { -} - -std::unique_ptr<AsyncRequest> VectorTileSource::monitorTile(const Callback& callback) { - return fileSource.request(resource, [callback, this](Response res) { +VectorTileSource::VectorTileSource(GeometryTileData& tileData_, + const Resource& resource_, + FileSource& fileSource_) + : GeometryTileSource(tileData_), resource(resource_), fileSource(fileSource_) { + request = fileSource.request(resource, [this](Response res) { if (res.error) { - callback(std::make_exception_ptr(std::runtime_error(res.error->message)), nullptr, - res.modified, res.expires); + tileData.setData(std::make_exception_ptr(std::runtime_error(res.error->message)), + nullptr, res.modified, res.expires); } else if (res.notModified) { return; } else if (res.noContent) { - callback(nullptr, nullptr, res.modified, res.expires); + tileData.setData(nullptr, nullptr, res.modified, res.expires); } else { - callback(nullptr, std::make_unique<VectorTile>(res.data), res.modified, res.expires); + tileData.setData(nullptr, std::make_unique<VectorTile>(res.data), res.modified, + res.expires); } }); } diff --git a/src/mbgl/tile/vector_tile_source.hpp b/src/mbgl/tile/vector_tile_source.hpp index 32f45a1a23..fb64c7512e 100644 --- a/src/mbgl/tile/vector_tile_source.hpp +++ b/src/mbgl/tile/vector_tile_source.hpp @@ -7,17 +7,17 @@ namespace mbgl { class FileSource; +class AsyncRequest; class VectorTileSource : public GeometryTileSource { public: - VectorTileSource(const Resource&, FileSource&); + VectorTileSource(GeometryTileData&, const Resource&, FileSource&); virtual ~VectorTileSource() = default; - std::unique_ptr<AsyncRequest> monitorTile(const Callback&) override; - private: const Resource resource; FileSource& fileSource; + std::unique_ptr<AsyncRequest> request; }; } // namespace mbgl |