diff options
author | John Firebaugh <john.firebaugh@gmail.com> | 2015-09-22 16:58:38 -0700 |
---|---|---|
committer | John Firebaugh <john.firebaugh@gmail.com> | 2015-09-28 14:10:00 -0700 |
commit | 028abaab00f2ff3a19c67366c3a9f8c803e27423 (patch) | |
tree | edd263033a8b24326ab8e284377e319aa174bf8a | |
parent | aec145ded3b9c0b4f928fb7cb1d92faac4e0e89a (diff) | |
download | qtlocation-mapboxgl-028abaab00f2ff3a19c67366c3a9f8c803e27423.tar.gz |
Ensure that LiveTileData can be reparsed
Annotation tiles may become partially parsed just like regular tiles,
for example if a point annotation is added to the map before the style's
sprite has been loaded. In such cases, they need to be reparsed or the
annotation will not be rendered. Previously, the code path for reparsing
would be short-circuited by a dynamic_cast<VectorTileData*> followed by
a null check. This commit removes that case and adds (back) a virtual
reparse method to the TileData interface.
-rw-r--r-- | .gitignore | 1 | ||||
-rw-r--r-- | src/mbgl/map/live_tile_data.cpp | 19 | ||||
-rw-r--r-- | src/mbgl/map/live_tile_data.hpp | 4 | ||||
-rw-r--r-- | src/mbgl/map/source.cpp | 8 | ||||
-rw-r--r-- | src/mbgl/map/tile_data.hpp | 1 | ||||
-rw-r--r-- | src/mbgl/map/vector_tile_data.hpp | 2 | ||||
-rw-r--r-- | test/api/annotations.cpp | 28 | ||||
-rw-r--r-- | test/fixtures/api/empty.json | 6 | ||||
-rw-r--r-- | test/output/.gitkeep | 0 |
9 files changed, 46 insertions, 23 deletions
diff --git a/.gitignore b/.gitignore index bd6707ba9a..4d0b4074c2 100644 --- a/.gitignore +++ b/.gitignore @@ -25,6 +25,7 @@ /test/fixtures/api/1.png /test/fixtures/api/2.png /test/fixtures/database/*.db +/test/output /include/mbgl/shader/shaders.hpp /src/shader/shaders_gl.cpp /src/shader/shaders_gles2.cpp diff --git a/src/mbgl/map/live_tile_data.cpp b/src/mbgl/map/live_tile_data.cpp index 0b73b52f36..fbb9c10de0 100644 --- a/src/mbgl/map/live_tile_data.cpp +++ b/src/mbgl/map/live_tile_data.cpp @@ -13,7 +13,7 @@ using namespace mbgl; LiveTileData::LiveTileData(const TileID& id_, - const LiveTile* tile, + const LiveTile* tile_, Style& style_, const SourceInfo& source_, std::function<void()> callback) @@ -25,7 +25,8 @@ LiveTileData::LiveTileData(const TileID& id_, style_, style_.layers, state, - std::make_unique<CollisionTile>(0, 0, false)) { + std::make_unique<CollisionTile>(0, 0, false)), + tile(tile_) { state = State::loaded; if (!tile) { @@ -33,7 +34,19 @@ LiveTileData::LiveTileData(const TileID& id_, return; } + reparse(callback); +} + +bool LiveTileData::reparse(std::function<void()> callback) { + if (parsing || (state != State::loaded && state != State::partial)) { + return false; + } + + parsing = true; + workRequest = worker.parseLiveTile(tileWorker, *tile, [this, callback] (TileParseResult result) { + parsing = false; + if (result.is<State>()) { state = result.get<State>(); } else { @@ -43,6 +56,8 @@ LiveTileData::LiveTileData(const TileID& id_, callback(); }); + + return true; } LiveTileData::~LiveTileData() { diff --git a/src/mbgl/map/live_tile_data.hpp b/src/mbgl/map/live_tile_data.hpp index 5c4220fd67..c6507bbc3e 100644 --- a/src/mbgl/map/live_tile_data.hpp +++ b/src/mbgl/map/live_tile_data.hpp @@ -20,6 +20,8 @@ public: std::function<void ()> callback); ~LiveTileData(); + bool reparse(std::function<void ()> callback) override; + void cancel() override; Bucket* getBucket(const StyleLayer&) override; @@ -27,6 +29,8 @@ private: Worker& worker; TileWorker tileWorker; std::unique_ptr<WorkRequest> workRequest; + bool parsing = false; + const LiveTile* tile; }; } diff --git a/src/mbgl/map/source.cpp b/src/mbgl/map/source.cpp index 5899fea1ec..572973b79a 100644 --- a/src/mbgl/map/source.cpp +++ b/src/mbgl/map/source.cpp @@ -234,15 +234,13 @@ bool Source::handlePartialTile(const TileID& id, Worker&) { return true; } - // Note: this uses a raw pointer; we don't want the callback binding to have a - // shared pointer. - VectorTileData* data = dynamic_cast<VectorTileData*>(it->second.lock().get()); + auto data = it->second.lock(); if (!data) { return true; } - return data->reparse([this, data]() { - emitTileLoaded(false); + return data->reparse([this]() { + emitTileLoaded(false); }); } diff --git a/src/mbgl/map/tile_data.hpp b/src/mbgl/map/tile_data.hpp index 047ccd5cd0..fcbf25fb62 100644 --- a/src/mbgl/map/tile_data.hpp +++ b/src/mbgl/map/tile_data.hpp @@ -72,6 +72,7 @@ public: virtual Bucket* getBucket(const StyleLayer&) = 0; + virtual bool reparse(std::function<void ()>) { return true; } virtual void redoPlacement(float, float, bool) {} bool isReady() const { diff --git a/src/mbgl/map/vector_tile_data.hpp b/src/mbgl/map/vector_tile_data.hpp index 4db0cbe004..c004e804b7 100644 --- a/src/mbgl/map/vector_tile_data.hpp +++ b/src/mbgl/map/vector_tile_data.hpp @@ -28,7 +28,7 @@ public: void request(float pixelRatio, const std::function<void()>& callback); - bool reparse(std::function<void ()> callback); + bool reparse(std::function<void ()> callback) override; void redoPlacement(float angle, float pitch, bool collisionDebug) override; diff --git a/test/api/annotations.cpp b/test/api/annotations.cpp index 33374d4386..39862b1069 100644 --- a/test/api/annotations.cpp +++ b/test/api/annotations.cpp @@ -1,5 +1,3 @@ -#include "../fixtures/fixture_log_observer.hpp" -#include "../fixtures/mock_file_source.hpp" #include "../fixtures/util.hpp" #include <mbgl/annotation/point_annotation.hpp> @@ -7,30 +5,30 @@ #include <mbgl/map/still_image.hpp> #include <mbgl/platform/default/headless_display.hpp> #include <mbgl/platform/default/headless_view.hpp> +#include <mbgl/storage/default_file_source.hpp> +#include <mbgl/util/image.hpp> +#include <mbgl/util/io.hpp> #include <future> #include <vector> -TEST(API, PointAnnotation) { +TEST(Annotations, PointAnnotation) { using namespace mbgl; auto display = std::make_shared<mbgl::HeadlessDisplay>(); HeadlessView view(display, 1); - - MockFileSource fileSource(MockFileSource::Success, ""); + DefaultFileSource fileSource(nullptr); Map map(view, fileSource, MapMode::Still); - map.setStyleURL("test/fixtures/resources/style.json"); - - std::vector<PointAnnotation> points; - points.emplace_back(PointAnnotation({ 50.0, 50.0 }, "default_marker")); - - map.addPointAnnotations(points); + map.setStyleJSON(util::read_file("test/fixtures/api/empty.json"), ""); + map.addPointAnnotation(PointAnnotation({ 0, 0 }, "default_marker")); - std::promise<bool> promise; - map.renderStill([&promise](std::exception_ptr, std::unique_ptr<const StillImage>) { - promise.set_value(true); + std::promise<std::unique_ptr<const StillImage>> promise; + map.renderStill([&promise](std::exception_ptr, std::unique_ptr<const StillImage> image) { + promise.set_value(std::move(image)); }); - promise.get_future().get(); + auto result = promise.get_future().get(); + const std::string png = util::compress_png(result->width, result->height, result->pixels.get()); + util::write_file("test/output/point_annotation.png", png); } diff --git a/test/fixtures/api/empty.json b/test/fixtures/api/empty.json new file mode 100644 index 0000000000..acc8a630ca --- /dev/null +++ b/test/fixtures/api/empty.json @@ -0,0 +1,6 @@ +{ + "version": 8, + "sources": {}, + "layers": [], + "sprite": "asset://TEST_DATA/fixtures/resources/sprite" +} diff --git a/test/output/.gitkeep b/test/output/.gitkeep new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/test/output/.gitkeep |