From 14559245d8924241141e461451bb01c540198948 Mon Sep 17 00:00:00 2001 From: Tim Sylvester Date: Fri, 7 Feb 2025 10:48:16 -0800 Subject: [PATCH] Eliminate copies in deferred cleanup (#3035) --- .clang-tidy | 3 +- .gitmodules | 4 + BUILD.bazel | 1 + CMakeLists.txt | 8 +- include/mbgl/actor/scheduler.hpp | 24 ++++-- include/mbgl/mtl/uniform_buffer.hpp | 2 +- include/mbgl/renderer/renderer_observer.hpp | 13 ++- include/mbgl/storage/database_file_source.hpp | 46 +++++----- include/mbgl/storage/file_source.hpp | 7 +- include/mbgl/storage/online_file_source.hpp | 2 +- include/mbgl/util/run_loop.hpp | 10 +-- .../MapLibreAndroid/src/cpp/CMakeLists.txt | 1 + .../src/cpp/android_renderer_frontend.cpp | 9 +- .../src/cpp/asset_manager_file_source.cpp | 5 +- .../src/cpp/asset_manager_file_source.hpp | 2 +- .../MapLibreAndroid/src/cpp/file_source.cpp | 6 +- .../MapLibreAndroid/src/cpp/file_source.hpp | 2 +- .../src/cpp/http_file_source.cpp | 19 +++-- .../MapLibreAndroid/src/cpp/map_renderer.cpp | 2 +- .../MapLibreAndroid/src/cpp/map_renderer.hpp | 4 +- .../src/cpp/map_renderer_runnable.cpp | 2 +- .../src/cpp/map_renderer_runnable.hpp | 4 +- platform/android/android.cmake | 2 + platform/android/src/run_loop.cpp | 2 +- platform/android/src/run_loop_impl.hpp | 4 +- platform/darwin/src/http_file_source.mm | 10 +-- .../mbgl/storage/file_source_request.hpp | 6 +- .../default/src/mbgl/map/map_snapshotter.cpp | 8 +- .../src/mbgl/storage/asset_file_source.cpp | 3 +- .../src/mbgl/storage/database_file_source.cpp | 83 ++++++++++--------- .../src/mbgl/storage/file_source_request.cpp | 4 +- .../src/mbgl/storage/http_file_source.cpp | 11 +-- .../src/mbgl/storage/local_file_source.cpp | 5 +- .../src/mbgl/storage/main_resource_loader.cpp | 7 +- .../src/mbgl/storage/mbtiles_file_source.cpp | 29 +++---- .../src/mbgl/storage/online_file_source.cpp | 17 ++-- .../src/mbgl/storage/pmtiles_file_source.cpp | 3 +- platform/default/src/mbgl/util/run_loop.cpp | 6 +- platform/node/CMakeLists.txt | 3 + platform/node/src/node_map.cpp | 2 +- platform/node/src/node_map.hpp | 2 +- platform/node/src/node_request.cpp | 4 +- platform/node/src/node_request.hpp | 4 +- platform/qt/src/mbgl/http_file_source.cpp | 5 +- platform/qt/src/mbgl/http_request.cpp | 6 +- platform/qt/src/mbgl/http_request.hpp | 4 +- platform/qt/src/mbgl/run_loop.cpp | 2 +- platform/qt/src/mbgl/run_loop_impl.hpp | 3 +- platform/qt/src/utils/scheduler.cpp | 8 +- platform/qt/src/utils/scheduler.hpp | 6 +- render-test/file_source.cpp | 3 +- render-test/file_source.hpp | 2 +- src/mbgl/actor/scheduler.cpp | 10 +-- src/mbgl/map/map_impl.cpp | 12 ++- src/mbgl/map/map_impl.hpp | 4 +- src/mbgl/renderer/image_manager.cpp | 8 +- src/mbgl/renderer/image_manager_observer.hpp | 2 +- src/mbgl/renderer/render_orchestrator.cpp | 6 +- src/mbgl/renderer/render_orchestrator.hpp | 2 +- src/mbgl/storage/asset_file_source.hpp | 2 +- src/mbgl/storage/http_file_source.hpp | 2 +- src/mbgl/storage/local_file_source.hpp | 2 +- src/mbgl/storage/main_resource_loader.hpp | 2 +- src/mbgl/storage/mbtiles_file_source.hpp | 2 +- src/mbgl/storage/pmtiles_file_source.hpp | 2 +- src/mbgl/tile/geometry_tile_worker.cpp | 13 +-- src/mbgl/tile/tile_cache.cpp | 45 +++------- src/mbgl/util/stopwatch.hpp | 6 +- src/mbgl/util/thread_pool.cpp | 6 +- src/mbgl/util/thread_pool.hpp | 16 ++-- test/actor/actor.test.cpp | 6 +- test/renderer/image_manager.test.cpp | 2 +- test/src/mbgl/test/fake_file_source.hpp | 14 ++-- test/src/mbgl/test/stub_file_source.cpp | 5 +- test/src/mbgl/test/stub_file_source.hpp | 6 +- test/storage/sync_file_source.test.cpp | 2 +- vendor/BUILD.bazel | 9 ++ vendor/nontype_functional | 1 + vendor/nontype_functional.cmake | 21 +++++ 79 files changed, 346 insertions(+), 292 deletions(-) create mode 160000 vendor/nontype_functional create mode 100644 vendor/nontype_functional.cmake diff --git a/.clang-tidy b/.clang-tidy index e50cf88144e..5394510eeda 100644 --- a/.clang-tidy +++ b/.clang-tidy @@ -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: '.*' diff --git a/.gitmodules b/.gitmodules index 72537dd37ef..0f420a3ae15 100644 --- a/.gitmodules +++ b/.gitmodules @@ -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 diff --git a/BUILD.bazel b/BUILD.bazel index 9b387f5a613..df44344f58e 100644 --- a/BUILD.bazel +++ b/BUILD.bazel @@ -127,6 +127,7 @@ cc_library( "//vendor:earcut.hpp", "//vendor:eternal", "//vendor:mapbox-base", + "//vendor:nontype_functional", "//vendor:parsedate", "//vendor:pmtiles", "//vendor:polylabel", diff --git a/CMakeLists.txt b/CMakeLists.txt index 3c6b1da70de..049d8915627 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -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 + $<$: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 $<$: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 ) diff --git a/include/mbgl/actor/scheduler.hpp b/include/mbgl/actor/scheduler.hpp index 8b2f81f22b8..00926287026 100644 --- a/include/mbgl/actor/scheduler.hpp +++ b/include/mbgl/actor/scheduler.hpp @@ -4,6 +4,8 @@ #include +#include + #include #include #include @@ -36,16 +38,18 @@ class Mailbox; */ class Scheduler { public: + using Task = std23::move_only_function; + virtual ~Scheduler() = default; /// Enqueues a function for execution. - virtual void schedule(std::function&&) = 0; - virtual void schedule(const util::SimpleIdentity, std::function&&) = 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 makeWeakPtr() = 0; /// Enqueues a function for execution on the render thread owned by the given tag. - virtual void runOnRenderThread(const util::SimpleIdentity, std::function&&) {} + 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 @@ class Scheduler { /// 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 bindOnce(std::function); + 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 @@ class Scheduler { [[nodiscard]] static std::shared_ptr GetSequenced(); /// Set a function to be called when an exception occurs on a thread controlled by the scheduler - void setExceptionHandler(std::function handler_) { handler = std::move(handler_); } + void setExceptionHandler(std23::move_only_function handler_) { + handler = std::move(handler_); + } protected: - std::function handler; + std23::move_only_function handler; private: template @@ -136,8 +142,8 @@ class TaggedScheduler { /// @brief Get the wrapped scheduler const std::shared_ptr& get() const noexcept { return scheduler; } - void schedule(std::function&& fn) { scheduler->schedule(tag, std::move(fn)); } - void runOnRenderThread(std::function&& 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); } diff --git a/include/mbgl/mtl/uniform_buffer.hpp b/include/mbgl/mtl/uniform_buffer.hpp index 9dfbdb1a8ab..9352bfedc47 100644 --- a/include/mbgl/mtl/uniform_buffer.hpp +++ b/include/mbgl/mtl/uniform_buffer.hpp @@ -43,7 +43,7 @@ class UniformBufferArray final : public gfx::UniformBufferArray { } 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 { diff --git a/include/mbgl/renderer/renderer_observer.hpp b/include/mbgl/renderer/renderer_observer.hpp index 5df817afa43..693451d9a38 100644 --- a/include/mbgl/renderer/renderer_observer.hpp +++ b/include/mbgl/renderer/renderer_observer.hpp @@ -1,15 +1,15 @@ #pragma once -#include -#include -#include -#include +#include #include #include +#include +#include +#include +#include #include #include -#include #include namespace mbgl { @@ -55,8 +55,7 @@ class RendererObserver { virtual void onDidFinishRenderingMap() {} /// Style is missing an image - using StyleImageMissingCallback = std::function; - 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&) {} // Entry point for custom shader registration diff --git a/include/mbgl/storage/database_file_source.hpp b/include/mbgl/storage/database_file_source.hpp index 3c3bcbeea3e..020f9ff7f44 100644 --- a/include/mbgl/storage/database_file_source.hpp +++ b/include/mbgl/storage/database_file_source.hpp @@ -16,8 +16,8 @@ class DatabaseFileSource : public FileSource { ~DatabaseFileSource() override; /// FileSource overrides - std::unique_ptr request(const Resource&, Callback) override; - void forward(const Resource&, const Response&, std::function callback) override; + std::unique_ptr request(const Resource&, std::function) 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 @@ class DatabaseFileSource : public FileSource { * 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 callback); + virtual void setDatabasePath(const std::string&, std23::move_only_function&& callback); /** * Delete existing database and re-initialize. @@ -38,7 +38,7 @@ class DatabaseFileSource : public FileSource { * 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); + virtual void resetDatabase(std23::move_only_function&&); /** * Packs the existing database file into a minimal amount of disk space. @@ -50,7 +50,7 @@ class DatabaseFileSource : public FileSource { * 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 callback); + virtual void packDatabase(std23::move_only_function&& callback); /** * Sets whether packing the database file occurs automatically after an @@ -87,7 +87,7 @@ class DatabaseFileSource : public FileSource { * Resources overlapping with offline regions will not be affected * by this call. */ - virtual void invalidateAmbientCache(std::function); + virtual void invalidateAmbientCache(std23::move_only_function&&); /** * Erase resources from the ambient cache, freeing storage space. @@ -100,7 +100,7 @@ class DatabaseFileSource : public FileSource { * Resources overlapping with offline regions will not be affected * by this call. */ - virtual void clearAmbientCache(std::function); + virtual void clearAmbientCache(std23::move_only_function&&); /** * Sets the maximum size in bytes for the ambient cache. @@ -122,7 +122,8 @@ class DatabaseFileSource : public FileSource { * 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 callback); + virtual void setMaximumAmbientCacheSize(uint64_t size, + std23::move_only_function&& callback); // Offline @@ -134,7 +135,7 @@ class DatabaseFileSource : public FileSource { * responsibility of the SDK bindings to re-execute a user-provided callback * on the main thread. */ - virtual void listOfflineRegions(std::function)>); + virtual void listOfflineRegions(std23::move_only_function)>&&); /** * Retrieve given region in the offline database. @@ -144,8 +145,9 @@ class DatabaseFileSource : public FileSource { * responsibility of the SDK bindings to re-execute a user-provided callback * on the main thread. */ - virtual void getOfflineRegion(int64_t regionID, - std::function, std::exception_ptr>)>); + virtual void getOfflineRegion( + int64_t regionID, + std23::move_only_function, std::exception_ptr>)>&&); /** * Create an offline region in the database. @@ -161,18 +163,19 @@ class DatabaseFileSource : public FileSource { */ virtual void createOfflineRegion(const OfflineRegionDefinition& definition, const OfflineRegionMetadata& metadata, - std::function)>); + std23::move_only_function)>&&); /** * Update an offline region metadata in the database. */ - virtual void updateOfflineMetadata(int64_t regionID, - const OfflineRegionMetadata& metadata, - std::function)>); + virtual void updateOfflineMetadata( + int64_t regionID, + const OfflineRegionMetadata& metadata, + std23::move_only_function)>&&); /** * Register an observer to be notified when the state of the region changes. */ - virtual void setOfflineRegionObserver(const OfflineRegion&, std::unique_ptr); + virtual void setOfflineRegionObserver(const OfflineRegion&, std::unique_ptr&&); /** * Pause or resume downloading of regional resources. @@ -185,8 +188,9 @@ class DatabaseFileSource : public FileSource { * 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)>) const; + virtual void getOfflineRegionStatus( + const OfflineRegion&, + std23::move_only_function)>&&) const; /** * Merge offline regions from a secondary database into the main offline database. @@ -209,7 +213,7 @@ class DatabaseFileSource : public FileSource { * does not contain all the tiles or resources required by the region definition. */ virtual void mergeOfflineRegions(const std::string& sideDatabasePath, - std::function)>); + std23::move_only_function)>&&); /** * Remove an offline region from the database and perform any resources @@ -231,7 +235,7 @@ class DatabaseFileSource : public FileSource { * 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); + virtual void deleteOfflineRegion(const OfflineRegion&, std23::move_only_function&&); /** * Invalidate all the tiles from an offline region forcing Mapbox GL to @@ -239,7 +243,7 @@ class DatabaseFileSource : public FileSource { * 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); + virtual void invalidateOfflineRegion(const OfflineRegion&, std23::move_only_function&&); /** * Changing or bypassing this limit without permission from Mapbox is diff --git a/include/mbgl/storage/file_source.hpp b/include/mbgl/storage/file_source.hpp index 6a70154df41..c5756470b16 100644 --- a/include/mbgl/storage/file_source.hpp +++ b/include/mbgl/storage/file_source.hpp @@ -1,5 +1,6 @@ #pragma once +#include #include #include #include @@ -38,21 +39,19 @@ class FileSource { FileSource& operator=(const FileSource&) = delete; virtual ~FileSource() = default; - using Callback = std::function; - /// 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 request(const Resource&, Callback) = 0; + virtual std::unique_ptr request(const Resource&, std::function) = 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) {} + 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 diff --git a/include/mbgl/storage/online_file_source.hpp b/include/mbgl/storage/online_file_source.hpp index 797e4070047..228fe0f8e98 100644 --- a/include/mbgl/storage/online_file_source.hpp +++ b/include/mbgl/storage/online_file_source.hpp @@ -19,7 +19,7 @@ class OnlineFileSource : public FileSource { private: // FileSource overrides - std::unique_ptr request(const Resource&, Callback) override; + std::unique_ptr request(const Resource&, std::function) override; bool canRequest(const Resource&) const override; void pause() override; void resume() override; diff --git a/include/mbgl/util/run_loop.hpp b/include/mbgl/util/run_loop.hpp index 755f4aeb7fd..1a91d5eba1c 100644 --- a/include/mbgl/util/run_loop.hpp +++ b/include/mbgl/util/run_loop.hpp @@ -54,10 +54,10 @@ class RunLoop : public Scheduler, private util::noncopyable { /// 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 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&& callback); + void addWatch(int fd, Event, std23::move_only_function&& callback); void removeWatch(int fd); // Invoke fn(args...) on this RunLoop. @@ -80,8 +80,8 @@ class RunLoop : public Scheduler, private util::noncopyable { return std::make_unique(task); } - void schedule(std::function&& fn) override { invoke(std::move(fn)); } - void schedule(const util::SimpleIdentity, std::function&& 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 makeWeakPtr() override { return weakFactory.makeWeakPtr(); } void waitForEmpty(const util::SimpleIdentity = util::SimpleIdentity::Empty) override; @@ -131,7 +131,7 @@ class RunLoop : public Scheduler, private util::noncopyable { } } - std::function platformCallback; + Scheduler::Task platformCallback; Queue defaultQueue; Queue highPriorityQueue; diff --git a/platform/android/MapLibreAndroid/src/cpp/CMakeLists.txt b/platform/android/MapLibreAndroid/src/cpp/CMakeLists.txt index 05902547e94..80a4beb2060 100644 --- a/platform/android/MapLibreAndroid/src/cpp/CMakeLists.txt +++ b/platform/android/MapLibreAndroid/src/cpp/CMakeLists.txt @@ -241,6 +241,7 @@ target_link_libraries(maplibre $<$:-fuse-ld=gold> Mapbox::Base::jni.hpp mbgl-core + mbgl-vendor-nontype_functional mbgl-vendor-unique_resource) install(TARGETS maplibre LIBRARY DESTINATION lib) diff --git a/platform/android/MapLibreAndroid/src/cpp/android_renderer_frontend.cpp b/platform/android/MapLibreAndroid/src/cpp/android_renderer_frontend.cpp index 0f5ddb66235..0dba1aacb4f 100644 --- a/platform/android/MapLibreAndroid/src/cpp/android_renderer_frontend.cpp +++ b/platform/android/MapLibreAndroid/src/cpp/android_renderer_frontend.cpp @@ -1,17 +1,16 @@ #include "android_renderer_frontend.hpp" +#include "android_renderer_backend.hpp" -#include #include #include #include +#include #include #include #include #include #include -#include "android_renderer_backend.hpp" - namespace mbgl { namespace android { @@ -45,8 +44,8 @@ class ForwardingRendererObserver : public RendererObserver { 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& ids) override { diff --git a/platform/android/MapLibreAndroid/src/cpp/asset_manager_file_source.cpp b/platform/android/MapLibreAndroid/src/cpp/asset_manager_file_source.cpp index d7b5b6e9647..ac51833f87a 100644 --- a/platform/android/MapLibreAndroid/src/cpp/asset_manager_file_source.cpp +++ b/platform/android/MapLibreAndroid/src/cpp/asset_manager_file_source.cpp @@ -70,7 +70,8 @@ AssetManagerFileSource::AssetManagerFileSource(jni::JNIEnv& env, AssetManagerFileSource::~AssetManagerFileSource() = default; -std::unique_ptr AssetManagerFileSource::request(const Resource& resource, Callback callback) { +std::unique_ptr AssetManagerFileSource::request(const Resource& resource, + std::function callback) { auto req = std::make_unique(std::move(callback)); impl->actor().invoke(&Impl::request, resource.url, req->actor()); @@ -79,7 +80,7 @@ std::unique_ptr 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) { diff --git a/platform/android/MapLibreAndroid/src/cpp/asset_manager_file_source.hpp b/platform/android/MapLibreAndroid/src/cpp/asset_manager_file_source.hpp index 166fc03980f..b2b79b6e789 100644 --- a/platform/android/MapLibreAndroid/src/cpp/asset_manager_file_source.hpp +++ b/platform/android/MapLibreAndroid/src/cpp/asset_manager_file_source.hpp @@ -23,7 +23,7 @@ class AssetManagerFileSource : public FileSource { const ClientOptions); ~AssetManagerFileSource() override; - std::unique_ptr request(const Resource&, Callback) override; + std::unique_ptr request(const Resource&, std::function) override; bool canRequest(const Resource&) const override; void setResourceOptions(ResourceOptions options) override; diff --git a/platform/android/MapLibreAndroid/src/cpp/file_source.cpp b/platform/android/MapLibreAndroid/src/cpp/file_source.cpp index 6ad4ee95d6d..4ccdaf83940 100644 --- a/platform/android/MapLibreAndroid/src/cpp/file_source.cpp +++ b/platform/android/MapLibreAndroid/src/cpp/file_source.cpp @@ -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 assetFileSource; if (android::MapLibre::hasInstance(*env)) { auto assetManager = android::MapLibre::getAssetManager(*env); assetFileSource = std::make_unique( - *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&) { diff --git a/platform/android/MapLibreAndroid/src/cpp/file_source.hpp b/platform/android/MapLibreAndroid/src/cpp/file_source.hpp index 421ef2e4602..5637e306d69 100644 --- a/platform/android/MapLibreAndroid/src/cpp/file_source.hpp +++ b/platform/android/MapLibreAndroid/src/cpp/file_source.hpp @@ -93,7 +93,7 @@ class FileSource { mbgl::ResourceOptions resourceOptions; mbgl::ClientOptions clientOptions; std::unique_ptr> resourceTransform; - std::function pathChangeCallback; + std23::move_only_function pathChangeCallback; std::shared_ptr databaseSource; std::shared_ptr onlineSource; std::shared_ptr resourceLoader; diff --git a/platform/android/MapLibreAndroid/src/cpp/http_file_source.cpp b/platform/android/MapLibreAndroid/src/cpp/http_file_source.cpp index 13bc72a8b86..5526cb933da 100644 --- a/platform/android/MapLibreAndroid/src/cpp/http_file_source.cpp +++ b/platform/android/MapLibreAndroid/src/cpp/http_file_source.cpp @@ -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); + ~HTTPRequest() override; void onFailure(jni::JNIEnv&, int type, const jni::String& message); void onResponse(jni::JNIEnv&, @@ -57,7 +57,7 @@ class HTTPRequest : public AsyncRequest { private: Resource resource; - FileSource::Callback callback; + std::function 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 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(env, cacheControl).c_str()); + const auto cc = http::CacheControl::parse(jni::Make(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(body.Length(env), char()); - jni::GetArrayRegion(env, *body, 0, data->size(), reinterpret_cast(&(*data)[0])); + jni::GetArrayRegion(env, *body, 0, data->size(), reinterpret_cast(data->data())); response.data = data; } else { response.data = std::make_shared(); @@ -221,8 +221,9 @@ HTTPFileSource::HTTPFileSource(const ResourceOptions& resourceOptions, const Cli HTTPFileSource::~HTTPFileSource() = default; -std::unique_ptr HTTPFileSource::request(const Resource& resource, Callback callback) { - return std::make_unique(*impl->env, resource, callback); +std::unique_ptr HTTPFileSource::request(const Resource& resource, + std::function callback) { + return std::make_unique(*impl->env, resource, std::move(callback)); } void HTTPFileSource::setResourceOptions(ResourceOptions options) { diff --git a/platform/android/MapLibreAndroid/src/cpp/map_renderer.cpp b/platform/android/MapLibreAndroid/src/cpp/map_renderer.cpp index fc235a67f4c..763a40c608a 100644 --- a/platform/android/MapLibreAndroid/src/cpp/map_renderer.cpp +++ b/platform/android/MapLibreAndroid/src/cpp/map_renderer.cpp @@ -63,7 +63,7 @@ ActorRef MapRenderer::actor() const { return *rendererRef; } -void MapRenderer::schedule(std::function&& scheduled) { +void MapRenderer::schedule(Task&& scheduled) { MLN_TRACE_FUNC(); try { // Create a runnable diff --git a/platform/android/MapLibreAndroid/src/cpp/map_renderer.hpp b/platform/android/MapLibreAndroid/src/cpp/map_renderer.hpp index 9fc962c0d35..1e6a1ec740b 100644 --- a/platform/android/MapLibreAndroid/src/cpp/map_renderer.hpp +++ b/platform/android/MapLibreAndroid/src/cpp/map_renderer.hpp @@ -72,8 +72,8 @@ class MapRenderer : public Scheduler { // From Scheduler. Schedules by using callbacks to the // JVM to process the mailbox on the right thread. - void schedule(std::function&& scheduled) override; - void schedule(const util::SimpleIdentity, std::function&& 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 makeWeakPtr() override { return weakFactory.makeWeakPtr(); } diff --git a/platform/android/MapLibreAndroid/src/cpp/map_renderer_runnable.cpp b/platform/android/MapLibreAndroid/src/cpp/map_renderer_runnable.cpp index 805bcac8f9f..f7a2d24d92e 100644 --- a/platform/android/MapLibreAndroid/src/cpp/map_renderer_runnable.cpp +++ b/platform/android/MapLibreAndroid/src/cpp/map_renderer_runnable.cpp @@ -5,7 +5,7 @@ namespace mbgl { namespace android { -MapRendererRunnable::MapRendererRunnable(jni::JNIEnv& env, std::function 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 diff --git a/platform/android/MapLibreAndroid/src/cpp/map_renderer_runnable.hpp b/platform/android/MapLibreAndroid/src/cpp/map_renderer_runnable.hpp index 392e8a002d0..d96c3c7f053 100644 --- a/platform/android/MapLibreAndroid/src/cpp/map_renderer_runnable.hpp +++ b/platform/android/MapLibreAndroid/src/cpp/map_renderer_runnable.hpp @@ -23,7 +23,7 @@ class MapRendererRunnable { static void registerNative(jni::JNIEnv&); - MapRendererRunnable(jni::JNIEnv&, std::function); + MapRendererRunnable(jni::JNIEnv&, Scheduler::Task&&); // Only for jni registration, unused MapRendererRunnable(jni::JNIEnv&) { assert(false); } @@ -37,7 +37,7 @@ class MapRendererRunnable { private: jni::Global> javaPeer; - std::function function; + Scheduler::Task function; }; } // namespace android diff --git a/platform/android/android.cmake b/platform/android/android.cmake index fbddbb2a4f0..63fa9e20e3d 100644 --- a/platform/android/android.cmake +++ b/platform/android/android.cmake @@ -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 ) diff --git a/platform/android/src/run_loop.cpp b/platform/android/src/run_loop.cpp index 71d5b759ee2..f3b80a4ee19 100644 --- a/platform/android/src/run_loop.cpp +++ b/platform/android/src/run_loop.cpp @@ -290,7 +290,7 @@ void RunLoop::stop() { }); } -void RunLoop::addWatch(int fd, Event event, std::function&& cb) { +void RunLoop::addWatch(int fd, Event event, std23::move_only_function&& cb) { MBGL_VERIFY_THREAD(tid); if (event == Event::Read) { diff --git a/platform/android/src/run_loop_impl.hpp b/platform/android/src/run_loop_impl.hpp index 4f0eff4103a..034f4672d80 100644 --- a/platform/android/src/run_loop_impl.hpp +++ b/platform/android/src/run_loop_impl.hpp @@ -16,8 +16,6 @@ struct ALooper; namespace mbgl { namespace util { -using WatchCallback = std::function; - template class Thread; class Alarm; @@ -49,7 +47,7 @@ class RunLoop::Impl { std::atomic running; std::atomic_flag coalesce = ATOMIC_FLAG_INIT; - std::unordered_map readPoll; + std::unordered_map> readPoll; private: friend RunLoop; diff --git a/platform/darwin/src/http_file_source.mm b/platform/darwin/src/http_file_source.mm index 8c2fe83c4c3..3bdd1991d3a 100644 --- a/platform/darwin/src/http_file_source.mm +++ b/platform/darwin/src/http_file_source.mm @@ -55,9 +55,9 @@ void cancel() { class HTTPRequest : public AsyncRequest { public: - HTTPRequest(FileSource::Callback callback_) + HTTPRequest(std::function callback_) : shared(std::make_shared(response, async)), - callback(callback_) { + callback(std::move(callback_)) { } ~HTTPRequest() override { @@ -71,7 +71,7 @@ void cancel() { NSURLSessionDataTask* task = nil; private: - FileSource::Callback callback; + std::function callback; Response response; util::AsyncTask async { [this] { @@ -248,8 +248,8 @@ BOOL isValidMapboxEndpoint(NSURL *url) { return url; } -std::unique_ptr HTTPFileSource::request(const Resource& resource, Callback callback) { - auto request = std::make_unique(callback); +std::unique_ptr HTTPFileSource::request(const Resource& resource, std::function callback) { + auto request = std::make_unique(std::move(callback)); auto shared = request->shared; // Explicit copy so that it also gets copied into the completion handler block below. @autoreleasepool { diff --git a/platform/default/include/mbgl/storage/file_source_request.hpp b/platform/default/include/mbgl/storage/file_source_request.hpp index 79ad53ff289..11fc0d5f987 100644 --- a/platform/default/include/mbgl/storage/file_source_request.hpp +++ b/platform/default/include/mbgl/storage/file_source_request.hpp @@ -13,7 +13,7 @@ class Mailbox; class FileSourceRequest final : public AsyncRequest { public: - FileSourceRequest(FileSource::Callback&& callback); + FileSourceRequest(std::function callback); ~FileSourceRequest() final; void onCancel(std::function&& callback); @@ -22,8 +22,8 @@ class FileSourceRequest final : public AsyncRequest { ActorRef actor(); private: - FileSource::Callback responseCallback = nullptr; - std::function cancelCallback = nullptr; + std::function responseCallback; + std23::move_only_function cancelCallback; std::shared_ptr mailbox; }; diff --git a/platform/default/src/mbgl/map/map_snapshotter.cpp b/platform/default/src/mbgl/map/map_snapshotter.cpp index e42fe0719c4..f1c3145efa2 100644 --- a/platform/default/src/mbgl/map/map_snapshotter.cpp +++ b/platform/default/src/mbgl/map/map_snapshotter.cpp @@ -46,8 +46,8 @@ class ForwardingRendererObserver final : public RendererObserver { 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 @@ class SnapshotterRenderer final : public RendererObserver { 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 observer) { diff --git a/platform/default/src/mbgl/storage/asset_file_source.cpp b/platform/default/src/mbgl/storage/asset_file_source.cpp index a43c0be9679..5785e1a7fb3 100644 --- a/platform/default/src/mbgl/storage/asset_file_source.cpp +++ b/platform/default/src/mbgl/storage/asset_file_source.cpp @@ -77,7 +77,8 @@ AssetFileSource::AssetFileSource(const ResourceOptions& resourceOptions, const C AssetFileSource::~AssetFileSource() = default; -std::unique_ptr AssetFileSource::request(const Resource& resource, Callback callback) { +std::unique_ptr AssetFileSource::request(const Resource& resource, + std::function callback) { auto req = std::make_unique(std::move(callback)); impl->actor().invoke(&Impl::request, resource.url, req->actor()); diff --git a/platform/default/src/mbgl/storage/database_file_source.cpp b/platform/default/src/mbgl/storage/database_file_source.cpp index fa674c55512..a88c95948c0 100644 --- a/platform/default/src/mbgl/storage/database_file_source.cpp +++ b/platform/default/src/mbgl/storage/database_file_source.cpp @@ -38,68 +38,73 @@ class DatabaseFileSourceThread { req.invoke(&FileSourceRequest::setResponse, *offlineResponse); } - void setDatabasePath(const std::string& path, const std::function& callback) { + void setDatabasePath(const std::string& path, std23::move_only_function&& callback) { db->changePath(path); if (callback) { callback(); } } - void forward(const Resource& resource, const Response& response, const std::function& callback) { + void forward(const Resource& resource, const Response& response, Scheduler::Task&& callback) { db->put(resource, response); if (callback) { callback(); } } - void resetDatabase(const std::function& callback) { callback(db->resetDatabase()); } + void resetDatabase(std23::move_only_function&& callback) { + callback(db->resetDatabase()); + } - void packDatabase(const std::function& callback) { callback(db->pack()); } + void packDatabase(std23::move_only_function&& 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& callback) { + void invalidateAmbientCache(std23::move_only_function&& callback) { callback(db->invalidateAmbientCache()); } - void clearAmbientCache(const std::function& callback) { + void clearAmbientCache(std23::move_only_function&& callback) { callback(db->clearAmbientCache()); } - void setMaximumAmbientCacheSize(uint64_t size, const std::function& callback) { + void setMaximumAmbientCacheSize(uint64_t size, std23::move_only_function&& callback) { callback(db->setMaximumAmbientCacheSize(size)); } - void listRegions(const std::function)>& callback) { + void listRegions(std23::move_only_function)>&& callback) { callback(db->listRegions()); } - void getRegion(const int64_t regionID, - const std::function, std::exception_ptr>)>& callback) { + void getRegion( + const int64_t regionID, + std23::move_only_function, std::exception_ptr>)>&& callback) { callback(db->getRegion(regionID)); } void createRegion(const OfflineRegionDefinition& definition, const OfflineRegionMetadata& metadata, - const std::function)>& callback) { + std23::move_only_function)>&& callback) { callback(db->createRegion(definition, metadata)); } void mergeOfflineRegions(const std::string& sideDatabasePath, - const std::function)>& callback) { + std23::move_only_function)>&& callback) { callback(db->mergeDatabase(sideDatabasePath)); } - void updateMetadata(const int64_t regionID, - const OfflineRegionMetadata& metadata, - const std::function)>& callback) { + void updateMetadata( + const int64_t regionID, + const OfflineRegionMetadata& metadata, + std23::move_only_function)>&& callback) { callback(db->updateMetadata(regionID, metadata)); } - void getRegionStatus(int64_t regionID, - const std::function)>& callback) { + void getRegionStatus( + int64_t regionID, + std23::move_only_function)>&& callback) { if (auto download = getDownload(regionID)) { callback(download.value()->getStatus()); } else { @@ -107,12 +112,12 @@ class DatabaseFileSourceThread { } } - void deleteRegion(OfflineRegion region, const std::function& callback) { + void deleteRegion(OfflineRegion region, std23::move_only_function&& callback) { downloads.erase(region.getID()); callback(db->deleteRegion(std::move(region))); } - void invalidateRegion(int64_t regionID, const std::function& callback) { + void invalidateRegion(int64_t regionID, std23::move_only_function&& callback) { callback(db->invalidateRegion(regionID)); } @@ -211,16 +216,17 @@ DatabaseFileSource::DatabaseFileSource(const ResourceOptions& resourceOptions, c DatabaseFileSource::~DatabaseFileSource() = default; -std::unique_ptr DatabaseFileSource::request(const Resource& resource, Callback callback) { +std::unique_ptr DatabaseFileSource::request(const Resource& resource, + std::function callback) { auto req = std::make_unique(std::move(callback)); impl->actor().invoke(&DatabaseFileSourceThread::request, resource, req->actor()); return req; } -void DatabaseFileSource::forward(const Resource& res, const Response& response, std::function callback) { +void DatabaseFileSource::forward(const Resource& res, const Response& response, Scheduler::Task&& callback) { if (res.storagePolicy == Resource::StoragePolicy::Volatile) return; - std::function 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 callback) { +void DatabaseFileSource::setDatabasePath(const std::string& path, std23::move_only_function&& callback) { impl->actor().invoke(&DatabaseFileSourceThread::setDatabasePath, path, std::move(callback)); } -void DatabaseFileSource::resetDatabase(std::function callback) { +void DatabaseFileSource::resetDatabase(std23::move_only_function&& callback) { impl->actor().invoke(&DatabaseFileSourceThread::resetDatabase, std::move(callback)); } -void DatabaseFileSource::packDatabase(std::function callback) { +void DatabaseFileSource::packDatabase(std23::move_only_function&& 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 callback) { +void DatabaseFileSource::invalidateAmbientCache(std23::move_only_function&& callback) { impl->actor().invoke(&DatabaseFileSourceThread::invalidateAmbientCache, std::move(callback)); } -void DatabaseFileSource::clearAmbientCache(std::function callback) { +void DatabaseFileSource::clearAmbientCache(std23::move_only_function&& callback) { impl->actor().invoke(&DatabaseFileSourceThread::clearAmbientCache, std::move(callback)); } -void DatabaseFileSource::setMaximumAmbientCacheSize(uint64_t size, std::function callback) { +void DatabaseFileSource::setMaximumAmbientCacheSize(uint64_t size, + std23::move_only_function&& callback) { impl->actor().invoke(&DatabaseFileSourceThread::setMaximumAmbientCacheSize, size, std::move(callback)); } void DatabaseFileSource::listOfflineRegions( - std::function)> callback) { + std23::move_only_function)>&& callback) { impl->actor().invoke(&DatabaseFileSourceThread::listRegions, std::move(callback)); } void DatabaseFileSource::getOfflineRegion( - const int64_t regionID, std::function, std::exception_ptr>)> callback) { + const int64_t regionID, + std23::move_only_function, std::exception_ptr>)>&& callback) { impl->actor().invoke(&DatabaseFileSourceThread::getRegion, regionID, std::move(callback)); } void DatabaseFileSource::createOfflineRegion( const OfflineRegionDefinition& definition, const OfflineRegionMetadata& metadata, - std::function)> callback) { + std23::move_only_function)>&& callback) { impl->actor().invoke(&DatabaseFileSourceThread::createRegion, definition, metadata, std::move(callback)); } void DatabaseFileSource::mergeOfflineRegions( - const std::string& sideDatabasePath, std::function)> callback) { + const std::string& sideDatabasePath, + std23::move_only_function)>&& callback) { impl->actor().invoke(&DatabaseFileSourceThread::mergeOfflineRegions, sideDatabasePath, std::move(callback)); } void DatabaseFileSource::updateOfflineMetadata( const int64_t regionID, const OfflineRegionMetadata& metadata, - std::function)> callback) { + std23::move_only_function)>&& callback) { impl->actor().invoke(&DatabaseFileSourceThread::updateMetadata, regionID, metadata, std::move(callback)); } void DatabaseFileSource::deleteOfflineRegion(const OfflineRegion& region, - std::function callback) { + std23::move_only_function&& callback) { impl->actor().invoke(&DatabaseFileSourceThread::deleteRegion, region, std::move(callback)); } void DatabaseFileSource::invalidateOfflineRegion(const OfflineRegion& region, - std::function callback) { + std23::move_only_function&& callback) { impl->actor().invoke(&DatabaseFileSourceThread::invalidateRegion, region.getID(), std::move(callback)); } void DatabaseFileSource::setOfflineRegionObserver(const OfflineRegion& region, - std::unique_ptr observer) { + std::unique_ptr&& 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)> callback) const { + std23::move_only_function)>&& callback) const { impl->actor().invoke(&DatabaseFileSourceThread::getRegionStatus, region.getID(), std::move(callback)); } diff --git a/platform/default/src/mbgl/storage/file_source_request.cpp b/platform/default/src/mbgl/storage/file_source_request.cpp index c8d5ae46a1f..e13f88c5125 100644 --- a/platform/default/src/mbgl/storage/file_source_request.cpp +++ b/platform/default/src/mbgl/storage/file_source_request.cpp @@ -5,8 +5,8 @@ namespace mbgl { -FileSourceRequest::FileSourceRequest(FileSource::Callback&& callback) - : responseCallback(callback), +FileSourceRequest::FileSourceRequest(std::function callback) + : responseCallback(std::move(callback)), mailbox(std::make_shared(*Scheduler::GetCurrent())) {} FileSourceRequest::~FileSourceRequest() { diff --git a/platform/default/src/mbgl/storage/http_file_source.cpp b/platform/default/src/mbgl/storage/http_file_source.cpp index 6bb4ff9220a..977ae24cb90 100644 --- a/platform/default/src/mbgl/storage/http_file_source.cpp +++ b/platform/default/src/mbgl/storage/http_file_source.cpp @@ -79,7 +79,7 @@ class HTTPFileSource::Impl { class HTTPRequest : public AsyncRequest { public: - HTTPRequest(HTTPFileSource::Impl *, Resource, FileSource::Callback); + HTTPRequest(HTTPFileSource::Impl *, Resource, std::function); ~HTTPRequest() override; void handleResult(CURLcode code); @@ -90,7 +90,7 @@ class HTTPRequest : public AsyncRequest { HTTPFileSource::Impl *context = nullptr; Resource resource; - FileSource::Callback callback; + std::function callback; // Will store the current response. std::shared_ptr 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 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 HTTPFileSource::request(const Resource &resource, Callback callback) { - return std::make_unique(impl.get(), resource, callback); +std::unique_ptr HTTPFileSource::request(const Resource &resource, + std::function callback) { + return std::make_unique(impl.get(), resource, std::move(callback)); } void HTTPFileSource::setResourceOptions(ResourceOptions options) { diff --git a/platform/default/src/mbgl/storage/local_file_source.cpp b/platform/default/src/mbgl/storage/local_file_source.cpp index 3fef8ee7862..c20498c174f 100644 --- a/platform/default/src/mbgl/storage/local_file_source.cpp +++ b/platform/default/src/mbgl/storage/local_file_source.cpp @@ -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 LocalFileSource::request(const Resource& resource, Callback callback) { +std::unique_ptr LocalFileSource::request(const Resource& resource, + std::function callback) { auto req = std::make_unique(std::move(callback)); impl->actor().invoke(&Impl::request, resource, req->actor()); diff --git a/platform/default/src/mbgl/storage/main_resource_loader.cpp b/platform/default/src/mbgl/storage/main_resource_loader.cpp index 2f523f1e8d2..6915a8fe60c 100644 --- a/platform/default/src/mbgl/storage/main_resource_loader.cpp +++ b/platform/default/src/mbgl/storage/main_resource_loader.cpp @@ -55,7 +55,7 @@ class MainResourceLoaderThread { " Action: " << "Requesting," << " URL: " << res.url.c_str() << " Size: " << (response.data != nullptr ? response.data->size() : 0) << "B," - << " Time") + << " Time"); } callback(response); }); @@ -169,7 +169,7 @@ class MainResourceLoader::Impl { resourceOptions(resourceOptions_.clone()), clientOptions(clientOptions_.clone()) {} - std::unique_ptr request(const Resource& resource, Callback callback) { + std::unique_ptr request(const Resource& resource, std::function callback) { auto req = std::make_unique(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 MainResourceLoader::request(const Resource& resource, Callback callback) { +std::unique_ptr MainResourceLoader::request(const Resource& resource, + std::function callback) { return impl->request(resource, std::move(callback)); } diff --git a/platform/default/src/mbgl/storage/mbtiles_file_source.cpp b/platform/default/src/mbgl/storage/mbtiles_file_source.cpp index 29b9be2de1d..167123fb7e7 100644 --- a/platform/default/src/mbgl/storage/mbtiles_file_source.cpp +++ b/platform/default/src/mbgl/storage/mbtiles_file_source.cpp @@ -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 @@ class MBTilesFileSource::Impl { 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 @@ class MBTilesFileSource::Impl { // Load data for specific tile void request_tile(const Resource &resource, ActorRef 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(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 @@ class MBTilesFileSource::Impl { auto ptr = db_cache.find(path); if (ptr != db_cache.end()) { return ptr->second; - }; + } auto ptr2 = db_cache.insert(std::pair( 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 MBTilesFileSource::request(const Resource &resource, FileSource::Callback callback) { +std::unique_ptr MBTilesFileSource::request(const Resource &resource, + std::function callback) { auto req = std::make_unique(std::move(callback)); // assume if there is a tile request, that the mbtiles file has been validated @@ -296,7 +297,7 @@ std::unique_ptr 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; diff --git a/platform/default/src/mbgl/storage/online_file_source.cpp b/platform/default/src/mbgl/storage/online_file_source.cpp index 077fc915fc7..7c9515c0d5c 100644 --- a/platform/default/src/mbgl/storage/online_file_source.cpp +++ b/platform/default/src/mbgl/storage/online_file_source.cpp @@ -37,9 +37,7 @@ constexpr const char* ONLINE_STATUS_KEY = "online-status"; class OnlineFileSourceThread; struct OnlineFileRequest { - using Callback = std::function; - - OnlineFileRequest(Resource resource_, Callback callback_, OnlineFileSourceThread& impl_); + OnlineFileRequest(Resource resource_, std::function&& callback_, OnlineFileSourceThread& impl_); ~OnlineFileRequest(); void networkIsReachableAgain(); @@ -56,7 +54,7 @@ struct OnlineFileRequest { Resource resource; std::unique_ptr request; util::Timer timer; - Callback callback; + std::function callback; std::function cancelCallback = nullptr; std::shared_ptr mailbox; @@ -303,7 +301,7 @@ class OnlineFileSourceThread { std::set 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> tasks; @@ -320,7 +318,7 @@ class OnlineFileSource::Impl { resourceOptions.clone(), clientOptions.clone())) {} - std::unique_ptr request(Callback callback, Resource res) { + std::unique_ptr request(std::function callback, Resource res) { auto req = std::make_unique(std::move(callback)); req->onCancel( [actorRef = thread->actor(), req = req.get()]() { actorRef.invoke(&OnlineFileSourceThread::cancel, req); }); @@ -429,7 +427,9 @@ class OnlineFileSource::Impl { const std::unique_ptr> thread; }; -OnlineFileRequest::OnlineFileRequest(Resource resource_, Callback callback_, OnlineFileSourceThread& impl_) +OnlineFileRequest::OnlineFileRequest(Resource resource_, + std::function&& 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 OnlineFileSource::request(const Resource& resource, Callback callback) { +std::unique_ptr OnlineFileSource::request(const Resource& resource, + std::function callback) { Resource res = resource; const TileServerOptions options = impl->getResourceOptions().tileServerOptions(); diff --git a/platform/default/src/mbgl/storage/pmtiles_file_source.cpp b/platform/default/src/mbgl/storage/pmtiles_file_source.cpp index 9089f65ea8f..7cd00be039e 100644 --- a/platform/default/src/mbgl/storage/pmtiles_file_source.cpp +++ b/platform/default/src/mbgl/storage/pmtiles_file_source.cpp @@ -547,7 +547,8 @@ PMTilesFileSource::PMTilesFileSource(const ResourceOptions& resourceOptions, con resourceOptions.clone(), clientOptions.clone())) {} -std::unique_ptr PMTilesFileSource::request(const Resource& resource, FileSource::Callback callback) { +std::unique_ptr PMTilesFileSource::request(const Resource& resource, + std::function callback) { auto req = std::make_unique(std::move(callback)); // assume if there is a tile request, that the pmtiles file has been validated diff --git a/platform/default/src/mbgl/util/run_loop.cpp b/platform/default/src/mbgl/util/run_loop.cpp index 0076299c655..c444737260c 100644 --- a/platform/default/src/mbgl/util/run_loop.cpp +++ b/platform/default/src/mbgl/util/run_loop.cpp @@ -48,8 +48,8 @@ struct Watch { uv_poll_t poll; int fd; - std::function eventCallback; - std::function closeCallback; + std23::move_only_function eventCallback; + std23::move_only_function 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&& callback) { +void RunLoop::addWatch(int fd, Event event, std23::move_only_function&& callback) { MBGL_VERIFY_THREAD(tid); Watch* watch = nullptr; diff --git a/platform/node/CMakeLists.txt b/platform/node/CMakeLists.txt index c7eedf18702..4626784688b 100644 --- a/platform/node/CMakeLists.txt +++ b/platform/node/CMakeLists.txt @@ -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 diff --git a/platform/node/src/node_map.cpp b/platform/node/src/node_map.cpp index b67ed90a19d..c4295c587b2 100644 --- a/platform/node/src/node_map.cpp +++ b/platform/node/src/node_map.cpp @@ -1537,7 +1537,7 @@ NodeMap::~NodeMap() { } std::unique_ptr NodeFileSource::request(const mbgl::Resource& resource, - mbgl::FileSource::Callback callback_) { + std::function callback_) { assert(nodeMap); Nan::HandleScope scope; diff --git a/platform/node/src/node_map.hpp b/platform/node/src/node_map.hpp index 9f170d32750..5b9df1bda35 100644 --- a/platform/node/src/node_map.hpp +++ b/platform/node/src/node_map.hpp @@ -103,7 +103,7 @@ struct NodeFileSource : public mbgl::FileSource { NodeFileSource(NodeMap* nodeMap_) : nodeMap(nodeMap_) {} ~NodeFileSource() override = default; - std::unique_ptr request(const mbgl::Resource&, mbgl::FileSource::Callback) final; + std::unique_ptr request(const mbgl::Resource&, std::function) final; bool canRequest(const mbgl::Resource&) const override; void setResourceOptions(mbgl::ResourceOptions) override; mbgl::ResourceOptions getResourceOptions() override; diff --git a/platform/node/src/node_request.cpp b/platform/node/src/node_request.cpp index 916c7edc2ed..68543262862 100644 --- a/platform/node/src/node_request.cpp +++ b/platform/node/src/node_request.cpp @@ -7,7 +7,7 @@ namespace node_mbgl { -NodeRequest::NodeRequest(mbgl::FileSource::Callback callback_, NodeAsyncRequest* asyncRequest_) +NodeRequest::NodeRequest(std::function callback_, NodeAsyncRequest* asyncRequest_) : callback(std::move(callback_)), asyncRequest(asyncRequest_) { asyncRequest->request = this; @@ -42,7 +42,7 @@ void NodeRequest::Init(v8::Local target) { void NodeRequest::New(const Nan::FunctionCallbackInfo& info) { auto target = reinterpret_cast(info[0].As()->Value()); - auto callback = reinterpret_cast(info[1].As()->Value()); + auto callback = reinterpret_cast*>(info[1].As()->Value()); auto asyncRequest = reinterpret_cast(info[2].As()->Value()); auto request = new NodeRequest(*callback, asyncRequest); diff --git a/platform/node/src/node_request.hpp b/platform/node/src/node_request.hpp index fa8f8752e0d..f87253646e8 100644 --- a/platform/node/src/node_request.hpp +++ b/platform/node/src/node_request.hpp @@ -22,7 +22,7 @@ struct NodeAsyncRequest : public mbgl::AsyncRequest { class NodeRequest : public Nan::ObjectWrap { public: - NodeRequest(mbgl::FileSource::Callback, NodeAsyncRequest*); + NodeRequest(std::function, NodeAsyncRequest*); ~NodeRequest() override; static Nan::Persistent constructor; @@ -34,7 +34,7 @@ class NodeRequest : public Nan::ObjectWrap { void unrefRequest(); - mbgl::FileSource::Callback callback; + std::function callback; NodeAsyncRequest* asyncRequest; Nan::AsyncResource* asyncResource = new Nan::AsyncResource("mbgl:execute"); }; diff --git a/platform/qt/src/mbgl/http_file_source.cpp b/platform/qt/src/mbgl/http_file_source.cpp index b5885940c15..54c8a17fc04 100644 --- a/platform/qt/src/mbgl/http_file_source.cpp +++ b/platform/qt/src/mbgl/http_file_source.cpp @@ -106,8 +106,9 @@ HTTPFileSource::HTTPFileSource(const ResourceOptions& resourceOptions, const Cli HTTPFileSource::~HTTPFileSource() = default; -std::unique_ptr HTTPFileSource::request(const Resource& resource, Callback callback) { - return std::make_unique(impl.get(), resource, callback); +std::unique_ptr HTTPFileSource::request(const Resource& resource, + std::function callback) { + return std::make_unique(impl.get(), resource, std::move(callback)); } void HTTPFileSource::setResourceOptions(ResourceOptions options) { diff --git a/platform/qt/src/mbgl/http_request.cpp b/platform/qt/src/mbgl/http_request.cpp index 973760a419a..da2e7e01ee1 100644 --- a/platform/qt/src/mbgl/http_request.cpp +++ b/platform/qt/src/mbgl/http_request.cpp @@ -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 callback) : m_context(context), m_resource(resource), - m_callback(callback) { + m_callback(std::move(callback)) { m_context->request(this); } diff --git a/platform/qt/src/mbgl/http_request.hpp b/platform/qt/src/mbgl/http_request.hpp index 5486b686caf..e74a7ecfad7 100644 --- a/platform/qt/src/mbgl/http_request.hpp +++ b/platform/qt/src/mbgl/http_request.hpp @@ -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); virtual ~HTTPRequest(); QUrl requestUrl() const; @@ -25,7 +25,7 @@ class HTTPRequest : public AsyncRequest { private: HTTPFileSource::Impl* m_context; Resource m_resource; - FileSource::Callback m_callback; + std::function m_callback; bool m_handled = false; }; diff --git a/platform/qt/src/mbgl/run_loop.cpp b/platform/qt/src/mbgl/run_loop.cpp index ea1828dea07..9831602ecd3 100644 --- a/platform/qt/src/mbgl/run_loop.cpp +++ b/platform/qt/src/mbgl/run_loop.cpp @@ -107,7 +107,7 @@ void RunLoop::waitForEmpty([[maybe_unused]] const mbgl::util::SimpleIdentity tag } } -void RunLoop::addWatch(int fd, Event event, std::function&& cb) { +void RunLoop::addWatch(int fd, Event event, std23::move_only_function&& cb) { MBGL_VERIFY_THREAD(tid); if (event == Event::Read || event == Event::ReadWrite) { diff --git a/platform/qt/src/mbgl/run_loop_impl.hpp b/platform/qt/src/mbgl/run_loop_impl.hpp index c1fe8578e31..b5fc3ef48ff 100644 --- a/platform/qt/src/mbgl/run_loop_impl.hpp +++ b/platform/qt/src/mbgl/run_loop_impl.hpp @@ -13,8 +13,7 @@ namespace mbgl { namespace util { -using WatchCallback = std::function; -using WatchPair = std::pair, WatchCallback>; +using WatchPair = std::pair, std23::move_only_function>; class RunLoop::Impl : public QObject { Q_OBJECT diff --git a/platform/qt/src/utils/scheduler.cpp b/platform/qt/src/utils/scheduler.cpp index 7ab5364c562..af99ed7335f 100644 --- a/platform/qt/src/utils/scheduler.cpp +++ b/platform/qt/src/utils/scheduler.cpp @@ -13,7 +13,11 @@ Scheduler::~Scheduler() { MBGL_VERIFY_THREAD(tid); } -void Scheduler::schedule(std::function&& 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 lock(m_taskQueueMutex); m_taskQueue.push(std::move(function)); @@ -23,7 +27,7 @@ void Scheduler::schedule(std::function&& function) { } void Scheduler::processEvents() { - std::queue> taskQueue; + std::queue taskQueue; { const std::unique_lock lock(m_taskQueueMutex); std::swap(taskQueue, m_taskQueue); diff --git a/platform/qt/src/utils/scheduler.hpp b/platform/qt/src/utils/scheduler.hpp index 99b26b7b757..15020a9f4cb 100644 --- a/platform/qt/src/utils/scheduler.hpp +++ b/platform/qt/src/utils/scheduler.hpp @@ -1,6 +1,7 @@ #pragma once #include +#include #include #include @@ -20,7 +21,8 @@ class Scheduler : public QObject, public mbgl::Scheduler { ~Scheduler() override; // mbgl::Scheduler implementation. - void schedule(std::function&& 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 @@ class Scheduler : public QObject, public mbgl::Scheduler { std::mutex m_taskQueueMutex; std::condition_variable cvEmpty; std::atomic pendingItems; - std::queue> m_taskQueue; + std::queue m_taskQueue; mapbox::base::WeakPtrFactory weakFactory{this}; // Do not add members here, see `WeakPtrFactory` }; diff --git a/render-test/file_source.cpp b/render-test/file_source.cpp index 30b1f679e1f..081b63cf899 100644 --- a/render-test/file_source.cpp +++ b/render-test/file_source.cpp @@ -32,7 +32,8 @@ ProxyFileSource::ProxyFileSource(std::shared_ptr defaultResourceLoad ProxyFileSource::~ProxyFileSource() = default; -std::unique_ptr ProxyFileSource::request(const Resource& resource, Callback callback) { +std::unique_ptr ProxyFileSource::request(const Resource& resource, + std::function callback) { auto transformed = resource; // If offline, force always loading the resource from the cache diff --git a/render-test/file_source.hpp b/render-test/file_source.hpp index c06d223079d..baa916100ff 100644 --- a/render-test/file_source.hpp +++ b/render-test/file_source.hpp @@ -12,7 +12,7 @@ class ProxyFileSource : public FileSource { ProxyFileSource(std::shared_ptr, const ResourceOptions&, const ClientOptions&); ~ProxyFileSource(); - std::unique_ptr request(const Resource&, Callback) override; + std::unique_ptr request(const Resource&, std::function) override; bool canRequest(const Resource&) const override { return true; } /** diff --git a/src/mbgl/actor/scheduler.cpp b/src/mbgl/actor/scheduler.cpp index 68a55cbef9c..a55c06e9dfd 100644 --- a/src/mbgl/actor/scheduler.cpp +++ b/src/mbgl/actor/scheduler.cpp @@ -5,7 +5,7 @@ namespace mbgl { -std::function Scheduler::bindOnce(std::function 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::GetSequenced() { if (auto scheduler = weaks[lastUsedIndex].lock()) { return scheduler; - } else { - auto result = std::make_shared(); - weaks[lastUsedIndex] = result; - return result; } + + auto result = std::make_shared(); + weaks[lastUsedIndex] = result; + return result; } } // namespace mbgl diff --git a/src/mbgl/map/map_impl.cpp b/src/mbgl/map/map_impl.cpp index 6b5a6454f18..3bf43a3ed2c 100644 --- a/src/mbgl/map/map_impl.cpp +++ b/src/mbgl/map/map_impl.cpp @@ -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& done) { +void Map::Impl::onStyleImageMissing(const std::string& id, Scheduler::Task&& done) { if (!style->getImage(id)) observer.onStyleImageMissing(id); done(); diff --git a/src/mbgl/map/map_impl.hpp b/src/mbgl/map/map_impl.hpp index d093b30f227..c1cee52636f 100644 --- a/src/mbgl/map/map_impl.hpp +++ b/src/mbgl/map/map_impl.hpp @@ -52,7 +52,7 @@ class Map::Impl final : public style::Observer, public RendererObserver { void onDidFinishRenderingFrame(RenderMode, bool, bool, double, double) final; void onWillStartRenderingMap() final; void onDidFinishRenderingMap() final; - void onStyleImageMissing(const std::string&, const std::function&) final; + void onStyleImageMissing(const std::string&, Scheduler::Task&&) final; void onRemoveUnusedStyleImages(const std::vector&) final; void onRegisterShaders(gfx::ShaderRegistry&) final; @@ -88,7 +88,7 @@ class Map::Impl final : public style::Observer, public RendererObserver { uint8_t prefetchZoomDelta = util::DEFAULT_PREFETCH_ZOOM_DELTA; bool loading = false; - bool rendererFullyLoaded; + bool rendererFullyLoaded{false}; std::unique_ptr stillImageRequest; }; diff --git a/src/mbgl/renderer/image_manager.cpp b/src/mbgl/renderer/image_manager.cpp index c2b7bca9358..2ed998d8c27 100644 --- a/src/mbgl/renderer/image_manager.cpp +++ b/src/mbgl/renderer/image_manager.cpp @@ -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 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. diff --git a/src/mbgl/renderer/image_manager_observer.hpp b/src/mbgl/renderer/image_manager_observer.hpp index a057c99f847..f5f7ba624e1 100644 --- a/src/mbgl/renderer/image_manager_observer.hpp +++ b/src/mbgl/renderer/image_manager_observer.hpp @@ -11,7 +11,7 @@ class ImageManagerObserver { public: virtual ~ImageManagerObserver() = default; - virtual void onStyleImageMissing(const std::string&, const std::function& done) { done(); } + virtual void onStyleImageMissing(const std::string&, Scheduler::Task&& done) { done(); } virtual void onRemoveUnusedStyleImages(const std::vector&) {} }; diff --git a/src/mbgl/renderer/render_orchestrator.cpp b/src/mbgl/renderer/render_orchestrator.cpp index c9762831a1b..8cd82d1b834 100644 --- a/src/mbgl/renderer/render_orchestrator.cpp +++ b/src/mbgl/renderer/render_orchestrator.cpp @@ -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& 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& unusedImageIDs) { diff --git a/src/mbgl/renderer/render_orchestrator.hpp b/src/mbgl/renderer/render_orchestrator.hpp index 5065b189ae6..95d4179e0eb 100644 --- a/src/mbgl/renderer/render_orchestrator.hpp +++ b/src/mbgl/renderer/render_orchestrator.hpp @@ -186,7 +186,7 @@ class RenderOrchestrator final : public GlyphManagerObserver, public ImageManage void onTileAction(RenderSource&, TileOperation, const OverscaledTileID&, const std::string&) override; // ImageManagerObserver implementation - void onStyleImageMissing(const std::string&, const std::function&) override; + void onStyleImageMissing(const std::string&, Scheduler::Task&&) override; void onRemoveUnusedStyleImages(const std::vector&) override; #if MLN_DRAWABLE_RENDERER diff --git a/src/mbgl/storage/asset_file_source.hpp b/src/mbgl/storage/asset_file_source.hpp index 8db775592d1..7b1cfb4e670 100644 --- a/src/mbgl/storage/asset_file_source.hpp +++ b/src/mbgl/storage/asset_file_source.hpp @@ -16,7 +16,7 @@ class AssetFileSource : public FileSource { AssetFileSource(const ResourceOptions& resourceOptions, const ClientOptions& clientOptions); ~AssetFileSource() override; - std::unique_ptr request(const Resource&, Callback) override; + std::unique_ptr request(const Resource&, std::function) override; bool canRequest(const Resource&) const override; void pause() override; void resume() override; diff --git a/src/mbgl/storage/http_file_source.hpp b/src/mbgl/storage/http_file_source.hpp index 7a123395896..1ed2d7db158 100644 --- a/src/mbgl/storage/http_file_source.hpp +++ b/src/mbgl/storage/http_file_source.hpp @@ -13,7 +13,7 @@ class HTTPFileSource : public FileSource { HTTPFileSource(const ResourceOptions& resourceOptions, const ClientOptions& clientOptions); ~HTTPFileSource() override; - std::unique_ptr request(const Resource&, Callback) override; + std::unique_ptr request(const Resource&, std::function) override; bool canRequest(const Resource& resource) const override { return resource.hasLoadingMethod(Resource::LoadingMethod::Network); } diff --git a/src/mbgl/storage/local_file_source.hpp b/src/mbgl/storage/local_file_source.hpp index 79a90de6720..cdaca136777 100644 --- a/src/mbgl/storage/local_file_source.hpp +++ b/src/mbgl/storage/local_file_source.hpp @@ -16,7 +16,7 @@ class LocalFileSource : public FileSource { LocalFileSource(const ResourceOptions& resourceOptions, const ClientOptions& clientOptions); ~LocalFileSource() override; - std::unique_ptr request(const Resource&, Callback) override; + std::unique_ptr request(const Resource&, std::function) override; bool canRequest(const Resource&) const override; void pause() override; void resume() override; diff --git a/src/mbgl/storage/main_resource_loader.hpp b/src/mbgl/storage/main_resource_loader.hpp index 6b6ddc54266..5e3063bfff9 100644 --- a/src/mbgl/storage/main_resource_loader.hpp +++ b/src/mbgl/storage/main_resource_loader.hpp @@ -14,7 +14,7 @@ class MainResourceLoader final : public FileSource { ~MainResourceLoader() override; bool supportsCacheOnlyRequests() const override; - std::unique_ptr request(const Resource&, Callback) override; + std::unique_ptr request(const Resource&, std::function) override; bool canRequest(const Resource&) const override; void pause() override; void resume() override; diff --git a/src/mbgl/storage/mbtiles_file_source.hpp b/src/mbgl/storage/mbtiles_file_source.hpp index 876d348c653..658b00ecb9a 100644 --- a/src/mbgl/storage/mbtiles_file_source.hpp +++ b/src/mbgl/storage/mbtiles_file_source.hpp @@ -13,7 +13,7 @@ class MBTilesFileSource : public FileSource { MBTilesFileSource(const ResourceOptions& resourceOptions, const ClientOptions& clientOptions); ~MBTilesFileSource() override; - std::unique_ptr request(const Resource&, Callback) override; + std::unique_ptr request(const Resource&, std::function) override; bool canRequest(const Resource&) const override; void setResourceOptions(ResourceOptions) override; diff --git a/src/mbgl/storage/pmtiles_file_source.hpp b/src/mbgl/storage/pmtiles_file_source.hpp index 47d34139efe..6d710f2e2a8 100644 --- a/src/mbgl/storage/pmtiles_file_source.hpp +++ b/src/mbgl/storage/pmtiles_file_source.hpp @@ -12,7 +12,7 @@ class PMTilesFileSource : public FileSource { PMTilesFileSource(const ResourceOptions& resourceOptions, const ClientOptions& clientOptions); ~PMTilesFileSource() override; - std::unique_ptr request(const Resource&, Callback) override; + std::unique_ptr request(const Resource&, std::function) override; bool canRequest(const Resource&) const override; void setResourceOptions(ResourceOptions) override; diff --git a/src/mbgl/tile/geometry_tile_worker.cpp b/src/mbgl/tile/geometry_tile_worker.cpp index 24a81c4ca70..7e90e7c477c 100644 --- a/src/mbgl/tile/geometry_tile_worker.cpp +++ b/src/mbgl/tile/geometry_tile_worker.cpp @@ -14,12 +14,13 @@ #include #include #include -#include -#include #include -#include +#include #include +#include +#include #include +#include #include #include @@ -372,9 +373,9 @@ void GeometryTileWorker::parse() { return; } - MBGL_TIMING_START(watch) + MBGL_TIMING_START(watch); - std::unordered_map> symbolLayoutMap; + mbgl::unordered_map> symbolLayoutMap; renderData.clear(); layouts.clear(); @@ -495,7 +496,7 @@ void GeometryTileWorker::finalizeLayout() { return; } - MBGL_TIMING_START(watch) + MBGL_TIMING_START(watch); std::optional glyphAtlasImage; ImageAtlas iconAtlas = makeImageAtlas(imageMap, patternMap, versionMap); if (!layouts.empty()) { diff --git a/src/mbgl/tile/tile_cache.cpp b/src/mbgl/tile/tile_cache.cpp index 5104c3ea6ef..5302b9abe1a 100644 --- a/src/mbgl/tile/tile_cache.cpp +++ b/src/mbgl/tile/tile_cache.cpp @@ -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>&& 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> items; -}; -} // namespace - void TileCache::deferredRelease(std::unique_ptr&& 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 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 counterLock(deferredSignalLock); deferredDeletionsPending--; deferredSignal.notify_all(); - }}; - - threadPool.schedule(std::move(func)); + }}); + pendingReleases.clear(); } void TileCache::add(const OverscaledTileID& key, std::unique_ptr&& tile) { diff --git a/src/mbgl/util/stopwatch.hpp b/src/mbgl/util/stopwatch.hpp index 3e29122c0ab..693c4266e44 100644 --- a/src/mbgl/util/stopwatch.hpp +++ b/src/mbgl/util/stopwatch.hpp @@ -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 diff --git a/src/mbgl/util/thread_pool.cpp b/src/mbgl/util/thread_pool.cpp index bf2ad316df7..655e076eed8 100644 --- a/src/mbgl/util/thread_pool.cpp +++ b/src/mbgl/util/thread_pool.cpp @@ -59,7 +59,7 @@ std::thread ThreadedSchedulerBase::makeSchedulerThread(size_t index) { // 2. Visit a task from each for (auto& q : pending) { - std::function tasklet; + Task tasklet; { std::lock_guard lock(q->lock); if (q->queue.size()) { @@ -105,11 +105,11 @@ std::thread ThreadedSchedulerBase::makeSchedulerThread(size_t index) { }); } -void ThreadedSchedulerBase::schedule(std::function&& fn) { +void ThreadedSchedulerBase::schedule(Task&& fn) { schedule(uniqueID, std::move(fn)); } -void ThreadedSchedulerBase::schedule(const util::SimpleIdentity tag, std::function&& fn) { +void ThreadedSchedulerBase::schedule(const util::SimpleIdentity tag, Task&& fn) { MLN_TRACE_FUNC(); assert(fn); if (!fn) return; diff --git a/src/mbgl/util/thread_pool.hpp b/src/mbgl/util/thread_pool.hpp index b1614666179..afa30b09f5b 100644 --- a/src/mbgl/util/thread_pool.hpp +++ b/src/mbgl/util/thread_pool.hpp @@ -22,12 +22,12 @@ class ThreadedSchedulerBase : public Scheduler { /// @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&& 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&& fn) override; + void schedule(const util::SimpleIdentity tag, Task&& fn) override; const util::SimpleIdentity uniqueID; protected: @@ -56,10 +56,10 @@ class ThreadedSchedulerBase : public Scheduler { // Task queues bucketed by tag address struct Queue { - std::atomic runningCount; /* running tasks */ - std::condition_variable cv; /* queue empty condition */ - std::mutex lock; /* lock */ - std::queue> queue; /* pending task queue */ + std::atomic runningCount; /* running tasks */ + std::condition_variable cv; /* queue empty condition */ + std::mutex lock; /* lock */ + std::queue queue; /* pending task queue */ }; mbgl::unordered_map> taggedQueue; }; @@ -90,7 +90,7 @@ class ThreadedScheduler : public ThreadedSchedulerBase { } } - void runOnRenderThread(const util::SimpleIdentity tag, std::function&& fn) override { + void runOnRenderThread(const util::SimpleIdentity tag, Task&& fn) override { std::shared_ptr queue; { std::lock_guard lock(taggedRenderQueueLock); @@ -149,7 +149,7 @@ class ThreadedScheduler : public ThreadedSchedulerBase { std::vector threads; struct RenderQueue { - std::queue> queue; + std::queue queue; std::mutex mutex; }; mbgl::unordered_map> taggedRenderQueue; diff --git a/test/actor/actor.test.cpp b/test/actor/actor.test.cpp index 406f788d70a..23821822534 100644 --- a/test/actor/actor.test.cpp +++ b/test/actor/actor.test.cpp @@ -94,16 +94,14 @@ TEST(Actor, DestructionBlocksOnSend) { void waitForEmpty(const util::SimpleIdentity) override { assert(false); } - void schedule(std::function&&) 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&& fn) override final { - schedule(std::move(fn)); - } + void schedule(const util::SimpleIdentity, Task&& fn) override final { schedule(std::move(fn)); } mapbox::base::WeakPtr makeWeakPtr() override { return weakFactory.makeWeakPtr(); } diff --git a/test/renderer/image_manager.test.cpp b/test/renderer/image_manager.test.cpp index 282b4982259..8f92f472087 100644 --- a/test/renderer/image_manager.test.cpp +++ b/test/renderer/image_manager.test.cpp @@ -149,7 +149,7 @@ class StubImageManagerObserver : public ImageManagerObserver { int count = 0; std::function imageMissing = [](const std::string&) { }; - void onStyleImageMissing(const std::string& id, const std::function& done) override { + void onStyleImageMissing(const std::string& id, Scheduler::Task&& done) override { count++; imageMissing(id); done(); diff --git a/test/src/mbgl/test/fake_file_source.hpp b/test/src/mbgl/test/fake_file_source.hpp index 95752b0037c..bfb1937d99c 100644 --- a/test/src/mbgl/test/fake_file_source.hpp +++ b/test/src/mbgl/test/fake_file_source.hpp @@ -27,12 +27,12 @@ class FakeFileSource : public FileSource { class FakeFileRequest : public AsyncRequest { public: Resource resource; - Callback callback; + std::function callback; std::list& list; std::list::iterator link; - FakeFileRequest(Resource resource_, Callback callback_, std::list& list_) + FakeFileRequest(Resource resource_, std::function callback_, std::list& list_) : resource(std::move(resource_)), callback(std::move(callback_)), list(list_), @@ -47,8 +47,8 @@ class FakeFileSource : public FileSource { FakeFileSource() : FakeFileSource(ResourceOptions::Default(), ClientOptions()) {} - std::unique_ptr request(const Resource& resource, Callback callback) override { - return std::make_unique(resource, callback, requests); + std::unique_ptr request(const Resource& resource, std::function callback) override { + return std::make_unique(resource, std::move(callback), requests); } bool canRequest(const Resource&) const override { return true; } @@ -62,7 +62,7 @@ class FakeFileSource : public FileSource { 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 @@ class FakeOnlineFileSource : public FakeFileSource { FakeOnlineFileSource(const ResourceOptions& resourceOptions_, const ClientOptions& clientOptions_) : FakeFileSource(resourceOptions_, clientOptions_) {} - std::unique_ptr request(const Resource& resource, Callback callback) override { - return FakeFileSource::request(resource, callback); + std::unique_ptr request(const Resource& resource, std::function callback) override { + return FakeFileSource::request(resource, std::move(callback)); } bool respond(Resource::Kind kind, const Response& response) { return FakeFileSource::respond(kind, response); } diff --git a/test/src/mbgl/test/stub_file_source.cpp b/test/src/mbgl/test/stub_file_source.cpp index 598b20b666a..d0b8bfb4f6a 100644 --- a/test/src/mbgl/test/stub_file_source.cpp +++ b/test/src/mbgl/test/stub_file_source.cpp @@ -60,7 +60,8 @@ StubFileSource::StubFileSource(const ResourceOptions& resourceOptions_, StubFileSource::~StubFileSource() = default; -std::unique_ptr StubFileSource::request(const Resource& resource, Callback callback) { +std::unique_ptr StubFileSource::request(const Resource& resource, + std::function callback) { auto req = std::make_unique(*this); if (type == ResponseType::Synchronous) { std::optional res = response(resource); @@ -68,7 +69,7 @@ std::unique_ptr 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; } diff --git a/test/src/mbgl/test/stub_file_source.hpp b/test/src/mbgl/test/stub_file_source.hpp index 1bad4a74d22..06c11aeeebf 100644 --- a/test/src/mbgl/test/stub_file_source.hpp +++ b/test/src/mbgl/test/stub_file_source.hpp @@ -23,8 +23,8 @@ class StubFileSource : public FileSource { StubFileSource(ResponseType = ResponseType::Asynchronous); ~StubFileSource() override; - std::unique_ptr request(const Resource&, Callback) override; - bool canRequest(const Resource&) const override { return true; } + std::unique_ptr request(const Resource&, std::function) 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 @@ class StubFileSource : public FileSource { // The default behavior is to throw if no per-kind callback has been set. std::optional defaultResponse(const Resource&); - std::unordered_map> pending; + std::unordered_map>> pending; ResponseType type; util::Timer timer; std::map properties; diff --git a/test/storage/sync_file_source.test.cpp b/test/storage/sync_file_source.test.cpp index 8a87ba1412c..dbc95fb91ca 100644 --- a/test/storage/sync_file_source.test.cpp +++ b/test/storage/sync_file_source.test.cpp @@ -18,7 +18,7 @@ using namespace mbgl; class SyncFileSource : public FileSource { public: - std::unique_ptr request(const Resource& resource, FileSource::Callback callback) override { + std::unique_ptr request(const Resource& resource, std::function callback) override { Response response; auto it = assets.find(resource.url); if (it == assets.end()) { diff --git a/vendor/BUILD.bazel b/vendor/BUILD.bazel index 78fbf69c6c8..fa43bda1372 100644 --- a/vendor/BUILD.bazel +++ b/vendor/BUILD.bazel @@ -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"], +) diff --git a/vendor/nontype_functional b/vendor/nontype_functional new file mode 160000 index 00000000000..6fae3505138 --- /dev/null +++ b/vendor/nontype_functional @@ -0,0 +1 @@ +Subproject commit 6fae3505138a74c0bf2380ca769b4193b891d13e diff --git a/vendor/nontype_functional.cmake b/vendor/nontype_functional.cmake new file mode 100644 index 00000000000..0673e9c1ca3 --- /dev/null +++ b/vendor/nontype_functional.cmake @@ -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 +)