diff options
author | Ivo van Dongen <info@ivovandongen.nl> | 2017-05-24 19:02:05 +0300 |
---|---|---|
committer | Ivo van Dongen <info@ivovandongen.nl> | 2017-05-30 13:42:46 +0300 |
commit | 4198f176145443f7d2ad93eebd317dbc04f5cabb (patch) | |
tree | 1833cd71593bea1337fd7d4693ed793d42c7e0f3 | |
parent | d4d4f82060fffded3672125c5cceb2caf3eec4f9 (diff) | |
download | qtlocation-mapboxgl-4198f176145443f7d2ad93eebd317dbc04f5cabb.tar.gz |
[core] asset file source actor
-rw-r--r-- | platform/default/asset_file_source.cpp | 74 | ||||
-rw-r--r-- | platform/default/default_file_source.cpp | 2 | ||||
-rw-r--r-- | src/mbgl/storage/asset_file_source.hpp | 8 | ||||
-rw-r--r-- | test/storage/asset_file_source.test.cpp | 22 |
4 files changed, 80 insertions, 26 deletions
diff --git a/platform/default/asset_file_source.cpp b/platform/default/asset_file_source.cpp index 1832818378..23180d736c 100644 --- a/platform/default/asset_file_source.cpp +++ b/platform/default/asset_file_source.cpp @@ -1,5 +1,7 @@ #include <mbgl/storage/asset_file_source.hpp> #include <mbgl/storage/response.hpp> + +#include <mbgl/actor/actor.hpp> #include <mbgl/util/string.hpp> #include <mbgl/util/thread.hpp> #include <mbgl/util/url.hpp> @@ -12,15 +14,34 @@ namespace mbgl { -class AssetFileSource::Impl { +class RequestCallback { public: - Impl(std::string root_) - : root(std::move(root_)) { + RequestCallback(ActorRef<RequestCallback>, FileSource::Callback callback_) + :callback(callback_) { + }; + + ~RequestCallback() = default; + + void operator() (Response response) { + callback(response); } - void request(const std::string& url, FileSource::Callback callback) { +private: + FileSource::Callback callback; +}; + +class AssetRequest { +public: + AssetRequest(ActorRef<AssetRequest>) { + + } + ~AssetRequest() = default; + + void send(const std::string root, const Resource& resource, ActorRef<RequestCallback> callback) { std::string path; + auto url = resource.url; + if (url.size() <= 8 || url[8] == '/') { // This is an empty or absolute path. path = mbgl::util::percentDecode(url.substr(8)); @@ -43,28 +64,55 @@ public: 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())); + Response::Error::Reason::Other, + util::toString(std::current_exception())); } } - callback(response); + callback.invoke(&RequestCallback::operator(), response); + } +}; + +class AssetRequestHandle : public AsyncRequest { +public: + AssetRequestHandle(Scheduler& scheduler, const std::string root, const Resource& resource, FileSource::Callback callback_) + : request(scheduler) + , callback(scheduler, callback_) { + request.invoke(&AssetRequest::send, root, resource, callback.self()); + } + + ~AssetRequestHandle() = default; + +private: + Actor<AssetRequest> request; + Actor<RequestCallback> callback; +}; + + +class AssetFileSource::Impl { +public: + Impl(Scheduler& scheduler_, const std::string& root_) + : scheduler(scheduler_) + , root(root_) { + } + + std::unique_ptr<AsyncRequest> request(const Resource& resource, Callback callback) { + return std::make_unique<AssetRequestHandle>(scheduler, root, resource, callback); } private: - std::string root; + Scheduler& scheduler; + const 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(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 thread->invokeWithCallback(&Impl::request, resource.url, callback); + return impl->request(resource, callback); } } // namespace mbgl diff --git a/platform/default/default_file_source.cpp b/platform/default/default_file_source.cpp index 7d0a393ce5..3b69aeb857 100644 --- a/platform/default/default_file_source.cpp +++ b/platform/default/default_file_source.cpp @@ -183,7 +183,7 @@ DefaultFileSource::DefaultFileSource(Scheduler& scheduler, const std::string& cachePath, const std::string& assetRoot, uint64_t maximumCacheSize) - : DefaultFileSource(scheduler, cachePath, std::make_unique<AssetFileSource>(assetRoot), maximumCacheSize) { + : DefaultFileSource(scheduler, cachePath, std::make_unique<AssetFileSource>(scheduler, assetRoot), maximumCacheSize) { } DefaultFileSource::DefaultFileSource(Scheduler&, diff --git a/src/mbgl/storage/asset_file_source.hpp b/src/mbgl/storage/asset_file_source.hpp index 71e5bbdab3..c37803a5eb 100644 --- a/src/mbgl/storage/asset_file_source.hpp +++ b/src/mbgl/storage/asset_file_source.hpp @@ -4,20 +4,18 @@ namespace mbgl { -namespace util { -template <typename T> class Thread; -} // namespace util +class Scheduler; class AssetFileSource : public FileSource { public: - AssetFileSource(const std::string& assetRoot); + AssetFileSource(Scheduler& scheduler, const std::string& assetRoot); ~AssetFileSource() override; std::unique_ptr<AsyncRequest> request(const Resource&, Callback) override; private: class Impl; - std::unique_ptr<util::Thread<Impl>> thread; + std::unique_ptr<Impl> impl; }; } // namespace mbgl diff --git a/test/storage/asset_file_source.test.cpp b/test/storage/asset_file_source.test.cpp index 010a2c9dc7..bdfa22426d 100644 --- a/test/storage/asset_file_source.test.cpp +++ b/test/storage/asset_file_source.test.cpp @@ -3,6 +3,7 @@ #include <mbgl/util/chrono.hpp> #include <mbgl/util/run_loop.hpp> #include <mbgl/util/thread.hpp> +#include <mbgl/util/default_thread_pool.hpp> #include <gtest/gtest.h> @@ -12,15 +13,17 @@ using namespace mbgl; TEST(AssetFileSource, Load) { util::RunLoop loop; - AssetFileSource fs("test/fixtures/storage/assets"); + ThreadPool threadPool {4}; + AssetFileSource fs(threadPool, "test/fixtures/storage/assets"); // iOS seems to run out of file descriptors... #if TARGET_OS_IPHONE unsigned numThreads = 30; #else - unsigned numThreads = 50; + unsigned numThreads = 1; #endif + auto callback = [&] { if (!--numThreads) { loop.stop(); @@ -79,7 +82,8 @@ TEST(AssetFileSource, Load) { TEST(AssetFileSource, EmptyFile) { util::RunLoop loop; - AssetFileSource fs("test/fixtures/storage/assets"); + ThreadPool threadPool {1}; + AssetFileSource fs(threadPool, "test/fixtures/storage/assets"); std::unique_ptr<AsyncRequest> req = fs.request({ Resource::Unknown, "asset://empty" }, [&](Response res) { req.reset(); @@ -95,7 +99,8 @@ TEST(AssetFileSource, EmptyFile) { TEST(AssetFileSource, NonEmptyFile) { util::RunLoop loop; - AssetFileSource fs("test/fixtures/storage/assets"); + ThreadPool threadPool {1}; + AssetFileSource fs(threadPool, "test/fixtures/storage/assets"); std::unique_ptr<AsyncRequest> req = fs.request({ Resource::Unknown, "asset://nonempty" }, [&](Response res) { req.reset(); @@ -111,7 +116,8 @@ TEST(AssetFileSource, NonEmptyFile) { TEST(AssetFileSource, NonExistentFile) { util::RunLoop loop; - AssetFileSource fs("test/fixtures/storage/assets"); + ThreadPool threadPool {1}; + AssetFileSource fs(threadPool, "test/fixtures/storage/assets"); std::unique_ptr<AsyncRequest> req = fs.request({ Resource::Unknown, "asset://does_not_exist" }, [&](Response res) { req.reset(); @@ -128,7 +134,8 @@ TEST(AssetFileSource, NonExistentFile) { TEST(AssetFileSource, ReadDirectory) { util::RunLoop loop; - AssetFileSource fs("test/fixtures/storage/assets"); + ThreadPool threadPool {1}; + AssetFileSource fs(threadPool, "test/fixtures/storage/assets"); std::unique_ptr<AsyncRequest> req = fs.request({ Resource::Unknown, "asset://directory" }, [&](Response res) { req.reset(); @@ -145,7 +152,8 @@ TEST(AssetFileSource, ReadDirectory) { TEST(AssetFileSource, URLEncoding) { util::RunLoop loop; - AssetFileSource fs("test/fixtures/storage/assets"); + ThreadPool threadPool {1}; + AssetFileSource fs(threadPool, "test/fixtures/storage/assets"); std::unique_ptr<AsyncRequest> req = fs.request({ Resource::Unknown, "asset://%6eonempty" }, [&](Response res) { req.reset(); |