diff options
author | Konstantin Käfer <mail@kkaefer.com> | 2017-01-11 17:56:03 +0100 |
---|---|---|
committer | Konstantin Käfer <mail@kkaefer.com> | 2017-01-11 17:56:03 +0100 |
commit | 69b188d8b2dc34e232912d6cae01af55c745dbcf (patch) | |
tree | a50a66da58bf811a2d8666d4a584f50d2c088421 | |
parent | a720cd6b6bf114a67a8136523a23ad86af2fc8b6 (diff) | |
download | qtlocation-mapboxgl-69b188d8b2dc34e232912d6cae01af55c745dbcf.tar.gz |
[core] also conver Android's AssetFileSource to the actor modelupstream/filesource-actor
-rw-r--r-- | platform/android/src/asset_file_source.cpp | 66 | ||||
-rw-r--r-- | platform/default/asset_file_source.cpp | 126 | ||||
-rw-r--r-- | src/mbgl/storage/asset_file_source.hpp | 10 |
3 files changed, 112 insertions, 90 deletions
diff --git a/platform/android/src/asset_file_source.cpp b/platform/android/src/asset_file_source.cpp index d677d326d8..2f535df9ac 100644 --- a/platform/android/src/asset_file_source.cpp +++ b/platform/android/src/asset_file_source.cpp @@ -1,9 +1,13 @@ #include <mbgl/storage/asset_file_source.hpp> #include <mbgl/storage/response.hpp> +#include <mbgl/util/run_loop.hpp> #include <mbgl/util/util.hpp> #include <mbgl/util/thread.hpp> #include <mbgl/util/url.hpp> +#include <mbgl/actor/actor.hpp> +#include <mbgl/actor/actor_ref.hpp> + #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wshadow" #include <zip.h> @@ -35,13 +39,23 @@ struct ZipFileHolder { namespace mbgl { -class AssetFileSource::Impl { +class AssetFileRequest : public AsyncRequest { +public: + AssetFileRequest(std::shared_ptr<FileSource::Callback> callback_) + : callback(std::move(callback_)) { + } + +private: + std::shared_ptr<FileSource::Callback> callback; +}; + +class AssetFileSource::Worker { public: - Impl(const std::string& root_) - : root(root_) { + Worker(ActorRef<Worker>, ActorRef<AssetFileSource> parent_, std::string root_) + : parent(std::move(parent_)), root(std::move(root_)) { } - void request(const std::string& url, FileSource::Callback callback) { + void readFile(const std::string& url, std::weak_ptr<Callback> callback) { ZipHolder archive = ::zip_open(root.c_str(), 0, nullptr); if (!archive.archive) { reportError(Response::Error::Reason::Other, "Could not open zip archive", callback); @@ -76,29 +90,55 @@ public: Response response; response.data = buf; - callback(response); + + parent.invoke(&AssetFileSource::respond, callback, response); } - void reportError(Response::Error::Reason reason, const char * message, FileSource::Callback callback) { + void reportError(Response::Error::Reason reason, + const char* message, + std::weak_ptr<Callback> callback) { Response response; response.error = std::make_unique<Response::Error>(reason, message); - callback(response); + parent.invoke(&AssetFileSource::respond, callback, response); } private: + ActorRef<AssetFileSource> parent; std::string root; }; -AssetFileSource::AssetFileSource(const std::string& root) - : thread(std::make_unique<util::Thread<Impl>>( - util::ThreadContext{"AssetFileSource", util::ThreadPriority::Low}, - root)) { +// AssetFileSource::AssetFileSource(const std::string& root) +// : thread(std::make_unique<util::Thread<Impl>>( +// util::ThreadContext{"AssetFileSource", util::ThreadPriority::Low}, +// root)) { +// } + +// AssetFileSource::~AssetFileSource() = default; + +// std::unique_ptr<AsyncRequest> AssetFileSource::request(const Resource& resource, Callback callback) { +// return thread->invokeWithCallback(&Impl::request, resource.url, callback); +// } + + +AssetFileSource::AssetFileSource(Scheduler& scheduler, const std::string& root) + : mailbox(std::make_shared<Mailbox>(*util::RunLoop::Get())), + worker(std::make_unique<Actor<Worker>>( + scheduler, ActorRef<AssetFileSource>(*this, mailbox), root)) { } AssetFileSource::~AssetFileSource() = default; -std::unique_ptr<AsyncRequest> AssetFileSource::request(const Resource& resource, Callback callback) { - return thread->invokeWithCallback(&Impl::request, resource.url, callback); +std::unique_ptr<AsyncRequest> AssetFileSource::request(const Resource& resource, + Callback callback) { + auto cb = std::make_shared<Callback>(std::move(callback)); + worker->invoke(&Worker::readFile, resource.url, cb); + return std::make_unique<AssetFileRequest>(std::move(cb)); +} + +void AssetFileSource::respond(std::weak_ptr<Callback> callback, Response response) { + if (auto locked = callback.lock()) { + (*locked)(response); + } } } diff --git a/platform/default/asset_file_source.cpp b/platform/default/asset_file_source.cpp index de7556b656..9ca002039b 100644 --- a/platform/default/asset_file_source.cpp +++ b/platform/default/asset_file_source.cpp @@ -1,10 +1,10 @@ #include <mbgl/storage/asset_file_source.hpp> #include <mbgl/storage/response.hpp> #include <mbgl/util/io.hpp> +#include <mbgl/util/run_loop.hpp> #include <mbgl/util/string.hpp> #include <mbgl/util/url.hpp> #include <mbgl/util/util.hpp> -#include <mbgl/util/run_loop.hpp> #include <mbgl/actor/actor.hpp> #include <mbgl/actor/actor_ref.hpp> @@ -15,101 +15,77 @@ namespace mbgl { -class AssetFileSource::Impl { +class AssetFileRequest : public AsyncRequest { public: - Impl(Scheduler&, const std::string& root); - - class Request; - std::unique_ptr<Request> readFile(const Resource&, Callback); - void respond(std::weak_ptr<Callback>, Response); + AssetFileRequest(std::shared_ptr<FileSource::Callback> callback_) + : callback(std::move(callback_)) { + } private: - std::shared_ptr<Mailbox> mailbox{ std::make_shared<Mailbox>(*util::RunLoop::Get()) }; - class Worker { - public: - Worker(ActorRef<Worker>, ActorRef<Impl>, std::string root); - - void readFile(const std::string& url, std::weak_ptr<Callback>); - - private: - ActorRef<Impl> impl; - const std::string root; - }; - Actor<Worker> worker; + std::shared_ptr<FileSource::Callback> callback; }; -class AssetFileSource::Impl::Request : public AsyncRequest { +class AssetFileSource::Worker { public: - Request(std::shared_ptr<Callback> callback_) : callback(std::move(callback_)) { + Worker(ActorRef<Worker>, ActorRef<AssetFileSource> parent_, std::string root_) + : parent(std::move(parent_)), root(std::move(root_)) { } + void readFile(const std::string& url, std::weak_ptr<Callback> callback) { + std::string path; + + if (url.size() <= 8 || url[8] == '/') { + // This is an empty or absolute path. + path = mbgl::util::percentDecode(url.substr(8)); + } else { + // This is a relative path. Prefix with the application root. + path = root + "/" + mbgl::util::percentDecode(url.substr(8)); + } -private: - std::shared_ptr<Callback> callback; -}; - -AssetFileSource::Impl::Worker::Worker(ActorRef<Worker>, ActorRef<Impl> impl_, std::string root_) - : impl(std::move(impl_)), root(std::move(root_)) { -} - -void AssetFileSource::Impl::Worker::readFile(const std::string& url, - std::weak_ptr<Callback> callback) { - std::string path; + Response response; + + struct stat buf; + int result = stat(path.c_str(), &buf); + + if (result == 0 && S_ISDIR(buf.st_mode)) { + response.error = std::make_unique<Response::Error>(Response::Error::Reason::NotFound); + } else if (result == -1 && errno == ENOENT) { + response.error = std::make_unique<Response::Error>(Response::Error::Reason::NotFound); + } else { + try { + response.data = std::make_shared<std::string>(util::read_file(path)); + } catch (...) { + response.error = std::make_unique<Response::Error>( + Response::Error::Reason::Other, util::toString(std::current_exception())); + } + } - if (url.size() <= 8 || url[8] == '/') { - // This is an empty or absolute path. - path = mbgl::util::percentDecode(url.substr(8)); - } else { - // This is a relative path. Prefix with the application root. - path = root + "/" + mbgl::util::percentDecode(url.substr(8)); + parent.invoke(&AssetFileSource::respond, callback, response); } - Response response; - - struct stat buf; - int result = stat(path.c_str(), &buf); - - if (result == 0 && S_ISDIR(buf.st_mode)) { - response.error = std::make_unique<Response::Error>(Response::Error::Reason::NotFound); - } else if (result == -1 && errno == ENOENT) { - response.error = std::make_unique<Response::Error>(Response::Error::Reason::NotFound); - } else { - try { - response.data = std::make_shared<std::string>(util::read_file(path)); - } catch (...) { - response.error = std::make_unique<Response::Error>( - Response::Error::Reason::Other, util::toString(std::current_exception())); - } - } +private: + ActorRef<AssetFileSource> parent; + const std::string root; +}; - impl.invoke(&Impl::respond, callback, response); +AssetFileSource::AssetFileSource(Scheduler& scheduler, const std::string& root) + : mailbox(std::make_shared<Mailbox>(*util::RunLoop::Get())), + worker(std::make_unique<Actor<Worker>>( + scheduler, ActorRef<AssetFileSource>(*this, mailbox), root)) { } -AssetFileSource::Impl::Impl(Scheduler& scheduler, const std::string& root) - : worker(scheduler, ActorRef<Impl>(*this, mailbox), root) { -} +AssetFileSource::~AssetFileSource() = default; -std::unique_ptr<AssetFileSource::Impl::Request> -AssetFileSource::Impl::readFile(const Resource& resource, Callback callback) { +std::unique_ptr<AsyncRequest> AssetFileSource::request(const Resource& resource, + Callback callback) { auto cb = std::make_shared<Callback>(std::move(callback)); - worker.invoke(&Worker::readFile, resource.url, cb); - return std::make_unique<Request>(std::move(cb)); + worker->invoke(&Worker::readFile, resource.url, cb); + return std::make_unique<AssetFileRequest>(std::move(cb)); } -void AssetFileSource::Impl::respond(std::weak_ptr<Callback> callback, Response response) { +void AssetFileSource::respond(std::weak_ptr<Callback> callback, Response response) { if (auto locked = callback.lock()) { (*locked)(response); } } -AssetFileSource::AssetFileSource(Scheduler& scheduler, const std::string& root) - : impl(std::make_unique<Impl>(scheduler, root)) { -} - -AssetFileSource::~AssetFileSource() = default; - -std::unique_ptr<AsyncRequest> AssetFileSource::request(const Resource& resource, - Callback callback) { - return impl->readFile(resource, std::move(callback)); -} - } // namespace mbgl diff --git a/src/mbgl/storage/asset_file_source.hpp b/src/mbgl/storage/asset_file_source.hpp index b3f861fb27..461752a1e6 100644 --- a/src/mbgl/storage/asset_file_source.hpp +++ b/src/mbgl/storage/asset_file_source.hpp @@ -4,7 +4,9 @@ namespace mbgl { +template <class> class Actor; class Scheduler; +class Mailbox; class AssetFileSource : public FileSource { public: @@ -14,8 +16,12 @@ public: std::unique_ptr<AsyncRequest> request(const Resource&, Callback) override; private: - class Impl; - const std::unique_ptr<Impl> impl; + void respond(std::weak_ptr<Callback>, Response); + +private: + std::shared_ptr<Mailbox> mailbox; + class Worker; + const std::unique_ptr<Actor<Worker>> worker; }; } // namespace mbgl |