summaryrefslogtreecommitdiff
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)
downloadqtlocation-mapboxgl-upstream/galinelle_setStyle++.tar.gz
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 62bb39e8c2..0636b80f5f 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 83d6ad5bb4..1b39c3cbf3 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 b5dfea8e1a..a2b26aabff 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 6c794d7f84..86a378e98d 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 59b8133cf7..7c3e4265db 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 98f9921514..3c672dbffc 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 533a137a3d..a03dd13e6b 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 108787c422..0460428cf2 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 3e28221f7b..3c1ca760f5 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 061669f560..f48cd86680 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 bc2a37fe07..37e3ae9e6d 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 416662f9e5..4cb0b63890 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 8a821e5a5e..6649e2dd11 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 d5961b5901..13cd7bc4e1 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 ca165e24f0..25e278ee8a 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 0286aaaec3..1825cd08ae 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 c866431ac1..c9fbd903a5 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 77e936ff3b..f9ab804cf9 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 f3d11ab898..bbe0c738e1 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 25fd268dc8..ceaee4bb71 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 f5f7610096..faefaa53a4 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 a5a2875f2e..4428ffc594 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 43b409ae87..5ff6888ed1 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 d282c874ef..a31915498a 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" };