summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/mbgl/renderer/image_manager.cpp28
-rw-r--r--src/mbgl/renderer/image_manager.hpp7
-rw-r--r--test/renderer/image_manager.test.cpp13
3 files changed, 39 insertions, 9 deletions
diff --git a/src/mbgl/renderer/image_manager.cpp b/src/mbgl/renderer/image_manager.cpp
index 25acd6bd25..2ea47225f8 100644
--- a/src/mbgl/renderer/image_manager.cpp
+++ b/src/mbgl/renderer/image_manager.cpp
@@ -1,4 +1,6 @@
#include <mbgl/renderer/image_manager.hpp>
+#include <mbgl/actor/actor.hpp>
+#include <mbgl/actor/scheduler.hpp>
#include <mbgl/util/logging.hpp>
#include <mbgl/gfx/context.hpp>
#include <mbgl/renderer/image_manager_observer.hpp>
@@ -116,7 +118,7 @@ void ImageManager::removeRequestor(ImageRequestor& requestor) {
void ImageManager::notifyIfMissingImageAdded() {
for (auto it = missingImageRequestors.begin(); it != missingImageRequestors.end();) {
- if (it->second.callbacksRemaining == 0) {
+ if (it->second.callbacks.empty()) {
notify(*it->first, it->second.pair);
missingImageRequestors.erase(it++);
} else {
@@ -137,19 +139,29 @@ void ImageManager::checkMissingAndNotify(ImageRequestor& requestor, const ImageR
if (missing > 0) {
ImageRequestor* requestorPtr = &requestor;
- missingImageRequestors.emplace(requestorPtr, MissingImageRequestPair { std::move(pair), missing });
+ auto emplaced = missingImageRequestors.emplace(requestorPtr, MissingImageRequestPair { pair, {} });
+ assert(emplaced.second);
for (const auto& dependency : pair.first) {
auto it = images.find(dependency.first);
if (it == images.end()) {
assert(observer != nullptr);
- observer->onStyleImageMissing(dependency.first, [this, requestorPtr]() {
- auto requestorIt = missingImageRequestors.find(requestorPtr);
- if (requestorIt != missingImageRequestors.end()) {
- assert(requestorIt->second.callbacksRemaining > 0);
- requestorIt->second.callbacksRemaining--;
- }
+ auto callback = std::make_unique<ActorCallback>(
+ *Scheduler::GetCurrent(),
+ [this, requestorPtr, imageId = dependency.first] {
+ auto requestorIt = missingImageRequestors.find(requestorPtr);
+ if (requestorIt != missingImageRequestors.end()) {
+ assert(requestorIt->second.callbacks.find(imageId) != requestorIt->second.callbacks.end());
+ requestorIt->second.callbacks.erase(imageId);
+ }
+ });
+
+ auto actorRef = callback->self();
+ emplaced.first->second.callbacks.emplace(dependency.first, std::move(callback));
+ observer->onStyleImageMissing(dependency.first, [actorRef]() mutable {
+ actorRef.invoke(&Callback::operator());
});
+
}
}
diff --git a/src/mbgl/renderer/image_manager.hpp b/src/mbgl/renderer/image_manager.hpp
index 99887ae384..bec811317e 100644
--- a/src/mbgl/renderer/image_manager.hpp
+++ b/src/mbgl/renderer/image_manager.hpp
@@ -15,6 +15,9 @@
namespace mbgl {
+template <class T>
+class Actor;
+
namespace gfx {
class Context;
} // namespace gfx
@@ -66,9 +69,11 @@ private:
bool loaded = false;
std::map<ImageRequestor*, ImageRequestPair> requestors;
+ using Callback = std::function<void()>;
+ using ActorCallback = Actor<Callback>;
struct MissingImageRequestPair {
ImageRequestPair pair;
- unsigned int callbacksRemaining;
+ std::map<std::string, std::unique_ptr<ActorCallback>> callbacks;
};
std::map<ImageRequestor*, MissingImageRequestPair> missingImageRequestors;
ImageMap images;
diff --git a/test/renderer/image_manager.test.cpp b/test/renderer/image_manager.test.cpp
index d124e67e10..b9ec099f93 100644
--- a/test/renderer/image_manager.test.cpp
+++ b/test/renderer/image_manager.test.cpp
@@ -117,6 +117,7 @@ public:
};
TEST(ImageManager, NotifiesRequestorWhenSpriteIsLoaded) {
+ util::RunLoop runLoop;
ImageManager imageManager;
StubImageRequestor requestor;
bool notified = false;
@@ -132,11 +133,15 @@ TEST(ImageManager, NotifiesRequestorWhenSpriteIsLoaded) {
ImageDependencies dependencies;
dependencies.emplace("one", ImageType::Icon);
imageManager.getImages(requestor, std::make_pair(dependencies, imageCorrelationID));
+ runLoop.runOnce();
+
ASSERT_FALSE(notified);
imageManager.setLoaded(true);
+ runLoop.runOnce();
ASSERT_FALSE(notified);
imageManager.notifyIfMissingImageAdded();
+ runLoop.runOnce();
ASSERT_TRUE(notified);
}
@@ -169,6 +174,7 @@ class StubImageManagerObserver : public ImageManagerObserver {
};
TEST(ImageManager, OnStyleImageMissingBeforeSpriteLoaded) {
+ util::RunLoop runLoop;
ImageManager imageManager;
StubImageRequestor requestor;
StubImageManagerObserver observer;
@@ -185,16 +191,19 @@ TEST(ImageManager, OnStyleImageMissingBeforeSpriteLoaded) {
ImageDependencies dependencies;
dependencies.emplace("pre", ImageType::Icon);
imageManager.getImages(requestor, std::make_pair(dependencies, imageCorrelationID));
+ runLoop.runOnce();
EXPECT_EQ(observer.count, 0);
ASSERT_FALSE(notified);
imageManager.setLoaded(true);
+ runLoop.runOnce();
EXPECT_EQ(observer.count, 1);
ASSERT_FALSE(notified);
imageManager.notifyIfMissingImageAdded();
+ runLoop.runOnce();
EXPECT_EQ(observer.count, 1);
ASSERT_TRUE(notified);
@@ -202,6 +211,7 @@ TEST(ImageManager, OnStyleImageMissingBeforeSpriteLoaded) {
}
TEST(ImageManager, OnStyleImageMissingAfterSpriteLoaded) {
+ util::RunLoop runLoop;
ImageManager imageManager;
StubImageRequestor requestor;
StubImageManagerObserver observer;
@@ -218,16 +228,19 @@ TEST(ImageManager, OnStyleImageMissingAfterSpriteLoaded) {
ASSERT_FALSE(notified);
imageManager.setLoaded(true);
+ runLoop.runOnce();
uint64_t imageCorrelationID = 0;
ImageDependencies dependencies;
dependencies.emplace("after", ImageType::Icon);
imageManager.getImages(requestor, std::make_pair(dependencies, imageCorrelationID));
+ runLoop.runOnce();
EXPECT_EQ(observer.count, 1);
ASSERT_FALSE(notified);
imageManager.notifyIfMissingImageAdded();
+ runLoop.runOnce();
EXPECT_EQ(observer.count, 1);
ASSERT_TRUE(notified);