diff options
author | Ansis Brammanis <ansis@mapbox.com> | 2019-03-27 17:21:19 -0400 |
---|---|---|
committer | Ansis Brammanis <ansis@mapbox.com> | 2019-03-27 17:21:19 -0400 |
commit | cb64dd625206aa0a0b2267aed957d8eb2e5d8f23 (patch) | |
tree | 49c6394d98f640cb3f5a27c1297c04ffac6ca444 | |
parent | 2883ea10b023d2260dce03c8f18f8b7ffafa6c8c (diff) |
use callbacks for onStyleImageMissing
We need some asynchronous way of telling the renderer when the listener
has been called. This is important on Android when the renderer and map
exist on separate threads.
-rw-r--r-- | include/mbgl/map/map_observer.hpp | 3 | ||||
-rw-r--r-- | include/mbgl/renderer/renderer_observer.hpp | 2 | ||||
-rw-r--r-- | src/mbgl/map/map_impl.cpp | 15 | ||||
-rw-r--r-- | src/mbgl/map/map_impl.hpp | 2 | ||||
-rw-r--r-- | src/mbgl/renderer/image_manager.cpp | 35 | ||||
-rw-r--r-- | src/mbgl/renderer/image_manager.hpp | 6 | ||||
-rw-r--r-- | src/mbgl/renderer/image_manager_observer.hpp | 2 | ||||
-rw-r--r-- | src/mbgl/renderer/renderer_impl.cpp | 6 | ||||
-rw-r--r-- | src/mbgl/renderer/renderer_impl.hpp | 2 |
9 files changed, 54 insertions, 19 deletions
diff --git a/include/mbgl/map/map_observer.hpp b/include/mbgl/map/map_observer.hpp index 39fe516ff..e405c5dd0 100644 --- a/include/mbgl/map/map_observer.hpp +++ b/include/mbgl/map/map_observer.hpp @@ -1,6 +1,7 @@ #pragma once #include <mbgl/style/source.hpp> +#include <mbgl/style/image.hpp> #include <cstdint> #include <string> @@ -46,7 +47,7 @@ public: virtual void onDidFinishLoadingStyle() {} virtual void onSourceChanged(style::Source&) {} virtual void onDidBecomeIdle() {} - virtual void onStyleImageMissing(const std::string&) {} + virtual void onStyleImageMissing(const std::string&, std::function<void(optional<std::unique_ptr<mbgl::style::Image>>)> callback) { callback({}); } }; } // namespace mbgl diff --git a/include/mbgl/renderer/renderer_observer.hpp b/include/mbgl/renderer/renderer_observer.hpp index 71620355e..e2b3441e3 100644 --- a/include/mbgl/renderer/renderer_observer.hpp +++ b/include/mbgl/renderer/renderer_observer.hpp @@ -33,7 +33,7 @@ public: virtual void onDidFinishRenderingMap() {} // Style is missing an image - virtual void onStyleImageMissing(const std::string&) {} + virtual void onStyleImageMissing(const std::string&, std::function<void()> done) { done(); } }; } // namespace mbgl diff --git a/src/mbgl/map/map_impl.cpp b/src/mbgl/map/map_impl.cpp index ecb923836..0edf26e26 100644 --- a/src/mbgl/map/map_impl.cpp +++ b/src/mbgl/map/map_impl.cpp @@ -172,8 +172,19 @@ void Map::Impl::jumpTo(const CameraOptions& camera) { onUpdate(); } -void Map::Impl::onStyleImageMissing(const std::string& id) { - observer.onStyleImageMissing(id); +void Map::Impl::onStyleImageMissing(const std::string& id, std::function<void()> done) { + + if (style->getImage(id) != nullptr) { + done(); + return; + } + + observer.onStyleImageMissing(id, [this, done](optional<std::unique_ptr<mbgl::style::Image>> image = {}) { + if (image) { + style->addImage(std::move(*image)); + } + done(); + }); } } // namespace mbgl diff --git a/src/mbgl/map/map_impl.hpp b/src/mbgl/map/map_impl.hpp index 425e136b6..0e0b47e8a 100644 --- a/src/mbgl/map/map_impl.hpp +++ b/src/mbgl/map/map_impl.hpp @@ -47,7 +47,7 @@ public: void onDidFinishRenderingFrame(RenderMode, bool) final; void onWillStartRenderingMap() final; void onDidFinishRenderingMap() final; - void onStyleImageMissing(const std::string&) final; + void onStyleImageMissing(const std::string&, std::function<void()>) final; // Map void jumpTo(const CameraOptions&); diff --git a/src/mbgl/renderer/image_manager.cpp b/src/mbgl/renderer/image_manager.cpp index f756e201c..cdcf83210 100644 --- a/src/mbgl/renderer/image_manager.cpp +++ b/src/mbgl/renderer/image_manager.cpp @@ -92,23 +92,42 @@ void ImageManager::removeRequestor(ImageRequestor& requestor) { } void ImageManager::imagesAdded() { - for (const auto& entry : missingImageRequestors) { - notify(*entry.first, entry.second); + for (auto it = missingImageRequestors.begin(); it != missingImageRequestors.end();) { + if (it->second.callbacksRemaining == 0) { + notify(*it->first, it->second.pair); + missingImageRequestors.erase(it++); + } else { + it++; + } } - requestors.clear(); } void ImageManager::checkMissingAndNotify(ImageRequestor& requestor, const ImageRequestPair& pair) { - bool missing = false; + int missing = 0; for (const auto& dependency : pair.first) { auto it = images.find(dependency.first); if (it == images.end()) { - missing = true; - observer->onStyleImageMissing(dependency.first); + missing++; } } - if (missing) { - missingImageRequestors.emplace(&requestor, std::move(pair)); + + + if (missing > 0) { + ImageRequestor* requestorPtr = &requestor; + missingImageRequestors.emplace(requestorPtr, MissingImageRequestPair { std::move(pair), missing }); + + for (const auto& dependency : pair.first) { + auto it = images.find(dependency.first); + if (it == images.end()) { + observer->onStyleImageMissing(dependency.first, [this, requestorPtr]() { + auto it = missingImageRequestors.find(requestorPtr); + if (it != missingImageRequestors.end()) { + it->second.callbacksRemaining--; + } + }); + } + } + } else { notify(requestor, pair); } diff --git a/src/mbgl/renderer/image_manager.hpp b/src/mbgl/renderer/image_manager.hpp index 9adb0fa11..789183dd1 100644 --- a/src/mbgl/renderer/image_manager.hpp +++ b/src/mbgl/renderer/image_manager.hpp @@ -64,7 +64,11 @@ private: bool loaded = false; std::unordered_map<ImageRequestor*, ImageRequestPair> requestors; - std::unordered_map<ImageRequestor*, ImageRequestPair> missingImageRequestors; + struct MissingImageRequestPair { + ImageRequestPair pair; + int callbacksRemaining; + }; + std::unordered_map<ImageRequestor*, MissingImageRequestPair> missingImageRequestors; ImageMap images; ImageManagerObserver* observer = nullptr; diff --git a/src/mbgl/renderer/image_manager_observer.hpp b/src/mbgl/renderer/image_manager_observer.hpp index e483c5b8f..ff4ed1f48 100644 --- a/src/mbgl/renderer/image_manager_observer.hpp +++ b/src/mbgl/renderer/image_manager_observer.hpp @@ -6,7 +6,7 @@ class ImageManagerObserver { public: virtual ~ImageManagerObserver() = default; - virtual void onStyleImageMissing(const std::string&) {} + virtual void onStyleImageMissing(const std::string&, std::function<void()>) {} }; } // namespace mbgl diff --git a/src/mbgl/renderer/renderer_impl.cpp b/src/mbgl/renderer/renderer_impl.cpp index adef3890b..e6ce6a63b 100644 --- a/src/mbgl/renderer/renderer_impl.cpp +++ b/src/mbgl/renderer/renderer_impl.cpp @@ -159,8 +159,8 @@ void Renderer::Impl::render(const UpdateParameters& updateParameters) { imageManager->updateImage(entry.second.after); } - imageManager->imagesAdded(); imageManager->setLoaded(updateParameters.spriteLoaded); + imageManager->imagesAdded(); const LayerDifference layerDiff = diffLayers(layerImpls, updateParameters.layers); @@ -836,8 +836,8 @@ void Renderer::Impl::onTileChanged(RenderSource&, const OverscaledTileID&) { observer->onInvalidate(); } -void Renderer::Impl::onStyleImageMissing(const std::string& id) { - observer->onStyleImageMissing(id); +void Renderer::Impl::onStyleImageMissing(const std::string& id, std::function<void()> done) { + observer->onStyleImageMissing(id, done); } } // namespace mbgl diff --git a/src/mbgl/renderer/renderer_impl.hpp b/src/mbgl/renderer/renderer_impl.hpp index 8ec7d2698..624b4c273 100644 --- a/src/mbgl/renderer/renderer_impl.hpp +++ b/src/mbgl/renderer/renderer_impl.hpp @@ -89,7 +89,7 @@ private: void onTileError(RenderSource&, const OverscaledTileID&, std::exception_ptr) override; // ImageManagerObserver implementation - void onStyleImageMissing(const std::string&) override; + void onStyleImageMissing(const std::string&, std::function<void()>) override; void updateFadingTiles(); |