diff --git a/CMakeLists.txt b/CMakeLists.txt index d1ca0a15a..fab5319f7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -532,8 +532,6 @@ add_library( ${PROJECT_SOURCE_DIR}/src/mbgl/sprite/sprite_loader.cpp ${PROJECT_SOURCE_DIR}/src/mbgl/sprite/sprite_loader.hpp ${PROJECT_SOURCE_DIR}/src/mbgl/sprite/sprite_loader_observer.hpp - ${PROJECT_SOURCE_DIR}/src/mbgl/sprite/sprite_loader_worker.cpp - ${PROJECT_SOURCE_DIR}/src/mbgl/sprite/sprite_loader_worker.hpp ${PROJECT_SOURCE_DIR}/src/mbgl/sprite/sprite_parser.cpp ${PROJECT_SOURCE_DIR}/src/mbgl/sprite/sprite_parser.hpp ${PROJECT_SOURCE_DIR}/src/mbgl/storage/asset_file_source.hpp diff --git a/src/mbgl/sprite/sprite_loader.cpp b/src/mbgl/sprite/sprite_loader.cpp index 60bab2bf6..da0571424 100644 --- a/src/mbgl/sprite/sprite_loader.cpp +++ b/src/mbgl/sprite/sprite_loader.cpp @@ -2,7 +2,6 @@ #include #include #include -#include #include #include #include @@ -20,24 +19,15 @@ namespace mbgl { static SpriteLoaderObserver nullObserver; -struct SpriteLoader::Loader { - Loader(SpriteLoader& imageManager) - : mailbox(std::make_shared(*Scheduler::GetCurrent())), - worker(Scheduler::GetBackground(), ActorRef(imageManager, mailbox)) { - } - +struct SpriteLoader::Data { std::shared_ptr image; std::shared_ptr json; std::unique_ptr jsonRequest; std::unique_ptr spriteRequest; - std::shared_ptr mailbox; - Actor worker; }; SpriteLoader::SpriteLoader(float pixelRatio_) - : pixelRatio(pixelRatio_) - , observer(&nullObserver) { -} + : pixelRatio(pixelRatio_), observer(&nullObserver), threadPool(Scheduler::GetBackground()) {} SpriteLoader::~SpriteLoader() = default; @@ -48,56 +38,70 @@ void SpriteLoader::load(const std::string& url, FileSource& fileSource) { return; } - loader = std::make_unique(*this); + data = std::make_unique(); - loader->jsonRequest = fileSource.request(Resource::spriteJSON(url, pixelRatio), [this](Response res) { + data->jsonRequest = fileSource.request(Resource::spriteJSON(url, pixelRatio), [this](Response res) { if (res.error) { observer->onSpriteError(std::make_exception_ptr(std::runtime_error(res.error->message))); } else if (res.notModified) { return; } else if (res.noContent) { - loader->json = std::make_shared(); + data->json = std::make_shared(); emitSpriteLoadedIfComplete(); } else { // Only trigger a sprite loaded event we got new data. - assert(loader->json != res.data); - loader->json = std::move(res.data); + assert(data->json != res.data); + data->json = std::move(res.data); emitSpriteLoadedIfComplete(); } }); - loader->spriteRequest = fileSource.request(Resource::spriteImage(url, pixelRatio), [this](Response res) { + data->spriteRequest = fileSource.request(Resource::spriteImage(url, pixelRatio), [this](Response res) { if (res.error) { observer->onSpriteError(std::make_exception_ptr(std::runtime_error(res.error->message))); } else if (res.notModified) { return; } else if (res.noContent) { - loader->image = std::make_shared(); + data->image = std::make_shared(); emitSpriteLoadedIfComplete(); } else { - assert(loader->image != res.data); - loader->image = std::move(res.data); + assert(data->image != res.data); + data->image = std::move(res.data); emitSpriteLoadedIfComplete(); } }); } void SpriteLoader::emitSpriteLoadedIfComplete() { - assert(loader); - - if (!loader->image || !loader->json) { + assert(data); + if (!data->image || !data->json) { return; } - loader->worker.self().invoke(&SpriteLoaderWorker::parse, loader->image, loader->json); -} + struct ParseResult { + std::vector> images; + std::exception_ptr error; + }; -void SpriteLoader::onParsed(std::vector> result) { - observer->onSpriteLoaded(std::move(result)); -} + auto parseClosure = [image = data->image, json = data->json]() -> ParseResult { + try { + return {parseSprite(*image, *json), nullptr}; + } catch (...) { + return {{}, std::current_exception()}; + } + }; -void SpriteLoader::onError(std::exception_ptr err) { - observer->onSpriteError(err); + auto resultClosure = [this, weak = weakFactory.makeWeakPtr()](ParseResult result) { + if (!weak) return; // This instance has been deleted. + + if (result.error) { + observer->onSpriteError(result.error); + return; + } + observer->onSpriteLoaded(std::move(result.images)); + }; + + threadPool->scheduleAndReplyValue(parseClosure, resultClosure); } void SpriteLoader::setObserver(SpriteLoaderObserver* observer_) { diff --git a/src/mbgl/sprite/sprite_loader.hpp b/src/mbgl/sprite/sprite_loader.hpp index d82c51e2d..c22c030cf 100644 --- a/src/mbgl/sprite/sprite_loader.hpp +++ b/src/mbgl/sprite/sprite_loader.hpp @@ -13,6 +13,7 @@ namespace mbgl { class FileSource; class SpriteLoaderObserver; +class Scheduler; class SpriteLoader { public: @@ -28,15 +29,15 @@ private: // Invoked by SpriteAtlasWorker friend class SpriteLoaderWorker; - void onParsed(std::vector>); - void onError(std::exception_ptr); const float pixelRatio; - struct Loader; - std::unique_ptr loader; + struct Data; + std::unique_ptr data; SpriteLoaderObserver* observer = nullptr; + std::shared_ptr threadPool; + mapbox::base::WeakPtrFactory weakFactory{this}; }; } // namespace mbgl diff --git a/src/mbgl/sprite/sprite_loader_worker.cpp b/src/mbgl/sprite/sprite_loader_worker.cpp deleted file mode 100644 index 4bded33d5..000000000 --- a/src/mbgl/sprite/sprite_loader_worker.cpp +++ /dev/null @@ -1,29 +0,0 @@ -#include -#include -#include - -namespace mbgl { - -SpriteLoaderWorker::SpriteLoaderWorker(ActorRef, ActorRef parent_) - : parent(std::move(parent_)) { -} - -void SpriteLoaderWorker::parse(std::shared_ptr image, - std::shared_ptr json) { - try { - if (!image) { - // This shouldn't happen, since we always invoke it with a non-empty pointer. - throw std::runtime_error("missing sprite image"); - } - if (!json) { - // This shouldn't happen, since we always invoke it with a non-empty pointer. - throw std::runtime_error("missing sprite metadata"); - } - - parent.invoke(&SpriteLoader::onParsed, parseSprite(*image, *json)); - } catch (...) { - parent.invoke(&SpriteLoader::onError, std::current_exception()); - } -} - -} // namespace mbgl diff --git a/src/mbgl/sprite/sprite_loader_worker.hpp b/src/mbgl/sprite/sprite_loader_worker.hpp deleted file mode 100644 index d61e07d14..000000000 --- a/src/mbgl/sprite/sprite_loader_worker.hpp +++ /dev/null @@ -1,23 +0,0 @@ -#pragma once - -#include -#include - -#include -#include - -namespace mbgl { - -class SpriteLoader; - -class SpriteLoaderWorker { -public: - SpriteLoaderWorker(ActorRef, ActorRef); - - void parse(std::shared_ptr image, std::shared_ptr json); - -private: - ActorRef parent; -}; - -} // namespace mbgl