summaryrefslogtreecommitdiff
path: root/platform/default
diff options
context:
space:
mode:
Diffstat (limited to 'platform/default')
-rw-r--r--platform/default/asset_file_source.cpp17
-rw-r--r--platform/default/async_task.cpp2
-rw-r--r--platform/default/bidi.cpp6
-rw-r--r--platform/default/default_file_source.cpp165
-rw-r--r--platform/default/image.cpp2
-rw-r--r--platform/default/jpeg_reader.cpp8
-rw-r--r--platform/default/local_file_source.cpp15
-rw-r--r--platform/default/mbgl/gl/headless_backend.cpp3
-rw-r--r--platform/default/mbgl/gl/headless_backend.hpp2
-rw-r--r--platform/default/mbgl/gl/offscreen_view.cpp1
-rw-r--r--platform/default/mbgl/gl/offscreen_view.hpp2
-rw-r--r--platform/default/mbgl/storage/offline_download.cpp85
-rw-r--r--platform/default/online_file_source.cpp44
-rw-r--r--platform/default/png_reader.cpp2
-rw-r--r--platform/default/sqlite3.cpp8
-rw-r--r--platform/default/timer.cpp2
16 files changed, 213 insertions, 151 deletions
diff --git a/platform/default/asset_file_source.cpp b/platform/default/asset_file_source.cpp
index 1832818378..343f3b70ce 100644
--- a/platform/default/asset_file_source.cpp
+++ b/platform/default/asset_file_source.cpp
@@ -1,4 +1,5 @@
#include <mbgl/storage/asset_file_source.hpp>
+#include <mbgl/storage/file_source_request.hpp>
#include <mbgl/storage/response.hpp>
#include <mbgl/util/string.hpp>
#include <mbgl/util/thread.hpp>
@@ -14,11 +15,11 @@ namespace mbgl {
class AssetFileSource::Impl {
public:
- Impl(std::string root_)
+ Impl(ActorRef<Impl>, std::string root_)
: root(std::move(root_)) {
}
- void request(const std::string& url, FileSource::Callback callback) {
+ void request(const std::string& url, ActorRef<FileSourceRequest> req) {
std::string path;
if (url.size() <= 8 || url[8] == '/') {
@@ -48,7 +49,7 @@ public:
}
}
- callback(response);
+ req.invoke(&FileSourceRequest::setResponse, response);
}
private:
@@ -56,15 +57,17 @@ private:
};
AssetFileSource::AssetFileSource(const std::string& root)
- : thread(std::make_unique<util::Thread<Impl>>(
- util::ThreadContext{"AssetFileSource", util::ThreadPriority::Low},
- root)) {
+ : impl(std::make_unique<util::Thread<Impl>>("AssetFileSource", root)) {
}
AssetFileSource::~AssetFileSource() = default;
std::unique_ptr<AsyncRequest> AssetFileSource::request(const Resource& resource, Callback callback) {
- return thread->invokeWithCallback(&Impl::request, resource.url, callback);
+ auto req = std::make_unique<FileSourceRequest>(std::move(callback));
+
+ impl->actor().invoke(&Impl::request, resource.url, req->actor());
+
+ return std::move(req);
}
} // namespace mbgl
diff --git a/platform/default/async_task.cpp b/platform/default/async_task.cpp
index 5fa9db8d33..50891056d8 100644
--- a/platform/default/async_task.cpp
+++ b/platform/default/async_task.cpp
@@ -16,7 +16,7 @@ public:
: async(new uv_async_t),
task(std::move(fn)) {
- uv_loop_t* loop = reinterpret_cast<uv_loop_t*>(RunLoop::getLoopHandle());
+ auto* loop = reinterpret_cast<uv_loop_t*>(RunLoop::getLoopHandle());
if (uv_async_init(loop, async, asyncCallback) != 0) {
throw std::runtime_error("Failed to initialize async.");
}
diff --git a/platform/default/bidi.cpp b/platform/default/bidi.cpp
index a76c4bcaac..d475c387b3 100644
--- a/platform/default/bidi.cpp
+++ b/platform/default/bidi.cpp
@@ -30,7 +30,7 @@ std::u16string applyArabicShaping(const std::u16string& input) {
UErrorCode errorCode = U_ZERO_ERROR;
const int32_t outputLength =
- u_shapeArabic(mbgl::utf16char_cast<const UChar*>(input.c_str()), static_cast<int32_t>(input.size()), NULL, 0,
+ u_shapeArabic(mbgl::utf16char_cast<const UChar*>(input.c_str()), static_cast<int32_t>(input.size()), nullptr, 0,
(U_SHAPE_LETTERS_SHAPE & U_SHAPE_LETTERS_MASK) |
(U_SHAPE_TEXT_DIRECTION_LOGICAL & U_SHAPE_TEXT_DIRECTION_MASK),
&errorCode);
@@ -57,7 +57,7 @@ void BiDi::mergeParagraphLineBreaks(std::set<size_t>& lineBreakPoints) {
for (int32_t i = 0; i < paragraphCount; i++) {
UErrorCode errorCode = U_ZERO_ERROR;
int32_t paragraphEndIndex;
- ubidi_getParagraphByIndex(impl->bidiText, i, NULL, &paragraphEndIndex, NULL, &errorCode);
+ ubidi_getParagraphByIndex(impl->bidiText, i, nullptr, &paragraphEndIndex, nullptr, &errorCode);
if (U_FAILURE(errorCode)) {
throw std::runtime_error(std::string("ProcessedBiDiText::mergeParagraphLineBreaks: ") +
@@ -92,7 +92,7 @@ std::vector<std::u16string> BiDi::processText(const std::u16string& input,
UErrorCode errorCode = U_ZERO_ERROR;
ubidi_setPara(impl->bidiText, mbgl::utf16char_cast<const UChar*>(input.c_str()), static_cast<int32_t>(input.size()),
- UBIDI_DEFAULT_LTR, NULL, &errorCode);
+ UBIDI_DEFAULT_LTR, nullptr, &errorCode);
if (U_FAILURE(errorCode)) {
throw std::runtime_error(std::string("BiDi::processText: ") + u_errorName(errorCode));
diff --git a/platform/default/default_file_source.cpp b/platform/default/default_file_source.cpp
index 7db0b85461..bf8d7b6348 100644
--- a/platform/default/default_file_source.cpp
+++ b/platform/default/default_file_source.cpp
@@ -1,9 +1,11 @@
#include <mbgl/storage/default_file_source.hpp>
#include <mbgl/storage/asset_file_source.hpp>
+#include <mbgl/storage/file_source_request.hpp>
#include <mbgl/storage/local_file_source.hpp>
#include <mbgl/storage/online_file_source.hpp>
#include <mbgl/storage/offline_database.hpp>
#include <mbgl/storage/offline_download.hpp>
+#include <mbgl/storage/resource_transform.hpp>
#include <mbgl/util/platform.hpp>
#include <mbgl/util/url.hpp>
@@ -26,8 +28,10 @@ namespace mbgl {
class DefaultFileSource::Impl {
public:
- Impl(const std::string& cachePath, uint64_t maximumCacheSize)
- : offlineDatabase(cachePath, maximumCacheSize) {
+ Impl(ActorRef<Impl>, std::shared_ptr<FileSource> assetFileSource_, const std::string& cachePath, uint64_t maximumCacheSize)
+ : assetFileSource(assetFileSource_)
+ , localFileSource(std::make_unique<LocalFileSource>())
+ , offlineDatabase(cachePath, maximumCacheSize) {
}
void setAPIBaseURL(const std::string& url) {
@@ -46,7 +50,7 @@ public:
return onlineFileSource.getAccessToken();
}
- void setResourceTransform(OnlineFileSource::ResourceTransform&& transform) {
+ void setResourceTransform(optional<ActorRef<ResourceTransform>>&& transform) {
onlineFileSource.setResourceTransform(std::move(transform));
}
@@ -104,36 +108,50 @@ public:
getDownload(regionID).setState(state);
}
- void request(AsyncRequest* req, Resource resource, Callback callback) {
- Resource revalidation = resource;
-
- const bool hasPrior = resource.priorEtag || resource.priorModified || resource.priorExpires;
- if (!hasPrior || resource.necessity == Resource::Optional) {
- auto offlineResponse = offlineDatabase.get(resource);
-
- if (resource.necessity == Resource::Optional && !offlineResponse) {
- // Ensure there's always a response that we can send, so the caller knows that
- // there's no optional data available in the cache.
- offlineResponse.emplace();
- offlineResponse->noContent = true;
- offlineResponse->error = std::make_unique<Response::Error>(
- Response::Error::Reason::NotFound, "Not found in offline database");
+ void request(AsyncRequest* req, Resource resource, ActorRef<FileSourceRequest> ref) {
+ auto callback = [ref] (const Response& res) mutable {
+ ref.invoke(&FileSourceRequest::setResponse, res);
+ };
+
+ if (isAssetURL(resource.url)) {
+ //Asset request
+ tasks[req] = assetFileSource->request(resource, callback);
+ } else if (LocalFileSource::acceptsURL(resource.url)) {
+ //Local file request
+ tasks[req] = localFileSource->request(resource, callback);
+ } else {
+ // Try the offline database
+ Resource revalidation = resource;
+
+ const bool hasPrior = resource.priorEtag || resource.priorModified || resource.priorExpires;
+ if (!hasPrior || resource.necessity == Resource::Optional) {
+ auto offlineResponse = offlineDatabase.get(resource);
+
+ if (resource.necessity == Resource::Optional && !offlineResponse) {
+ // Ensure there's always a response that we can send, so the caller knows that
+ // there's no optional data available in the cache.
+ offlineResponse.emplace();
+ offlineResponse->noContent = true;
+ offlineResponse->error = std::make_unique<Response::Error>(
+ Response::Error::Reason::NotFound, "Not found in offline database");
+ }
+
+ if (offlineResponse) {
+ revalidation.priorModified = offlineResponse->modified;
+ revalidation.priorExpires = offlineResponse->expires;
+ revalidation.priorEtag = offlineResponse->etag;
+ callback(*offlineResponse);
+ }
}
- if (offlineResponse) {
- revalidation.priorModified = offlineResponse->modified;
- revalidation.priorExpires = offlineResponse->expires;
- revalidation.priorEtag = offlineResponse->etag;
- callback(*offlineResponse);
+ // Get from the online file source
+ if (resource.necessity == Resource::Required) {
+ tasks[req] = onlineFileSource.request(revalidation, [=] (Response onlineResponse) mutable {
+ this->offlineDatabase.put(revalidation, onlineResponse);
+ callback(onlineResponse);
+ });
}
}
-
- if (resource.necessity == Resource::Required) {
- tasks[req] = onlineFileSource.request(revalidation, [=] (Response onlineResponse) {
- this->offlineDatabase.put(revalidation, onlineResponse);
- callback(onlineResponse);
- });
- }
}
void cancel(AsyncRequest* req) {
@@ -158,6 +176,9 @@ private:
std::make_unique<OfflineDownload>(regionID, offlineDatabase.getRegionDefinition(regionID), offlineDatabase, onlineFileSource)).first->second;
}
+ // shared so that destruction is done on the creating thread
+ const std::shared_ptr<FileSource> assetFileSource;
+ const std::unique_ptr<FileSource> localFileSource;
OfflineDatabase offlineDatabase;
OnlineFileSource onlineFileSource;
std::unordered_map<AsyncRequest*, std::unique_ptr<AsyncRequest>> tasks;
@@ -173,118 +194,102 @@ DefaultFileSource::DefaultFileSource(const std::string& cachePath,
DefaultFileSource::DefaultFileSource(const std::string& cachePath,
std::unique_ptr<FileSource>&& assetFileSource_,
uint64_t maximumCacheSize)
- : thread(std::make_unique<util::Thread<Impl>>(util::ThreadContext{"DefaultFileSource", util::ThreadPriority::Low},
- cachePath, maximumCacheSize)),
- assetFileSource(std::move(assetFileSource_)),
- localFileSource(std::make_unique<LocalFileSource>()) {
+ : assetFileSource(std::move(assetFileSource_))
+ , impl(std::make_unique<util::Thread<Impl>>("DefaultFileSource", assetFileSource, cachePath, maximumCacheSize)) {
}
DefaultFileSource::~DefaultFileSource() = default;
void DefaultFileSource::setAPIBaseURL(const std::string& baseURL) {
- thread->invoke(&Impl::setAPIBaseURL, baseURL);
- cachedBaseURL = baseURL;
+ impl->actor().invoke(&Impl::setAPIBaseURL, baseURL);
+
+ {
+ std::lock_guard<std::mutex> lock(cachedBaseURLMutex);
+ cachedBaseURL = baseURL;
+ }
}
-std::string DefaultFileSource::getAPIBaseURL() const {
+std::string DefaultFileSource::getAPIBaseURL() {
+ std::lock_guard<std::mutex> lock(cachedBaseURLMutex);
return cachedBaseURL;
}
void DefaultFileSource::setAccessToken(const std::string& accessToken) {
- thread->invoke(&Impl::setAccessToken, accessToken);
- cachedAccessToken = accessToken;
+ impl->actor().invoke(&Impl::setAccessToken, accessToken);
+
+ {
+ std::lock_guard<std::mutex> lock(cachedAccessTokenMutex);
+ cachedAccessToken = accessToken;
+ }
}
-std::string DefaultFileSource::getAccessToken() const {
+std::string DefaultFileSource::getAccessToken() {
+ std::lock_guard<std::mutex> lock(cachedAccessTokenMutex);
return cachedAccessToken;
}
-void DefaultFileSource::setResourceTransform(std::function<std::string(Resource::Kind, std::string&&)> transform) {
- if (transform) {
- auto loop = util::RunLoop::Get();
- thread->invoke(&Impl::setResourceTransform, [loop, transform](Resource::Kind kind_, std::string&& url_, auto callback_) {
- return loop->invokeWithCallback([transform](Resource::Kind kind, std::string&& url, auto callback) {
- callback(transform(kind, std::move(url)));
- }, kind_, std::move(url_), callback_);
- });
- } else {
- thread->invoke(&Impl::setResourceTransform, nullptr);
- }
+void DefaultFileSource::setResourceTransform(optional<ActorRef<ResourceTransform>>&& transform) {
+ impl->actor().invoke(&Impl::setResourceTransform, std::move(transform));
}
std::unique_ptr<AsyncRequest> DefaultFileSource::request(const Resource& resource, Callback callback) {
- class DefaultFileRequest : public AsyncRequest {
- public:
- DefaultFileRequest(Resource resource_, FileSource::Callback callback_, util::Thread<DefaultFileSource::Impl>& thread_)
- : thread(thread_),
- workRequest(thread.invokeWithCallback(&DefaultFileSource::Impl::request, this, resource_, callback_)) {
- }
+ auto req = std::make_unique<FileSourceRequest>(std::move(callback));
- ~DefaultFileRequest() override {
- thread.invoke(&DefaultFileSource::Impl::cancel, this);
- }
+ req->onCancel([fs = impl->actor(), req = req.get()] () mutable { fs.invoke(&Impl::cancel, req); });
- util::Thread<DefaultFileSource::Impl>& thread;
- std::unique_ptr<AsyncRequest> workRequest;
- };
+ impl->actor().invoke(&Impl::request, req.get(), resource, req->actor());
- if (isAssetURL(resource.url)) {
- return assetFileSource->request(resource, callback);
- } else if (LocalFileSource::acceptsURL(resource.url)) {
- return localFileSource->request(resource, callback);
- } else {
- return std::make_unique<DefaultFileRequest>(resource, callback, *thread);
- }
+ return std::move(req);
}
void DefaultFileSource::listOfflineRegions(std::function<void (std::exception_ptr, optional<std::vector<OfflineRegion>>)> callback) {
- thread->invoke(&Impl::listRegions, callback);
+ impl->actor().invoke(&Impl::listRegions, callback);
}
void DefaultFileSource::createOfflineRegion(const OfflineRegionDefinition& definition,
const OfflineRegionMetadata& metadata,
std::function<void (std::exception_ptr, optional<OfflineRegion>)> callback) {
- thread->invoke(&Impl::createRegion, definition, metadata, callback);
+ impl->actor().invoke(&Impl::createRegion, definition, metadata, callback);
}
void DefaultFileSource::updateOfflineMetadata(const int64_t regionID,
const OfflineRegionMetadata& metadata,
std::function<void (std::exception_ptr, optional<OfflineRegionMetadata>)> callback) {
- thread->invoke(&Impl::updateMetadata, regionID, metadata, callback);
+ impl->actor().invoke(&Impl::updateMetadata, regionID, metadata, callback);
}
void DefaultFileSource::deleteOfflineRegion(OfflineRegion&& region, std::function<void (std::exception_ptr)> callback) {
- thread->invoke(&Impl::deleteRegion, std::move(region), callback);
+ impl->actor().invoke(&Impl::deleteRegion, std::move(region), callback);
}
void DefaultFileSource::setOfflineRegionObserver(OfflineRegion& region, std::unique_ptr<OfflineRegionObserver> observer) {
- thread->invoke(&Impl::setRegionObserver, region.getID(), std::move(observer));
+ impl->actor().invoke(&Impl::setRegionObserver, region.getID(), std::move(observer));
}
void DefaultFileSource::setOfflineRegionDownloadState(OfflineRegion& region, OfflineRegionDownloadState state) {
- thread->invoke(&Impl::setRegionDownloadState, region.getID(), state);
+ impl->actor().invoke(&Impl::setRegionDownloadState, region.getID(), state);
}
void DefaultFileSource::getOfflineRegionStatus(OfflineRegion& region, std::function<void (std::exception_ptr, optional<OfflineRegionStatus>)> callback) const {
- thread->invoke(&Impl::getRegionStatus, region.getID(), callback);
+ impl->actor().invoke(&Impl::getRegionStatus, region.getID(), callback);
}
void DefaultFileSource::setOfflineMapboxTileCountLimit(uint64_t limit) const {
- thread->invokeSync(&Impl::setOfflineMapboxTileCountLimit, limit);
+ impl->actor().invoke(&Impl::setOfflineMapboxTileCountLimit, limit);
}
void DefaultFileSource::pause() {
- thread->pause();
+ impl->pause();
}
void DefaultFileSource::resume() {
- thread->resume();
+ impl->resume();
}
// For testing only:
void DefaultFileSource::put(const Resource& resource, const Response& response) {
- thread->invokeSync(&Impl::put, resource, response);
+ impl->actor().invoke(&Impl::put, resource, response);
}
} // namespace mbgl
diff --git a/platform/default/image.cpp b/platform/default/image.cpp
index ad9d83a08d..447c6bcd66 100644
--- a/platform/default/image.cpp
+++ b/platform/default/image.cpp
@@ -12,7 +12,7 @@ PremultipliedImage decodePNG(const uint8_t*, size_t);
PremultipliedImage decodeJPEG(const uint8_t*, size_t);
PremultipliedImage decodeImage(const std::string& string) {
- const uint8_t* data = reinterpret_cast<const uint8_t*>(string.data());
+ const auto* data = reinterpret_cast<const uint8_t*>(string.data());
const size_t size = string.size();
#if !defined(__ANDROID__) && !defined(__APPLE__)
diff --git a/platform/default/jpeg_reader.cpp b/platform/default/jpeg_reader.cpp
index c5e9d880c0..5f613f9423 100644
--- a/platform/default/jpeg_reader.cpp
+++ b/platform/default/jpeg_reader.cpp
@@ -21,12 +21,12 @@ struct jpeg_stream_wrapper {
};
static void init_source(j_decompress_ptr cinfo) {
- jpeg_stream_wrapper* wrap = reinterpret_cast<jpeg_stream_wrapper*>(cinfo->src);
+ auto* wrap = reinterpret_cast<jpeg_stream_wrapper*>(cinfo->src);
wrap->stream->seekg(0, std::ios_base::beg);
}
static boolean fill_input_buffer(j_decompress_ptr cinfo) {
- jpeg_stream_wrapper* wrap = reinterpret_cast<jpeg_stream_wrapper*>(cinfo->src);
+ auto* wrap = reinterpret_cast<jpeg_stream_wrapper*>(cinfo->src);
wrap->stream->read(reinterpret_cast<char*>(&wrap->buffer[0]), BUF_SIZE);
std::streamsize size = wrap->stream->gcount();
wrap->manager.next_input_byte = wrap->buffer.data();
@@ -36,7 +36,7 @@ static boolean fill_input_buffer(j_decompress_ptr cinfo) {
static void skip(j_decompress_ptr cinfo, long count) {
if (count <= 0) return; // A zero or negative skip count should be treated as a no-op.
- jpeg_stream_wrapper* wrap = reinterpret_cast<jpeg_stream_wrapper*>(cinfo->src);
+ auto* wrap = reinterpret_cast<jpeg_stream_wrapper*>(cinfo->src);
if (wrap->manager.bytes_in_buffer > 0 && count < static_cast<long>(wrap->manager.bytes_in_buffer))
{
@@ -59,7 +59,7 @@ static void attach_stream(j_decompress_ptr cinfo, std::istream* in) {
cinfo->src = (struct jpeg_source_mgr *)
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT, sizeof(jpeg_stream_wrapper));
}
- jpeg_stream_wrapper * src = reinterpret_cast<jpeg_stream_wrapper*> (cinfo->src);
+ auto * src = reinterpret_cast<jpeg_stream_wrapper*> (cinfo->src);
src->manager.init_source = init_source;
src->manager.fill_input_buffer = fill_input_buffer;
src->manager.skip_input_data = skip;
diff --git a/platform/default/local_file_source.cpp b/platform/default/local_file_source.cpp
index 93b42f5fa0..21a291d8d4 100644
--- a/platform/default/local_file_source.cpp
+++ b/platform/default/local_file_source.cpp
@@ -1,4 +1,5 @@
#include <mbgl/storage/local_file_source.hpp>
+#include <mbgl/storage/file_source_request.hpp>
#include <mbgl/storage/response.hpp>
#include <mbgl/util/string.hpp>
#include <mbgl/util/thread.hpp>
@@ -21,7 +22,9 @@ namespace mbgl {
class LocalFileSource::Impl {
public:
- void request(const std::string& url, FileSource::Callback callback) {
+ Impl(ActorRef<Impl>) {}
+
+ void request(const std::string& url, ActorRef<FileSourceRequest> req) {
// Cut off the protocol
std::string path = mbgl::util::percentDecode(url.substr(protocolLength));
@@ -44,19 +47,23 @@ public:
}
}
- callback(response);
+ req.invoke(&FileSourceRequest::setResponse, response);
}
};
LocalFileSource::LocalFileSource()
- : thread(std::make_unique<util::Thread<Impl>>(util::ThreadContext{"LocalFileSource", util::ThreadPriority::Low})) {
+ : impl(std::make_unique<util::Thread<Impl>>("LocalFileSource")) {
}
LocalFileSource::~LocalFileSource() = default;
std::unique_ptr<AsyncRequest> LocalFileSource::request(const Resource& resource, Callback callback) {
- return thread->invokeWithCallback(&Impl::request, resource.url, callback);
+ auto req = std::make_unique<FileSourceRequest>(std::move(callback));
+
+ impl->actor().invoke(&Impl::request, resource.url, req->actor());
+
+ return std::move(req);
}
bool LocalFileSource::acceptsURL(const std::string& url) {
diff --git a/platform/default/mbgl/gl/headless_backend.cpp b/platform/default/mbgl/gl/headless_backend.cpp
index d2fbf4e4c7..df3a517823 100644
--- a/platform/default/mbgl/gl/headless_backend.cpp
+++ b/platform/default/mbgl/gl/headless_backend.cpp
@@ -9,8 +9,7 @@
namespace mbgl {
-HeadlessBackend::HeadlessBackend() {
-}
+HeadlessBackend::HeadlessBackend() = default;
HeadlessBackend::HeadlessBackend(std::shared_ptr<HeadlessDisplay> display_)
: display(std::move(display_)) {
diff --git a/platform/default/mbgl/gl/headless_backend.hpp b/platform/default/mbgl/gl/headless_backend.hpp
index 128b579bd2..26033acf82 100644
--- a/platform/default/mbgl/gl/headless_backend.hpp
+++ b/platform/default/mbgl/gl/headless_backend.hpp
@@ -20,7 +20,7 @@ public:
void invalidate() override;
struct Impl {
- virtual ~Impl() {}
+ virtual ~Impl() = default;
virtual void activateContext() = 0;
virtual void deactivateContext() {}
};
diff --git a/platform/default/mbgl/gl/offscreen_view.cpp b/platform/default/mbgl/gl/offscreen_view.cpp
index 5424e03c96..e7cf7cffe5 100644
--- a/platform/default/mbgl/gl/offscreen_view.cpp
+++ b/platform/default/mbgl/gl/offscreen_view.cpp
@@ -24,6 +24,7 @@ public:
context.bindFramebuffer = framebuffer->framebuffer;
}
+ context.scissorTest = false;
context.viewport = { 0, 0, size };
}
diff --git a/platform/default/mbgl/gl/offscreen_view.hpp b/platform/default/mbgl/gl/offscreen_view.hpp
index bf1a9889cd..eb888272e5 100644
--- a/platform/default/mbgl/gl/offscreen_view.hpp
+++ b/platform/default/mbgl/gl/offscreen_view.hpp
@@ -12,7 +12,7 @@ class Context;
class OffscreenView : public View {
public:
OffscreenView(gl::Context&, Size size = { 256, 256 });
- ~OffscreenView();
+ ~OffscreenView() override;
void bind() override;
diff --git a/platform/default/mbgl/storage/offline_download.cpp b/platform/default/mbgl/storage/offline_download.cpp
index 901f996a4f..7f0001f64b 100644
--- a/platform/default/mbgl/storage/offline_download.cpp
+++ b/platform/default/mbgl/storage/offline_download.cpp
@@ -5,8 +5,10 @@
#include <mbgl/storage/response.hpp>
#include <mbgl/storage/http_file_source.hpp>
#include <mbgl/style/parser.hpp>
-#include <mbgl/style/sources/geojson_source_impl.hpp>
-#include <mbgl/style/tile_source_impl.hpp>
+#include <mbgl/style/sources/vector_source.hpp>
+#include <mbgl/style/sources/raster_source.hpp>
+#include <mbgl/style/sources/geojson_source.hpp>
+#include <mbgl/style/sources/image_source.hpp>
#include <mbgl/style/conversion/json.hpp>
#include <mbgl/style/conversion/tileset.hpp>
#include <mbgl/text/glyph.hpp>
@@ -19,6 +21,8 @@
namespace mbgl {
+using namespace style;
+
OfflineDownload::OfflineDownload(int64_t id_,
OfflineRegionDefinition&& definition_,
OfflineDatabase& offlineDatabase_,
@@ -71,22 +75,15 @@ OfflineRegionStatus OfflineDownload::getStatus() const {
result.requiredResourceCountIsPrecise = true;
for (const auto& source : parser.sources) {
- SourceType type = source->baseImpl->type;
-
- switch (type) {
- case SourceType::Vector:
- case SourceType::Raster: {
- style::TileSourceImpl* tileSource =
- static_cast<style::TileSourceImpl*>(source->baseImpl.get());
- const variant<std::string, Tileset>& urlOrTileset = tileSource->getURLOrTileset();
- const uint16_t tileSize = tileSource->getTileSize();
+ SourceType type = source->getType();
+ auto handleTiledSource = [&] (const variant<std::string, Tileset>& urlOrTileset, const uint16_t tileSize) {
if (urlOrTileset.is<Tileset>()) {
result.requiredResourceCount +=
definition.tileCover(type, tileSize, urlOrTileset.get<Tileset>().zoomRange).size();
} else {
result.requiredResourceCount += 1;
- const std::string& url = urlOrTileset.get<std::string>();
+ const auto& url = urlOrTileset.get<std::string>();
optional<Response> sourceResponse = offlineDatabase.get(Resource::source(url));
if (sourceResponse) {
style::conversion::Error error;
@@ -99,12 +96,32 @@ OfflineRegionStatus OfflineDownload::getStatus() const {
result.requiredResourceCountIsPrecise = false;
}
}
+ };
+
+ switch (type) {
+ case SourceType::Vector: {
+ const auto& vectorSource = *source->as<VectorSource>();
+ handleTiledSource(vectorSource.getURLOrTileset(), util::tileSize);
+ break;
+ }
+
+ case SourceType::Raster: {
+ const auto& rasterSource = *source->as<RasterSource>();
+ handleTiledSource(rasterSource.getURLOrTileset(), rasterSource.getTileSize());
break;
}
case SourceType::GeoJSON: {
- style::GeoJSONSource* geojsonSource = source->as<style::GeoJSONSource>();
- if (geojsonSource->getURL()) {
+ const auto& geojsonSource = *source->as<GeoJSONSource>();
+ if (geojsonSource.getURL()) {
+ result.requiredResourceCount += 1;
+ }
+ break;
+ }
+
+ case SourceType::Image: {
+ const auto& imageSource = *source->as<ImageSource>();
+ if (imageSource.getURL()) {
result.requiredResourceCount += 1;
}
break;
@@ -138,20 +155,13 @@ void OfflineDownload::activateDownload() {
parser.parse(*styleResponse.data);
for (const auto& source : parser.sources) {
- SourceType type = source->baseImpl->type;
-
- switch (type) {
- case SourceType::Vector:
- case SourceType::Raster: {
- const style::TileSourceImpl* tileSource =
- static_cast<style::TileSourceImpl*>(source->baseImpl.get());
- const variant<std::string, Tileset>& urlOrTileset = tileSource->getURLOrTileset();
- const uint16_t tileSize = tileSource->getTileSize();
+ SourceType type = source->getType();
+ auto handleTiledSource = [&] (const variant<std::string, Tileset>& urlOrTileset, const uint16_t tileSize) {
if (urlOrTileset.is<Tileset>()) {
queueTiles(type, tileSize, urlOrTileset.get<Tileset>());
} else {
- const std::string& url = urlOrTileset.get<std::string>();
+ const auto& url = urlOrTileset.get<std::string>();
status.requiredResourceCountIsPrecise = false;
status.requiredResourceCount++;
requiredSourceURLs.insert(url);
@@ -170,15 +180,34 @@ void OfflineDownload::activateDownload() {
}
});
}
+ };
+
+ switch (type) {
+ case SourceType::Vector: {
+ const auto& vectorSource = *source->as<VectorSource>();
+ handleTiledSource(vectorSource.getURLOrTileset(), util::tileSize);
+ break;
+ }
+
+ case SourceType::Raster: {
+ const auto& rasterSource = *source->as<RasterSource>();
+ handleTiledSource(rasterSource.getURLOrTileset(), rasterSource.getTileSize());
break;
}
case SourceType::GeoJSON: {
- style::GeoJSONSource::Impl* geojsonSource =
- static_cast<style::GeoJSONSource::Impl*>(source->baseImpl.get());
+ const auto& geojsonSource = *source->as<GeoJSONSource>();
+ if (geojsonSource.getURL()) {
+ queueResource(Resource::source(*geojsonSource.getURL()));
+ }
+ break;
+ }
- if (geojsonSource->getURL()) {
- queueResource(Resource::source(*geojsonSource->getURL()));
+ case SourceType::Image: {
+ const auto& imageSource = *source->as<ImageSource>();
+ auto imageUrl = imageSource.getURL();
+ if (imageUrl && !imageUrl->empty()) {
+ queueResource(Resource::image(*imageUrl));
}
break;
}
diff --git a/platform/default/online_file_source.cpp b/platform/default/online_file_source.cpp
index a72b6f4efc..f10e0f8ffb 100644
--- a/platform/default/online_file_source.cpp
+++ b/platform/default/online_file_source.cpp
@@ -2,16 +2,18 @@
#include <mbgl/storage/http_file_source.hpp>
#include <mbgl/storage/network_status.hpp>
+#include <mbgl/storage/resource_transform.hpp>
#include <mbgl/storage/response.hpp>
#include <mbgl/util/logging.hpp>
+#include <mbgl/actor/mailbox.hpp>
#include <mbgl/util/constants.hpp>
-#include <mbgl/util/thread.hpp>
#include <mbgl/util/mapbox.hpp>
#include <mbgl/util/exception.hpp>
#include <mbgl/util/chrono.hpp>
#include <mbgl/util/async_task.hpp>
#include <mbgl/util/noncopyable.hpp>
+#include <mbgl/util/run_loop.hpp>
#include <mbgl/util/timer.hpp>
#include <mbgl/util/http_timeout.hpp>
@@ -35,12 +37,17 @@ public:
void schedule(optional<Timestamp> expires);
void completed(Response);
+ void setTransformedURL(const std::string&& url);
+ ActorRef<OnlineFileRequest> actor();
+
OnlineFileSource::Impl& impl;
Resource resource;
std::unique_ptr<AsyncRequest> request;
util::Timer timer;
Callback callback;
+ std::shared_ptr<Mailbox> mailbox;
+
// Counts the number of times a response was already expired when received. We're using
// this to add a delay when making a new request so we don't keep retrying immediately
// in case of a server serving expired tiles.
@@ -66,15 +73,12 @@ public:
void add(OnlineFileRequest* request) {
allRequests.insert(request);
if (resourceTransform) {
- // When there's a Resource transform callback set, replace the resource with the
+ // Request the ResourceTransform actor a new url and replace the resource url with the
// transformed one before proceeding to schedule the request.
- request->request =
- resourceTransform(request->resource.kind, std::move(request->resource.url),
- [request](std::string&& url) {
- request->request.release();
- request->resource.url = std::move(url);
- request->schedule();
- });
+ resourceTransform->invoke(&ResourceTransform::transform, request->resource.kind,
+ std::move(request->resource.url), [ref = request->actor()](const std::string&& url) mutable {
+ ref.invoke(&OnlineFileRequest::setTransformedURL, std::move(url));
+ });
} else {
request->schedule();
}
@@ -145,7 +149,7 @@ public:
return activeRequests.find(request) != activeRequests.end();
}
- void setResourceTransform(ResourceTransform&& transform) {
+ void setResourceTransform(optional<ActorRef<ResourceTransform>>&& transform) {
resourceTransform = std::move(transform);
}
@@ -156,7 +160,7 @@ private:
}
}
- ResourceTransform resourceTransform;
+ optional<ActorRef<ResourceTransform>> resourceTransform;
/**
* The lifetime of a request is:
@@ -189,6 +193,7 @@ std::unique_ptr<AsyncRequest> OnlineFileSource::request(const Resource& resource
switch (resource.kind) {
case Resource::Kind::Unknown:
+ case Resource::Kind::Image:
break;
case Resource::Kind::Style:
@@ -216,7 +221,7 @@ std::unique_ptr<AsyncRequest> OnlineFileSource::request(const Resource& resource
return std::make_unique<OnlineFileRequest>(std::move(res), std::move(callback), *impl);
}
-void OnlineFileSource::setResourceTransform(ResourceTransform&& transform) {
+void OnlineFileSource::setResourceTransform(optional<ActorRef<ResourceTransform>>&& transform) {
impl->setResourceTransform(std::move(transform));
}
@@ -361,4 +366,19 @@ void OnlineFileRequest::networkIsReachableAgain() {
}
}
+void OnlineFileRequest::setTransformedURL(const std::string&& url) {
+ resource.url = std::move(url);
+ schedule();
+}
+
+ActorRef<OnlineFileRequest> OnlineFileRequest::actor() {
+ if (!mailbox) {
+ // Lazy constructed because this can be costly and
+ // the ResourceTransform is not used by many apps.
+ mailbox = std::make_shared<Mailbox>(*util::RunLoop::Get());
+ }
+
+ return ActorRef<OnlineFileRequest>(*this, mailbox);
+}
+
} // namespace mbgl
diff --git a/platform/default/png_reader.cpp b/platform/default/png_reader.cpp
index 29ef3058e1..4d4ee29d1f 100644
--- a/platform/default/png_reader.cpp
+++ b/platform/default/png_reader.cpp
@@ -40,7 +40,7 @@ static void user_warning_fn(png_structp, png_const_charp warning_msg) {
}
static void png_read_data(png_structp png_ptr, png_bytep data, png_size_t length) {
- std::istream* fin = reinterpret_cast<std::istream*>(png_get_io_ptr(png_ptr));
+ auto* fin = reinterpret_cast<std::istream*>(png_get_io_ptr(png_ptr));
fin->read(reinterpret_cast<char*>(data), length);
std::streamsize read_count = fin->gcount();
if (read_count < 0 || static_cast<png_size_t>(read_count) != length)
diff --git a/platform/default/sqlite3.cpp b/platform/default/sqlite3.cpp
index 304d5e9aba..0707f9255c 100644
--- a/platform/default/sqlite3.cpp
+++ b/platform/default/sqlite3.cpp
@@ -107,8 +107,7 @@ Database &Database::operator=(Database &&other) {
return *this;
}
-Database::~Database() {
-}
+Database::~Database() = default;
void Database::setBusyTimeout(std::chrono::milliseconds timeout) {
assert(impl);
@@ -151,8 +150,7 @@ Statement &Statement::operator=(Statement &&other) {
return *this;
}
-Statement::~Statement() {
-}
+Statement::~Statement() = default;
template <> void Statement::bind(int offset, std::nullptr_t) {
assert(impl);
@@ -314,7 +312,7 @@ template <> std::string Statement::get(int offset) {
template <> std::vector<uint8_t> Statement::get(int offset) {
assert(impl);
- const uint8_t* begin = reinterpret_cast<const uint8_t*>(sqlite3_column_blob(impl->stmt, offset));
+ const auto* begin = reinterpret_cast<const uint8_t*>(sqlite3_column_blob(impl->stmt, offset));
const uint8_t* end = begin + sqlite3_column_bytes(impl->stmt, offset);
return { begin, end };
}
diff --git a/platform/default/timer.cpp b/platform/default/timer.cpp
index cd0e6da6aa..90a85bfc1f 100644
--- a/platform/default/timer.cpp
+++ b/platform/default/timer.cpp
@@ -10,7 +10,7 @@ namespace util {
class Timer::Impl {
public:
Impl() : timer(new uv_timer_t) {
- uv_loop_t* loop = reinterpret_cast<uv_loop_t*>(RunLoop::getLoopHandle());
+ auto* loop = reinterpret_cast<uv_loop_t*>(RunLoop::getLoopHandle());
if (uv_timer_init(loop, timer) != 0) {
throw std::runtime_error("Failed to initialize timer.");
}