aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGali Nelle <galinelle.mapbox@gmail.com>2020-02-03 18:59:19 +0200
committerGali Nelle <galinelle.mapbox@gmail.com>2020-02-04 13:55:44 +0200
commit4b0eef6104bf8c33bf105b7173dbc5f0f65e1efb (patch)
treee932d3b62227d677b8e40c87277261546a80c4c5
parent391a5642e0b6ce1a07debfadd7619baf5bb04c9e (diff)
Move AnnotationManager inside Style, make Style sharedupstream/galinelle_setStyle++
This change enables to share a style across Maps. The goal is to avoid loading the same style multiple times if multiple maps with the same style are used. Use cases range from minimap to snapshotters. This change moves the AnnotationManager inside the Style itself. In this way, the old behavior is retained under the old use-cases: single map-single style. When using the style on multiple maps, changing annotations on the style, or on one map will result in changing them on all maps where that style is used. To add more flexibility, moving forward, a possible solution can be to support multiple stacked styles in the Map, that will then be flattened in the map. In this way a style will be a group of layers that can be added or removed without much troubles. Practical use case would be a style with the annotations on top of a style for the base map, that could be changed by the user. This would allow avoiding the current required procedure of modifying the new style when it gets set, in order to add the annotations.
-rw-r--r--include/mbgl/map/map.hpp5
-rw-r--r--include/mbgl/style/style.hpp6
-rw-r--r--src/mbgl/annotation/annotation_manager.cpp27
-rw-r--r--src/mbgl/annotation/annotation_manager.hpp6
-rw-r--r--src/mbgl/annotation/fill_annotation_impl.cpp2
-rw-r--r--src/mbgl/annotation/fill_annotation_impl.hpp2
-rw-r--r--src/mbgl/annotation/line_annotation_impl.cpp2
-rw-r--r--src/mbgl/annotation/line_annotation_impl.hpp2
-rw-r--r--src/mbgl/annotation/shape_annotation_impl.hpp2
-rw-r--r--src/mbgl/map/map.cpp28
-rw-r--r--src/mbgl/map/map_impl.cpp46
-rw-r--r--src/mbgl/map/map_impl.hpp19
-rw-r--r--src/mbgl/style/style.cpp12
-rw-r--r--src/mbgl/style/style_impl.cpp169
-rw-r--r--src/mbgl/style/style_impl.hpp59
-rw-r--r--test/style/source.test.cpp2
-rw-r--r--test/style/style.test.cpp8
-rw-r--r--test/style/style_layer.test.cpp4
-rw-r--r--test/tile/custom_geometry_tile.test.cpp2
-rw-r--r--test/tile/geojson_tile.test.cpp2
-rw-r--r--test/tile/raster_dem_tile.test.cpp2
-rw-r--r--test/tile/raster_tile.test.cpp2
-rw-r--r--test/tile/tile_cache.test.cpp2
-rw-r--r--test/tile/vector_tile.test.cpp2
24 files changed, 243 insertions, 170 deletions
diff --git a/include/mbgl/map/map.hpp b/include/mbgl/map/map.hpp
index 62bb39e8c..0636b80f5 100644
--- a/include/mbgl/map/map.hpp
+++ b/include/mbgl/map/map.hpp
@@ -34,7 +34,7 @@ public:
explicit Map(RendererFrontend&,
MapObserver&,
const MapOptions&,
- const ResourceOptions&);
+ const ResourceOptions &resourceOptions = ResourceOptions());
~Map();
// Register a callback that will get called (on the render thread) when all resources have
@@ -48,8 +48,9 @@ public:
style::Style& getStyle();
const style::Style& getStyle() const;
+ std::shared_ptr<style::Style> getStylePointer();
- void setStyle(std::unique_ptr<style::Style>);
+ void setStyle(const std::shared_ptr<mbgl::style::Style>&);
// Transition
void cancelTransitions();
diff --git a/include/mbgl/style/style.hpp b/include/mbgl/style/style.hpp
index 83d6ad5bb..1b39c3cbf 100644
--- a/include/mbgl/style/style.hpp
+++ b/include/mbgl/style/style.hpp
@@ -11,6 +11,7 @@
namespace mbgl {
class FileSource;
+class ResourceOptions;
namespace style {
@@ -18,10 +19,12 @@ class Light;
class Image;
class Source;
class Layer;
+class StyleImpl;
class Style {
public:
Style(std::shared_ptr<FileSource>, float pixelRatio);
+ Style(const ResourceOptions& resourceOptions, float pixelRatio);
~Style();
void loadJSON(const std::string&);
@@ -70,8 +73,7 @@ public:
std::unique_ptr<Layer> removeLayer(const std::string& layerID);
// Private implementation
- class Impl;
- const std::unique_ptr<Impl> impl;
+ const std::unique_ptr<StyleImpl> impl;
};
} // namespace style
diff --git a/src/mbgl/annotation/annotation_manager.cpp b/src/mbgl/annotation/annotation_manager.cpp
index b5dfea8e1..a2b26aabf 100644
--- a/src/mbgl/annotation/annotation_manager.cpp
+++ b/src/mbgl/annotation/annotation_manager.cpp
@@ -31,17 +31,12 @@ 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_)
+AnnotationManager::AnnotationManager(StyleImpl& style_)
: style(style_) {
};
AnnotationManager::~AnnotationManager() = default;
-void AnnotationManager::setStyle(Style& style_) {
- CHECK_ANNOTATIONS_ENABLED_AND_RETURN();
- style = style_;
-}
-
void AnnotationManager::onStyleLoaded() {
CHECK_ANNOTATIONS_ENABLED_AND_RETURN();
updateStyle();
@@ -83,13 +78,13 @@ void AnnotationManager::add(const AnnotationID& id, const SymbolAnnotation& anno
void AnnotationManager::add(const AnnotationID& id, const LineAnnotation& annotation) {
ShapeAnnotationImpl& impl = *shapeAnnotations.emplace(id,
std::make_unique<LineAnnotationImpl>(id, annotation)).first->second;
- impl.updateStyle(*style.get().impl);
+ impl.updateStyle(style);
}
void AnnotationManager::add(const AnnotationID& id, const FillAnnotation& annotation) {
ShapeAnnotationImpl& impl = *shapeAnnotations.emplace(id,
std::make_unique<FillAnnotationImpl>(id, annotation)).first->second;
- impl.updateStyle(*style.get().impl);
+ impl.updateStyle(style);
}
void AnnotationManager::update(const AnnotationID& id, const SymbolAnnotation& annotation) {
@@ -140,7 +135,7 @@ void AnnotationManager::remove(const AnnotationID& id) {
symbolAnnotations.erase(id);
} else if (shapeAnnotations.find(id) != shapeAnnotations.end()) {
auto it = shapeAnnotations.find(id);
- *style.get().impl->removeLayer(it->second->layerID);
+ style.removeLayer(it->second->layerID);
shapeAnnotations.erase(it);
} else {
assert(false); // Should never happen
@@ -178,8 +173,8 @@ std::unique_ptr<AnnotationTileData> AnnotationManager::getTileData(const Canonic
void AnnotationManager::updateStyle() {
// Create annotation source, point layer, and point bucket. We do everything via Style::Impl
// because we don't want annotation mutations to trigger Style::Impl::styleMutated to be set.
- if (!style.get().impl->getSource(SourceID)) {
- style.get().impl->addSource(std::make_unique<AnnotationSource>());
+ if (!style.getSource(SourceID)) {
+ style.addSource(std::make_unique<AnnotationSource>());
std::unique_ptr<SymbolLayer> layer = std::make_unique<SymbolLayer>(PointLayerID, SourceID);
@@ -190,13 +185,13 @@ void AnnotationManager::updateStyle() {
layer->setIconAllowOverlap(true);
layer->setIconIgnorePlacement(true);
- style.get().impl->addLayer(std::move(layer));
+ style.addLayer(std::move(layer));
}
std::lock_guard<std::mutex> lock(mutex);
for (const auto& shape : shapeAnnotations) {
- shape.second->updateStyle(*style.get().impl);
+ shape.second->updateStyle(style);
}
for (const auto& image : images) {
@@ -206,7 +201,7 @@ void AnnotationManager::updateStyle() {
// of which images need to be added because we don't know if the style is the same
// instance as in the last updateStyle call. If it's a new style, we need to add all
// images.)
- style.get().impl->addImage(std::make_unique<style::Image>(image.second));
+ style.addImage(std::make_unique<style::Image>(image.second));
}
}
@@ -247,7 +242,7 @@ void AnnotationManager::addImage(std::unique_ptr<style::Image> image) {
images.erase(id);
auto inserted = images.emplace(id, style::Image(id, image->getImage().clone(),
image->getPixelRatio(), image->isSdf()));
- style.get().impl->addImage(std::make_unique<style::Image>(inserted.first->second));
+ style.addImage(std::make_unique<style::Image>(inserted.first->second));
}
void AnnotationManager::removeImage(const std::string& id_) {
@@ -255,7 +250,7 @@ void AnnotationManager::removeImage(const std::string& id_) {
std::lock_guard<std::mutex> lock(mutex);
const std::string id = prefixedImageID(id_);
images.erase(id);
- style.get().impl->removeImage(id);
+ style.removeImage(id);
}
double AnnotationManager::getTopOffsetPixelsForImage(const std::string& id_) {
diff --git a/src/mbgl/annotation/annotation_manager.hpp b/src/mbgl/annotation/annotation_manager.hpp
index 6c794d7f8..86a378e98 100644
--- a/src/mbgl/annotation/annotation_manager.hpp
+++ b/src/mbgl/annotation/annotation_manager.hpp
@@ -21,11 +21,12 @@ class ShapeAnnotationImpl;
namespace style {
class Style;
+class StyleImpl;
} // namespace style
class AnnotationManager : private util::noncopyable {
public:
- AnnotationManager(style::Style&);
+ AnnotationManager(style::StyleImpl&);
~AnnotationManager();
AnnotationID addAnnotation(const Annotation&);
@@ -36,7 +37,6 @@ public:
void removeImage(const std::string&);
double getTopOffsetPixelsForImage(const std::string&);
- void setStyle(style::Style&);
void onStyleLoaded();
void updateData();
@@ -63,7 +63,7 @@ private:
std::unique_ptr<AnnotationTileData> getTileData(const CanonicalTileID&);
- std::reference_wrapper<style::Style> style;
+ style::StyleImpl& style;
std::mutex mutex;
diff --git a/src/mbgl/annotation/fill_annotation_impl.cpp b/src/mbgl/annotation/fill_annotation_impl.cpp
index 59b8133cf..7c3e4265d 100644
--- a/src/mbgl/annotation/fill_annotation_impl.cpp
+++ b/src/mbgl/annotation/fill_annotation_impl.cpp
@@ -12,7 +12,7 @@ FillAnnotationImpl::FillAnnotationImpl(AnnotationID id_, FillAnnotation annotati
annotation(ShapeAnnotationGeometry::visit(annotation_.geometry, CloseShapeAnnotation{}), annotation_.opacity, annotation_.color, annotation_.outlineColor) {
}
-void FillAnnotationImpl::updateStyle(Style::Impl& style) const {
+void FillAnnotationImpl::updateStyle(StyleImpl& style) const {
Layer* layer = style.getLayer(layerID);
if (!layer) {
diff --git a/src/mbgl/annotation/fill_annotation_impl.hpp b/src/mbgl/annotation/fill_annotation_impl.hpp
index 98f992151..3c672dbff 100644
--- a/src/mbgl/annotation/fill_annotation_impl.hpp
+++ b/src/mbgl/annotation/fill_annotation_impl.hpp
@@ -9,7 +9,7 @@ class FillAnnotationImpl : public ShapeAnnotationImpl {
public:
FillAnnotationImpl(AnnotationID, FillAnnotation);
- void updateStyle(style::Style::Impl&) const final;
+ void updateStyle(style::StyleImpl&) const final;
const ShapeAnnotationGeometry& geometry() const final;
private:
diff --git a/src/mbgl/annotation/line_annotation_impl.cpp b/src/mbgl/annotation/line_annotation_impl.cpp
index 533a137a3..a03dd13e6 100644
--- a/src/mbgl/annotation/line_annotation_impl.cpp
+++ b/src/mbgl/annotation/line_annotation_impl.cpp
@@ -12,7 +12,7 @@ LineAnnotationImpl::LineAnnotationImpl(AnnotationID id_, LineAnnotation annotati
annotation(ShapeAnnotationGeometry::visit(annotation_.geometry, CloseShapeAnnotation{}), annotation_.opacity, annotation_.width, annotation_.color) {
}
-void LineAnnotationImpl::updateStyle(Style::Impl& style) const {
+void LineAnnotationImpl::updateStyle(StyleImpl& style) const {
Layer* layer = style.getLayer(layerID);
if (!layer) {
diff --git a/src/mbgl/annotation/line_annotation_impl.hpp b/src/mbgl/annotation/line_annotation_impl.hpp
index 108787c42..0460428cf 100644
--- a/src/mbgl/annotation/line_annotation_impl.hpp
+++ b/src/mbgl/annotation/line_annotation_impl.hpp
@@ -9,7 +9,7 @@ class LineAnnotationImpl : public ShapeAnnotationImpl {
public:
LineAnnotationImpl(AnnotationID, LineAnnotation);
- void updateStyle(style::Style::Impl&) const final;
+ void updateStyle(style::StyleImpl&) const final;
const ShapeAnnotationGeometry& geometry() const final;
private:
diff --git a/src/mbgl/annotation/shape_annotation_impl.hpp b/src/mbgl/annotation/shape_annotation_impl.hpp
index 3e28221f7..3c1ca760f 100644
--- a/src/mbgl/annotation/shape_annotation_impl.hpp
+++ b/src/mbgl/annotation/shape_annotation_impl.hpp
@@ -20,7 +20,7 @@ public:
ShapeAnnotationImpl(const AnnotationID);
virtual ~ShapeAnnotationImpl() = default;
- virtual void updateStyle(style::Style::Impl&) const = 0;
+ virtual void updateStyle(style::StyleImpl&) const = 0;
virtual const ShapeAnnotationGeometry& geometry() const = 0;
void updateTileData(const CanonicalTileID&, AnnotationTileData&);
diff --git a/src/mbgl/map/map.cpp b/src/mbgl/map/map.cpp
index 061669f56..f48cd8668 100644
--- a/src/mbgl/map/map.cpp
+++ b/src/mbgl/map/map.cpp
@@ -33,7 +33,8 @@ Map::Map(RendererFrontend& frontend,
: impl(std::make_unique<Impl>(
frontend,
observer,
- FileSourceManager::get() ? FileSourceManager::get()->getFileSource(ResourceLoader, resourceOptions) : nullptr,
+// FileSourceManager::get() ? FileSourceManager::get()->getFileSource(ResourceLoader, resourceOptions) : nullptr,
+ resourceOptions,
mapOptions)) {}
Map::Map(std::unique_ptr<Impl> impl_) : impl(std::move(impl_)) {}
@@ -87,13 +88,14 @@ const style::Style& Map::getStyle() const {
return *impl->style;
}
-void Map::setStyle(std::unique_ptr<Style> style) {
+std::shared_ptr<Style> Map::getStylePointer()
+{
+ return impl->style;
+}
+
+void Map::setStyle(const std::shared_ptr<Style>& style) {
assert(style);
- impl->onStyleLoading();
- impl->style = std::move(style);
- if (LayerManager::annotationsEnabled) {
- impl->annotationManager.setStyle(*impl->style);
- }
+ impl->setStyle(style);
}
#pragma mark - Transitions
@@ -399,26 +401,26 @@ std::vector<LatLng> Map::latLngsForPixels(const std::vector<ScreenCoordinate>& s
void Map::addAnnotationImage(std::unique_ptr<style::Image> image) {
if (LayerManager::annotationsEnabled) {
- impl->annotationManager.addImage(std::move(image));
+ impl->style->impl->annotationManager.addImage(std::move(image));
}
}
void Map::removeAnnotationImage(const std::string& id) {
if (LayerManager::annotationsEnabled) {
- impl->annotationManager.removeImage(id);
+ impl->style->impl->annotationManager.removeImage(id);
}
}
double Map::getTopOffsetPixelsForAnnotationImage(const std::string& id) {
if (LayerManager::annotationsEnabled) {
- return impl->annotationManager.getTopOffsetPixelsForImage(id);
+ return impl->style->impl->annotationManager.getTopOffsetPixelsForImage(id);
}
return 0.0;
}
AnnotationID Map::addAnnotation(const Annotation& annotation) {
if (LayerManager::annotationsEnabled) {
- auto result = impl->annotationManager.addAnnotation(annotation);
+ auto result = impl->style->impl->annotationManager.addAnnotation(annotation);
impl->onUpdate();
return result;
}
@@ -427,7 +429,7 @@ AnnotationID Map::addAnnotation(const Annotation& annotation) {
void Map::updateAnnotation(AnnotationID id, const Annotation& annotation) {
if (LayerManager::annotationsEnabled) {
- if (impl->annotationManager.updateAnnotation(id, annotation)) {
+ if (impl->style->impl->annotationManager.updateAnnotation(id, annotation)) {
impl->onUpdate();
}
}
@@ -435,7 +437,7 @@ void Map::updateAnnotation(AnnotationID id, const Annotation& annotation) {
void Map::removeAnnotation(AnnotationID annotation) {
if (LayerManager::annotationsEnabled) {
- impl->annotationManager.removeAnnotation(annotation);
+ impl->style->impl->annotationManager.removeAnnotation(annotation);
impl->onUpdate();
}
}
diff --git a/src/mbgl/map/map_impl.cpp b/src/mbgl/map/map_impl.cpp
index bc2a37fe0..37e3ae9e6 100644
--- a/src/mbgl/map/map_impl.cpp
+++ b/src/mbgl/map/map_impl.cpp
@@ -9,7 +9,7 @@ namespace mbgl {
Map::Impl::Impl(RendererFrontend& frontend_,
MapObserver& observer_,
- std::shared_ptr<FileSource> fileSource_,
+ const ResourceOptions &resourceOptions_,
const MapOptions& mapOptions)
: observer(observer_),
rendererFrontend(frontend_),
@@ -17,11 +17,27 @@ Map::Impl::Impl(RendererFrontend& frontend_,
mode(mapOptions.mapMode()),
pixelRatio(mapOptions.pixelRatio()),
crossSourceCollisions(mapOptions.crossSourceCollisions()),
- fileSource(std::move(fileSource_)),
- style(std::make_unique<style::Style>(fileSource, pixelRatio)),
- annotationManager(*style) {
+ style(std::make_shared<style::Style>(resourceOptions_, pixelRatio)) {
+ init(mapOptions);
+}
+
+Map::Impl::Impl(RendererFrontend &frontend_,
+ MapObserver &observer_,
+ std::shared_ptr<FileSource> fileSource_,
+ const MapOptions &mapOptions)
+ : observer(observer_),
+ rendererFrontend(frontend_),
+ transform(observer, mapOptions.constrainMode(), mapOptions.viewportMode()),
+ mode(mapOptions.mapMode()),
+ pixelRatio(mapOptions.pixelRatio()),
+ crossSourceCollisions(mapOptions.crossSourceCollisions()),
+ style(std::make_shared<style::Style>(fileSource_, pixelRatio)) {
+ init(mapOptions);
+}
+
+void Map::Impl::init(const MapOptions& mapOptions) {
transform.setNorthOrientation(mapOptions.northOrientation());
- style->impl->setObserver(this);
+ style->impl->addObserver(this);
rendererFrontend.setObserver(*this);
transform.resize(mapOptions.size());
}
@@ -62,8 +78,8 @@ void Map::Impl::onUpdate() {
style->impl->getImageImpls(),
style->impl->getSourceImpls(),
style->impl->getLayerImpls(),
- annotationManager,
- fileSource,
+ style->impl->annotationManager,
+ style->impl->fileSource,
prefetchZoomDelta,
bool(stillImageRequest),
crossSourceCollisions
@@ -82,9 +98,7 @@ void Map::Impl::onStyleLoaded() {
if (!cameraMutated) {
jumpTo(style->getDefaultCamera());
}
- if (LayerManager::annotationsEnabled) {
- annotationManager.onStyleLoaded();
- }
+
observer.onDidFinishLoadingStyle();
}
@@ -169,6 +183,18 @@ void Map::Impl::jumpTo(const CameraOptions& camera) {
onUpdate();
}
+void Map::Impl::setStyle(const std::shared_ptr<style::Style>& style_)
+{
+ onStyleLoading();
+ style->impl->removeObserver(this);
+ style = style_;
+ style->impl->addObserver(this);
+ if (style->impl->isLoaded())
+ onStyleLoaded();
+ else if (style->impl->getLastError())
+ onStyleError(style->impl->getLastError());
+}
+
void Map::Impl::onStyleImageMissing(const std::string& id, std::function<void()> done) {
if (style->getImage(id) == nullptr) {
diff --git a/src/mbgl/map/map_impl.hpp b/src/mbgl/map/map_impl.hpp
index 416662f9e..4cb0b6389 100644
--- a/src/mbgl/map/map_impl.hpp
+++ b/src/mbgl/map/map_impl.hpp
@@ -1,6 +1,5 @@
#pragma once
-#include <mbgl/annotation/annotation_manager.hpp>
#include <mbgl/map/map.hpp>
#include <mbgl/map/map_observer.hpp>
#include <mbgl/map/map_options.hpp>
@@ -28,7 +27,14 @@ struct StillImageRequest {
class Map::Impl : public style::Observer, public RendererObserver {
public:
- Impl(RendererFrontend&, MapObserver&, std::shared_ptr<FileSource>, const MapOptions&);
+ Impl(RendererFrontend&,
+ MapObserver&,
+ const ResourceOptions&,
+ const MapOptions&);
+ Impl(RendererFrontend&,
+ MapObserver&,
+ std::shared_ptr<FileSource>,
+ const MapOptions&); // Used in tests
~Impl() final;
// StyleObserver
@@ -50,6 +56,7 @@ public:
// Map
void jumpTo(const CameraOptions&);
+ void setStyle(const std::shared_ptr<style::Style>& style);
MapObserver& observer;
RendererFrontend& rendererFrontend;
@@ -62,10 +69,7 @@ public:
MapDebugOptions debugOptions { MapDebugOptions::NoDebug };
- std::shared_ptr<FileSource> fileSource;
-
- std::unique_ptr<style::Style> style;
- AnnotationManager annotationManager;
+ std::shared_ptr<style::Style> style;
bool cameraMutated = false;
@@ -74,6 +78,9 @@ public:
bool loading = false;
bool rendererFullyLoaded;
std::unique_ptr<StillImageRequest> stillImageRequest;
+
+private:
+ void init(const MapOptions&);
};
} // namespace mbgl
diff --git a/src/mbgl/style/style.cpp b/src/mbgl/style/style.cpp
index 8a821e5a5..6649e2dd1 100644
--- a/src/mbgl/style/style.cpp
+++ b/src/mbgl/style/style.cpp
@@ -4,12 +4,18 @@
#include <mbgl/style/image.hpp>
#include <mbgl/style/source.hpp>
#include <mbgl/style/layer.hpp>
+#include <mbgl/storage/file_source_manager.hpp>
+#include <mbgl/storage/resource_options.hpp>
namespace mbgl {
namespace style {
Style::Style(std::shared_ptr<FileSource> fileSource, float pixelRatio)
- : impl(std::make_unique<Impl>(std::move(fileSource), pixelRatio)) {}
+ : impl(std::make_unique<StyleImpl>(std::move(fileSource), pixelRatio)) {}
+
+Style::Style(const ResourceOptions &resourceOptions, float pixelRatio)
+ : impl(std::make_unique<StyleImpl>(FileSourceManager::get() ? FileSourceManager::get()->getFileSource(ResourceLoader, resourceOptions) : nullptr,
+ pixelRatio)) {}
Style::~Style() = default;
@@ -79,7 +85,7 @@ std::vector<Source*> Style::getSources() {
}
std::vector<const Source*> Style::getSources() const {
- return const_cast<const Impl&>(*impl).getSources();
+ return const_cast<const StyleImpl&>(*impl).getSources();
}
Source* Style::getSource(const std::string& id) {
@@ -107,7 +113,7 @@ std::vector<Layer*> Style::getLayers() {
}
std::vector<const Layer*> Style::getLayers() const {
- return const_cast<const Impl&>(*impl).getLayers();
+ return const_cast<const StyleImpl&>(*impl).getLayers();
}
Layer* Style::getLayer(const std::string& layerID) {
diff --git a/src/mbgl/style/style_impl.cpp b/src/mbgl/style/style_impl.cpp
index d5961b590..13cd7bc4e 100644
--- a/src/mbgl/style/style_impl.cpp
+++ b/src/mbgl/style/style_impl.cpp
@@ -30,34 +30,38 @@ namespace style {
static Observer nullObserver;
-Style::Impl::Impl(std::shared_ptr<FileSource> fileSource_, float pixelRatio)
- : fileSource(std::move(fileSource_)),
+StyleImpl::StyleImpl(std::shared_ptr<FileSource> fileSource_, float pixelRatio)
+ : annotationManager(*this),
+ fileSource(std::move(fileSource_)),
spriteLoader(std::make_unique<SpriteLoader>(pixelRatio)),
- light(std::make_unique<Light>()),
- observer(&nullObserver) {
+ light(std::make_unique<Light>()) {
spriteLoader->setObserver(this);
light->setObserver(this);
}
-Style::Impl::~Impl() = default;
+StyleImpl::~StyleImpl() = default;
-void Style::Impl::loadJSON(const std::string& json_) {
+void StyleImpl::loadJSON(const std::string& json_) {
lastError = nullptr;
- observer->onStyleLoading();
+ for (auto &observer: observers)
+ observer->onStyleLoading();
url.clear();
parse(json_);
}
-void Style::Impl::loadURL(const std::string& url_) {
+void StyleImpl::loadURL(const std::string& url_) {
if (!fileSource) {
- observer->onStyleError(
- std::make_exception_ptr(util::StyleLoadException("Unable to find resource provider for style url.")));
+ for (auto &observer: observers) {
+ observer->onStyleError(
+ std::make_exception_ptr(util::StyleLoadException("Unable to find resource provider for style url.")));
+ }
return;
}
lastError = nullptr;
- observer->onStyleLoading();
+ for (auto &observer: observers)
+ observer->onStyleLoading();
loaded = false;
url = url_;
@@ -71,8 +75,10 @@ void Style::Impl::loadURL(const std::string& url_) {
if (res.error) {
const std::string message = "loading style failed: " + res.error->message;
Log::Error(Event::Setup, message.c_str());
- observer->onStyleError(std::make_exception_ptr(util::StyleLoadException(message)));
- observer->onResourceError(std::make_exception_ptr(std::runtime_error(res.error->message)));
+ for (auto &observer: observers) {
+ observer->onStyleError(std::make_exception_ptr(util::StyleLoadException(message)));
+ observer->onResourceError(std::make_exception_ptr(std::runtime_error(res.error->message)));
+ }
} else if (res.notModified || res.noContent) {
return;
} else {
@@ -81,14 +87,16 @@ void Style::Impl::loadURL(const std::string& url_) {
});
}
-void Style::Impl::parse(const std::string& json_) {
+void StyleImpl::parse(const std::string& json_) {
Parser parser;
if (auto error = parser.parse(json_)) {
std::string message = "Failed to parse style: " + util::toString(error);
Log::Error(Event::ParseStyle, message.c_str());
- observer->onStyleError(std::make_exception_ptr(util::StyleParseException(message)));
- observer->onResourceError(error);
+ for (auto &observer: observers) {
+ observer->onStyleError(std::make_exception_ptr(util::StyleParseException(message)));
+ observer->onResourceError(error);
+ }
return;
}
@@ -127,26 +135,29 @@ void Style::Impl::parse(const std::string& json_) {
glyphURL = parser.glyphURL;
loaded = true;
- observer->onStyleLoaded();
+
+ annotationManager.onStyleLoaded();
+ for (auto &observer: observers)
+ observer->onStyleLoaded();
}
-std::string Style::Impl::getJSON() const {
+std::string StyleImpl::getJSON() const {
return json;
}
-std::string Style::Impl::getURL() const {
+std::string StyleImpl::getURL() const {
return url;
}
-void Style::Impl::setTransitionOptions(const TransitionOptions& options) {
+void StyleImpl::setTransitionOptions(const TransitionOptions& options) {
transitionOptions = options;
}
-TransitionOptions Style::Impl::getTransitionOptions() const {
+TransitionOptions StyleImpl::getTransitionOptions() const {
return transitionOptions;
}
-void Style::Impl::addSource(std::unique_ptr<Source> source) {
+void StyleImpl::addSource(std::unique_ptr<Source> source) {
if (sources.get(source->getID())) {
std::string msg = "Source " + source->getID() + " already exists";
throw std::runtime_error(msg.c_str());
@@ -159,7 +170,7 @@ void Style::Impl::addSource(std::unique_ptr<Source> source) {
}
}
-std::unique_ptr<Source> Style::Impl::removeSource(const std::string& id) {
+std::unique_ptr<Source> StyleImpl::removeSource(const std::string& id) {
// Check if source is in use
for (const auto& layer: layers) {
if (layer->getSourceID() == id) {
@@ -177,20 +188,20 @@ std::unique_ptr<Source> Style::Impl::removeSource(const std::string& id) {
return source;
}
-std::vector<Layer*> Style::Impl::getLayers() {
+std::vector<Layer*> StyleImpl::getLayers() {
return layers.getWrappers();
}
-std::vector<const Layer*> Style::Impl::getLayers() const {
+std::vector<const Layer*> StyleImpl::getLayers() const {
auto wrappers = layers.getWrappers();
return std::vector<const Layer*>(wrappers.begin(), wrappers.end());
}
-Layer* Style::Impl::getLayer(const std::string& id) const {
+Layer* StyleImpl::getLayer(const std::string& id) const {
return layers.get(id);
}
-Layer* Style::Impl::addLayer(std::unique_ptr<Layer> layer, optional<std::string> before) {
+Layer* StyleImpl::addLayer(std::unique_ptr<Layer> layer, optional<std::string> before) {
// TODO: verify source
if (Source* source = sources.get(layer->getSourceID())) {
if (!source->supportsLayerType(layer->baseImpl->getTypeInfo())) {
@@ -208,54 +219,56 @@ Layer* Style::Impl::addLayer(std::unique_ptr<Layer> layer, optional<std::string>
layer->setObserver(this);
Layer* result = layers.add(std::move(layer), before);
- observer->onUpdate();
+ for (auto &observer: observers)
+ observer->onUpdate();
return result;
}
-std::unique_ptr<Layer> Style::Impl::removeLayer(const std::string& id) {
+std::unique_ptr<Layer> StyleImpl::removeLayer(const std::string& id) {
std::unique_ptr<Layer> layer = layers.remove(id);
if (layer) {
layer->setObserver(nullptr);
- observer->onUpdate();
+ for (auto &observer: observers)
+ observer->onUpdate();
}
return layer;
}
-void Style::Impl::setLight(std::unique_ptr<Light> light_) {
+void StyleImpl::setLight(std::unique_ptr<Light> light_) {
light = std::move(light_);
light->setObserver(this);
onLightChanged(*light);
}
-Light* Style::Impl::getLight() const {
+Light* StyleImpl::getLight() const {
return light.get();
}
-std::string Style::Impl::getName() const {
+std::string StyleImpl::getName() const {
return name;
}
-CameraOptions Style::Impl::getDefaultCamera() const {
+CameraOptions StyleImpl::getDefaultCamera() const {
return defaultCamera;
}
-std::vector<Source*> Style::Impl::getSources() {
+std::vector<Source*> StyleImpl::getSources() {
return sources.getWrappers();
}
-std::vector<const Source*> Style::Impl::getSources() const {
+std::vector<const Source*> StyleImpl::getSources() const {
auto wrappers = sources.getWrappers();
return std::vector<const Source*>(wrappers.begin(), wrappers.end());
}
-Source* Style::Impl::getSource(const std::string& id) const {
+Source* StyleImpl::getSource(const std::string& id) const {
return sources.get(id);
}
-bool Style::Impl::isLoaded() const {
+bool StyleImpl::isLoaded() const {
if (!loaded) {
return false;
}
@@ -273,98 +286,116 @@ bool Style::Impl::isLoaded() const {
return true;
}
-void Style::Impl::addImage(std::unique_ptr<style::Image> image) {
+void StyleImpl::addImage(std::unique_ptr<style::Image> image) {
images.remove(image->getID()); // We permit using addImage to update.
images.add(std::move(image));
- observer->onUpdate();
+ for (auto &observer: observers)
+ observer->onUpdate();
}
-void Style::Impl::removeImage(const std::string& id) {
+void StyleImpl::removeImage(const std::string& id) {
images.remove(id);
}
-const style::Image* Style::Impl::getImage(const std::string& id) const {
+const style::Image* StyleImpl::getImage(const std::string& id) const {
return images.get(id);
}
-void Style::Impl::setObserver(style::Observer* observer_) {
- observer = observer_;
+void StyleImpl::addObserver(style::Observer* observer) {
+ observers.insert(observer);
+}
+
+void StyleImpl::removeObserver(Observer *observer)
+{
+ observers.erase(observer);
}
-void Style::Impl::onSourceLoaded(Source& source) {
+void StyleImpl::onSourceLoaded(Source& source) {
sources.update(source);
- observer->onSourceLoaded(source);
- observer->onUpdate();
+ for (auto &observer: observers)
+ observer->onSourceLoaded(source);
+ for (auto &observer: observers)
+ observer->onUpdate();
}
-void Style::Impl::onSourceChanged(Source& source) {
+void StyleImpl::onSourceChanged(Source& source) {
sources.update(source);
- observer->onSourceChanged(source);
- observer->onUpdate();
+ for (auto &observer: observers)
+ observer->onSourceChanged(source);
+ for (auto &observer: observers)
+ observer->onUpdate();
}
-void Style::Impl::onSourceError(Source& source, std::exception_ptr error) {
+void StyleImpl::onSourceError(Source& source, std::exception_ptr error) {
lastError = error;
Log::Error(Event::Style, "Failed to load source %s: %s",
source.getID().c_str(), util::toString(error).c_str());
- observer->onSourceError(source, error);
- observer->onResourceError(error);
+ for (auto &observer: observers)
+ observer->onSourceError(source, error);
+ for (auto &observer: observers)
+ observer->onResourceError(error);
}
-void Style::Impl::onSourceDescriptionChanged(Source& source) {
+void StyleImpl::onSourceDescriptionChanged(Source& source) {
sources.update(source);
- observer->onSourceDescriptionChanged(source);
+ for (auto &observer: observers)
+ observer->onSourceDescriptionChanged(source);
if (!source.loaded && fileSource) {
source.loadDescription(*fileSource);
}
}
-void Style::Impl::onSpriteLoaded(std::vector<std::unique_ptr<Image>>&& images_) {
+void StyleImpl::onSpriteLoaded(std::vector<std::unique_ptr<Image>>&& images_) {
for (auto& image : images_) {
addImage(std::move(image));
}
spriteLoaded = true;
- observer->onUpdate(); // For *-pattern properties.
+ for (auto &observer: observers)
+ observer->onUpdate(); // For *-pattern properties.
}
-void Style::Impl::onSpriteError(std::exception_ptr error) {
+void StyleImpl::onSpriteError(std::exception_ptr error) {
lastError = error;
Log::Error(Event::Style, "Failed to load sprite: %s", util::toString(error).c_str());
- observer->onResourceError(error);
+ for (auto &observer: observers)
+ observer->onResourceError(error);
// Unblock rendering tiles (even though sprite request has failed).
spriteLoaded = true;
- observer->onUpdate();
+ for (auto &observer: observers)
+ observer->onUpdate();
}
-void Style::Impl::onLayerChanged(Layer& layer) {
+void StyleImpl::onLayerChanged(Layer& layer) {
layers.update(layer);
- observer->onUpdate();
+ for (auto &observer: observers)
+ observer->onUpdate();
}
-void Style::Impl::onLightChanged(const Light&) {
- observer->onUpdate();
+void StyleImpl::onLightChanged(const Light&) {
+ for (auto &observer: observers)
+ observer->onUpdate();
}
-void Style::Impl::dumpDebugLogs() const {
+void StyleImpl::dumpDebugLogs() const {
Log::Info(Event::General, "styleURL: %s", url.c_str());
for (const auto& source : sources) {
source->dumpDebugLogs();
}
}
-const std::string& Style::Impl::getGlyphURL() const {
+const std::string& StyleImpl::getGlyphURL() const {
return glyphURL;
}
-Immutable<std::vector<Immutable<Image::Impl>>> Style::Impl::getImageImpls() const {
+Immutable<std::vector<Immutable<Image::Impl>>> StyleImpl::getImageImpls() const {
return images.getImpls();
}
-Immutable<std::vector<Immutable<Source::Impl>>> Style::Impl::getSourceImpls() const {
+Immutable<std::vector<Immutable<Source::Impl>>> StyleImpl::getSourceImpls() const {
return sources.getImpls();
}
-Immutable<std::vector<Immutable<Layer::Impl>>> Style::Impl::getLayerImpls() const {
+Immutable<std::vector<Immutable<Layer::Impl>>> StyleImpl::getLayerImpls() const {
return layers.getImpls();
}
diff --git a/src/mbgl/style/style_impl.hpp b/src/mbgl/style/style_impl.hpp
index ca165e24f..25e278ee8 100644
--- a/src/mbgl/style/style_impl.hpp
+++ b/src/mbgl/style/style_impl.hpp
@@ -11,6 +11,7 @@
#include <mbgl/style/source.hpp>
#include <mbgl/style/layer.hpp>
#include <mbgl/style/collection.hpp>
+#include <mbgl/annotation/annotation_manager.hpp>
#include <mbgl/map/camera.hpp>
@@ -22,6 +23,7 @@
#include <string>
#include <vector>
#include <unordered_map>
+#include <set>
namespace mbgl {
@@ -31,14 +33,14 @@ class SpriteLoader;
namespace style {
-class Style::Impl : public SpriteLoaderObserver,
+class StyleImpl : public SpriteLoaderObserver,
public SourceObserver,
public LayerObserver,
public LightObserver,
public util::noncopyable {
public:
- Impl(std::shared_ptr<FileSource>, float pixelRatio);
- ~Impl() override;
+ StyleImpl(std::shared_ptr<FileSource>, float pixelRatio);
+ ~StyleImpl() override;
void loadJSON(const std::string&);
void loadURL(const std::string&);
@@ -46,7 +48,8 @@ public:
std::string getJSON() const;
std::string getURL() const;
- void setObserver(Observer*);
+ void addObserver(Observer* observer);
+ void removeObserver(Observer* observer);
bool isLoaded() const;
@@ -90,15 +93,34 @@ public:
void dumpDebugLogs() const;
- bool mutated = false;
- bool loaded = false;
- bool spriteLoaded = false;
-
private:
void parse(const std::string&);
+ // SpriteLoaderObserver implementation.
+ void onSpriteLoaded(std::vector<std::unique_ptr<Image>>&&) override;
+ void onSpriteError(std::exception_ptr) override;
+
+ // SourceObserver implementation.
+ void onSourceLoaded(Source&) override;
+ void onSourceChanged(Source&) override;
+ void onSourceError(Source&, std::exception_ptr) override;
+ void onSourceDescriptionChanged(Source&) override;
+
+ // LayerObserver implementation.
+ void onLayerChanged(Layer&) override;
+
+ // LightObserver implementation.
+ void onLightChanged(const Light&) override;
+
+public:
+ bool mutated = false;
+ bool loaded = false;
+ bool spriteLoaded = false;
+ AnnotationManager annotationManager; // ToDo: move annotations into an own style, stackable inside the View (=Map), so that
+ // they can change independently of the rest of the style and be combined with different styles arbitrarily.
std::shared_ptr<FileSource> fileSource;
+private:
std::string url;
std::string json;
@@ -115,26 +137,7 @@ private:
// Defaults
std::string name;
CameraOptions defaultCamera;
-
- // SpriteLoaderObserver implementation.
- void onSpriteLoaded(std::vector<std::unique_ptr<Image>>&&) override;
- void onSpriteError(std::exception_ptr) override;
-
- // SourceObserver implementation.
- void onSourceLoaded(Source&) override;
- void onSourceChanged(Source&) override;
- void onSourceError(Source&, std::exception_ptr) override;
- void onSourceDescriptionChanged(Source&) override;
-
- // LayerObserver implementation.
- void onLayerChanged(Layer&) override;
-
- // LightObserver implementation.
- void onLightChanged(const Light&) override;
-
- Observer nullObserver;
- Observer* observer = &nullObserver;
-
+ std::set<Observer*> observers;
std::exception_ptr lastError;
};
diff --git a/test/style/source.test.cpp b/test/style/source.test.cpp
index 0286aaaec..1825cd08a 100644
--- a/test/style/source.test.cpp
+++ b/test/style/source.test.cpp
@@ -59,7 +59,7 @@ public:
Transform transform;
TransformState transformState;
Style style{fileSource, 1};
- AnnotationManager annotationManager { style };
+ AnnotationManager annotationManager { *style.impl };
ImageManager imageManager;
GlyphManager glyphManager;
diff --git a/test/style/style.test.cpp b/test/style/style.test.cpp
index c866431ac..c9fbd903a 100644
--- a/test/style/style.test.cpp
+++ b/test/style/style.test.cpp
@@ -19,7 +19,7 @@ TEST(Style, Properties) {
util::RunLoop loop;
auto fileSource = std::make_shared<StubFileSource>();
- Style::Impl style { fileSource, 1.0 };
+ StyleImpl style { fileSource, 1.0 };
style.loadJSON(R"STYLE({"name": "Test"})STYLE");
ASSERT_EQ("Test", style.getName());
@@ -61,7 +61,7 @@ TEST(Style, DuplicateSource) {
util::RunLoop loop;
auto fileSource = std::make_shared<StubFileSource>();
- Style::Impl style { fileSource, 1.0 };
+ StyleImpl style { fileSource, 1.0 };
style.loadJSON(util::read_file("test/fixtures/resources/style-unused-sources.json"));
@@ -82,7 +82,7 @@ TEST(Style, RemoveSourceInUse) {
Log::setObserver(std::unique_ptr<Log::Observer>(log));
auto fileSource = std::make_shared<StubFileSource>();
- Style::Impl style { fileSource, 1.0 };
+ StyleImpl style { fileSource, 1.0 };
style.loadJSON(util::read_file("test/fixtures/resources/style-unused-sources.json"));
@@ -107,7 +107,7 @@ TEST(Style, RemoveSourceInUse) {
TEST(Style, SourceImplsOrder) {
util::RunLoop loop;
auto fileSource = std::make_shared<StubFileSource>();
- Style::Impl style{fileSource, 1.0};
+ StyleImpl style{fileSource, 1.0};
style.addSource(std::make_unique<VectorSource>("c", "mapbox://mapbox.mapbox-terrain-v2"));
style.addSource(std::make_unique<VectorSource>("b", "mapbox://mapbox.mapbox-terrain-v2"));
diff --git a/test/style/style_layer.test.cpp b/test/style/style_layer.test.cpp
index 77e936ff3..f9ab804cf 100644
--- a/test/style/style_layer.test.cpp
+++ b/test/style/style_layer.test.cpp
@@ -284,7 +284,7 @@ TEST(Layer, DuplicateLayer) {
// Setup style
auto fileSource = std::make_shared<StubFileSource>();
- Style::Impl style { fileSource, 1.0 };
+ StyleImpl style { fileSource, 1.0 };
style.loadJSON(util::read_file("test/fixtures/resources/style-unused-sources.json"));
// Add initial layer
@@ -305,7 +305,7 @@ TEST(Layer, IncompatibleLayer) {
// Setup style
auto fileSource = std::make_shared<StubFileSource>();
- Style::Impl style{fileSource, 1.0};
+ StyleImpl style{fileSource, 1.0};
style.loadJSON(util::read_file("test/fixtures/resources/style-unused-sources.json"));
// Try to add duplicate
diff --git a/test/tile/custom_geometry_tile.test.cpp b/test/tile/custom_geometry_tile.test.cpp
index f3d11ab89..bbe0c738e 100644
--- a/test/tile/custom_geometry_tile.test.cpp
+++ b/test/tile/custom_geometry_tile.test.cpp
@@ -26,7 +26,7 @@ public:
TransformState transformState;
util::RunLoop loop;
style::Style style{fileSource, 1};
- AnnotationManager annotationManager { style };
+ AnnotationManager annotationManager { *style.impl };
ImageManager imageManager;
GlyphManager glyphManager;
diff --git a/test/tile/geojson_tile.test.cpp b/test/tile/geojson_tile.test.cpp
index 25fd268dc..ceaee4bb7 100644
--- a/test/tile/geojson_tile.test.cpp
+++ b/test/tile/geojson_tile.test.cpp
@@ -26,7 +26,7 @@ public:
TransformState transformState;
util::RunLoop loop;
style::Style style{fileSource, 1};
- AnnotationManager annotationManager { style };
+ AnnotationManager annotationManager { *style.impl };
ImageManager imageManager;
GlyphManager glyphManager;
Tileset tileset { { "https://example.com" }, { 0, 22 }, "none" };
diff --git a/test/tile/raster_dem_tile.test.cpp b/test/tile/raster_dem_tile.test.cpp
index f5f761009..faefaa53a 100644
--- a/test/tile/raster_dem_tile.test.cpp
+++ b/test/tile/raster_dem_tile.test.cpp
@@ -20,7 +20,7 @@ public:
TransformState transformState;
util::RunLoop loop;
style::Style style{fileSource, 1};
- AnnotationManager annotationManager { style };
+ AnnotationManager annotationManager { *style.impl };
ImageManager imageManager;
GlyphManager glyphManager;
Tileset tileset { { "https://example.com" }, { 0, 22 }, "none" };
diff --git a/test/tile/raster_tile.test.cpp b/test/tile/raster_tile.test.cpp
index a5a2875f2..4428ffc59 100644
--- a/test/tile/raster_tile.test.cpp
+++ b/test/tile/raster_tile.test.cpp
@@ -20,7 +20,7 @@ public:
TransformState transformState;
util::RunLoop loop;
style::Style style{fileSource, 1};
- AnnotationManager annotationManager { style };
+ AnnotationManager annotationManager { *style.impl };
ImageManager imageManager;
GlyphManager glyphManager;
Tileset tileset { { "https://example.com" }, { 0, 22 }, "none" };
diff --git a/test/tile/tile_cache.test.cpp b/test/tile/tile_cache.test.cpp
index 43b409ae8..5ff6888ed 100644
--- a/test/tile/tile_cache.test.cpp
+++ b/test/tile/tile_cache.test.cpp
@@ -29,7 +29,7 @@ public:
TransformState transformState;
util::RunLoop loop;
style::Style style{fileSource, 1};
- AnnotationManager annotationManager{style};
+ AnnotationManager annotationManager { *style.impl };
ImageManager imageManager;
GlyphManager glyphManager;
Tileset tileset{{"https://example.com"}, {0, 22}, "none"};
diff --git a/test/tile/vector_tile.test.cpp b/test/tile/vector_tile.test.cpp
index d282c874e..a31915498 100644
--- a/test/tile/vector_tile.test.cpp
+++ b/test/tile/vector_tile.test.cpp
@@ -26,7 +26,7 @@ public:
TransformState transformState;
util::RunLoop loop;
style::Style style{fileSource, 1};
- AnnotationManager annotationManager { style };
+ AnnotationManager annotationManager { *style.impl };
ImageManager imageManager;
GlyphManager glyphManager;
Tileset tileset { { "https://example.com" }, { 0, 22 }, "none" };