diff options
Diffstat (limited to 'platform/default')
-rw-r--r-- | platform/default/asset_file_source.cpp | 17 | ||||
-rw-r--r-- | platform/default/async_task.cpp | 2 | ||||
-rw-r--r-- | platform/default/bidi.cpp | 6 | ||||
-rw-r--r-- | platform/default/default_file_source.cpp | 165 | ||||
-rw-r--r-- | platform/default/image.cpp | 2 | ||||
-rw-r--r-- | platform/default/jpeg_reader.cpp | 8 | ||||
-rw-r--r-- | platform/default/local_file_source.cpp | 15 | ||||
-rw-r--r-- | platform/default/mbgl/gl/headless_backend.cpp | 3 | ||||
-rw-r--r-- | platform/default/mbgl/gl/headless_backend.hpp | 2 | ||||
-rw-r--r-- | platform/default/mbgl/gl/offscreen_view.cpp | 1 | ||||
-rw-r--r-- | platform/default/mbgl/gl/offscreen_view.hpp | 2 | ||||
-rw-r--r-- | platform/default/mbgl/storage/offline_download.cpp | 85 | ||||
-rw-r--r-- | platform/default/online_file_source.cpp | 44 | ||||
-rw-r--r-- | platform/default/png_reader.cpp | 2 | ||||
-rw-r--r-- | platform/default/sqlite3.cpp | 8 | ||||
-rw-r--r-- | platform/default/timer.cpp | 2 |
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, ¶graphEndIndex, NULL, &errorCode); + ubidi_getParagraphByIndex(impl->bidiText, i, nullptr, ¶graphEndIndex, 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."); } |