From 73ddf43268e83209f11020b86793fd63744560c1 Mon Sep 17 00:00:00 2001 From: Gali Nelle Date: Sun, 15 Mar 2020 17:31:15 +0200 Subject: Add Map::Impl::get to retrieve the Impl from Map This allow to access the map private implementation if necessary. --- include/mbgl/map/map.hpp | 3 +- src/mbgl/annotation/annotation_manager.cpp | 107 +++++++++++++++++------------ src/mbgl/annotation/annotation_manager.hpp | 18 +---- src/mbgl/map/map_impl.cpp | 10 ++- src/mbgl/map/map_impl.hpp | 3 + 5 files changed, 80 insertions(+), 61 deletions(-) diff --git a/include/mbgl/map/map.hpp b/include/mbgl/map/map.hpp index 62bb39e8c2..aa9267755f 100644 --- a/include/mbgl/map/map.hpp +++ b/include/mbgl/map/map.hpp @@ -31,6 +31,7 @@ class Style; class Map : private util::noncopyable { public: + class Impl; explicit Map(RendererFrontend&, MapObserver&, const MapOptions&, @@ -127,11 +128,11 @@ public: void dumpDebugLogs() const; protected: - class Impl; const std::unique_ptr impl; // For testing only. Map(std::unique_ptr); + friend class Impl; }; } // namespace mbgl diff --git a/src/mbgl/annotation/annotation_manager.cpp b/src/mbgl/annotation/annotation_manager.cpp index b5dfea8e1a..c4d9f3fb8e 100644 --- a/src/mbgl/annotation/annotation_manager.cpp +++ b/src/mbgl/annotation/annotation_manager.cpp @@ -4,6 +4,7 @@ #include #include #include + #include #include #include @@ -31,10 +32,27 @@ const std::string AnnotationManager::SourceID = "com.mapbox.annotations"; const std::string AnnotationManager::PointLayerID = "com.mapbox.annotations.points"; const std::string AnnotationManager::ShapeLayerID = "com.mapbox.annotations.shape."; -AnnotationManager::AnnotationManager(Style& style_) - : style(style_) { +class AnnotationManager::Impl : private util::noncopyable { +public: + using SymbolAnnotationTree = boost::geometry::index::rtree, + boost::geometry::index::rstar<16, 4>>; + // Unlike std::unordered_map, std::map is guaranteed to sort by AnnotationID, ensuring that older annotations are + // below newer annotations. + using SymbolAnnotationMap = std::map>; + using ShapeAnnotationMap = std::map>; + using ImageMap = std::unordered_map; + + SymbolAnnotationTree symbolTree; + SymbolAnnotationMap symbolAnnotations; + ShapeAnnotationMap shapeAnnotations; + ImageMap images; + + std::unordered_set tiles; }; + +AnnotationManager::AnnotationManager(Style& style_) : style(style_), impl(std::make_unique()){}; + AnnotationManager::~AnnotationManager() = default; void AnnotationManager::setStyle(Style& style_) { @@ -75,26 +93,28 @@ void AnnotationManager::removeAnnotation(const AnnotationID& id) { } void AnnotationManager::add(const AnnotationID& id, const SymbolAnnotation& annotation) { - auto impl = std::make_shared(id, annotation); - symbolTree.insert(impl); - symbolAnnotations.emplace(id, impl); + auto impl_ = std::make_shared(id, annotation); + AnnotationManager::impl->symbolTree.insert(impl_); + AnnotationManager::impl->symbolAnnotations.emplace(id, impl_); } void AnnotationManager::add(const AnnotationID& id, const LineAnnotation& annotation) { - ShapeAnnotationImpl& impl = *shapeAnnotations.emplace(id, - std::make_unique(id, annotation)).first->second; - impl.updateStyle(*style.get().impl); + ShapeAnnotationImpl& impl_ = + *AnnotationManager::impl->shapeAnnotations.emplace(id, std::make_unique(id, annotation)) + .first->second; + impl_.updateStyle(*style.get().impl); } void AnnotationManager::add(const AnnotationID& id, const FillAnnotation& annotation) { - ShapeAnnotationImpl& impl = *shapeAnnotations.emplace(id, - std::make_unique(id, annotation)).first->second; - impl.updateStyle(*style.get().impl); + ShapeAnnotationImpl& impl_ = + *AnnotationManager::impl->shapeAnnotations.emplace(id, std::make_unique(id, annotation)) + .first->second; + impl_.updateStyle(*style.get().impl); } void AnnotationManager::update(const AnnotationID& id, const SymbolAnnotation& annotation) { - auto it = symbolAnnotations.find(id); - if (it == symbolAnnotations.end()) { + auto it = AnnotationManager::impl->symbolAnnotations.find(id); + if (it == AnnotationManager::impl->symbolAnnotations.end()) { assert(false); // Attempt to update a non-existent symbol annotation return; } @@ -110,45 +130,45 @@ void AnnotationManager::update(const AnnotationID& id, const SymbolAnnotation& a } void AnnotationManager::update(const AnnotationID& id, const LineAnnotation& annotation) { - auto it = shapeAnnotations.find(id); - if (it == shapeAnnotations.end()) { + auto it = AnnotationManager::impl->shapeAnnotations.find(id); + if (it == AnnotationManager::impl->shapeAnnotations.end()) { assert(false); // Attempt to update a non-existent shape annotation return; } - shapeAnnotations.erase(it); + AnnotationManager::impl->shapeAnnotations.erase(it); add(id, annotation); dirty = true; } void AnnotationManager::update(const AnnotationID& id, const FillAnnotation& annotation) { - auto it = shapeAnnotations.find(id); - if (it == shapeAnnotations.end()) { + auto it = AnnotationManager::impl->shapeAnnotations.find(id); + if (it == AnnotationManager::impl->shapeAnnotations.end()) { assert(false); // Attempt to update a non-existent shape annotation return; } - shapeAnnotations.erase(it); + AnnotationManager::impl->shapeAnnotations.erase(it); add(id, annotation); dirty = true; } void AnnotationManager::remove(const AnnotationID& id) { CHECK_ANNOTATIONS_ENABLED_AND_RETURN(); - if (symbolAnnotations.find(id) != symbolAnnotations.end()) { - symbolTree.remove(symbolAnnotations.at(id)); - symbolAnnotations.erase(id); - } else if (shapeAnnotations.find(id) != shapeAnnotations.end()) { - auto it = shapeAnnotations.find(id); + if (AnnotationManager::impl->symbolAnnotations.find(id) != AnnotationManager::impl->symbolAnnotations.end()) { + AnnotationManager::impl->symbolTree.remove(AnnotationManager::impl->symbolAnnotations.at(id)); + AnnotationManager::impl->symbolAnnotations.erase(id); + } else if (AnnotationManager::impl->shapeAnnotations.find(id) != AnnotationManager::impl->shapeAnnotations.end()) { + auto it = AnnotationManager::impl->shapeAnnotations.find(id); *style.get().impl->removeLayer(it->second->layerID); - shapeAnnotations.erase(it); + AnnotationManager::impl->shapeAnnotations.erase(it); } else { assert(false); // Should never happen } } std::unique_ptr AnnotationManager::getTileData(const CanonicalTileID& tileID) { - if (symbolAnnotations.empty() && shapeAnnotations.empty()) + if (AnnotationManager::impl->symbolAnnotations.empty() && AnnotationManager::impl->shapeAnnotations.empty()) return nullptr; auto tileData = std::make_unique(); @@ -162,13 +182,12 @@ std::unique_ptr AnnotationManager::getTileData(const Canonic // The rendering/querying logic will make sure the symbols show up in only one of the tiles tileBounds.extend(LatLng(tileBounds.south() - 0.000000001, tileBounds.west() - 0.000000001)); tileBounds.extend(LatLng(tileBounds.north() + 0.000000001, tileBounds.east() + 0.000000001)); - - symbolTree.query(boost::geometry::index::intersects(tileBounds), - boost::make_function_output_iterator([&](const auto& val){ - val->updateLayer(tileID, *pointLayer); - })); - for (const auto& shape : shapeAnnotations) { + AnnotationManager::impl->symbolTree.query( + boost::geometry::index::intersects(tileBounds), + boost::make_function_output_iterator([&](const auto& val) { val->updateLayer(tileID, *pointLayer); })); + + for (const auto& shape : AnnotationManager::impl->shapeAnnotations) { shape.second->updateTileData(tileID, *tileData); } @@ -195,11 +214,11 @@ void AnnotationManager::updateStyle() { std::lock_guard lock(mutex); - for (const auto& shape : shapeAnnotations) { + for (const auto& shape : AnnotationManager::impl->shapeAnnotations) { shape.second->updateStyle(*style.get().impl); } - for (const auto& image : images) { + for (const auto& image : AnnotationManager::impl->images) { // Call addImage even for images we may have previously added, because we must support // addAnnotationImage being used to update an existing image. Creating a new image is // relatively cheap, as it copies only the Immutable reference. (We can't keep track @@ -214,7 +233,7 @@ void AnnotationManager::updateData() { CHECK_ANNOTATIONS_ENABLED_AND_RETURN(); std::lock_guard lock(mutex); if (dirty) { - for (auto& tile : tiles) { + for (auto& tile : AnnotationManager::impl->tiles) { tile->setData(getTileData(tile->id.canonical)); } dirty = false; @@ -224,14 +243,14 @@ void AnnotationManager::updateData() { void AnnotationManager::addTile(AnnotationTile& tile) { CHECK_ANNOTATIONS_ENABLED_AND_RETURN(); std::lock_guard lock(mutex); - tiles.insert(&tile); + AnnotationManager::impl->tiles.insert(&tile); tile.setData(getTileData(tile.id.canonical)); } void AnnotationManager::removeTile(AnnotationTile& tile) { CHECK_ANNOTATIONS_ENABLED_AND_RETURN(); std::lock_guard lock(mutex); - tiles.erase(&tile); + AnnotationManager::impl->tiles.erase(&tile); } // To ensure that annotation images do not collide with images from the style, @@ -244,9 +263,9 @@ void AnnotationManager::addImage(std::unique_ptr image) { CHECK_ANNOTATIONS_ENABLED_AND_RETURN(); std::lock_guard lock(mutex); const std::string id = prefixedImageID(image->getID()); - images.erase(id); - auto inserted = images.emplace(id, style::Image(id, image->getImage().clone(), - image->getPixelRatio(), image->isSdf())); + AnnotationManager::impl->images.erase(id); + auto inserted = AnnotationManager::impl->images.emplace( + id, style::Image(id, image->getImage().clone(), image->getPixelRatio(), image->isSdf())); style.get().impl->addImage(std::make_unique(inserted.first->second)); } @@ -254,7 +273,7 @@ void AnnotationManager::removeImage(const std::string& id_) { CHECK_ANNOTATIONS_ENABLED_AND_RETURN(); std::lock_guard lock(mutex); const std::string id = prefixedImageID(id_); - images.erase(id); + AnnotationManager::impl->images.erase(id); style.get().impl->removeImage(id); } @@ -262,8 +281,10 @@ double AnnotationManager::getTopOffsetPixelsForImage(const std::string& id_) { CHECK_ANNOTATIONS_ENABLED_AND_RETURN(0.0); std::lock_guard lock(mutex); const std::string id = prefixedImageID(id_); - auto it = images.find(id); - return it != images.end() ? -(it->second.getImage().size.height / it->second.getPixelRatio()) / 2 : 0.0; + auto it = AnnotationManager::impl->images.find(id); + return it != AnnotationManager::impl->images.end() + ? -(it->second.getImage().size.height / it->second.getPixelRatio()) / 2 + : 0.0; } } // namespace mbgl diff --git a/src/mbgl/annotation/annotation_manager.hpp b/src/mbgl/annotation/annotation_manager.hpp index a9389d8ca9..65ef3a3cbf 100644 --- a/src/mbgl/annotation/annotation_manager.hpp +++ b/src/mbgl/annotation/annotation_manager.hpp @@ -1,7 +1,6 @@ #pragma once #include -#include #include #include @@ -18,8 +17,6 @@ namespace mbgl { class LatLngBounds; class AnnotationTile; class AnnotationTileData; -class SymbolAnnotationImpl; -class ShapeAnnotationImpl; namespace style { class Style; @@ -75,19 +72,8 @@ private: AnnotationID nextID = 0; - using SymbolAnnotationTree = boost::geometry::index::rtree, boost::geometry::index::rstar<16, 4>>; - // Unlike std::unordered_map, std::map is guaranteed to sort by AnnotationID, ensuring that older annotations are below newer annotations. - // - using SymbolAnnotationMap = std::map>; - using ShapeAnnotationMap = std::map>; - using ImageMap = std::unordered_map; - - SymbolAnnotationTree symbolTree; - SymbolAnnotationMap symbolAnnotations; - ShapeAnnotationMap shapeAnnotations; - ImageMap images; - - std::unordered_set tiles; + class Impl; + const std::unique_ptr impl; mapbox::base::WeakPtrFactory weakFactory{this}; }; diff --git a/src/mbgl/map/map_impl.cpp b/src/mbgl/map/map_impl.cpp index 0edc715134..2d1ce3d386 100644 --- a/src/mbgl/map/map_impl.cpp +++ b/src/mbgl/map/map_impl.cpp @@ -30,7 +30,15 @@ Map::Impl::~Impl() { // Explicitly reset the RendererFrontend first to ensure it releases // All shared resources (AnnotationManager) rendererFrontend.reset(); -}; +} + +Map::Impl *Map::Impl::get(Map& map) { + return map.impl.get(); +} + +const Map::Impl *Map::Impl::get(const Map& map) { + return map.impl.get(); +} #pragma mark - Map::Impl StyleObserver diff --git a/src/mbgl/map/map_impl.hpp b/src/mbgl/map/map_impl.hpp index 416662f9e5..b89a584fae 100644 --- a/src/mbgl/map/map_impl.hpp +++ b/src/mbgl/map/map_impl.hpp @@ -31,6 +31,9 @@ public: Impl(RendererFrontend&, MapObserver&, std::shared_ptr, const MapOptions&); ~Impl() final; + static Map::Impl *get(Map&); + static const Map::Impl *get(const Map&); + // StyleObserver void onSourceChanged(style::Source&) final; void onUpdate() final; -- cgit v1.2.1