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.
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -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
|
||||
|
||||
@@ -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() {
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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");
|
||||
map.setStyleJSON(util::read_file("test/fixtures/api/empty.json"), "");
|
||||
map.addPointAnnotation(PointAnnotation({ 0, 0 }, "default_marker"));
|
||||
|
||||
std::vector<PointAnnotation> points;
|
||||
points.emplace_back(PointAnnotation({ 50.0, 50.0 }, "default_marker"));
|
||||
|
||||
map.addPointAnnotations(points);
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
6
test/fixtures/api/empty.json
vendored
Normal file
6
test/fixtures/api/empty.json
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"version": 8,
|
||||
"sources": {},
|
||||
"layers": [],
|
||||
"sprite": "asset://TEST_DATA/fixtures/resources/sprite"
|
||||
}
|
||||
0
test/output/.gitkeep
Normal file
0
test/output/.gitkeep
Normal file
Reference in New Issue
Block a user