aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMikhail Pozdnyakov <mikhail.pozdnyakov@mapbox.com>2019-10-10 11:43:17 +0300
committerMikhail Pozdnyakov <mikhail.pozdnyakov@mapbox.com>2019-10-10 15:39:34 +0300
commit2f973e9646b49f80c7af6851d38cf1029a31a232 (patch)
tree9858bf0bf9b600a2b14f03d7134f0823a3ec1405
parent76346944f3f6809bed7dd7ce4ef82343fc069423 (diff)
[core] Introduce Scheduler::bindOnce() and use it in ImageManager
-rw-r--r--include/mbgl/actor/scheduler.hpp10
-rw-r--r--src/mbgl/actor/scheduler.cpp9
-rw-r--r--src/mbgl/renderer/image_manager.cpp8
3 files changed, 21 insertions, 6 deletions
diff --git a/include/mbgl/actor/scheduler.hpp b/include/mbgl/actor/scheduler.hpp
index 7338c3ab3..bb2cf124b 100644
--- a/include/mbgl/actor/scheduler.hpp
+++ b/include/mbgl/actor/scheduler.hpp
@@ -40,6 +40,16 @@ public:
// Makes a weak pointer to this Scheduler.
virtual mapbox::base::WeakPtr<Scheduler> makeWeakPtr() = 0;
+ // Returns a closure wrapping the given one.
+ //
+ // When the returned closure is invoked for the first time, it schedules
+ // the given closure to this scheduler, the consequent calls of the
+ // returned closure are ignored.
+ //
+ // If this scheduler is already deleted by the time the returnded closure is
+ // first invoked, the call is ignored.
+ std::function<void()> bindOnce(std::function<void()>);
+
// Set/Get the current Scheduler for this thread
static Scheduler* GetCurrent();
static void SetCurrent(Scheduler*);
diff --git a/src/mbgl/actor/scheduler.cpp b/src/mbgl/actor/scheduler.cpp
index 5fd9a133b..81e259fe1 100644
--- a/src/mbgl/actor/scheduler.cpp
+++ b/src/mbgl/actor/scheduler.cpp
@@ -4,7 +4,14 @@
namespace mbgl {
-util::ThreadLocal<Scheduler> g_currentScheduler;
+std::function<void()> Scheduler::bindOnce(std::function<void()> fn) {
+ assert(fn);
+ return [scheduler = makeWeakPtr(), scheduled = std::move(fn)]() mutable {
+ if (!scheduled) return; // Repeated call.
+ auto schedulerGuard = scheduler.lock();
+ if (scheduler) scheduler->schedule(std::move(scheduled));
+ };
+}
static auto& current() {
static util::ThreadLocal<Scheduler> scheduler;
diff --git a/src/mbgl/renderer/image_manager.cpp b/src/mbgl/renderer/image_manager.cpp
index 65defc54c..0920f5a65 100644
--- a/src/mbgl/renderer/image_manager.cpp
+++ b/src/mbgl/renderer/image_manager.cpp
@@ -204,6 +204,7 @@ void ImageManager::checkMissingAndNotify(ImageRequestor& requestor, const ImageR
}
requestedImages[missingImage].emplace(requestorPtr);
requestor.addPendingRequest(missingImage);
+
auto removePendingRequests = [this, missingImage] {
auto existingRequest = requestedImages.find(missingImage);
if (existingRequest == requestedImages.end()) {
@@ -214,11 +215,8 @@ void ImageManager::checkMissingAndNotify(ImageRequestor& requestor, const ImageR
req->removePendingRequest(missingImage);
}
};
-
- Scheduler& scheduler = *Scheduler::GetCurrent();
- auto callback = [&scheduler, removePendingRequests]() { scheduler.schedule(removePendingRequests); };
-
- observer->onStyleImageMissing(missingImage, std::move(callback));
+ observer->onStyleImageMissing(missingImage,
+ Scheduler::GetCurrent()->bindOnce(std::move(removePendingRequests)));
}
} else {
// Associate requestor with an image that was provided by the client.