#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include namespace mbgl { static SpriteLoaderObserver nullObserver; struct SpriteLoader::Loader { Loader(SpriteLoader& imageManager) : mailbox(std::make_shared(*Scheduler::GetCurrent())), worker(Scheduler::GetBackground(), ActorRef(imageManager, mailbox)) { } 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) { } SpriteLoader::~SpriteLoader() = default; void SpriteLoader::load(const std::string& url, FileSource& fileSource) { if (url.empty()) { // Treat a non-existent sprite as a successfully loaded empty sprite. observer->onSpriteLoaded({}); return; } loader = std::make_unique(*this); loader->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(); emitSpriteLoadedIfComplete(); } else if (loader->json != res.data) { // They can be equal, see OnlineFileRequest::completed(). // Only trigger a sprite loaded event we got new data. loader->json = std::move(res.data); emitSpriteLoadedIfComplete(); } }); loader->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(); emitSpriteLoadedIfComplete(); } else if (loader->image != res.data) { // They can be equal - see OnlineFileRequest::completed(). loader->image = std::move(res.data); emitSpriteLoadedIfComplete(); } }); } void SpriteLoader::emitSpriteLoadedIfComplete() { assert(loader); if (!loader->image || !loader->json) { return; } loader->worker.self().invoke(&SpriteLoaderWorker::parse, loader->image, loader->json); } void SpriteLoader::onParsed(std::vector> result) { observer->onSpriteLoaded(std::move(result)); } void SpriteLoader::onError(std::exception_ptr err) { observer->onSpriteError(err); } void SpriteLoader::setObserver(SpriteLoaderObserver* observer_) { observer = observer_; } } // namespace mbgl