[core] Introduce Scheduler::bindOnce() and use it in ImageManager

This commit is contained in:
Mikhail Pozdnyakov
2019-10-10 11:43:17 +03:00
parent 76346944f3
commit 2f973e9646
3 changed files with 21 additions and 6 deletions

View File

@@ -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*);

View File

@@ -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;

View File

@@ -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.