summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJohn Firebaugh <john.firebaugh@gmail.com>2017-04-21 13:35:34 -0700
committerJohn Firebaugh <john.firebaugh@gmail.com>2017-06-22 08:04:39 -0700
commit1520a56813f82bbe875774fdc2b3df26392278d6 (patch)
treed8f6ccc10e118bd2be6a954951c037f9c2fc1384 /src
parentbe7e9bbb8d54c775127f53d793c117c4bf5e2764 (diff)
downloadqtlocation-mapboxgl-1520a56813f82bbe875774fdc2b3df26392278d6.tar.gz
[all] Promote Style to public API
Diffstat (limited to 'src')
-rw-r--r--src/mbgl/annotation/annotation_manager.cpp7
-rw-r--r--src/mbgl/annotation/annotation_manager.hpp7
-rw-r--r--src/mbgl/annotation/fill_annotation_impl.cpp4
-rw-r--r--src/mbgl/annotation/fill_annotation_impl.hpp2
-rw-r--r--src/mbgl/annotation/line_annotation_impl.cpp4
-rw-r--r--src/mbgl/annotation/line_annotation_impl.hpp2
-rw-r--r--src/mbgl/annotation/shape_annotation_impl.hpp7
-rw-r--r--src/mbgl/map/map.cpp157
-rw-r--r--src/mbgl/renderer/update_parameters.hpp4
-rw-r--r--src/mbgl/style/style.cpp307
-rw-r--r--src/mbgl/style/style_impl.cpp321
-rw-r--r--src/mbgl/style/style_impl.hpp (renamed from src/mbgl/style/style.hpp)24
12 files changed, 449 insertions, 397 deletions
diff --git a/src/mbgl/annotation/annotation_manager.cpp b/src/mbgl/annotation/annotation_manager.cpp
index 58bda6052e..a69dba1bf2 100644
--- a/src/mbgl/annotation/annotation_manager.cpp
+++ b/src/mbgl/annotation/annotation_manager.cpp
@@ -4,7 +4,7 @@
#include <mbgl/annotation/symbol_annotation_impl.hpp>
#include <mbgl/annotation/line_annotation_impl.hpp>
#include <mbgl/annotation/fill_annotation_impl.hpp>
-#include <mbgl/style/style.hpp>
+#include <mbgl/style/style_impl.hpp>
#include <mbgl/style/layers/symbol_layer.hpp>
#include <mbgl/style/layers/symbol_layer_impl.hpp>
#include <mbgl/storage/file_source.hpp>
@@ -149,8 +149,9 @@ std::unique_ptr<AnnotationTileData> AnnotationManager::getTileData(const Canonic
return tileData;
}
-void AnnotationManager::updateStyle(Style& style) {
- // Create annotation source, point layer, and point bucket
+void AnnotationManager::updateStyle(Style::Impl& style) {
+ // 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.getSource(SourceID)) {
style.addSource(std::make_unique<AnnotationSource>());
diff --git a/src/mbgl/annotation/annotation_manager.hpp b/src/mbgl/annotation/annotation_manager.hpp
index c2ed5ba89f..6906791db7 100644
--- a/src/mbgl/annotation/annotation_manager.hpp
+++ b/src/mbgl/annotation/annotation_manager.hpp
@@ -4,6 +4,7 @@
#include <mbgl/annotation/symbol_annotation_impl.hpp>
#include <mbgl/style/image.hpp>
#include <mbgl/map/update.hpp>
+#include <mbgl/style/style.hpp>
#include <mbgl/util/noncopyable.hpp>
#include <mutex>
@@ -20,10 +21,6 @@ class AnnotationTileData;
class SymbolAnnotationImpl;
class ShapeAnnotationImpl;
-namespace style {
-class Style;
-} // namespace style
-
class AnnotationManager : private util::noncopyable {
public:
AnnotationManager();
@@ -37,7 +34,7 @@ public:
void removeImage(const std::string&);
double getTopOffsetPixelsForImage(const std::string&);
- void updateStyle(style::Style&);
+ void updateStyle(style::Style::Impl&);
void updateData();
void addTile(AnnotationTile&);
diff --git a/src/mbgl/annotation/fill_annotation_impl.cpp b/src/mbgl/annotation/fill_annotation_impl.cpp
index 484870c45c..5dc36edab0 100644
--- a/src/mbgl/annotation/fill_annotation_impl.cpp
+++ b/src/mbgl/annotation/fill_annotation_impl.cpp
@@ -1,6 +1,6 @@
#include <mbgl/annotation/fill_annotation_impl.hpp>
#include <mbgl/annotation/annotation_manager.hpp>
-#include <mbgl/style/style.hpp>
+#include <mbgl/style/style_impl.hpp>
#include <mbgl/style/layers/fill_layer.hpp>
namespace mbgl {
@@ -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& style) const {
+void FillAnnotationImpl::updateStyle(Style::Impl& 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 6376eee880..5c49e447b8 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, uint8_t maxZoom);
- void updateStyle(style::Style&) const final;
+ void updateStyle(style::Style::Impl&) 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 65379c42a8..8954ecfa58 100644
--- a/src/mbgl/annotation/line_annotation_impl.cpp
+++ b/src/mbgl/annotation/line_annotation_impl.cpp
@@ -1,6 +1,6 @@
#include <mbgl/annotation/line_annotation_impl.hpp>
#include <mbgl/annotation/annotation_manager.hpp>
-#include <mbgl/style/style.hpp>
+#include <mbgl/style/style_impl.hpp>
#include <mbgl/style/layers/line_layer.hpp>
namespace mbgl {
@@ -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& style) const {
+void LineAnnotationImpl::updateStyle(Style::Impl& 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 7945da5d97..548a094d53 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, uint8_t maxZoom);
- void updateStyle(style::Style&) const final;
+ void updateStyle(style::Style::Impl&) 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 800b4ec313..ed9e8d015a 100644
--- a/src/mbgl/annotation/shape_annotation_impl.hpp
+++ b/src/mbgl/annotation/shape_annotation_impl.hpp
@@ -4,6 +4,7 @@
#include <mbgl/annotation/annotation.hpp>
#include <mbgl/util/geometry.hpp>
+#include <mbgl/style/style.hpp>
#include <string>
#include <memory>
@@ -13,16 +14,12 @@ namespace mbgl {
class AnnotationTileData;
class CanonicalTileID;
-namespace style {
-class Style;
-} // namespace style
-
class ShapeAnnotationImpl {
public:
ShapeAnnotationImpl(const AnnotationID, const uint8_t maxZoom);
virtual ~ShapeAnnotationImpl() = default;
- virtual void updateStyle(style::Style&) const = 0;
+ virtual void updateStyle(style::Style::Impl&) 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 73a540a16a..3aed91cda4 100644
--- a/src/mbgl/map/map.cpp
+++ b/src/mbgl/map/map.cpp
@@ -6,12 +6,8 @@
#include <mbgl/map/transform.hpp>
#include <mbgl/map/transform_state.hpp>
#include <mbgl/annotation/annotation_manager.hpp>
-#include <mbgl/style/style.hpp>
-#include <mbgl/style/source.hpp>
-#include <mbgl/style/layer.hpp>
-#include <mbgl/style/light.hpp>
+#include <mbgl/style/style_impl.hpp>
#include <mbgl/style/observer.hpp>
-#include <mbgl/style/transition_options.hpp>
#include <mbgl/renderer/update_parameters.hpp>
#include <mbgl/renderer/painter.hpp>
#include <mbgl/renderer/render_source.hpp>
@@ -101,7 +97,6 @@ public:
std::string styleURL;
std::string styleJSON;
- bool styleMutated = false;
bool cameraMutated = false;
std::unique_ptr<AsyncRequest> styleRequest;
@@ -166,7 +161,7 @@ Map::Impl::Impl(Map& map_,
}
}) {
style = std::make_unique<Style>(scheduler, fileSource, pixelRatio);
- style->setObserver(this);
+ style->impl->setObserver(this);
}
Map::~Map() {
@@ -196,8 +191,8 @@ void Map::renderStill(View& view, StillImageCallback callback) {
return;
}
- if (impl->style->getLastError()) {
- callback(impl->style->getLastError());
+ if (impl->style->impl->getLastError()) {
+ callback(impl->style->impl->getLastError());
return;
}
@@ -228,8 +223,8 @@ void Map::Impl::render(View& view) {
transform.updateTransitions(timePoint);
- if (style->loaded && updateFlags & Update::AnnotationStyle) {
- annotationManager.updateStyle(*style);
+ if (style->impl->loaded && updateFlags & Update::AnnotationStyle) {
+ annotationManager.updateStyle(*style->impl);
}
if (updateFlags & Update::AnnotationData) {
@@ -251,19 +246,19 @@ void Map::Impl::render(View& view) {
debugOptions,
timePoint,
transform.getState(),
- style->getGlyphURL(),
- style->spriteLoaded,
+ style->impl->getGlyphURL(),
+ style->impl->spriteLoaded,
style->getTransitionOptions(),
style->getLight()->impl,
- style->getImageImpls(),
- style->getSourceImpls(),
- style->getLayerImpls(),
+ style->impl->getImageImpls(),
+ style->impl->getSourceImpls(),
+ style->impl->getLayerImpls(),
scheduler,
fileSource,
annotationManager
});
- bool loaded = style->isLoaded() && renderStyle->isLoaded();
+ bool loaded = style->impl->isLoaded() && renderStyle->isLoaded();
if (mode == MapMode::Continuous) {
if (renderState == RenderState::Never) {
@@ -334,24 +329,21 @@ void Map::setStyleURL(const std::string& url) {
}
impl->loading = true;
-
impl->observer.onWillStartLoadingMap();
impl->styleRequest = nullptr;
impl->styleURL = url;
impl->styleJSON.clear();
-
- impl->style->loaded = false;
- impl->styleMutated = false;
+ impl->style->impl->loaded = false;
impl->styleRequest = impl->fileSource.request(Resource::style(impl->styleURL), [this](Response res) {
// Once we get a fresh style, or the style is mutated, stop revalidating.
- if (res.isFresh() || impl->styleMutated) {
+ if (res.isFresh() || impl->style->impl->mutated) {
impl->styleRequest.reset();
}
// Don't allow a loaded, mutated style to be overwritten with a new version.
- if (impl->styleMutated && impl->style->loaded) {
+ if (impl->style->impl->mutated && impl->style->impl->loaded) {
return;
}
@@ -381,26 +373,25 @@ void Map::setStyleJSON(const std::string& json) {
}
impl->loading = true;
-
impl->observer.onWillStartLoadingMap();
impl->styleURL.clear();
impl->styleJSON.clear();
- impl->styleMutated = false;
+ impl->style->impl->mutated = false;
impl->loadStyleJSON(json);
}
void Map::Impl::loadStyleJSON(const std::string& json) {
- style->setJSON(json);
+ style->impl->setJSON(json);
styleJSON = json;
if (!cameraMutated) {
// Zoom first because it may constrain subsequent operations.
- map.setZoom(map.getDefaultZoom());
- map.setLatLng(map.getDefaultLatLng());
- map.setBearing(map.getDefaultBearing());
- map.setPitch(map.getDefaultPitch());
+ map.setZoom(style->getDefaultZoom());
+ map.setLatLng(style->getDefaultLatLng());
+ map.setBearing(style->getDefaultBearing());
+ map.setPitch(style->getDefaultPitch());
}
onUpdate(Update::AnnotationStyle);
@@ -414,6 +405,14 @@ std::string Map::getStyleJSON() const {
return impl->styleJSON;
}
+style::Style& Map::getStyle() {
+ return *impl->style;
+}
+
+const style::Style& Map::getStyle() const {
+ return *impl->style;
+}
+
#pragma mark - Transitions
void Map::cancelTransitions() {
@@ -872,92 +871,6 @@ AnnotationIDs Map::queryPointAnnotations(const ScreenBox& box) {
return ids;
}
-#pragma mark - Style API
-
-std::vector<style::Source*> Map::getSources() {
- return impl->style->getSources();
-}
-
-style::Source* Map::getSource(const std::string& sourceID) {
- impl->styleMutated = true;
- return impl->style->getSource(sourceID);
-}
-
-void Map::addSource(std::unique_ptr<style::Source> source) {
- impl->styleMutated = true;
- impl->style->addSource(std::move(source));
-}
-
-std::unique_ptr<Source> Map::removeSource(const std::string& sourceID) {
- impl->styleMutated = true;
- return impl->style->removeSource(sourceID);
-}
-
-std::vector<style::Layer*> Map::getLayers() {
- return impl->style->getLayers();
-}
-
-Layer* Map::getLayer(const std::string& layerID) {
- impl->styleMutated = true;
- return impl->style->getLayer(layerID);
-}
-
-void Map::addLayer(std::unique_ptr<Layer> layer, const optional<std::string>& before) {
- impl->styleMutated = true;
- impl->style->addLayer(std::move(layer), before);
- impl->onUpdate(Update::Repaint);
-}
-
-std::unique_ptr<Layer> Map::removeLayer(const std::string& id) {
- impl->styleMutated = true;
- impl->onUpdate(Update::Repaint);
- return impl->style->removeLayer(id);
-}
-
-void Map::addImage(std::unique_ptr<style::Image> image) {
- impl->styleMutated = true;
- impl->style->addImage(std::move(image));
-}
-
-void Map::removeImage(const std::string& id) {
- impl->styleMutated = true;
- impl->style->removeImage(id);
-}
-
-const style::Image* Map::getImage(const std::string& id) {
- return impl->style->getImage(id);
-}
-
-void Map::setLight(std::unique_ptr<style::Light> light) {
- impl->style->setLight(std::move(light));
-}
-
-style::Light* Map::getLight() {
- return impl->style->getLight();
-}
-
-#pragma mark - Defaults
-
-std::string Map::getStyleName() const {
- return impl->style->getName();
-}
-
-LatLng Map::getDefaultLatLng() const {
- return impl->style->getDefaultLatLng();
-}
-
-double Map::getDefaultZoom() const {
- return impl->style->getDefaultZoom();
-}
-
-double Map::getDefaultBearing() const {
- return impl->style->getDefaultBearing();
-}
-
-double Map::getDefaultPitch() const {
- return impl->style->getDefaultPitch();
-}
-
#pragma mark - Toggles
void Map::setDebug(MapDebugOptions debugOptions) {
@@ -994,15 +907,7 @@ MapDebugOptions Map::getDebug() const {
}
bool Map::isFullyLoaded() const {
- return impl->style && impl->style->isLoaded() && impl->renderStyle && impl->renderStyle->isLoaded();
-}
-
-style::TransitionOptions Map::getTransitionOptions() const {
- return impl->style->getTransitionOptions();
-}
-
-void Map::setTransitionOptions(const style::TransitionOptions& options) {
- impl->style->setTransitionOptions(options);
+ return impl->style->impl->isLoaded() && impl->renderStyle && impl->renderStyle->isLoaded();
}
void Map::setSourceTileCacheSize(size_t size) {
@@ -1056,7 +961,7 @@ void Map::Impl::onResourceError(std::exception_ptr error) {
void Map::dumpDebugLogs() const {
Log::Info(Event::General, "--------------------------------------------------------------------------------");
Log::Info(Event::General, "MapContext::styleURL: %s", impl->styleURL.c_str());
- impl->style->dumpDebugLogs();
+ impl->style->impl->dumpDebugLogs();
if (impl->renderStyle) {
impl->renderStyle->dumpDebugLogs();
}
diff --git a/src/mbgl/renderer/update_parameters.hpp b/src/mbgl/renderer/update_parameters.hpp
index 7c44064b0b..ce79a4f31b 100644
--- a/src/mbgl/renderer/update_parameters.hpp
+++ b/src/mbgl/renderer/update_parameters.hpp
@@ -3,6 +3,10 @@
#include <mbgl/map/mode.hpp>
#include <mbgl/map/transform_state.hpp>
#include <mbgl/util/chrono.hpp>
+#include <mbgl/style/light.hpp>
+#include <mbgl/style/image.hpp>
+#include <mbgl/style/source.hpp>
+#include <mbgl/style/layer.hpp>
namespace mbgl {
diff --git a/src/mbgl/style/style.cpp b/src/mbgl/style/style.cpp
index 41b4310dcf..f8dfd48b5c 100644
--- a/src/mbgl/style/style.cpp
+++ b/src/mbgl/style/style.cpp
@@ -1,308 +1,129 @@
#include <mbgl/style/style.hpp>
-#include <mbgl/style/observer.hpp>
-#include <mbgl/style/source_impl.hpp>
-#include <mbgl/style/layers/symbol_layer.hpp>
-#include <mbgl/style/layers/custom_layer.hpp>
-#include <mbgl/style/layers/background_layer.hpp>
-#include <mbgl/style/layers/fill_layer.hpp>
-#include <mbgl/style/layers/fill_extrusion_layer.hpp>
-#include <mbgl/style/layers/line_layer.hpp>
-#include <mbgl/style/layers/circle_layer.hpp>
-#include <mbgl/style/layers/raster_layer.hpp>
-#include <mbgl/style/layer_impl.hpp>
-#include <mbgl/style/parser.hpp>
-#include <mbgl/style/transition_options.hpp>
-#include <mbgl/sprite/sprite_loader.hpp>
-#include <mbgl/util/exception.hpp>
-#include <mbgl/util/string.hpp>
-#include <mbgl/util/logging.hpp>
+#include <mbgl/style/style_impl.hpp>
+#include <mbgl/style/light.hpp>
+#include <mbgl/style/image.hpp>
+#include <mbgl/style/source.hpp>
+#include <mbgl/style/layer.hpp>
namespace mbgl {
namespace style {
-static Observer nullObserver;
-
-Style::Style(Scheduler& scheduler_, FileSource& fileSource_, float pixelRatio)
- : scheduler(scheduler_),
- fileSource(fileSource_),
- spriteLoader(std::make_unique<SpriteLoader>(pixelRatio)),
- light(std::make_unique<Light>()),
- observer(&nullObserver) {
- spriteLoader->setObserver(this);
- light->setObserver(this);
+Style::Style(Scheduler& scheduler, FileSource& fileSource, float pixelRatio)
+ : impl(std::make_unique<Impl>(scheduler, fileSource, pixelRatio)) {
}
Style::~Style() = default;
-void Style::setTransitionOptions(const TransitionOptions& options) {
- transitionOptions = options;
-}
-
-TransitionOptions Style::getTransitionOptions() const {
- return transitionOptions;
-}
-
-void Style::setJSON(const std::string& json) {
- sources.clear();
- layers.clear();
- images.clear();
-
- transitionOptions = {};
- transitionOptions.duration = util::DEFAULT_TRANSITION_DURATION;
-
- Parser parser;
- auto error = parser.parse(json);
-
- if (error) {
- 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);
- return;
- }
-
- for (auto& source : parser.sources) {
- addSource(std::move(source));
- }
-
- for (auto& layer : parser.layers) {
- addLayer(std::move(layer));
- }
-
- name = parser.name;
- defaultLatLng = parser.latLng;
- defaultZoom = parser.zoom;
- defaultBearing = parser.bearing;
- defaultPitch = parser.pitch;
- setLight(std::make_unique<Light>(parser.light));
-
- spriteLoader->load(parser.spriteURL, scheduler, fileSource);
- glyphURL = parser.glyphURL;
-
- loaded = true;
-
- observer->onStyleLoaded();
-}
-
-void Style::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());
- }
-
- source->setObserver(this);
- source->loadDescription(fileSource);
-
- sources.add(std::move(source));
-}
-
-struct SourceIdUsageEvaluator {
- const std::string& sourceId;
-
- bool operator()(BackgroundLayer&) { return false; }
- bool operator()(CustomLayer&) { return false; }
-
- template <class LayerType>
- bool operator()(LayerType& layer) {
- return layer.getSourceID() == sourceId;
- }
-};
-
-std::unique_ptr<Source> Style::removeSource(const std::string& id) {
- // Check if source is in use
- SourceIdUsageEvaluator sourceIdEvaluator {id};
- auto layerIt = std::find_if(layers.begin(), layers.end(), [&](const auto& layer) {
- return layer->accept(sourceIdEvaluator);
- });
-
- if (layerIt != layers.end()) {
- Log::Warning(Event::General, "Source '%s' is in use, cannot remove", id.c_str());
- return nullptr;
- }
-
- std::unique_ptr<Source> source = sources.remove(id);
-
- if (source) {
- source->setObserver(nullptr);
- }
-
- return source;
-}
-
-std::vector<Layer*> Style::getLayers() {
- return layers.getWrappers();
-}
-
-Layer* Style::getLayer(const std::string& id) const {
- return layers.get(id);
-}
-
-Layer* Style::addLayer(std::unique_ptr<Layer> layer, optional<std::string> before) {
- // TODO: verify source
-
- if (layers.get(layer->getID())) {
- throw std::runtime_error(std::string{"Layer "} + layer->getID() + " already exists");
- }
-
- layer->setObserver(this);
-
- return layers.add(std::move(layer), before);
-}
-
-std::unique_ptr<Layer> Style::removeLayer(const std::string& id) {
- std::unique_ptr<Layer> layer = layers.remove(id);
-
- if (layer) {
- layer->setObserver(nullptr);
- }
-
- return layer;
-}
-
-void Style::setLight(std::unique_ptr<Light> light_) {
- light = std::move(light_);
- light->setObserver(this);
- onLightChanged(*light);
-}
-
-Light* Style::getLight() const {
- return light.get();
-}
-
std::string Style::getName() const {
- return name;
+ return impl->getName();
}
LatLng Style::getDefaultLatLng() const {
- return defaultLatLng;
+ return impl->getDefaultLatLng();
}
double Style::getDefaultZoom() const {
- return defaultZoom;
+ return impl->getDefaultZoom();
}
double Style::getDefaultBearing() const {
- return defaultBearing;
+ return impl->getDefaultBearing();
}
double Style::getDefaultPitch() const {
- return defaultPitch;
+ return impl->getDefaultPitch();
}
-std::vector<Source*> Style::getSources() {
- return sources.getWrappers();
+TransitionOptions Style::getTransitionOptions() const {
+ return impl->getTransitionOptions();
}
-Source* Style::getSource(const std::string& id) const {
- return sources.get(id);
+void Style::setTransitionOptions(const TransitionOptions& options) {
+ impl->mutated = true;
+ impl->setTransitionOptions(options);
}
-bool Style::isLoaded() const {
- if (!loaded) {
- return false;
- }
-
- if (!spriteLoaded) {
- return false;
- }
-
- for (const auto& source: sources) {
- if (!source->loaded) {
- return false;
- }
- }
-
- return true;
+void Style::setLight(std::unique_ptr<Light> light) {
+ impl->setLight(std::move(light));
}
-void Style::addImage(std::unique_ptr<style::Image> image) {
- images.remove(image->getID()); // We permit using addImage to update.
- images.add(std::move(image));
+Light* Style::getLight() {
+ impl->mutated = true;
+ return impl->getLight();
}
-void Style::removeImage(const std::string& id) {
- images.remove(id);
+const Light* Style::getLight() const {
+ return impl->getLight();
}
-const style::Image* Style::getImage(const std::string& id) const {
- return images.get(id);
+const Image* Style::getImage(const std::string& name) const {
+ return impl->getImage(name);
}
-void Style::setObserver(style::Observer* observer_) {
- observer = observer_;
+void Style::addImage(std::unique_ptr<Image> image) {
+ impl->mutated = true;
+ impl->addImage(std::move(image));
}
-void Style::onSourceLoaded(Source& source) {
- sources.update(source);
- observer->onSourceLoaded(source);
- observer->onUpdate(Update::Repaint);
+void Style::removeImage(const std::string& name) {
+ impl->mutated = true;
+ impl->removeImage(name);
}
-void Style::onSourceChanged(Source& source) {
- sources.update(source);
- observer->onSourceChanged(source);
- observer->onUpdate(Update::Repaint);
+std::vector<Source*> Style::getSources() {
+ impl->mutated = true;
+ return impl->getSources();
}
-void Style::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);
+std::vector<const Source*> Style::getSources() const {
+ return const_cast<const Impl&>(*impl).getSources();
}
-void Style::onSourceDescriptionChanged(Source& source) {
- sources.update(source);
- observer->onSourceDescriptionChanged(source);
- if (!source.loaded) {
- source.loadDescription(fileSource);
- }
+Source* Style::getSource(const std::string& id) {
+ impl->mutated = true;
+ return impl->getSource(id);
}
-void Style::onSpriteLoaded(std::vector<std::unique_ptr<Image>>&& images_) {
- for (auto& image : images_) {
- addImage(std::move(image));
- }
- spriteLoaded = true;
- observer->onUpdate(Update::Repaint); // For *-pattern properties.
+const Source* Style::getSource(const std::string& id) const {
+ return impl->getSource(id);
}
-void Style::onSpriteError(std::exception_ptr error) {
- lastError = error;
- Log::Error(Event::Style, "Failed to load sprite: %s", util::toString(error).c_str());
- observer->onResourceError(error);
+void Style::addSource(std::unique_ptr<Source> source) {
+ impl->mutated = true;
+ impl->addSource(std::move(source));
}
-void Style::onLayerChanged(Layer& layer) {
- layers.update(layer);
- observer->onUpdate(Update::Repaint);
+std::unique_ptr<Source> Style::removeSource(const std::string& sourceID) {
+ impl->mutated = true;
+ return impl->removeSource(sourceID);
}
-void Style::onLightChanged(const Light&) {
- observer->onUpdate(Update::Repaint);
+std::vector<Layer*> Style::getLayers() {
+ impl->mutated = true;
+ return impl->getLayers();
}
-void Style::dumpDebugLogs() const {
- for (const auto& source : sources) {
- source->dumpDebugLogs();
- }
+std::vector<const Layer*> Style::getLayers() const {
+ return const_cast<const Impl&>(*impl).getLayers();
}
-const std::string& Style::getGlyphURL() const {
- return glyphURL;
+Layer* Style::getLayer(const std::string& layerID) {
+ impl->mutated = true;
+ return impl->getLayer(layerID);
}
-Immutable<std::vector<Immutable<Image::Impl>>> Style::getImageImpls() const {
- return images.getImpls();
+const Layer* Style::getLayer(const std::string& layerID) const {
+ return impl->getLayer(layerID);
}
-Immutable<std::vector<Immutable<Source::Impl>>> Style::getSourceImpls() const {
- return sources.getImpls();
+void Style::addLayer(std::unique_ptr<Layer> layer, const optional<std::string>& before) {
+ impl->mutated = true;
+ impl->addLayer(std::move(layer), before);
}
-Immutable<std::vector<Immutable<Layer::Impl>>> Style::getLayerImpls() const {
- return layers.getImpls();
+std::unique_ptr<Layer> Style::removeLayer(const std::string& id) {
+ impl->mutated = true;
+ return impl->removeLayer(id);
}
} // namespace style
diff --git a/src/mbgl/style/style_impl.cpp b/src/mbgl/style/style_impl.cpp
new file mode 100644
index 0000000000..7235226f84
--- /dev/null
+++ b/src/mbgl/style/style_impl.cpp
@@ -0,0 +1,321 @@
+#include <mbgl/style/style_impl.hpp>
+#include <mbgl/style/observer.hpp>
+#include <mbgl/style/source_impl.hpp>
+#include <mbgl/style/layers/symbol_layer.hpp>
+#include <mbgl/style/layers/custom_layer.hpp>
+#include <mbgl/style/layers/background_layer.hpp>
+#include <mbgl/style/layers/fill_layer.hpp>
+#include <mbgl/style/layers/fill_extrusion_layer.hpp>
+#include <mbgl/style/layers/line_layer.hpp>
+#include <mbgl/style/layers/circle_layer.hpp>
+#include <mbgl/style/layers/raster_layer.hpp>
+#include <mbgl/style/layer_impl.hpp>
+#include <mbgl/style/parser.hpp>
+#include <mbgl/style/transition_options.hpp>
+#include <mbgl/sprite/sprite_loader.hpp>
+#include <mbgl/util/exception.hpp>
+#include <mbgl/util/string.hpp>
+#include <mbgl/util/logging.hpp>
+
+namespace mbgl {
+namespace style {
+
+static Observer nullObserver;
+
+Style::Impl::Impl(Scheduler& scheduler_, FileSource& fileSource_, float pixelRatio)
+ : scheduler(scheduler_),
+ fileSource(fileSource_),
+ spriteLoader(std::make_unique<SpriteLoader>(pixelRatio)),
+ light(std::make_unique<Light>()),
+ observer(&nullObserver) {
+ spriteLoader->setObserver(this);
+ light->setObserver(this);
+}
+
+Style::Impl::~Impl() = default;
+
+void Style::Impl::setTransitionOptions(const TransitionOptions& options) {
+ transitionOptions = options;
+}
+
+TransitionOptions Style::Impl::getTransitionOptions() const {
+ return transitionOptions;
+}
+
+void Style::Impl::setJSON(const std::string& json) {
+ sources.clear();
+ layers.clear();
+ images.clear();
+
+ transitionOptions = {};
+ transitionOptions.duration = util::DEFAULT_TRANSITION_DURATION;
+
+ Parser parser;
+ auto error = parser.parse(json);
+
+ if (error) {
+ 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);
+ return;
+ }
+
+ for (auto& source : parser.sources) {
+ addSource(std::move(source));
+ }
+
+ for (auto& layer : parser.layers) {
+ addLayer(std::move(layer));
+ }
+
+ name = parser.name;
+ defaultLatLng = parser.latLng;
+ defaultZoom = parser.zoom;
+ defaultBearing = parser.bearing;
+ defaultPitch = parser.pitch;
+ setLight(std::make_unique<Light>(parser.light));
+
+ spriteLoader->load(parser.spriteURL, scheduler, fileSource);
+ glyphURL = parser.glyphURL;
+
+ loaded = true;
+
+ observer->onStyleLoaded();
+}
+
+void Style::Impl::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());
+ }
+
+ source->setObserver(this);
+ source->loadDescription(fileSource);
+
+ sources.add(std::move(source));
+}
+
+struct SourceIdUsageEvaluator {
+ const std::string& sourceId;
+
+ bool operator()(BackgroundLayer&) { return false; }
+ bool operator()(CustomLayer&) { return false; }
+
+ template <class LayerType>
+ bool operator()(LayerType& layer) {
+ return layer.getSourceID() == sourceId;
+ }
+};
+
+std::unique_ptr<Source> Style::Impl::removeSource(const std::string& id) {
+ // Check if source is in use
+ SourceIdUsageEvaluator sourceIdEvaluator {id};
+ auto layerIt = std::find_if(layers.begin(), layers.end(), [&](const auto& layer) {
+ return layer->accept(sourceIdEvaluator);
+ });
+
+ if (layerIt != layers.end()) {
+ Log::Warning(Event::General, "Source '%s' is in use, cannot remove", id.c_str());
+ return nullptr;
+ }
+
+ std::unique_ptr<Source> source = sources.remove(id);
+
+ if (source) {
+ source->setObserver(nullptr);
+ }
+
+ return source;
+}
+
+std::vector<Layer*> Style::Impl::getLayers() {
+ return layers.getWrappers();
+}
+
+std::vector<const Layer*> Style::Impl::getLayers() const {
+ auto wrappers = layers.getWrappers();
+ return std::vector<const Layer*>(wrappers.begin(), wrappers.end());
+}
+
+Layer* Style::Impl::getLayer(const std::string& id) const {
+ return layers.get(id);
+}
+
+Layer* Style::Impl::addLayer(std::unique_ptr<Layer> layer, optional<std::string> before) {
+ // TODO: verify source
+
+ if (layers.get(layer->getID())) {
+ throw std::runtime_error(std::string{"Layer "} + layer->getID() + " already exists");
+ }
+
+ layer->setObserver(this);
+ observer->onUpdate(Update::Repaint);
+
+ return layers.add(std::move(layer), before);
+}
+
+std::unique_ptr<Layer> Style::Impl::removeLayer(const std::string& id) {
+ std::unique_ptr<Layer> layer = layers.remove(id);
+
+ if (layer) {
+ layer->setObserver(nullptr);
+ observer->onUpdate(Update::Repaint);
+ }
+
+ return layer;
+}
+
+void Style::Impl::setLight(std::unique_ptr<Light> light_) {
+ light = std::move(light_);
+ light->setObserver(this);
+ onLightChanged(*light);
+}
+
+Light* Style::Impl::getLight() const {
+ return light.get();
+}
+
+std::string Style::Impl::getName() const {
+ return name;
+}
+
+LatLng Style::Impl::getDefaultLatLng() const {
+ return defaultLatLng;
+}
+
+double Style::Impl::getDefaultZoom() const {
+ return defaultZoom;
+}
+
+double Style::Impl::getDefaultBearing() const {
+ return defaultBearing;
+}
+
+double Style::Impl::getDefaultPitch() const {
+ return defaultPitch;
+}
+
+std::vector<Source*> Style::Impl::getSources() {
+ return sources.getWrappers();
+}
+
+std::vector<const Source*> Style::Impl::getSources() const {
+ auto wrappers = sources.getWrappers();
+ return std::vector<const Source*>(wrappers.begin(), wrappers.end());
+}
+
+Source* Style::Impl::getSource(const std::string& id) const {
+ return sources.get(id);
+}
+
+bool Style::Impl::isLoaded() const {
+ if (!loaded) {
+ return false;
+ }
+
+ if (!spriteLoaded) {
+ return false;
+ }
+
+ for (const auto& source: sources) {
+ if (!source->loaded) {
+ return false;
+ }
+ }
+
+ return true;
+}
+
+void Style::Impl::addImage(std::unique_ptr<style::Image> image) {
+ images.remove(image->getID()); // We permit using addImage to update.
+ images.add(std::move(image));
+}
+
+void Style::Impl::removeImage(const std::string& id) {
+ images.remove(id);
+}
+
+const style::Image* Style::Impl::getImage(const std::string& id) const {
+ return images.get(id);
+}
+
+void Style::Impl::setObserver(style::Observer* observer_) {
+ observer = observer_;
+}
+
+void Style::Impl::onSourceLoaded(Source& source) {
+ sources.update(source);
+ observer->onSourceLoaded(source);
+ observer->onUpdate(Update::Repaint);
+}
+
+void Style::Impl::onSourceChanged(Source& source) {
+ sources.update(source);
+ observer->onSourceChanged(source);
+ observer->onUpdate(Update::Repaint);
+}
+
+void Style::Impl::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);
+}
+
+void Style::Impl::onSourceDescriptionChanged(Source& source) {
+ sources.update(source);
+ observer->onSourceDescriptionChanged(source);
+ if (!source.loaded) {
+ source.loadDescription(fileSource);
+ }
+}
+
+void Style::Impl::onSpriteLoaded(std::vector<std::unique_ptr<Image>>&& images_) {
+ for (auto& image : images_) {
+ addImage(std::move(image));
+ }
+ spriteLoaded = true;
+ observer->onUpdate(Update::Repaint); // For *-pattern properties.
+}
+
+void Style::Impl::onSpriteError(std::exception_ptr error) {
+ lastError = error;
+ Log::Error(Event::Style, "Failed to load sprite: %s", util::toString(error).c_str());
+ observer->onResourceError(error);
+}
+
+void Style::Impl::onLayerChanged(Layer& layer) {
+ layers.update(layer);
+ observer->onUpdate(Update::Repaint);
+}
+
+void Style::Impl::onLightChanged(const Light&) {
+ observer->onUpdate(Update::Repaint);
+}
+
+void Style::Impl::dumpDebugLogs() const {
+ for (const auto& source : sources) {
+ source->dumpDebugLogs();
+ }
+}
+
+const std::string& Style::Impl::getGlyphURL() const {
+ return glyphURL;
+}
+
+Immutable<std::vector<Immutable<Image::Impl>>> Style::Impl::getImageImpls() const {
+ return images.getImpls();
+}
+
+Immutable<std::vector<Immutable<Source::Impl>>> Style::Impl::getSourceImpls() const {
+ return sources.getImpls();
+}
+
+Immutable<std::vector<Immutable<Layer::Impl>>> Style::Impl::getLayerImpls() const {
+ return layers.getImpls();
+}
+
+} // namespace style
+} // namespace mbgl
diff --git a/src/mbgl/style/style.hpp b/src/mbgl/style/style_impl.hpp
index 7e8f6f640b..2bdb51a26c 100644
--- a/src/mbgl/style/style.hpp
+++ b/src/mbgl/style/style_impl.hpp
@@ -1,5 +1,6 @@
#pragma once
+#include <mbgl/style/style.hpp>
#include <mbgl/style/transition_options.hpp>
#include <mbgl/style/observer.hpp>
#include <mbgl/style/source_observer.hpp>
@@ -28,14 +29,14 @@ class SpriteLoader;
namespace style {
-class Style : public SpriteLoaderObserver,
- public SourceObserver,
- public LayerObserver,
- public LightObserver,
- public util::noncopyable {
+class Style::Impl : public SpriteLoaderObserver,
+ public SourceObserver,
+ public LayerObserver,
+ public LightObserver,
+ public util::noncopyable {
public:
- Style(Scheduler&, FileSource&, float pixelRatio);
- ~Style() override;
+ Impl(Scheduler&, FileSource&, float pixelRatio);
+ ~Impl() override;
void setJSON(const std::string&);
@@ -47,13 +48,17 @@ public:
return lastError;
}
- std::vector<Source*> getSources();
+ std::vector< Source*> getSources();
+ std::vector<const Source*> getSources() const;
Source* getSource(const std::string& id) const;
+
void addSource(std::unique_ptr<Source>);
std::unique_ptr<Source> removeSource(const std::string& sourceID);
- std::vector<Layer*> getLayers();
+ std::vector< Layer*> getLayers();
+ std::vector<const Layer*> getLayers() const;
Layer* getLayer(const std::string& id) const;
+
Layer* addLayer(std::unique_ptr<Layer>,
optional<std::string> beforeLayerID = {});
std::unique_ptr<Layer> removeLayer(const std::string& layerID);
@@ -82,6 +87,7 @@ public:
void dumpDebugLogs() const;
+ bool mutated = false;
bool loaded = false;
bool spriteLoaded = false;