summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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.hpp25
-rw-r--r--test/style/source.test.cpp2
-rw-r--r--test/style/style.test.cpp12
-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, 228 insertions, 155 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 c5e8d7f156..e8d02e41b0 100644
--- a/include/mbgl/style/style.hpp
+++ b/include/mbgl/style/style.hpp
@@ -13,16 +13,19 @@
namespace mbgl {
class FileSource;
+class ResourceOptions;
namespace style {
class Light;
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&);
@@ -71,8 +74,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 af18720916..bdb6848794 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)) observer.onStyleImageMissing(id);
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 902cc1687c..0c3f42c6ec 100644
--- a/src/mbgl/style/style.cpp
+++ b/src/mbgl/style/style.cpp
@@ -1,6 +1,8 @@
#include <mbgl/style/image.hpp>
#include <mbgl/style/image_impl.hpp>
#include <mbgl/style/layer.hpp>
+#include <mbgl/storage/file_source_manager.hpp>
+#include <mbgl/storage/resource_options.hpp>
#include <mbgl/style/light.hpp>
#include <mbgl/style/source.hpp>
#include <mbgl/style/style.hpp>
@@ -10,7 +12,11 @@ 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;
@@ -82,7 +88,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) {
@@ -110,7 +116,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 59cb57aca6..1fe18ee260 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,7 +286,7 @@ 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) {
auto newImages = makeMutable<ImageImpls>(*images);
auto it =
std::lower_bound(newImages->begin(), newImages->end(), image->getID(), [](const auto& a, const std::string& b) {
@@ -286,10 +299,11 @@ void Style::Impl::addImage(std::unique_ptr<style::Image> image) {
newImages->insert(it, std::move(image->baseImpl));
}
images = std::move(newImages);
- observer->onUpdate();
+ for (auto &observer: observers)
+ observer->onUpdate();
}
-void Style::Impl::removeImage(const std::string& id) {
+void StyleImpl::removeImage(const std::string& id) {
auto newImages = makeMutable<ImageImpls>(*images);
auto found =
std::find_if(newImages->begin(), newImages->end(), [&id](const auto& image) { return image->id == id; });
@@ -301,92 +315,109 @@ void Style::Impl::removeImage(const std::string& id) {
images = std::move(newImages);
}
-optional<Immutable<style::Image::Impl>> Style::Impl::getImage(const std::string& id) const {
+optional<Immutable<style::Image::Impl>> StyleImpl::getImage(const std::string& id) const {
auto found = std::find_if(images->begin(), images->end(), [&id](const auto& image) { return image->id == id; });
if (found == images->end()) return nullopt;
return *found;
}
-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<Immutable<style::Image::Impl>> images_) {
+void StyleImpl::onSpriteLoaded(std::vector<Immutable<style::Image::Impl>> images_) {
auto newImages = makeMutable<ImageImpls>(*images);
newImages->insert(
newImages->end(), std::make_move_iterator(images_.begin()), std::make_move_iterator(images_.end()));
std::sort(newImages->begin(), newImages->end(), [](const auto& a, const auto& b) { return a->id < b->id; });
images = std::move(newImages);
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;
}
-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 c16b82e90b..b0eaf82786 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;
@@ -91,15 +94,17 @@ public:
void dumpDebugLogs() const;
+private:
+ void parse(const std::string&);
+public:
bool mutated = false;
bool loaded = false;
bool spriteLoaded = false;
-
-private:
- void parse(const std::string&);
-
+ 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;
@@ -116,6 +121,7 @@ private:
// Defaults
std::string name;
CameraOptions defaultCamera;
+ std::set<Observer*> observers;
// SpriteLoaderObserver implementation.
void onSpriteLoaded(std::vector<Immutable<style::Image::Impl>>) override;
@@ -133,9 +139,6 @@ private:
// LightObserver implementation.
void onLightChanged(const Light&) override;
- Observer nullObserver;
- Observer* observer = &nullObserver;
-
std::exception_ptr lastError;
};
diff --git a/test/style/source.test.cpp b/test/style/source.test.cpp
index dbc67681e9..15772902bf 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 2c9cdb5792..d968998165 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"));
@@ -129,7 +129,7 @@ TEST(Style, SourceImplsOrder) {
TEST(Style, AddRemoveImage) {
util::RunLoop loop;
auto fileSource = std::make_shared<StubFileSource>();
- Style::Impl style{fileSource, 1.0};
+ StyleImpl style{fileSource, 1.0};
style.addImage(std::make_unique<style::Image>("one", PremultipliedImage({16, 16}), 2));
style.addImage(std::make_unique<style::Image>("two", PremultipliedImage({16, 16}), 2));
style.addImage(std::make_unique<style::Image>("three", PremultipliedImage({16, 16}), 2));
@@ -140,4 +140,4 @@ TEST(Style, AddRemoveImage) {
EXPECT_TRUE(!!style.getImage("three"));
EXPECT_FALSE(!!style.getImage("two"));
EXPECT_FALSE(!!style.getImage("four"));
-} \ No newline at end of file
+}
diff --git a/test/style/style_layer.test.cpp b/test/style/style_layer.test.cpp
index 33573636d7..73179250fa 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 6e8a7e6981..783dbfcddf 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 b89a572f7f..7bf5dae267 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" };