diff --git a/src/mbgl/style/source_observer.hpp b/src/mbgl/style/source_observer.hpp index a6cdab6ba..dcbcaeaba 100644 --- a/src/mbgl/style/source_observer.hpp +++ b/src/mbgl/style/source_observer.hpp @@ -20,6 +20,9 @@ public: virtual void onSourceAttributionChanged(Source&, const std::string&) {} virtual void onSourceError(Source&, std::exception_ptr) {} + //Source description needs to be reloaded + virtual void onSourceDescriptionChanged(Source&) {} + virtual void onTileChanged(Source&, const OverscaledTileID&) {} virtual void onTileError(Source&, const OverscaledTileID&, std::exception_ptr) {} }; diff --git a/src/mbgl/style/sources/geojson_source_impl.cpp b/src/mbgl/style/sources/geojson_source_impl.cpp index 5b7ba4fc7..f4d47cae3 100644 --- a/src/mbgl/style/sources/geojson_source_impl.cpp +++ b/src/mbgl/style/sources/geojson_source_impl.cpp @@ -38,6 +38,12 @@ 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) { + loaded = false; + observer->onSourceDescriptionChanged(base); + } } optional GeoJSONSource::Impl::getURL() { @@ -132,6 +138,7 @@ void GeoJSONSource::Impl::loadDescription(FileSource& fileSource) { loaded = true; observer->onSourceLoaded(base); + req.reset(); } }); } diff --git a/src/mbgl/style/style.cpp b/src/mbgl/style/style.cpp index 522965b95..01ca5b6f3 100644 --- a/src/mbgl/style/style.cpp +++ b/src/mbgl/style/style.cpp @@ -491,6 +491,13 @@ void Style::onSourceError(Source& source, std::exception_ptr error) { observer->onResourceError(error); } +void Style::onSourceDescriptionChanged(Source& source) { + observer->onSourceDescriptionChanged(source); + if (!source.baseImpl->loaded) { + source.baseImpl->loadDescription(fileSource); + } +} + void Style::onTileChanged(Source& source, const OverscaledTileID& tileID) { observer->onTileChanged(source, tileID); observer->onUpdate(Update::Repaint); diff --git a/src/mbgl/style/style.hpp b/src/mbgl/style/style.hpp index 648bd4803..21b25857d 100644 --- a/src/mbgl/style/style.hpp +++ b/src/mbgl/style/style.hpp @@ -134,6 +134,7 @@ private: void onSourceLoaded(Source&) override; void onSourceAttributionChanged(Source&, const std::string&) override; void onSourceError(Source&, std::exception_ptr) override; + void onSourceDescriptionChanged(Source&) override; void onTileChanged(Source&, const OverscaledTileID&) override; void onTileError(Source&, const OverscaledTileID&, std::exception_ptr) override; diff --git a/test/src/mbgl/test/stub_style_observer.hpp b/test/src/mbgl/test/stub_style_observer.hpp index 7189fd8af..95280565f 100644 --- a/test/src/mbgl/test/stub_style_observer.hpp +++ b/test/src/mbgl/test/stub_style_observer.hpp @@ -38,6 +38,10 @@ public: if (sourceError) sourceError(source, error); } + void onSourceDescriptionChanged(Source& source) override { + if (sourceDescriptionChanged) sourceDescriptionChanged(source); + } + void onTileChanged(Source& source, const OverscaledTileID& tileID) override { if (tileChanged) tileChanged(source, tileID); }; @@ -58,6 +62,7 @@ public: std::function sourceLoaded; std::function sourceAttributionChanged; std::function sourceError; + std::function sourceDescriptionChanged; std::function tileChanged; std::function tileError; std::function resourceError; diff --git a/test/style/source.test.cpp b/test/style/source.test.cpp index 859aa8289..3270894a5 100644 --- a/test/style/source.test.cpp +++ b/test/style/source.test.cpp @@ -381,3 +381,37 @@ TEST(Source, RasterTileAttribution) { test.run(); } + +TEST(Source, GeoJSonSourceUrlUpdate) { + SourceTest test; + + test.fileSource.sourceResponse = [&] (const Resource& resource) { + EXPECT_EQ("url", resource.url); + Response response; + response.data = std::make_unique("{\"geometry\": {\"type\": \"Point\", \"coordinates\": [1.1, 1.1]}, \"type\": \"Feature\", \"properties\": {}}"); + return response; + }; + + test.observer.sourceDescriptionChanged = [&] (Source&) { + //Should be called (test will hang if it doesn't) + test.end(); + }; + + test.observer.tileError = [&] (Source&, const OverscaledTileID&, std::exception_ptr) { + FAIL() << "Should never be called"; + }; + + GeoJSONSource source("source"); + source.baseImpl->setObserver(&test.observer); + + //Load initial, so the source state will be loaded=true + source.baseImpl->loadDescription(test.fileSource); + + //Schedule an update + test.loop.invoke([&] () { + //Update the url + source.setURL(std::string("http://source-url.ext")); + }); + + test.run(); +}