Eliminate copies in deferred cleanup (#3035)

This commit is contained in:
Tim Sylvester
2025-02-07 10:48:16 -08:00
committed by GitHub
parent de8e34a19b
commit 14559245d8
79 changed files with 346 additions and 292 deletions

View File

@@ -113,7 +113,8 @@ Checks: [
-performance-enum-size,
-misc-include-cleaner,
-readability-redundant-inline-specifier,
-readability-avoid-nested-conditional-operator
-readability-avoid-nested-conditional-operator,
-cppcoreguidelines-pro-type-static-cast-downcast # no RTTI
]
WarningsAsErrors: '*'
HeaderFilterRegex: '.*'

4
.gitmodules vendored
View File

@@ -58,3 +58,7 @@
[submodule "vendor/PMTiles"]
path = vendor/PMTiles
url = https://github.com/protomaps/PMTiles.git
[submodule "vendor/nontype_functional"]
path = vendor/nontype_functional
url = https://github.com/zhihaoy/nontype_functional.git
branch = compat

View File

@@ -127,6 +127,7 @@ cc_library(
"//vendor:earcut.hpp",
"//vendor:eternal",
"//vendor:mapbox-base",
"//vendor:nontype_functional",
"//vendor:parsedate",
"//vendor:pmtiles",
"//vendor:polylabel",

View File

@@ -1448,6 +1448,8 @@ include(${PROJECT_SOURCE_DIR}/vendor/csscolorparser.cmake)
include(${PROJECT_SOURCE_DIR}/vendor/earcut.hpp.cmake)
include(${PROJECT_SOURCE_DIR}/vendor/eternal.cmake)
include(${PROJECT_SOURCE_DIR}/vendor/mapbox-base.cmake)
include(${PROJECT_SOURCE_DIR}/vendor/metal-cpp.cmake)
include(${PROJECT_SOURCE_DIR}/vendor/nontype_functional.cmake)
include(${PROJECT_SOURCE_DIR}/vendor/parsedate.cmake)
include(${PROJECT_SOURCE_DIR}/vendor/pmtiles.cmake)
include(${PROJECT_SOURCE_DIR}/vendor/polylabel.cmake)
@@ -1457,7 +1459,6 @@ include(${PROJECT_SOURCE_DIR}/vendor/unique_resource.cmake)
include(${PROJECT_SOURCE_DIR}/vendor/unordered_dense.cmake)
include(${PROJECT_SOURCE_DIR}/vendor/vector-tile.cmake)
include(${PROJECT_SOURCE_DIR}/vendor/wagyu.cmake)
include(${PROJECT_SOURCE_DIR}/vendor/metal-cpp.cmake)
if(MLN_USE_RUST)
include(${PROJECT_SOURCE_DIR}/rustutils/rustutils.cmake)
@@ -1475,6 +1476,7 @@ target_link_libraries(
mbgl-vendor-boost
mbgl-vendor-earcut.hpp
mbgl-vendor-eternal
$<$<BOOL:${MLN_WITH_METAL}>:mbgl-vendor-metal-cpp>
mbgl-vendor-parsedate
mbgl-vendor-pmtiles
mbgl-vendor-polylabel
@@ -1491,6 +1493,7 @@ target_link_libraries(
Mapbox::Base::geojson.hpp
Mapbox::Base::geometry.hpp
Mapbox::Base::variant
mbgl-vendor-nontype_functional
$<$<BOOL:${MLN_USE_TRACY}>:TracyClient>
unordered_dense
)
@@ -1514,6 +1517,8 @@ set(EXPORT_TARGETS
mbgl-vendor-boost
mbgl-vendor-earcut.hpp
mbgl-vendor-eternal
mbgl-vendor-metal-cpp
mbgl-vendor-nontype_functional
mbgl-vendor-parsedate
mbgl-vendor-pmtiles
mbgl-vendor-polylabel
@@ -1521,7 +1526,6 @@ set(EXPORT_TARGETS
mbgl-vendor-unique_resource
mbgl-vendor-vector-tile
mbgl-vendor-wagyu
mbgl-vendor-metal-cpp
unordered_dense
)

View File

@@ -4,6 +4,8 @@
#include <mapbox/std/weak.hpp>
#include <std23/move_only_function.h>
#include <functional>
#include <memory>
#include <type_traits>
@@ -36,16 +38,18 @@ class Mailbox;
*/
class Scheduler {
public:
using Task = std23::move_only_function<void()>;
virtual ~Scheduler() = default;
/// Enqueues a function for execution.
virtual void schedule(std::function<void()>&&) = 0;
virtual void schedule(const util::SimpleIdentity, std::function<void()>&&) = 0;
virtual void schedule(Task&&) = 0;
virtual void schedule(const util::SimpleIdentity, Task&&) = 0;
/// Makes a weak pointer to this Scheduler.
virtual mapbox::base::WeakPtr<Scheduler> makeWeakPtr() = 0;
/// Enqueues a function for execution on the render thread owned by the given tag.
virtual void runOnRenderThread(const util::SimpleIdentity, std::function<void()>&&) {}
virtual void runOnRenderThread(const util::SimpleIdentity, Task&&) {}
/// Run render thread jobs for the given tag
/// @param tag Tag of owner
/// @param closeQueue Runs all render jobs and then removes the internal queue.
@@ -57,9 +61,9 @@ public:
/// the given closure to this scheduler, the consequent calls of the
/// returned closure are ignored.
///
/// If this scheduler is already deleted by the time the returnded closure
/// If this scheduler is already deleted by the time the returned closure
/// is first invoked, the call is ignored.
std::function<void()> bindOnce(std::function<void()>);
Scheduler::Task bindOnce(Task&&);
/// Enqueues the given |task| for execution into this scheduler's task queue
/// and then enqueues the |reply| with the captured task result to the
@@ -103,10 +107,12 @@ public:
[[nodiscard]] static std::shared_ptr<Scheduler> GetSequenced();
/// Set a function to be called when an exception occurs on a thread controlled by the scheduler
void setExceptionHandler(std::function<void(const std::exception_ptr)> handler_) { handler = std::move(handler_); }
void setExceptionHandler(std23::move_only_function<void(const std::exception_ptr)> handler_) {
handler = std::move(handler_);
}
protected:
std::function<void(const std::exception_ptr)> handler;
std23::move_only_function<void(const std::exception_ptr)> handler;
private:
template <typename TaskFn, typename ReplyFn>
@@ -136,8 +142,8 @@ public:
/// @brief Get the wrapped scheduler
const std::shared_ptr<Scheduler>& get() const noexcept { return scheduler; }
void schedule(std::function<void()>&& fn) { scheduler->schedule(tag, std::move(fn)); }
void runOnRenderThread(std::function<void()>&& fn) { scheduler->runOnRenderThread(tag, std::move(fn)); }
void schedule(Scheduler::Task&& fn) { scheduler->schedule(tag, std::move(fn)); }
void runOnRenderThread(Scheduler::Task&& fn) { scheduler->runOnRenderThread(tag, std::move(fn)); }
void runRenderJobs(bool closeQueue = false) { scheduler->runRenderJobs(tag, closeQueue); }
void waitForEmpty() const noexcept { scheduler->waitForEmpty(tag); }

View File

@@ -43,7 +43,7 @@ public:
}
void bind(RenderPass& renderPass) const noexcept;
void unbind(RenderPass& renderPass) const noexcept {};
void unbind(RenderPass&) const noexcept {}
private:
gfx::UniqueUniformBuffer copy(const gfx::UniformBuffer& buffer) override {

View File

@@ -1,15 +1,15 @@
#pragma once
#include <mbgl/tile/tile_id.hpp>
#include <mbgl/util/font_stack.hpp>
#include <mbgl/text/glyph_range.hpp>
#include <mbgl/tile/tile_operation.hpp>
#include <mbgl/actor/scheduler.hpp>
#include <mbgl/gfx/backend.hpp>
#include <mbgl/shaders/shader_source.hpp>
#include <mbgl/text/glyph_range.hpp>
#include <mbgl/tile/tile_id.hpp>
#include <mbgl/tile/tile_operation.hpp>
#include <mbgl/util/font_stack.hpp>
#include <cstdint>
#include <exception>
#include <functional>
#include <string>
namespace mbgl {
@@ -55,8 +55,7 @@ public:
virtual void onDidFinishRenderingMap() {}
/// Style is missing an image
using StyleImageMissingCallback = std::function<void()>;
virtual void onStyleImageMissing(const std::string&, const StyleImageMissingCallback& done) { done(); }
virtual void onStyleImageMissing(const std::string&, Scheduler::Task&& done) { done(); }
virtual void onRemoveUnusedStyleImages(const std::vector<std::string>&) {}
// Entry point for custom shader registration

View File

@@ -16,8 +16,8 @@ public:
~DatabaseFileSource() override;
/// FileSource overrides
std::unique_ptr<AsyncRequest> request(const Resource&, Callback) override;
void forward(const Resource&, const Response&, std::function<void()> callback) override;
std::unique_ptr<AsyncRequest> request(const Resource&, std::function<void(Response)>) override;
void forward(const Resource&, const Response&, Scheduler::Task&& callback) override;
bool canRequest(const Resource&) const override;
void setProperty(const std::string&, const mapbox::base::Value&) override;
void pause() override;
@@ -29,7 +29,7 @@ public:
* Sets path of a database to be used by DatabaseFileSource and invokes
* provided callback when a database path is set.
*/
virtual void setDatabasePath(const std::string&, std::function<void()> callback);
virtual void setDatabasePath(const std::string&, std23::move_only_function<void()>&& callback);
/**
* Delete existing database and re-initialize.
@@ -38,7 +38,7 @@ public:
* will be executed on the database thread; it is the responsibility of the
* SDK bindings to re-execute a user-provided callback on the main thread.
*/
virtual void resetDatabase(std::function<void(std::exception_ptr)>);
virtual void resetDatabase(std23::move_only_function<void(std::exception_ptr)>&&);
/**
* Packs the existing database file into a minimal amount of disk space.
@@ -50,7 +50,7 @@ public:
* will be executed on the database thread; it is the responsibility of the
* SDK bindings to re-execute a user-provided callback on the main thread.
*/
virtual void packDatabase(std::function<void(std::exception_ptr)> callback);
virtual void packDatabase(std23::move_only_function<void(std::exception_ptr)>&& callback);
/**
* Sets whether packing the database file occurs automatically after an
@@ -87,7 +87,7 @@ public:
* Resources overlapping with offline regions will not be affected
* by this call.
*/
virtual void invalidateAmbientCache(std::function<void(std::exception_ptr)>);
virtual void invalidateAmbientCache(std23::move_only_function<void(std::exception_ptr)>&&);
/**
* Erase resources from the ambient cache, freeing storage space.
@@ -100,7 +100,7 @@ public:
* Resources overlapping with offline regions will not be affected
* by this call.
*/
virtual void clearAmbientCache(std::function<void(std::exception_ptr)>);
virtual void clearAmbientCache(std23::move_only_function<void(std::exception_ptr)>&&);
/**
* Sets the maximum size in bytes for the ambient cache.
@@ -122,7 +122,8 @@ public:
* This method should always be called before using the database,
* otherwise the default maximum size will be used.
*/
virtual void setMaximumAmbientCacheSize(uint64_t size, std::function<void(std::exception_ptr)> callback);
virtual void setMaximumAmbientCacheSize(uint64_t size,
std23::move_only_function<void(std::exception_ptr)>&& callback);
// Offline
@@ -134,7 +135,7 @@ public:
* responsibility of the SDK bindings to re-execute a user-provided callback
* on the main thread.
*/
virtual void listOfflineRegions(std::function<void(expected<OfflineRegions, std::exception_ptr>)>);
virtual void listOfflineRegions(std23::move_only_function<void(expected<OfflineRegions, std::exception_ptr>)>&&);
/**
* Retrieve given region in the offline database.
@@ -144,8 +145,9 @@ public:
* responsibility of the SDK bindings to re-execute a user-provided callback
* on the main thread.
*/
virtual void getOfflineRegion(int64_t regionID,
std::function<void(expected<std::optional<OfflineRegion>, std::exception_ptr>)>);
virtual void getOfflineRegion(
int64_t regionID,
std23::move_only_function<void(expected<std::optional<OfflineRegion>, std::exception_ptr>)>&&);
/**
* Create an offline region in the database.
@@ -161,18 +163,19 @@ public:
*/
virtual void createOfflineRegion(const OfflineRegionDefinition& definition,
const OfflineRegionMetadata& metadata,
std::function<void(expected<OfflineRegion, std::exception_ptr>)>);
std23::move_only_function<void(expected<OfflineRegion, std::exception_ptr>)>&&);
/**
* Update an offline region metadata in the database.
*/
virtual void updateOfflineMetadata(int64_t regionID,
const OfflineRegionMetadata& metadata,
std::function<void(expected<OfflineRegionMetadata, std::exception_ptr>)>);
virtual void updateOfflineMetadata(
int64_t regionID,
const OfflineRegionMetadata& metadata,
std23::move_only_function<void(expected<OfflineRegionMetadata, std::exception_ptr>)>&&);
/**
* Register an observer to be notified when the state of the region changes.
*/
virtual void setOfflineRegionObserver(const OfflineRegion&, std::unique_ptr<OfflineRegionObserver>);
virtual void setOfflineRegionObserver(const OfflineRegion&, std::unique_ptr<OfflineRegionObserver>&&);
/**
* Pause or resume downloading of regional resources.
@@ -185,8 +188,9 @@ public:
* be executed on the database thread; it is the responsibility of the SDK
* bindings to re-execute a user-provided callback on the main thread.
*/
virtual void getOfflineRegionStatus(const OfflineRegion&,
std::function<void(expected<OfflineRegionStatus, std::exception_ptr>)>) const;
virtual void getOfflineRegionStatus(
const OfflineRegion&,
std23::move_only_function<void(expected<OfflineRegionStatus, std::exception_ptr>)>&&) const;
/**
* Merge offline regions from a secondary database into the main offline database.
@@ -209,7 +213,7 @@ public:
* does not contain all the tiles or resources required by the region definition.
*/
virtual void mergeOfflineRegions(const std::string& sideDatabasePath,
std::function<void(expected<OfflineRegions, std::exception_ptr>)>);
std23::move_only_function<void(expected<OfflineRegions, std::exception_ptr>)>&&);
/**
* Remove an offline region from the database and perform any resources
@@ -231,7 +235,7 @@ public:
* will be executed on the database thread; it is the responsibility of the
* SDK bindings to re-execute a user-provided callback on the main thread.
*/
virtual void deleteOfflineRegion(const OfflineRegion&, std::function<void(std::exception_ptr)>);
virtual void deleteOfflineRegion(const OfflineRegion&, std23::move_only_function<void(std::exception_ptr)>&&);
/**
* Invalidate all the tiles from an offline region forcing Mapbox GL to
@@ -239,7 +243,7 @@ public:
* than deleting the offline region and downloading it again because if the
* data on the cache matches the server, no new data gets transmitted.
*/
virtual void invalidateOfflineRegion(const OfflineRegion&, std::function<void(std::exception_ptr)>);
virtual void invalidateOfflineRegion(const OfflineRegion&, std23::move_only_function<void(std::exception_ptr)>&&);
/**
* Changing or bypassing this limit without permission from Mapbox is

View File

@@ -1,5 +1,6 @@
#pragma once
#include <mbgl/actor/scheduler.hpp>
#include <mbgl/storage/resource_transform.hpp>
#include <mbgl/storage/response.hpp>
#include <mbgl/storage/resource_options.hpp>
@@ -38,21 +39,19 @@ public:
FileSource& operator=(const FileSource&) = delete;
virtual ~FileSource() = default;
using Callback = std::function<void(Response)>;
/// Request a resource. The callback will be called asynchronously, in the
/// same thread as the request was made. This thread must have an active
/// RunLoop. The request may be cancelled before completion by releasing the
/// returned AsyncRequest. If the request is cancelled before the callback
/// is executed, the callback will not be executed.
virtual std::unique_ptr<AsyncRequest> request(const Resource&, Callback) = 0;
virtual std::unique_ptr<AsyncRequest> request(const Resource&, std::function<void(Response)>) = 0;
/// Allows to forward response from one source to another.
/// Optionally, callback can be provided to receive notification for forward
/// operation.
//
// NOLINTNEXTLINE(performance-unnecessary-value-param)
virtual void forward(const Resource&, const Response&, std::function<void()>) {}
virtual void forward(const Resource&, const Response&, Scheduler::Task&&) {}
/// When a file source supports consulting a local cache only, it must
/// return true. Cache-only requests are requests that aren't as urgent, but

View File

@@ -19,7 +19,7 @@ public:
private:
// FileSource overrides
std::unique_ptr<AsyncRequest> request(const Resource&, Callback) override;
std::unique_ptr<AsyncRequest> request(const Resource&, std::function<void(Response)>) override;
bool canRequest(const Resource&) const override;
void pause() override;
void resume() override;

View File

@@ -54,10 +54,10 @@ public:
/// loop. It will be called from any thread and is up to the platform
/// to, after receiving the callback, call RunLoop::runOnce() from the
/// same thread as the Map object lives.
void setPlatformCallback(std::function<void()> callback) { platformCallback = std::move(callback); }
void setPlatformCallback(Scheduler::Task&& callback) { platformCallback = std::move(callback); }
// So far only needed by the libcurl backend.
void addWatch(int fd, Event, std::function<void(int, Event)>&& callback);
void addWatch(int fd, Event, std23::move_only_function<void(int, Event)>&& callback);
void removeWatch(int fd);
// Invoke fn(args...) on this RunLoop.
@@ -80,8 +80,8 @@ public:
return std::make_unique<WorkRequest>(task);
}
void schedule(std::function<void()>&& fn) override { invoke(std::move(fn)); }
void schedule(const util::SimpleIdentity, std::function<void()>&& fn) override { schedule(std::move(fn)); }
void schedule(Scheduler::Task&& fn) override { invoke(std::move(fn)); }
void schedule(const util::SimpleIdentity, Scheduler::Task&& fn) override { schedule(std::move(fn)); }
::mapbox::base::WeakPtr<Scheduler> makeWeakPtr() override { return weakFactory.makeWeakPtr(); }
void waitForEmpty(const util::SimpleIdentity = util::SimpleIdentity::Empty) override;
@@ -131,7 +131,7 @@ private:
}
}
std::function<void()> platformCallback;
Scheduler::Task platformCallback;
Queue defaultQueue;
Queue highPriorityQueue;

View File

@@ -241,6 +241,7 @@ target_link_libraries(maplibre
$<$<CONFIG:Release>:-fuse-ld=gold>
Mapbox::Base::jni.hpp
mbgl-core
mbgl-vendor-nontype_functional
mbgl-vendor-unique_resource)
install(TARGETS maplibre LIBRARY DESTINATION lib)

View File

@@ -1,17 +1,16 @@
#include "android_renderer_frontend.hpp"
#include "android_renderer_backend.hpp"
#include <mbgl/tile/tile_operation.hpp>
#include <mbgl/actor/scheduler.hpp>
#include <mbgl/renderer/renderer.hpp>
#include <mbgl/renderer/renderer_observer.hpp>
#include <mbgl/tile/tile_operation.hpp>
#include <mbgl/util/async_task.hpp>
#include <mbgl/util/geojson.hpp>
#include <mbgl/util/instrumentation.hpp>
#include <mbgl/util/run_loop.hpp>
#include <mbgl/util/thread.hpp>
#include "android_renderer_backend.hpp"
namespace mbgl {
namespace android {
@@ -45,8 +44,8 @@ public:
void onDidFinishRenderingMap() override { delegate.invoke(&RendererObserver::onDidFinishRenderingMap); }
void onStyleImageMissing(const std::string& id, const StyleImageMissingCallback& done) override {
delegate.invoke(&RendererObserver::onStyleImageMissing, id, done);
void onStyleImageMissing(const std::string& id, Scheduler::Task&& done) override {
delegate.invoke(&RendererObserver::onStyleImageMissing, id, std::move(done));
}
void onRemoveUnusedStyleImages(const std::vector<std::string>& ids) override {

View File

@@ -70,7 +70,8 @@ AssetManagerFileSource::AssetManagerFileSource(jni::JNIEnv& env,
AssetManagerFileSource::~AssetManagerFileSource() = default;
std::unique_ptr<AsyncRequest> AssetManagerFileSource::request(const Resource& resource, Callback callback) {
std::unique_ptr<AsyncRequest> AssetManagerFileSource::request(const Resource& resource,
std::function<void(Response)> callback) {
auto req = std::make_unique<FileSourceRequest>(std::move(callback));
impl->actor().invoke(&Impl::request, resource.url, req->actor());
@@ -79,7 +80,7 @@ std::unique_ptr<AsyncRequest> AssetManagerFileSource::request(const Resource& re
}
bool AssetManagerFileSource::canRequest(const Resource& resource) const {
return 0 == resource.url.rfind(mbgl::util::ASSET_PROTOCOL, 0);
return resource.url.starts_with(mbgl::util::ASSET_PROTOCOL);
}
void AssetManagerFileSource::setResourceOptions(ResourceOptions options) {

View File

@@ -23,7 +23,7 @@ public:
const ClientOptions);
~AssetManagerFileSource() override;
std::unique_ptr<AsyncRequest> request(const Resource&, Callback) override;
std::unique_ptr<AsyncRequest> request(const Resource&, std::function<void(Response)>) override;
bool canRequest(const Resource&) const override;
void setResourceOptions(ResourceOptions options) override;

View File

@@ -30,13 +30,13 @@ FileSource::FileSource(jni::JNIEnv& _env,
mbgl::FileSourceManager::get()->registerFileSourceFactory(
mbgl::FileSourceType::Asset,
[](const mbgl::ResourceOptions& resourceOptions, const mbgl::ClientOptions& clientOptions) {
[](const mbgl::ResourceOptions& resourceOptions_, const mbgl::ClientOptions& clientOptions_) {
auto env{android::AttachEnv()};
std::unique_ptr<mbgl::FileSource> assetFileSource;
if (android::MapLibre::hasInstance(*env)) {
auto assetManager = android::MapLibre::getAssetManager(*env);
assetFileSource = std::make_unique<AssetManagerFileSource>(
*env, assetManager, resourceOptions.clone(), clientOptions.clone());
*env, assetManager, resourceOptions_.clone(), clientOptions_.clone());
}
return assetFileSource;
});
@@ -161,7 +161,7 @@ void FileSource::setResourceCachePath(jni::JNIEnv& env,
pathChangeCallback = {};
});
databaseSource->setDatabasePath(newPath + DATABASE_FILE, pathChangeCallback);
databaseSource->setDatabasePath(newPath + DATABASE_FILE, std::move(pathChangeCallback));
}
void FileSource::resume(jni::JNIEnv&) {

View File

@@ -93,7 +93,7 @@ private:
mbgl::ResourceOptions resourceOptions;
mbgl::ClientOptions clientOptions;
std::unique_ptr<Actor<ResourceTransform::TransformCallback>> resourceTransform;
std::function<void()> pathChangeCallback;
std23::move_only_function<void()> pathChangeCallback;
std::shared_ptr<mbgl::DatabaseFileSource> databaseSource;
std::shared_ptr<mbgl::FileSource> onlineSource;
std::shared_ptr<mbgl::FileSource> resourceLoader;

View File

@@ -39,8 +39,8 @@ class HTTPRequest : public AsyncRequest {
public:
static constexpr auto Name() { return "org/maplibre/android/http/NativeHttpRequest"; };
HTTPRequest(jni::JNIEnv&, const Resource&, FileSource::Callback);
~HTTPRequest();
HTTPRequest(jni::JNIEnv&, const Resource&, std::function<void(Response)>);
~HTTPRequest() override;
void onFailure(jni::JNIEnv&, int type, const jni::String& message);
void onResponse(jni::JNIEnv&,
@@ -57,7 +57,7 @@ public:
private:
Resource resource;
FileSource::Callback callback;
std::function<void(Response)> callback;
Response response;
util::AsyncTask async{[this] {
@@ -88,9 +88,9 @@ void RegisterNativeHTTPRequest(jni::JNIEnv& env) {
} // namespace android
HTTPRequest::HTTPRequest(jni::JNIEnv& env, const Resource& resource_, FileSource::Callback callback_)
HTTPRequest::HTTPRequest(jni::JNIEnv& env, const Resource& resource_, std::function<void(Response)> callback_)
: resource(resource_),
callback(callback_) {
callback(std::move(callback_)) {
std::string dataRangeStr;
std::string etagStr;
std::string modifiedStr;
@@ -152,7 +152,7 @@ void HTTPRequest::onResponse(jni::JNIEnv& env,
}
if (cacheControl) {
const auto cc = http::CacheControl::parse(jni::Make<std::string>(env, cacheControl).c_str());
const auto cc = http::CacheControl::parse(jni::Make<std::string>(env, cacheControl));
response.expires = cc.toTimePoint();
response.mustRevalidate = cc.mustRevalidate;
}
@@ -164,7 +164,7 @@ void HTTPRequest::onResponse(jni::JNIEnv& env,
if (code == 200 || code == 206) {
if (body) {
auto data = std::make_shared<std::string>(body.Length(env), char());
jni::GetArrayRegion(env, *body, 0, data->size(), reinterpret_cast<jbyte*>(&(*data)[0]));
jni::GetArrayRegion(env, *body, 0, data->size(), reinterpret_cast<jbyte*>(data->data()));
response.data = data;
} else {
response.data = std::make_shared<std::string>();
@@ -221,8 +221,9 @@ HTTPFileSource::HTTPFileSource(const ResourceOptions& resourceOptions, const Cli
HTTPFileSource::~HTTPFileSource() = default;
std::unique_ptr<AsyncRequest> HTTPFileSource::request(const Resource& resource, Callback callback) {
return std::make_unique<HTTPRequest>(*impl->env, resource, callback);
std::unique_ptr<AsyncRequest> HTTPFileSource::request(const Resource& resource,
std::function<void(Response)> callback) {
return std::make_unique<HTTPRequest>(*impl->env, resource, std::move(callback));
}
void HTTPFileSource::setResourceOptions(ResourceOptions options) {

View File

@@ -63,7 +63,7 @@ ActorRef<Renderer> MapRenderer::actor() const {
return *rendererRef;
}
void MapRenderer::schedule(std::function<void()>&& scheduled) {
void MapRenderer::schedule(Task&& scheduled) {
MLN_TRACE_FUNC();
try {
// Create a runnable

View File

@@ -72,8 +72,8 @@ public:
// From Scheduler. Schedules by using callbacks to the
// JVM to process the mailbox on the right thread.
void schedule(std::function<void()>&& scheduled) override;
void schedule(const util::SimpleIdentity, std::function<void()>&& fn) override { schedule(std::move(fn)); };
void schedule(Task&& scheduled) override;
void schedule(const util::SimpleIdentity, Task&& fn) override { schedule(std::move(fn)); };
mapbox::base::WeakPtr<Scheduler> makeWeakPtr() override { return weakFactory.makeWeakPtr(); }

View File

@@ -5,7 +5,7 @@
namespace mbgl {
namespace android {
MapRendererRunnable::MapRendererRunnable(jni::JNIEnv& env, std::function<void()> function_)
MapRendererRunnable::MapRendererRunnable(jni::JNIEnv& env, Scheduler::Task&& function_)
: function(std::move(function_)) {
// Create the Java peer and hold on to a global reference
// Not using a weak reference here as this might oerflow

View File

@@ -23,7 +23,7 @@ public:
static void registerNative(jni::JNIEnv&);
MapRendererRunnable(jni::JNIEnv&, std::function<void()>);
MapRendererRunnable(jni::JNIEnv&, Scheduler::Task&&);
// Only for jni registration, unused
MapRendererRunnable(jni::JNIEnv&) { assert(false); }
@@ -37,7 +37,7 @@ public:
private:
jni::Global<jni::Object<MapRendererRunnable>> javaPeer;
std::function<void()> function;
Scheduler::Task function;
};
} // namespace android

View File

@@ -8,6 +8,7 @@ target_compile_definitions(
)
include(${PROJECT_SOURCE_DIR}/vendor/icu.cmake)
include(${PROJECT_SOURCE_DIR}/vendor/nontype_functional.cmake)
include(${PROJECT_SOURCE_DIR}/vendor/sqlite.cmake)
# cmake-format: off
@@ -107,6 +108,7 @@ target_link_libraries(
jnigraphics
log
mbgl-vendor-icu
mbgl-vendor-nontype_functional
mbgl-vendor-sqlite
z
)

View File

@@ -290,7 +290,7 @@ void RunLoop::stop() {
});
}
void RunLoop::addWatch(int fd, Event event, std::function<void(int, Event)>&& cb) {
void RunLoop::addWatch(int fd, Event event, std23::move_only_function<void(int, Event)>&& cb) {
MBGL_VERIFY_THREAD(tid);
if (event == Event::Read) {

View File

@@ -16,8 +16,6 @@ struct ALooper;
namespace mbgl {
namespace util {
using WatchCallback = std::function<void(int, RunLoop::Event)>;
template <typename T>
class Thread;
class Alarm;
@@ -49,7 +47,7 @@ public:
std::atomic<bool> running;
std::atomic_flag coalesce = ATOMIC_FLAG_INIT;
std::unordered_map<int, WatchCallback> readPoll;
std::unordered_map<int, std23::move_only_function<void(int, RunLoop::Event)>> readPoll;
private:
friend RunLoop;

View File

@@ -55,9 +55,9 @@ private:
class HTTPRequest : public AsyncRequest {
public:
HTTPRequest(FileSource::Callback callback_)
HTTPRequest(std::function<void(Response)> callback_)
: shared(std::make_shared<HTTPRequestShared>(response, async)),
callback(callback_) {
callback(std::move(callback_)) {
}
~HTTPRequest() override {
@@ -71,7 +71,7 @@ public:
NSURLSessionDataTask* task = nil;
private:
FileSource::Callback callback;
std::function<void(Response)> callback;
Response response;
util::AsyncTask async { [this] {
@@ -248,8 +248,8 @@ NSURL *resourceURL(const Resource& resource) {
return url;
}
std::unique_ptr<AsyncRequest> HTTPFileSource::request(const Resource& resource, Callback callback) {
auto request = std::make_unique<HTTPRequest>(callback);
std::unique_ptr<AsyncRequest> HTTPFileSource::request(const Resource& resource, std::function<void(Response)> callback) {
auto request = std::make_unique<HTTPRequest>(std::move(callback));
auto shared = request->shared; // Explicit copy so that it also gets copied into the completion handler block below.
@autoreleasepool {

View File

@@ -13,7 +13,7 @@ class Mailbox;
class FileSourceRequest final : public AsyncRequest {
public:
FileSourceRequest(FileSource::Callback&& callback);
FileSourceRequest(std::function<void(Response)> callback);
~FileSourceRequest() final;
void onCancel(std::function<void()>&& callback);
@@ -22,8 +22,8 @@ public:
ActorRef<FileSourceRequest> actor();
private:
FileSource::Callback responseCallback = nullptr;
std::function<void()> cancelCallback = nullptr;
std::function<void(Response)> responseCallback;
std23::move_only_function<void()> cancelCallback;
std::shared_ptr<Mailbox> mailbox;
};

View File

@@ -46,8 +46,8 @@ public:
delegate.invoke(f, mode, repaintNeeded, placementChanged, frameEncodingTime, frameRenderingTime);
}
void onStyleImageMissing(const std::string& image, const StyleImageMissingCallback& cb) override {
delegate.invoke(&RendererObserver::onStyleImageMissing, image, cb);
void onStyleImageMissing(const std::string& image, Scheduler::Task&& cb) override {
delegate.invoke(&RendererObserver::onStyleImageMissing, image, std::move(cb));
}
private:
@@ -95,8 +95,8 @@ public:
mode, repaintNeeded, placementChanged, frameEncodingTime, frameRenderingTime);
}
void onStyleImageMissing(const std::string& id, const StyleImageMissingCallback& done) override {
rendererObserver->onStyleImageMissing(id, done);
void onStyleImageMissing(const std::string& id, Scheduler::Task&& done) override {
rendererObserver->onStyleImageMissing(id, std::move(done));
}
void setObserver(std::shared_ptr<RendererObserver> observer) {

View File

@@ -77,7 +77,8 @@ AssetFileSource::AssetFileSource(const ResourceOptions& resourceOptions, const C
AssetFileSource::~AssetFileSource() = default;
std::unique_ptr<AsyncRequest> AssetFileSource::request(const Resource& resource, Callback callback) {
std::unique_ptr<AsyncRequest> AssetFileSource::request(const Resource& resource,
std::function<void(Response)> callback) {
auto req = std::make_unique<FileSourceRequest>(std::move(callback));
impl->actor().invoke(&Impl::request, resource.url, req->actor());

View File

@@ -38,68 +38,73 @@ public:
req.invoke(&FileSourceRequest::setResponse, *offlineResponse);
}
void setDatabasePath(const std::string& path, const std::function<void()>& callback) {
void setDatabasePath(const std::string& path, std23::move_only_function<void()>&& callback) {
db->changePath(path);
if (callback) {
callback();
}
}
void forward(const Resource& resource, const Response& response, const std::function<void()>& callback) {
void forward(const Resource& resource, const Response& response, Scheduler::Task&& callback) {
db->put(resource, response);
if (callback) {
callback();
}
}
void resetDatabase(const std::function<void(std::exception_ptr)>& callback) { callback(db->resetDatabase()); }
void resetDatabase(std23::move_only_function<void(std::exception_ptr)>&& callback) {
callback(db->resetDatabase());
}
void packDatabase(const std::function<void(std::exception_ptr)>& callback) { callback(db->pack()); }
void packDatabase(std23::move_only_function<void(std::exception_ptr)>&& callback) { callback(db->pack()); }
void runPackDatabaseAutomatically(bool autopack) { db->runPackDatabaseAutomatically(autopack); }
void put(const Resource& resource, const Response& response) { db->put(resource, response); }
void invalidateAmbientCache(const std::function<void(std::exception_ptr)>& callback) {
void invalidateAmbientCache(std23::move_only_function<void(std::exception_ptr)>&& callback) {
callback(db->invalidateAmbientCache());
}
void clearAmbientCache(const std::function<void(std::exception_ptr)>& callback) {
void clearAmbientCache(std23::move_only_function<void(std::exception_ptr)>&& callback) {
callback(db->clearAmbientCache());
}
void setMaximumAmbientCacheSize(uint64_t size, const std::function<void(std::exception_ptr)>& callback) {
void setMaximumAmbientCacheSize(uint64_t size, std23::move_only_function<void(std::exception_ptr)>&& callback) {
callback(db->setMaximumAmbientCacheSize(size));
}
void listRegions(const std::function<void(expected<OfflineRegions, std::exception_ptr>)>& callback) {
void listRegions(std23::move_only_function<void(expected<OfflineRegions, std::exception_ptr>)>&& callback) {
callback(db->listRegions());
}
void getRegion(const int64_t regionID,
const std::function<void(expected<std::optional<OfflineRegion>, std::exception_ptr>)>& callback) {
void getRegion(
const int64_t regionID,
std23::move_only_function<void(expected<std::optional<OfflineRegion>, std::exception_ptr>)>&& callback) {
callback(db->getRegion(regionID));
}
void createRegion(const OfflineRegionDefinition& definition,
const OfflineRegionMetadata& metadata,
const std::function<void(expected<OfflineRegion, std::exception_ptr>)>& callback) {
std23::move_only_function<void(expected<OfflineRegion, std::exception_ptr>)>&& callback) {
callback(db->createRegion(definition, metadata));
}
void mergeOfflineRegions(const std::string& sideDatabasePath,
const std::function<void(expected<OfflineRegions, std::exception_ptr>)>& callback) {
std23::move_only_function<void(expected<OfflineRegions, std::exception_ptr>)>&& callback) {
callback(db->mergeDatabase(sideDatabasePath));
}
void updateMetadata(const int64_t regionID,
const OfflineRegionMetadata& metadata,
const std::function<void(expected<OfflineRegionMetadata, std::exception_ptr>)>& callback) {
void updateMetadata(
const int64_t regionID,
const OfflineRegionMetadata& metadata,
std23::move_only_function<void(expected<OfflineRegionMetadata, std::exception_ptr>)>&& callback) {
callback(db->updateMetadata(regionID, metadata));
}
void getRegionStatus(int64_t regionID,
const std::function<void(expected<OfflineRegionStatus, std::exception_ptr>)>& callback) {
void getRegionStatus(
int64_t regionID,
std23::move_only_function<void(expected<OfflineRegionStatus, std::exception_ptr>)>&& callback) {
if (auto download = getDownload(regionID)) {
callback(download.value()->getStatus());
} else {
@@ -107,12 +112,12 @@ public:
}
}
void deleteRegion(OfflineRegion region, const std::function<void(std::exception_ptr)>& callback) {
void deleteRegion(OfflineRegion region, std23::move_only_function<void(std::exception_ptr)>&& callback) {
downloads.erase(region.getID());
callback(db->deleteRegion(std::move(region)));
}
void invalidateRegion(int64_t regionID, const std::function<void(std::exception_ptr)>& callback) {
void invalidateRegion(int64_t regionID, std23::move_only_function<void(std::exception_ptr)>&& callback) {
callback(db->invalidateRegion(regionID));
}
@@ -211,16 +216,17 @@ DatabaseFileSource::DatabaseFileSource(const ResourceOptions& resourceOptions, c
DatabaseFileSource::~DatabaseFileSource() = default;
std::unique_ptr<AsyncRequest> DatabaseFileSource::request(const Resource& resource, Callback callback) {
std::unique_ptr<AsyncRequest> DatabaseFileSource::request(const Resource& resource,
std::function<void(Response)> callback) {
auto req = std::make_unique<FileSourceRequest>(std::move(callback));
impl->actor().invoke(&DatabaseFileSourceThread::request, resource, req->actor());
return req;
}
void DatabaseFileSource::forward(const Resource& res, const Response& response, std::function<void()> callback) {
void DatabaseFileSource::forward(const Resource& res, const Response& response, Scheduler::Task&& callback) {
if (res.storagePolicy == Resource::StoragePolicy::Volatile) return;
std::function<void()> wrapper;
Scheduler::Task wrapper;
if (callback) {
wrapper = Scheduler::GetCurrent()->bindOnce(std::move(callback));
}
@@ -233,15 +239,15 @@ bool DatabaseFileSource::canRequest(const Resource& resource) const {
resource.url.rfind(mbgl::util::FILE_PROTOCOL, 0) == std::string::npos;
}
void DatabaseFileSource::setDatabasePath(const std::string& path, std::function<void()> callback) {
void DatabaseFileSource::setDatabasePath(const std::string& path, std23::move_only_function<void()>&& callback) {
impl->actor().invoke(&DatabaseFileSourceThread::setDatabasePath, path, std::move(callback));
}
void DatabaseFileSource::resetDatabase(std::function<void(std::exception_ptr)> callback) {
void DatabaseFileSource::resetDatabase(std23::move_only_function<void(std::exception_ptr)>&& callback) {
impl->actor().invoke(&DatabaseFileSourceThread::resetDatabase, std::move(callback));
}
void DatabaseFileSource::packDatabase(std::function<void(std::exception_ptr)> callback) {
void DatabaseFileSource::packDatabase(std23::move_only_function<void(std::exception_ptr)>&& callback) {
impl->actor().invoke(&DatabaseFileSourceThread::packDatabase, std::move(callback));
}
@@ -253,59 +259,62 @@ void DatabaseFileSource::put(const Resource& resource, const Response& response)
impl->actor().invoke(&DatabaseFileSourceThread::put, resource, response);
}
void DatabaseFileSource::invalidateAmbientCache(std::function<void(std::exception_ptr)> callback) {
void DatabaseFileSource::invalidateAmbientCache(std23::move_only_function<void(std::exception_ptr)>&& callback) {
impl->actor().invoke(&DatabaseFileSourceThread::invalidateAmbientCache, std::move(callback));
}
void DatabaseFileSource::clearAmbientCache(std::function<void(std::exception_ptr)> callback) {
void DatabaseFileSource::clearAmbientCache(std23::move_only_function<void(std::exception_ptr)>&& callback) {
impl->actor().invoke(&DatabaseFileSourceThread::clearAmbientCache, std::move(callback));
}
void DatabaseFileSource::setMaximumAmbientCacheSize(uint64_t size, std::function<void(std::exception_ptr)> callback) {
void DatabaseFileSource::setMaximumAmbientCacheSize(uint64_t size,
std23::move_only_function<void(std::exception_ptr)>&& callback) {
impl->actor().invoke(&DatabaseFileSourceThread::setMaximumAmbientCacheSize, size, std::move(callback));
}
void DatabaseFileSource::listOfflineRegions(
std::function<void(expected<OfflineRegions, std::exception_ptr>)> callback) {
std23::move_only_function<void(expected<OfflineRegions, std::exception_ptr>)>&& callback) {
impl->actor().invoke(&DatabaseFileSourceThread::listRegions, std::move(callback));
}
void DatabaseFileSource::getOfflineRegion(
const int64_t regionID, std::function<void(expected<std::optional<OfflineRegion>, std::exception_ptr>)> callback) {
const int64_t regionID,
std23::move_only_function<void(expected<std::optional<OfflineRegion>, std::exception_ptr>)>&& callback) {
impl->actor().invoke(&DatabaseFileSourceThread::getRegion, regionID, std::move(callback));
}
void DatabaseFileSource::createOfflineRegion(
const OfflineRegionDefinition& definition,
const OfflineRegionMetadata& metadata,
std::function<void(expected<OfflineRegion, std::exception_ptr>)> callback) {
std23::move_only_function<void(expected<OfflineRegion, std::exception_ptr>)>&& callback) {
impl->actor().invoke(&DatabaseFileSourceThread::createRegion, definition, metadata, std::move(callback));
}
void DatabaseFileSource::mergeOfflineRegions(
const std::string& sideDatabasePath, std::function<void(expected<OfflineRegions, std::exception_ptr>)> callback) {
const std::string& sideDatabasePath,
std23::move_only_function<void(expected<OfflineRegions, std::exception_ptr>)>&& callback) {
impl->actor().invoke(&DatabaseFileSourceThread::mergeOfflineRegions, sideDatabasePath, std::move(callback));
}
void DatabaseFileSource::updateOfflineMetadata(
const int64_t regionID,
const OfflineRegionMetadata& metadata,
std::function<void(expected<OfflineRegionMetadata, std::exception_ptr>)> callback) {
std23::move_only_function<void(expected<OfflineRegionMetadata, std::exception_ptr>)>&& callback) {
impl->actor().invoke(&DatabaseFileSourceThread::updateMetadata, regionID, metadata, std::move(callback));
}
void DatabaseFileSource::deleteOfflineRegion(const OfflineRegion& region,
std::function<void(std::exception_ptr)> callback) {
std23::move_only_function<void(std::exception_ptr)>&& callback) {
impl->actor().invoke(&DatabaseFileSourceThread::deleteRegion, region, std::move(callback));
}
void DatabaseFileSource::invalidateOfflineRegion(const OfflineRegion& region,
std::function<void(std::exception_ptr)> callback) {
std23::move_only_function<void(std::exception_ptr)>&& callback) {
impl->actor().invoke(&DatabaseFileSourceThread::invalidateRegion, region.getID(), std::move(callback));
}
void DatabaseFileSource::setOfflineRegionObserver(const OfflineRegion& region,
std::unique_ptr<OfflineRegionObserver> observer) {
std::unique_ptr<OfflineRegionObserver>&& observer) {
impl->actor().invoke(&DatabaseFileSourceThread::setRegionObserver, region.getID(), std::move(observer));
}
@@ -315,7 +324,7 @@ void DatabaseFileSource::setOfflineRegionDownloadState(const OfflineRegion& regi
void DatabaseFileSource::getOfflineRegionStatus(
const OfflineRegion& region,
std::function<void(expected<OfflineRegionStatus, std::exception_ptr>)> callback) const {
std23::move_only_function<void(expected<OfflineRegionStatus, std::exception_ptr>)>&& callback) const {
impl->actor().invoke(&DatabaseFileSourceThread::getRegionStatus, region.getID(), std::move(callback));
}

View File

@@ -5,8 +5,8 @@
namespace mbgl {
FileSourceRequest::FileSourceRequest(FileSource::Callback&& callback)
: responseCallback(callback),
FileSourceRequest::FileSourceRequest(std::function<void(Response)> callback)
: responseCallback(std::move(callback)),
mailbox(std::make_shared<Mailbox>(*Scheduler::GetCurrent())) {}
FileSourceRequest::~FileSourceRequest() {

View File

@@ -79,7 +79,7 @@ private:
class HTTPRequest : public AsyncRequest {
public:
HTTPRequest(HTTPFileSource::Impl *, Resource, FileSource::Callback);
HTTPRequest(HTTPFileSource::Impl *, Resource, std::function<void(Response)>);
~HTTPRequest() override;
void handleResult(CURLcode code);
@@ -90,7 +90,7 @@ private:
HTTPFileSource::Impl *context = nullptr;
Resource resource;
FileSource::Callback callback;
std::function<void(Response)> callback;
// Will store the current response.
std::shared_ptr<std::string> data;
@@ -264,7 +264,7 @@ ClientOptions HTTPFileSource::Impl::getClientOptions() {
return clientOptions.clone();
}
HTTPRequest::HTTPRequest(HTTPFileSource::Impl *context_, Resource resource_, FileSource::Callback callback_)
HTTPRequest::HTTPRequest(HTTPFileSource::Impl *context_, Resource resource_, std::function<void(Response)> callback_)
: context(context_),
resource(std::move(resource_)),
callback(std::move(callback_)),
@@ -458,8 +458,9 @@ HTTPFileSource::HTTPFileSource(const ResourceOptions &resourceOptions, const Cli
HTTPFileSource::~HTTPFileSource() = default;
std::unique_ptr<AsyncRequest> HTTPFileSource::request(const Resource &resource, Callback callback) {
return std::make_unique<HTTPRequest>(impl.get(), resource, callback);
std::unique_ptr<AsyncRequest> HTTPFileSource::request(const Resource &resource,
std::function<void(Response)> callback) {
return std::make_unique<HTTPRequest>(impl.get(), resource, std::move(callback));
}
void HTTPFileSource::setResourceOptions(ResourceOptions options) {

View File

@@ -13,7 +13,7 @@
namespace {
bool acceptsURL(const std::string& url) {
return 0 == url.rfind(mbgl::util::FILE_PROTOCOL, 0);
return url.starts_with(mbgl::util::FILE_PROTOCOL);
}
} // namespace
@@ -75,7 +75,8 @@ LocalFileSource::LocalFileSource(const ResourceOptions& resourceOptions, const C
LocalFileSource::~LocalFileSource() = default;
std::unique_ptr<AsyncRequest> LocalFileSource::request(const Resource& resource, Callback callback) {
std::unique_ptr<AsyncRequest> LocalFileSource::request(const Resource& resource,
std::function<void(Response)> callback) {
auto req = std::make_unique<FileSourceRequest>(std::move(callback));
impl->actor().invoke(&Impl::request, resource, req->actor());

View File

@@ -55,7 +55,7 @@ public:
" Action: " << "Requesting,"
<< " URL: " << res.url.c_str() << " Size: "
<< (response.data != nullptr ? response.data->size() : 0) << "B,"
<< " Time")
<< " Time");
}
callback(response);
});
@@ -169,7 +169,7 @@ public:
resourceOptions(resourceOptions_.clone()),
clientOptions(clientOptions_.clone()) {}
std::unique_ptr<AsyncRequest> request(const Resource& resource, Callback callback) {
std::unique_ptr<AsyncRequest> request(const Resource& resource, std::function<void(Response)> callback) {
auto req = std::make_unique<FileSourceRequest>(std::move(callback));
req->onCancel([actorRef = thread->actor(), req = req.get()]() {
@@ -258,7 +258,8 @@ bool MainResourceLoader::supportsCacheOnlyRequests() const {
return impl->supportsCacheOnlyRequests();
}
std::unique_ptr<AsyncRequest> MainResourceLoader::request(const Resource& resource, Callback callback) {
std::unique_ptr<AsyncRequest> MainResourceLoader::request(const Resource& resource,
std::function<void(Response)> callback) {
return impl->request(resource, std::move(callback));
}

View File

@@ -29,7 +29,7 @@
namespace {
bool acceptsURL(const std::string &url) {
return 0 == url.rfind(mbgl::util::MBTILES_PROTOCOL, 0);
return url.starts_with(mbgl::util::MBTILES_PROTOCOL);
}
std::string url_to_path(const std::string &url) {
@@ -107,7 +107,7 @@ public:
auto format_ptr = values.find("format");
std::string format = format_ptr == values.end() ? "png" : format_ptr->second;
if (format != "pbf" && values.count("scale") == 0) {
if (format != "pbf" && !values.contains("scale")) {
values["scale"] = "1";
}
@@ -184,19 +184,19 @@ public:
// Load data for specific tile
void request_tile(const Resource &resource, ActorRef<FileSourceRequest> req) {
std::string base_path = url_to_path(resource.url);
std::string path = db_path(base_path);
const std::string base_path = url_to_path(resource.url);
const std::string path = db_path(base_path);
auto &db = get_db(path);
int iy = resource.tileData->y;
int iz = resource.tileData->z;
const int iy = resource.tileData->y;
const int iz = static_cast<uint8_t>(resource.tileData->z);
auto x = std::to_string(resource.tileData->x);
auto y = std::to_string((int)(pow(2, iz) - 1) - iy);
auto z = std::to_string(iz);
const auto x = std::to_string(resource.tileData->x);
const auto y = std::to_string((int)(pow(2, iz) - 1) - iy);
const auto z = std::to_string(iz);
std::string sql = "SELECT tile_data FROM tiles where zoom_level = " + z + " AND tile_column = " + x +
" AND tile_row = " + y;
const std::string sql = "SELECT tile_data FROM tiles where zoom_level = " + z + " AND tile_column = " + x +
" AND tile_row = " + y;
mapbox::sqlite::Statement stmt(db, sql.c_str());
Response response;
@@ -255,7 +255,7 @@ private:
auto ptr = db_cache.find(path);
if (ptr != db_cache.end()) {
return ptr->second;
};
}
auto ptr2 = db_cache.insert(std::pair<std::string, mapbox::sqlite::Database>(
path, mapbox::sqlite::Database::open(path, mapbox::sqlite::ReadOnly)));
@@ -275,7 +275,8 @@ MBTilesFileSource::MBTilesFileSource(const ResourceOptions &resourceOptions, con
resourceOptions.clone(),
clientOptions.clone())) {}
std::unique_ptr<AsyncRequest> MBTilesFileSource::request(const Resource &resource, FileSource::Callback callback) {
std::unique_ptr<AsyncRequest> MBTilesFileSource::request(const Resource &resource,
std::function<void(Response)> callback) {
auto req = std::make_unique<FileSourceRequest>(std::move(callback));
// assume if there is a tile request, that the mbtiles file has been validated
@@ -296,7 +297,7 @@ std::unique_ptr<AsyncRequest> MBTilesFileSource::request(const Resource &resourc
// file must exist
auto path = url_to_path(resource.url);
struct stat buffer;
struct stat buffer{};
int result = stat(path.c_str(), &buffer);
if (result == -1 && errno == ENOENT) {
Response response;

View File

@@ -37,9 +37,7 @@ constexpr const char* ONLINE_STATUS_KEY = "online-status";
class OnlineFileSourceThread;
struct OnlineFileRequest {
using Callback = std::function<void(Response)>;
OnlineFileRequest(Resource resource_, Callback callback_, OnlineFileSourceThread& impl_);
OnlineFileRequest(Resource resource_, std::function<void(Response)>&& callback_, OnlineFileSourceThread& impl_);
~OnlineFileRequest();
void networkIsReachableAgain();
@@ -56,7 +54,7 @@ struct OnlineFileRequest {
Resource resource;
std::unique_ptr<AsyncRequest> request;
util::Timer timer;
Callback callback;
std::function<void(Response)> callback;
std::function<void()> cancelCallback = nullptr;
std::shared_ptr<Mailbox> mailbox;
@@ -303,7 +301,7 @@ private:
std::set<OnlineFileRequest*> activeRequests;
bool online = true;
uint32_t maximumConcurrentRequests;
uint32_t maximumConcurrentRequests = util::DEFAULT_MAXIMUM_CONCURRENT_REQUESTS;
HTTPFileSource httpFileSource;
util::AsyncTask reachability{std::bind(&OnlineFileSourceThread::networkIsReachableAgain, this)};
std::map<AsyncRequest*, std::unique_ptr<OnlineFileRequest>> tasks;
@@ -320,7 +318,7 @@ public:
resourceOptions.clone(),
clientOptions.clone())) {}
std::unique_ptr<AsyncRequest> request(Callback callback, Resource res) {
std::unique_ptr<AsyncRequest> request(std::function<void(Response)> callback, Resource res) {
auto req = std::make_unique<FileSourceRequest>(std::move(callback));
req->onCancel(
[actorRef = thread->actor(), req = req.get()]() { actorRef.invoke(&OnlineFileSourceThread::cancel, req); });
@@ -429,7 +427,9 @@ private:
const std::unique_ptr<util::Thread<OnlineFileSourceThread>> thread;
};
OnlineFileRequest::OnlineFileRequest(Resource resource_, Callback callback_, OnlineFileSourceThread& impl_)
OnlineFileRequest::OnlineFileRequest(Resource resource_,
std::function<void(Response)>&& callback_,
OnlineFileSourceThread& impl_)
: impl(impl_),
resource(std::move(resource_)),
callback(std::move(callback_)) {
@@ -616,7 +616,8 @@ OnlineFileSource::OnlineFileSource(const ResourceOptions& resourceOptions, const
OnlineFileSource::~OnlineFileSource() = default;
std::unique_ptr<AsyncRequest> OnlineFileSource::request(const Resource& resource, Callback callback) {
std::unique_ptr<AsyncRequest> OnlineFileSource::request(const Resource& resource,
std::function<void(Response)> callback) {
Resource res = resource;
const TileServerOptions options = impl->getResourceOptions().tileServerOptions();

View File

@@ -547,7 +547,8 @@ PMTilesFileSource::PMTilesFileSource(const ResourceOptions& resourceOptions, con
resourceOptions.clone(),
clientOptions.clone())) {}
std::unique_ptr<AsyncRequest> PMTilesFileSource::request(const Resource& resource, FileSource::Callback callback) {
std::unique_ptr<AsyncRequest> PMTilesFileSource::request(const Resource& resource,
std::function<void(Response)> callback) {
auto req = std::make_unique<FileSourceRequest>(std::move(callback));
// assume if there is a tile request, that the pmtiles file has been validated

View File

@@ -48,8 +48,8 @@ struct Watch {
uv_poll_t poll;
int fd;
std::function<void(int, RunLoop::Event)> eventCallback;
std::function<void()> closeCallback;
std23::move_only_function<void(int, RunLoop::Event)> eventCallback;
std23::move_only_function<void()> closeCallback;
};
RunLoop* RunLoop::Get() {
@@ -171,7 +171,7 @@ void RunLoop::waitForEmpty([[maybe_unused]] const mbgl::util::SimpleIdentity tag
}
}
void RunLoop::addWatch(int fd, Event event, std::function<void(int, Event)>&& callback) {
void RunLoop::addWatch(int fd, Event event, std23::move_only_function<void(int, Event)>&& callback) {
MBGL_VERIFY_THREAD(tid);
Watch* watch = nullptr;

View File

@@ -37,6 +37,7 @@ target_include_directories(
${PROJECT_SOURCE_DIR}/include
${PROJECT_SOURCE_DIR}/platform/default/include
${PROJECT_SOURCE_DIR}/src
${PROJECT_SOURCE_DIR}/vendor/nontype_functional/include
PRIVATE ${LIBUV_INCLUDE_DIRS}
)
@@ -44,6 +45,7 @@ target_link_libraries(
mbgl-node-loop
PUBLIC
Mapbox::Base
INTERFACE mbgl-vendor-nontype_functional
)
target_sources(
@@ -68,6 +70,7 @@ target_link_libraries(
mbgl-node
INTERFACE mbgl-node-loop
INTERFACE Mapbox::Map
INTERFACE mbgl-vendor-nontype_functional
)
# FIXME: Node bindings only run fully on Linux now because it requires libuv RunLoop (which is the default on Linux). Also, Sanitizer will

View File

@@ -1537,7 +1537,7 @@ NodeMap::~NodeMap() {
}
std::unique_ptr<mbgl::AsyncRequest> NodeFileSource::request(const mbgl::Resource& resource,
mbgl::FileSource::Callback callback_) {
std::function<void(mbgl::Response)> callback_) {
assert(nodeMap);
Nan::HandleScope scope;

View File

@@ -103,7 +103,7 @@ struct NodeFileSource : public mbgl::FileSource {
NodeFileSource(NodeMap* nodeMap_)
: nodeMap(nodeMap_) {}
~NodeFileSource() override = default;
std::unique_ptr<mbgl::AsyncRequest> request(const mbgl::Resource&, mbgl::FileSource::Callback) final;
std::unique_ptr<mbgl::AsyncRequest> request(const mbgl::Resource&, std::function<void(mbgl::Response)>) final;
bool canRequest(const mbgl::Resource&) const override;
void setResourceOptions(mbgl::ResourceOptions) override;
mbgl::ResourceOptions getResourceOptions() override;

View File

@@ -7,7 +7,7 @@
namespace node_mbgl {
NodeRequest::NodeRequest(mbgl::FileSource::Callback callback_, NodeAsyncRequest* asyncRequest_)
NodeRequest::NodeRequest(std::function<void(mbgl::Response)> callback_, NodeAsyncRequest* asyncRequest_)
: callback(std::move(callback_)),
asyncRequest(asyncRequest_) {
asyncRequest->request = this;
@@ -42,7 +42,7 @@ void NodeRequest::Init(v8::Local<v8::Object> target) {
void NodeRequest::New(const Nan::FunctionCallbackInfo<v8::Value>& info) {
auto target = reinterpret_cast<NodeMap*>(info[0].As<v8::External>()->Value());
auto callback = reinterpret_cast<mbgl::FileSource::Callback*>(info[1].As<v8::External>()->Value());
auto callback = reinterpret_cast<std::function<void(mbgl::Response)>*>(info[1].As<v8::External>()->Value());
auto asyncRequest = reinterpret_cast<NodeAsyncRequest*>(info[2].As<v8::External>()->Value());
auto request = new NodeRequest(*callback, asyncRequest);

View File

@@ -22,7 +22,7 @@ struct NodeAsyncRequest : public mbgl::AsyncRequest {
class NodeRequest : public Nan::ObjectWrap {
public:
NodeRequest(mbgl::FileSource::Callback, NodeAsyncRequest*);
NodeRequest(std::function<void(mbgl::Response)>, NodeAsyncRequest*);
~NodeRequest() override;
static Nan::Persistent<v8::Function> constructor;
@@ -34,7 +34,7 @@ public:
void unrefRequest();
mbgl::FileSource::Callback callback;
std::function<void(mbgl::Response)> callback;
NodeAsyncRequest* asyncRequest;
Nan::AsyncResource* asyncResource = new Nan::AsyncResource("mbgl:execute");
};

View File

@@ -106,8 +106,9 @@ HTTPFileSource::HTTPFileSource(const ResourceOptions& resourceOptions, const Cli
HTTPFileSource::~HTTPFileSource() = default;
std::unique_ptr<AsyncRequest> HTTPFileSource::request(const Resource& resource, Callback callback) {
return std::make_unique<HTTPRequest>(impl.get(), resource, callback);
std::unique_ptr<AsyncRequest> HTTPFileSource::request(const Resource& resource,
std::function<void(Response)> callback) {
return std::make_unique<HTTPRequest>(impl.get(), resource, std::move(callback));
}
void HTTPFileSource::setResourceOptions(ResourceOptions options) {

View File

@@ -13,10 +13,12 @@
namespace mbgl {
HTTPRequest::HTTPRequest(HTTPFileSource::Impl* context, const Resource& resource, FileSource::Callback callback)
HTTPRequest::HTTPRequest(HTTPFileSource::Impl* context,
const Resource& resource,
std::function<void(Response)> callback)
: m_context(context),
m_resource(resource),
m_callback(callback) {
m_callback(std::move(callback)) {
m_context->request(this);
}

View File

@@ -14,7 +14,7 @@ class Response;
class HTTPRequest : public AsyncRequest {
public:
HTTPRequest(HTTPFileSource::Impl*, const Resource&, FileSource::Callback);
HTTPRequest(HTTPFileSource::Impl*, const Resource&, std::function<void(Response)>);
virtual ~HTTPRequest();
QUrl requestUrl() const;
@@ -25,7 +25,7 @@ public:
private:
HTTPFileSource::Impl* m_context;
Resource m_resource;
FileSource::Callback m_callback;
std::function<void(Response)> m_callback;
bool m_handled = false;
};

View File

@@ -107,7 +107,7 @@ void RunLoop::waitForEmpty([[maybe_unused]] const mbgl::util::SimpleIdentity tag
}
}
void RunLoop::addWatch(int fd, Event event, std::function<void(int, Event)>&& cb) {
void RunLoop::addWatch(int fd, Event event, std23::move_only_function<void(int, Event)>&& cb) {
MBGL_VERIFY_THREAD(tid);
if (event == Event::Read || event == Event::ReadWrite) {

View File

@@ -13,8 +13,7 @@
namespace mbgl {
namespace util {
using WatchCallback = std::function<void(int, RunLoop::Event)>;
using WatchPair = std::pair<std::unique_ptr<QSocketNotifier>, WatchCallback>;
using WatchPair = std::pair<std::unique_ptr<QSocketNotifier>, std23::move_only_function<void(int, RunLoop::Event)>>;
class RunLoop::Impl : public QObject {
Q_OBJECT

View File

@@ -13,7 +13,11 @@ Scheduler::~Scheduler() {
MBGL_VERIFY_THREAD(tid);
}
void Scheduler::schedule(std::function<void()>&& function) {
void Scheduler::schedule(Task&& function) {
this->Scheduler::schedule(mbgl::util::SimpleIdentity::Empty, std::move(function));
}
void Scheduler::schedule(mbgl::util::SimpleIdentity, Task&& function) {
const std::lock_guard<std::mutex> lock(m_taskQueueMutex);
m_taskQueue.push(std::move(function));
@@ -23,7 +27,7 @@ void Scheduler::schedule(std::function<void()>&& function) {
}
void Scheduler::processEvents() {
std::queue<std::function<void()>> taskQueue;
std::queue<Task> taskQueue;
{
const std::unique_lock<std::mutex> lock(m_taskQueueMutex);
std::swap(taskQueue, m_taskQueue);

View File

@@ -1,6 +1,7 @@
#pragma once
#include <mbgl/actor/scheduler.hpp>
#include <mbgl/util/identity.hpp>
#include <mbgl/util/util.hpp>
#include <QObject>
@@ -20,7 +21,8 @@ public:
~Scheduler() override;
// mbgl::Scheduler implementation.
void schedule(std::function<void()>&& function) final;
void schedule(Task&&) final;
void schedule(mbgl::util::SimpleIdentity, Task&&) final;
void waitForEmpty(const mbgl::util::SimpleIdentity tag = mbgl::util::SimpleIdentity::Empty) override;
@@ -37,7 +39,7 @@ private:
std::mutex m_taskQueueMutex;
std::condition_variable cvEmpty;
std::atomic<std::size_t> pendingItems;
std::queue<std::function<void()>> m_taskQueue;
std::queue<Task> m_taskQueue;
mapbox::base::WeakPtrFactory<Scheduler> weakFactory{this};
// Do not add members here, see `WeakPtrFactory`
};

View File

@@ -32,7 +32,8 @@ ProxyFileSource::ProxyFileSource(std::shared_ptr<FileSource> defaultResourceLoad
ProxyFileSource::~ProxyFileSource() = default;
std::unique_ptr<AsyncRequest> ProxyFileSource::request(const Resource& resource, Callback callback) {
std::unique_ptr<AsyncRequest> ProxyFileSource::request(const Resource& resource,
std::function<void(Response)> callback) {
auto transformed = resource;
// If offline, force always loading the resource from the cache

View File

@@ -12,7 +12,7 @@ public:
ProxyFileSource(std::shared_ptr<FileSource>, const ResourceOptions&, const ClientOptions&);
~ProxyFileSource();
std::unique_ptr<AsyncRequest> request(const Resource&, Callback) override;
std::unique_ptr<AsyncRequest> request(const Resource&, std::function<void(Response)>) override;
bool canRequest(const Resource&) const override { return true; }
/**

View File

@@ -5,7 +5,7 @@
namespace mbgl {
std::function<void()> Scheduler::bindOnce(std::function<void()> fn) {
Scheduler::Task Scheduler::bindOnce(Scheduler::Task&& fn) {
assert(fn);
return [scheduler = makeWeakPtr(), scheduled = std::move(fn)]() mutable {
if (!scheduled) return; // Repeated call.
@@ -59,11 +59,11 @@ std::shared_ptr<Scheduler> Scheduler::GetSequenced() {
if (auto scheduler = weaks[lastUsedIndex].lock()) {
return scheduler;
} else {
auto result = std::make_shared<SequencedScheduler>();
weaks[lastUsedIndex] = result;
return result;
}
auto result = std::make_shared<SequencedScheduler>();
weaks[lastUsedIndex] = result;
return result;
}
} // namespace mbgl

View File

@@ -64,7 +64,7 @@ Map::Impl::~Impl() {
// Explicitly reset the RendererFrontend first to ensure it releases
// All shared resources (AnnotationManager)
rendererFrontend.reset();
};
}
// MARK: - Map::Impl StyleObserver
@@ -212,12 +212,10 @@ void Map::Impl::onWillStartRenderingMap() {
void Map::Impl::onDidFinishRenderingMap() {
if (mode == MapMode::Continuous && loading) {
observer.onDidFinishRenderingMap(MapObserver::RenderMode::Full);
if (loading) {
loading = false;
observer.onDidFinishLoadingMap();
}
loading = false;
observer.onDidFinishLoadingMap();
}
};
}
void Map::Impl::jumpTo(const CameraOptions& camera) {
cameraMutated = true;
@@ -225,7 +223,7 @@ void Map::Impl::jumpTo(const CameraOptions& camera) {
onUpdate();
}
void Map::Impl::onStyleImageMissing(const std::string& id, const std::function<void()>& done) {
void Map::Impl::onStyleImageMissing(const std::string& id, Scheduler::Task&& done) {
if (!style->getImage(id)) observer.onStyleImageMissing(id);
done();

View File

@@ -52,7 +52,7 @@ public:
void onDidFinishRenderingFrame(RenderMode, bool, bool, double, double) final;
void onWillStartRenderingMap() final;
void onDidFinishRenderingMap() final;
void onStyleImageMissing(const std::string&, const std::function<void()>&) final;
void onStyleImageMissing(const std::string&, Scheduler::Task&&) final;
void onRemoveUnusedStyleImages(const std::vector<std::string>&) final;
void onRegisterShaders(gfx::ShaderRegistry&) final;
@@ -88,7 +88,7 @@ public:
uint8_t prefetchZoomDelta = util::DEFAULT_PREFETCH_ZOOM_DELTA;
bool loading = false;
bool rendererFullyLoaded;
bool rendererFullyLoaded{false};
std::unique_ptr<StillImageRequest> stillImageRequest;
};

View File

@@ -231,7 +231,7 @@ void ImageManager::checkMissingAndNotify(ImageRequestor& requestor, const ImageR
if (!missingDependencies.empty()) {
ImageRequestor* requestorPtr = &requestor;
assert(!missingImageRequestors.count(requestorPtr));
assert(!missingImageRequestors.contains(requestorPtr));
missingImageRequestors.emplace(requestorPtr, pair);
for (const auto& dependency : missingDependencies) {
@@ -260,7 +260,7 @@ void ImageManager::checkMissingAndNotify(ImageRequestor& requestor, const ImageR
requestor.addPendingRequest(missingImage);
}
auto removePendingRequests = [this, missingImage] {
Scheduler::Task removePendingRequests = [this, missingImage] {
std::lock_guard<std::recursive_mutex> readWriteLock(rwLock);
auto existingRequest = requestedImages.find(missingImage);
if (existingRequest == requestedImages.end()) {
@@ -271,8 +271,8 @@ void ImageManager::checkMissingAndNotify(ImageRequestor& requestor, const ImageR
req->removePendingRequest(missingImage);
}
};
observer->onStyleImageMissing(missingImage,
Scheduler::GetCurrent()->bindOnce(std::move(removePendingRequests)));
Scheduler::Task bindRemove = Scheduler::GetCurrent()->bindOnce(std::move(removePendingRequests));
observer->onStyleImageMissing(missingImage, std::move(bindRemove));
}
} else {
// Associate requestor with an image that was provided by the client.

View File

@@ -11,7 +11,7 @@ class ImageManagerObserver {
public:
virtual ~ImageManagerObserver() = default;
virtual void onStyleImageMissing(const std::string&, const std::function<void()>& done) { done(); }
virtual void onStyleImageMissing(const std::string&, Scheduler::Task&& done) { done(); }
virtual void onRemoveUnusedStyleImages(const std::vector<std::string>&) {}
};

View File

@@ -54,7 +54,7 @@ const std::string& LayerRenderItem::getName() const {
}
#if MLN_DRAWABLE_RENDERER
void LayerRenderItem::updateDebugDrawables(DebugLayerGroupMap&, PaintParameters&) const {};
void LayerRenderItem::updateDebugDrawables(DebugLayerGroupMap&, PaintParameters&) const {}
#endif
namespace {
@@ -1065,10 +1065,10 @@ void RenderOrchestrator::onTileAction(RenderSource&,
observer->onTileAction(op, id, sourceID);
}
void RenderOrchestrator::onStyleImageMissing(const std::string& id, const std::function<void()>& done) {
void RenderOrchestrator::onStyleImageMissing(const std::string& id, Scheduler::Task&& done) {
MLN_TRACE_FUNC();
observer->onStyleImageMissing(id, done);
observer->onStyleImageMissing(id, std::move(done));
}
void RenderOrchestrator::onRemoveUnusedStyleImages(const std::vector<std::string>& unusedImageIDs) {

View File

@@ -186,7 +186,7 @@ private:
void onTileAction(RenderSource&, TileOperation, const OverscaledTileID&, const std::string&) override;
// ImageManagerObserver implementation
void onStyleImageMissing(const std::string&, const std::function<void()>&) override;
void onStyleImageMissing(const std::string&, Scheduler::Task&&) override;
void onRemoveUnusedStyleImages(const std::vector<std::string>&) override;
#if MLN_DRAWABLE_RENDERER

View File

@@ -16,7 +16,7 @@ public:
AssetFileSource(const ResourceOptions& resourceOptions, const ClientOptions& clientOptions);
~AssetFileSource() override;
std::unique_ptr<AsyncRequest> request(const Resource&, Callback) override;
std::unique_ptr<AsyncRequest> request(const Resource&, std::function<void(Response)>) override;
bool canRequest(const Resource&) const override;
void pause() override;
void resume() override;

View File

@@ -13,7 +13,7 @@ public:
HTTPFileSource(const ResourceOptions& resourceOptions, const ClientOptions& clientOptions);
~HTTPFileSource() override;
std::unique_ptr<AsyncRequest> request(const Resource&, Callback) override;
std::unique_ptr<AsyncRequest> request(const Resource&, std::function<void(Response)>) override;
bool canRequest(const Resource& resource) const override {
return resource.hasLoadingMethod(Resource::LoadingMethod::Network);
}

View File

@@ -16,7 +16,7 @@ public:
LocalFileSource(const ResourceOptions& resourceOptions, const ClientOptions& clientOptions);
~LocalFileSource() override;
std::unique_ptr<AsyncRequest> request(const Resource&, Callback) override;
std::unique_ptr<AsyncRequest> request(const Resource&, std::function<void(Response)>) override;
bool canRequest(const Resource&) const override;
void pause() override;
void resume() override;

View File

@@ -14,7 +14,7 @@ public:
~MainResourceLoader() override;
bool supportsCacheOnlyRequests() const override;
std::unique_ptr<AsyncRequest> request(const Resource&, Callback) override;
std::unique_ptr<AsyncRequest> request(const Resource&, std::function<void(Response)>) override;
bool canRequest(const Resource&) const override;
void pause() override;
void resume() override;

View File

@@ -13,7 +13,7 @@ public:
MBTilesFileSource(const ResourceOptions& resourceOptions, const ClientOptions& clientOptions);
~MBTilesFileSource() override;
std::unique_ptr<AsyncRequest> request(const Resource&, Callback) override;
std::unique_ptr<AsyncRequest> request(const Resource&, std::function<void(Response)>) override;
bool canRequest(const Resource&) const override;
void setResourceOptions(ResourceOptions) override;

View File

@@ -12,7 +12,7 @@ public:
PMTilesFileSource(const ResourceOptions& resourceOptions, const ClientOptions& clientOptions);
~PMTilesFileSource() override;
std::unique_ptr<AsyncRequest> request(const Resource&, Callback) override;
std::unique_ptr<AsyncRequest> request(const Resource&, std::function<void(Response)>) override;
bool canRequest(const Resource&) const override;
void setResourceOptions(ResourceOptions) override;

View File

@@ -14,12 +14,13 @@
#include <mbgl/renderer/layers/render_line_layer.hpp>
#include <mbgl/renderer/layers/render_symbol_layer.hpp>
#include <mbgl/renderer/buckets/symbol_bucket.hpp>
#include <mbgl/util/constants.hpp>
#include <mbgl/util/containers.hpp>
#include <mbgl/util/exception.hpp>
#include <mbgl/util/instrumentation.hpp>
#include <mbgl/util/logging.hpp>
#include <mbgl/util/constants.hpp>
#include <mbgl/util/string.hpp>
#include <mbgl/util/exception.hpp>
#include <mbgl/util/stopwatch.hpp>
#include <mbgl/util/string.hpp>
#include <mbgl/util/thread_pool.hpp>
#include <unordered_set>
@@ -372,9 +373,9 @@ void GeometryTileWorker::parse() {
return;
}
MBGL_TIMING_START(watch)
MBGL_TIMING_START(watch);
std::unordered_map<std::string, std::unique_ptr<SymbolLayout>> symbolLayoutMap;
mbgl::unordered_map<std::string, std::unique_ptr<SymbolLayout>> symbolLayoutMap;
renderData.clear();
layouts.clear();
@@ -495,7 +496,7 @@ void GeometryTileWorker::finalizeLayout() {
return;
}
MBGL_TIMING_START(watch)
MBGL_TIMING_START(watch);
std::optional<AlphaImage> glyphAtlasImage;
ImageAtlas iconAtlas = makeImageAtlas(imageMap, patternMap, versionMap);
if (!layouts.empty()) {

View File

@@ -14,7 +14,7 @@ TileCache::~TileCache() {
pendingReleases.clear();
std::unique_lock counterLock{deferredSignalLock};
deferredSignal.wait(counterLock, [&]() { return deferredDeletionsPending == 0; });
deferredSignal.wait(counterLock, [this]() { return deferredDeletionsPending == 0; });
}
void TileCache::setSize(size_t size_) {
@@ -37,24 +37,6 @@ void TileCache::setSize(size_t size_) {
assert(orderedKeys.size() <= size);
}
namespace {
/// This exists solely to prevent a problem where temporary lambda captures
/// are retained for the duration of the scope instead of being destroyed immediately.
struct CaptureWrapper {
CaptureWrapper(std::vector<std::unique_ptr<Tile>>&& items_)
: items(items_.size()) {
std::ranges::move(items_, items.begin());
}
CaptureWrapper(CaptureWrapper&&) = default;
/// This copy constructor is required to build, but doesn't seem to be called.
CaptureWrapper(const CaptureWrapper& other)
: items(other.items) {}
std::vector<std::shared_ptr<Tile>> items;
};
} // namespace
void TileCache::deferredRelease(std::unique_ptr<Tile>&& tile) {
MLN_TRACE_FUNC();
@@ -76,27 +58,22 @@ void TileCache::deferPendingReleases() {
deferredDeletionsPending++;
}
CaptureWrapper wrap{std::move(pendingReleases)};
// Move elements to a disposable container to be captured by the lambda
decltype(pendingReleases) pending{pendingReleases.size()};
std::ranges::move(pendingReleases, pending.begin());
pendingReleases.clear();
// The `std::function` must be created in a separate statement from the `schedule` call.
// Creating a `std::function` from a lambda involves a copy, which is why we must use
// `shared_ptr` rather than `unique_ptr` for the capture. As a result, a temporary holds
// a reference until the construction is complete and the lambda is destroyed.
// If this temporary outlives the `schedule` call, and the function is executed immediately
// by a waiting thread and is already complete, that temporary reference ends up being the
// last one and the destruction actually occurs here on this thread.
std::function<void()> func{[tile_{CaptureWrapper{std::move(wrap)}}, this]() mutable {
threadPool.schedule({[items{std::move(pending)}, this]() mutable {
MLN_TRACE_ZONE(deferPendingReleases lambda);
MLN_ZONE_VALUE(wrap_.releases.size());
tile_.items.clear();
MLN_ZONE_VALUE(items.size());
// Run the deletions
items.clear();
// Wake up a waiting destructor
std::lock_guard<std::mutex> counterLock(deferredSignalLock);
deferredDeletionsPending--;
deferredSignal.notify_all();
}};
threadPool.schedule(std::move(func));
}});
pendingReleases.clear();
}
void TileCache::add(const OverscaledTileID& key, std::unique_ptr<Tile>&& tile) {

View File

@@ -21,10 +21,10 @@ namespace util {
std::stringstream messageStream; \
messageStream << message; \
watch->report(messageStream.str()); \
} while (0);
} while (0)
#else
#define MBGL_TIMING_START(watch)
#define MBGL_TIMING_FINISH(watch, message)
#define MBGL_TIMING_START(watch) ((void)0)
#define MBGL_TIMING_FINISH(watch, message) ((void)0)
#endif
#ifndef DISABLE_STOPWATCH

View File

@@ -59,7 +59,7 @@ std::thread ThreadedSchedulerBase::makeSchedulerThread(size_t index) {
// 2. Visit a task from each
for (auto& q : pending) {
std::function<void()> tasklet;
Task tasklet;
{
std::lock_guard<std::mutex> lock(q->lock);
if (q->queue.size()) {
@@ -105,11 +105,11 @@ std::thread ThreadedSchedulerBase::makeSchedulerThread(size_t index) {
});
}
void ThreadedSchedulerBase::schedule(std::function<void()>&& fn) {
void ThreadedSchedulerBase::schedule(Task&& fn) {
schedule(uniqueID, std::move(fn));
}
void ThreadedSchedulerBase::schedule(const util::SimpleIdentity tag, std::function<void()>&& fn) {
void ThreadedSchedulerBase::schedule(const util::SimpleIdentity tag, Task&& fn) {
MLN_TRACE_FUNC();
assert(fn);
if (!fn) return;

View File

@@ -22,12 +22,12 @@ public:
/// @brief Schedule a generic task not assigned to any particular owner.
/// The scheduler itself will own the task.
/// @param fn Task to run
void schedule(std::function<void()>&& fn) override;
void schedule(Task&& fn) override;
/// @brief Schedule a task assigned to the given owner `tag`.
/// @param tag Identifier object to indicate ownership of `fn`
/// @param fn Task to run
void schedule(const util::SimpleIdentity tag, std::function<void()>&& fn) override;
void schedule(const util::SimpleIdentity tag, Task&& fn) override;
const util::SimpleIdentity uniqueID;
protected:
@@ -56,10 +56,10 @@ protected:
// Task queues bucketed by tag address
struct Queue {
std::atomic<std::size_t> runningCount; /* running tasks */
std::condition_variable cv; /* queue empty condition */
std::mutex lock; /* lock */
std::queue<std::function<void()>> queue; /* pending task queue */
std::atomic<std::size_t> runningCount; /* running tasks */
std::condition_variable cv; /* queue empty condition */
std::mutex lock; /* lock */
std::queue<Task> queue; /* pending task queue */
};
mbgl::unordered_map<util::SimpleIdentity, std::shared_ptr<Queue>> taggedQueue;
};
@@ -90,7 +90,7 @@ public:
}
}
void runOnRenderThread(const util::SimpleIdentity tag, std::function<void()>&& fn) override {
void runOnRenderThread(const util::SimpleIdentity tag, Task&& fn) override {
std::shared_ptr<RenderQueue> queue;
{
std::lock_guard<std::mutex> lock(taggedRenderQueueLock);
@@ -149,7 +149,7 @@ private:
std::vector<std::thread> threads;
struct RenderQueue {
std::queue<std::function<void()>> queue;
std::queue<Task> queue;
std::mutex mutex;
};
mbgl::unordered_map<util::SimpleIdentity, std::shared_ptr<RenderQueue>> taggedRenderQueue;

View File

@@ -94,16 +94,14 @@ TEST(Actor, DestructionBlocksOnSend) {
void waitForEmpty(const util::SimpleIdentity) override { assert(false); }
void schedule(std::function<void()>&&) final {
void schedule(Task&&) final {
promise.set_value();
future.wait();
std::this_thread::sleep_for(1ms);
waited = true;
}
void schedule(const util::SimpleIdentity, std::function<void()>&& fn) override final {
schedule(std::move(fn));
}
void schedule(const util::SimpleIdentity, Task&& fn) override final { schedule(std::move(fn)); }
mapbox::base::WeakPtr<Scheduler> makeWeakPtr() override { return weakFactory.makeWeakPtr(); }

View File

@@ -149,7 +149,7 @@ public:
int count = 0;
std::function<void(const std::string&)> imageMissing = [](const std::string&) {
};
void onStyleImageMissing(const std::string& id, const std::function<void()>& done) override {
void onStyleImageMissing(const std::string& id, Scheduler::Task&& done) override {
count++;
imageMissing(id);
done();

View File

@@ -27,12 +27,12 @@ public:
class FakeFileRequest : public AsyncRequest {
public:
Resource resource;
Callback callback;
std::function<void(Response)> callback;
std::list<FakeFileRequest*>& list;
std::list<FakeFileRequest*>::iterator link;
FakeFileRequest(Resource resource_, Callback callback_, std::list<FakeFileRequest*>& list_)
FakeFileRequest(Resource resource_, std::function<void(Response)> callback_, std::list<FakeFileRequest*>& list_)
: resource(std::move(resource_)),
callback(std::move(callback_)),
list(list_),
@@ -47,8 +47,8 @@ public:
FakeFileSource()
: FakeFileSource(ResourceOptions::Default(), ClientOptions()) {}
std::unique_ptr<AsyncRequest> request(const Resource& resource, Callback callback) override {
return std::make_unique<FakeFileRequest>(resource, callback, requests);
std::unique_ptr<AsyncRequest> request(const Resource& resource, std::function<void(Response)> callback) override {
return std::make_unique<FakeFileRequest>(resource, std::move(callback), requests);
}
bool canRequest(const Resource&) const override { return true; }
@@ -62,7 +62,7 @@ public:
if (requestFound) {
// Copy the callback, in case calling it deallocates the AsyncRequest.
Callback callback_ = (*it)->callback;
auto callback_ = (*it)->callback;
callback_(response);
}
@@ -89,8 +89,8 @@ public:
FakeOnlineFileSource(const ResourceOptions& resourceOptions_, const ClientOptions& clientOptions_)
: FakeFileSource(resourceOptions_, clientOptions_) {}
std::unique_ptr<AsyncRequest> request(const Resource& resource, Callback callback) override {
return FakeFileSource::request(resource, callback);
std::unique_ptr<AsyncRequest> request(const Resource& resource, std::function<void(Response)> callback) override {
return FakeFileSource::request(resource, std::move(callback));
}
bool respond(Resource::Kind kind, const Response& response) { return FakeFileSource::respond(kind, response); }

View File

@@ -60,7 +60,8 @@ StubFileSource::StubFileSource(const ResourceOptions& resourceOptions_,
StubFileSource::~StubFileSource() = default;
std::unique_ptr<AsyncRequest> StubFileSource::request(const Resource& resource, Callback callback) {
std::unique_ptr<AsyncRequest> StubFileSource::request(const Resource& resource,
std::function<void(Response)> callback) {
auto req = std::make_unique<StubFileRequest>(*this);
if (type == ResponseType::Synchronous) {
std::optional<Response> res = response(resource);
@@ -68,7 +69,7 @@ std::unique_ptr<AsyncRequest> StubFileSource::request(const Resource& resource,
callback(*res);
}
} else {
pending.emplace(req.get(), std::make_tuple(resource, response, callback));
pending.emplace(req.get(), std::make_tuple(resource, response, std::move(callback)));
}
return req;
}

View File

@@ -23,8 +23,8 @@ public:
StubFileSource(ResponseType = ResponseType::Asynchronous);
~StubFileSource() override;
std::unique_ptr<AsyncRequest> request(const Resource&, Callback) override;
bool canRequest(const Resource&) const override { return true; }
std::unique_ptr<AsyncRequest> request(const Resource&, std::function<void(Response)>) override;
bool canRequest(const Resource&) const noexcept override { return true; }
void remove(AsyncRequest*);
void setProperty(const std::string&, const mapbox::base::Value&) override;
mapbox::base::Value getProperty(const std::string&) const override;
@@ -57,7 +57,7 @@ private:
// The default behavior is to throw if no per-kind callback has been set.
std::optional<Response> defaultResponse(const Resource&);
std::unordered_map<AsyncRequest*, std::tuple<Resource, ResponseFunction, Callback>> pending;
std::unordered_map<AsyncRequest*, std::tuple<Resource, ResponseFunction, std::function<void(Response)>>> pending;
ResponseType type;
util::Timer timer;
std::map<std::string, mapbox::base::Value> properties;

View File

@@ -18,7 +18,7 @@ using namespace mbgl;
class SyncFileSource : public FileSource {
public:
std::unique_ptr<AsyncRequest> request(const Resource& resource, FileSource::Callback callback) override {
std::unique_ptr<AsyncRequest> request(const Resource& resource, std::function<void(Response)> callback) override {
Response response;
auto it = assets.find(resource.url);
if (it == assets.end()) {

9
vendor/BUILD.bazel vendored
View File

@@ -235,3 +235,12 @@ cc_library(
strip_include_prefix = "unordered_dense/include/ankerl",
visibility = ["//visibility:public"],
)
cc_library(
name = "nontype_functional",
srcs = [],
hdrs = glob(["nontype_functional/include/std23/*.h"]),
include_prefix = "std23",
strip_include_prefix = "nontype_functional/include/std23",
visibility = ["//visibility:public"],
)

1
vendor/nontype_functional vendored Submodule

21
vendor/nontype_functional.cmake vendored Normal file
View File

@@ -0,0 +1,21 @@
if(TARGET mbgl-vendor-nontype_functional)
return()
endif()
add_library(
mbgl-vendor-nontype_functional INTERFACE
)
target_include_directories(
mbgl-vendor-nontype_functional SYSTEM
INTERFACE ${CMAKE_CURRENT_LIST_DIR}/nontype_functional/include
)
set_target_properties(
mbgl-vendor-nontype_functional
PROPERTIES
INTERFACE_MAPLIBRE_NAME "nontype_functional"
INTERFACE_MAPLIBRE_URL "https://github.com/zhihaoy/nontype_functional"
INTERFACE_MAPLIBRE_AUTHOR "zhihaoy"
INTERFACE_MAPLIBRE_LICENSE ${CMAKE_CURRENT_LIST_DIR}/nontype_functional/LICENSE
)