summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIvo van Dongen <info@ivovandongen.nl>2017-05-24 19:02:05 +0300
committerIvo van Dongen <info@ivovandongen.nl>2017-05-30 13:42:46 +0300
commit4198f176145443f7d2ad93eebd317dbc04f5cabb (patch)
tree1833cd71593bea1337fd7d4693ed793d42c7e0f3
parentd4d4f82060fffded3672125c5cceb2caf3eec4f9 (diff)
downloadqtlocation-mapboxgl-4198f176145443f7d2ad93eebd317dbc04f5cabb.tar.gz
[core] asset file source actor
-rw-r--r--platform/default/asset_file_source.cpp74
-rw-r--r--platform/default/default_file_source.cpp2
-rw-r--r--src/mbgl/storage/asset_file_source.hpp8
-rw-r--r--test/storage/asset_file_source.test.cpp22
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();