diff --git a/include/mbgl/renderer/renderer_state.hpp b/include/mbgl/renderer/renderer_state.hpp index 1b300c190..27985ae99 100644 --- a/include/mbgl/renderer/renderer_state.hpp +++ b/include/mbgl/renderer/renderer_state.hpp @@ -8,7 +8,7 @@ namespace mbgl { class UpdateParameters; /** - * RendererState acts as a Memento-like object that is able to extract data out of UpdateParameters (an opaque object + * RendererState acts as a Memento object that is able to extract data out of UpdateParameters (an opaque object * from the public API perspective). */ class RendererState { @@ -17,6 +17,14 @@ public: // Obtains a CameraOptions out of a given UpdateParameters object. static CameraOptions getCameraOptions(UpdateParameters&, const EdgeInsets& = {}); + // Returns whether an image with the given ID exists from a given UpdateParamters object. + static bool hasImage(UpdateParameters&, const std::string& id); + + // Returns whether a layer with the given ID exists from a given UpdateParamters object. + static bool hasLayer(UpdateParameters&, const std::string& id); + + // Returns whether a source with the given ID exists from a given UpdateParamters object. + static bool hasSource(UpdateParameters&, const std::string& id); }; } // namespace mbgl diff --git a/platform/default/mbgl/gl/headless_frontend.cpp b/platform/default/mbgl/gl/headless_frontend.cpp index 1ec11a195..30def38f7 100644 --- a/platform/default/mbgl/gl/headless_frontend.cpp +++ b/platform/default/mbgl/gl/headless_frontend.cpp @@ -64,6 +64,30 @@ CameraOptions HeadlessFrontend::getCameraOptions() { return nullCamera; } +bool HeadlessFrontend::hasImage(const std::string& id) { + if (updateParameters) { + return RendererState::hasImage(*updateParameters, id); + } + + return false; +} + +bool HeadlessFrontend::hasLayer(const std::string& id) { + if (updateParameters) { + return RendererState::hasLayer(*updateParameters, id); + } + + return false; +} + +bool HeadlessFrontend::hasSource(const std::string& id) { + if (updateParameters) { + return RendererState::hasSource(*updateParameters, id); + } + + return false; +} + void HeadlessFrontend::setSize(Size size_) { if (size != size_) { size = size_; diff --git a/platform/default/mbgl/gl/headless_frontend.hpp b/platform/default/mbgl/gl/headless_frontend.hpp index 29ab30c93..45586033b 100644 --- a/platform/default/mbgl/gl/headless_frontend.hpp +++ b/platform/default/mbgl/gl/headless_frontend.hpp @@ -35,6 +35,10 @@ public: RendererBackend* getBackend(); CameraOptions getCameraOptions(); + bool hasImage(const std::string&); + bool hasLayer(const std::string&); + bool hasSource(const std::string&); + PremultipliedImage readStillImage(); PremultipliedImage render(Map&); diff --git a/src/mbgl/renderer/renderer_state.cpp b/src/mbgl/renderer/renderer_state.cpp index dc5c4c129..a024f37df 100644 --- a/src/mbgl/renderer/renderer_state.cpp +++ b/src/mbgl/renderer/renderer_state.cpp @@ -1,10 +1,42 @@ #include #include +#include +#include +#include + namespace mbgl { CameraOptions RendererState::getCameraOptions(UpdateParameters& updateParameters, const EdgeInsets& padding) { return updateParameters.transformState.getCameraOptions(padding); } +bool RendererState::hasImage(UpdateParameters& updateParameters, const std::string& id) { + for (const auto& image : *updateParameters.images) { + if (image.get()->id == id) { + return true; + } + } + return false; +} + +bool RendererState::hasLayer(UpdateParameters& updateParameters, const std::string& id) { + for (const auto& layer : *updateParameters.layers) { + if (layer.get()->id == id) { + return true; + } + } + return false; +} + +bool RendererState::hasSource(UpdateParameters& updateParameters, const std::string& id) { + for (const auto& source : *updateParameters.sources) { + if (source.get()->id == id) { + return true; + } + } + return false; +} + + } // namespace mbgl diff --git a/test/map/map.test.cpp b/test/map/map.test.cpp index a21f9c7e7..c57fe28ae 100644 --- a/test/map/map.test.cpp +++ b/test/map/map.test.cpp @@ -18,6 +18,8 @@ #include #include #include +#include +#include #include using namespace mbgl; @@ -69,12 +71,48 @@ TEST(Map, RendererState) { test.runLoop.runOnce(); test.frontend.render(test.map); + // RendererState::getCameraOptions const CameraOptions& options = test.frontend.getCameraOptions(); EXPECT_NEAR(options.center->latitude(), coordinate.latitude(), 1e-7); EXPECT_NEAR(options.center->longitude(), coordinate.longitude(), 1e-7); ASSERT_DOUBLE_EQ(*options.zoom, zoom); ASSERT_DOUBLE_EQ(*options.pitch, pitchInDegrees); EXPECT_NEAR(*options.angle, bearingInDegrees, 1e-7); + + // RendererState::hasImage + test.map.getStyle().addImage(std::make_unique("default_marker", decodeImage(util::read_file("test/fixtures/sprites/default_marker.png")), 1.0)); + + // The frontend has not yet been notified about the newly-added image. + EXPECT_FALSE(test.frontend.hasImage("default_marker")); + + test.runLoop.runOnce(); + test.frontend.render(test.map); + + EXPECT_TRUE(test.frontend.hasImage("default_marker")); + + // RendererState::hasSource + auto source = std::make_unique("GeoJSONSource"); + source->setGeoJSON( Geometry{ Point{ 0, 0 } } ); + test.map.getStyle().addSource(std::move(source)); + + // The frontend has not yet been notified about the newly-added source. + EXPECT_FALSE(test.frontend.hasSource("GeoJSONSource")); + + test.runLoop.runOnce(); + test.frontend.render(test.map); + + EXPECT_TRUE(test.frontend.hasSource("GeoJSONSource")); + + // RendererState::hasLayer + test.map.getStyle().addLayer(std::make_unique("SymbolLayer", "GeoJSONSource")); + + // The frontend has not yet been notified about the newly-added source. + EXPECT_FALSE(test.frontend.hasLayer("SymbolLayer")); + + test.runLoop.runOnce(); + test.frontend.render(test.map); + + EXPECT_TRUE(test.frontend.hasLayer("SymbolLayer")); } TEST(Map, LatLngBehavior) {