summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Firebaugh <john.firebaugh@gmail.com>2017-04-25 18:20:26 -0700
committerJohn Firebaugh <john.firebaugh@gmail.com>2017-05-12 11:26:27 -0700
commitc2a5894f2dbe9982830066ab9347b059e6e7d845 (patch)
treec09363c2025b80265de195969ee56cc64e567e70
parentd3f23b83d42de8ef23ea1dbd8abfc6276009531f (diff)
downloadqtlocation-mapboxgl-c2a5894f2dbe9982830066ab9347b059e6e7d845.tar.gz
[core] Immutable Impls
-rw-r--r--cmake/core-files.cmake6
-rw-r--r--include/mbgl/style/layer.hpp31
-rw-r--r--include/mbgl/style/layers/background_layer.hpp16
-rw-r--r--include/mbgl/style/layers/circle_layer.hpp16
-rw-r--r--include/mbgl/style/layers/custom_layer.hpp13
-rw-r--r--include/mbgl/style/layers/fill_extrusion_layer.hpp16
-rw-r--r--include/mbgl/style/layers/fill_layer.hpp16
-rw-r--r--include/mbgl/style/layers/layer.hpp.ejs16
-rw-r--r--include/mbgl/style/layers/line_layer.hpp16
-rw-r--r--include/mbgl/style/layers/raster_layer.hpp16
-rw-r--r--include/mbgl/style/layers/symbol_layer.hpp16
-rw-r--r--include/mbgl/style/light.hpp16
-rw-r--r--include/mbgl/style/light.hpp.ejs16
-rw-r--r--include/mbgl/style/source.hpp29
-rw-r--r--include/mbgl/style/sources/geojson_source.hpp16
-rw-r--r--include/mbgl/style/sources/raster_source.hpp17
-rw-r--r--include/mbgl/style/sources/vector_source.hpp17
-rw-r--r--include/mbgl/util/immutable.hpp127
-rw-r--r--include/mbgl/util/tileset.hpp5
m---------mapbox-gl-js0
-rw-r--r--platform/default/mbgl/storage/offline_download.cpp57
-rw-r--r--src/mbgl/annotation/annotation_source.cpp14
-rw-r--r--src/mbgl/annotation/annotation_source.hpp10
-rw-r--r--src/mbgl/annotation/render_annotation_source.cpp6
-rw-r--r--src/mbgl/annotation/render_annotation_source.hpp4
-rw-r--r--src/mbgl/geometry/feature_index.cpp2
-rw-r--r--src/mbgl/layout/symbol_layout.cpp6
-rw-r--r--src/mbgl/map/map.cpp4
-rw-r--r--src/mbgl/map/update.hpp1
-rw-r--r--src/mbgl/renderer/group_by_layout.cpp14
-rw-r--r--src/mbgl/renderer/painter.cpp16
-rw-r--r--src/mbgl/renderer/render_background_layer.cpp11
-rw-r--r--src/mbgl/renderer/render_background_layer.hpp5
-rw-r--r--src/mbgl/renderer/render_circle_layer.cpp11
-rw-r--r--src/mbgl/renderer/render_circle_layer.hpp5
-rw-r--r--src/mbgl/renderer/render_custom_layer.cpp9
-rw-r--r--src/mbgl/renderer/render_custom_layer.hpp5
-rw-r--r--src/mbgl/renderer/render_fill_extrusion_layer.cpp11
-rw-r--r--src/mbgl/renderer/render_fill_extrusion_layer.hpp5
-rw-r--r--src/mbgl/renderer/render_fill_layer.cpp11
-rw-r--r--src/mbgl/renderer/render_fill_layer.hpp5
-rw-r--r--src/mbgl/renderer/render_layer.cpp17
-rw-r--r--src/mbgl/renderer/render_layer.hpp9
-rw-r--r--src/mbgl/renderer/render_light.cpp13
-rw-r--r--src/mbgl/renderer/render_light.hpp12
-rw-r--r--src/mbgl/renderer/render_line_layer.cpp13
-rw-r--r--src/mbgl/renderer/render_line_layer.hpp6
-rw-r--r--src/mbgl/renderer/render_raster_layer.cpp11
-rw-r--r--src/mbgl/renderer/render_raster_layer.hpp5
-rw-r--r--src/mbgl/renderer/render_source.cpp6
-rw-r--r--src/mbgl/renderer/render_source.hpp6
-rw-r--r--src/mbgl/renderer/render_symbol_layer.cpp11
-rw-r--r--src/mbgl/renderer/render_symbol_layer.hpp4
-rw-r--r--src/mbgl/renderer/sources/render_geojson_source.cpp15
-rw-r--r--src/mbgl/renderer/sources/render_geojson_source.hpp5
-rw-r--r--src/mbgl/renderer/sources/render_raster_source.cpp13
-rw-r--r--src/mbgl/renderer/sources/render_raster_source.hpp5
-rw-r--r--src/mbgl/renderer/sources/render_vector_source.cpp13
-rw-r--r--src/mbgl/renderer/sources/render_vector_source.hpp5
-rw-r--r--src/mbgl/renderer/style_diff.cpp56
-rw-r--r--src/mbgl/renderer/style_diff.hpp30
-rw-r--r--src/mbgl/style/layer.cpp28
-rw-r--r--src/mbgl/style/layer_impl.cpp6
-rw-r--r--src/mbgl/style/layer_impl.hpp21
-rw-r--r--src/mbgl/style/layers/background_layer.cpp95
-rw-r--r--src/mbgl/style/layers/background_layer_impl.cpp2
-rw-r--r--src/mbgl/style/layers/background_layer_impl.hpp4
-rw-r--r--src/mbgl/style/layers/circle_layer.cpp224
-rw-r--r--src/mbgl/style/layers/circle_layer_impl.cpp2
-rw-r--r--src/mbgl/style/layers/circle_layer_impl.hpp4
-rw-r--r--src/mbgl/style/layers/custom_layer.cpp49
-rw-r--r--src/mbgl/style/layers/custom_layer_impl.cpp28
-rw-r--r--src/mbgl/style/layers/custom_layer_impl.hpp9
-rw-r--r--src/mbgl/style/layers/fill_extrusion_layer.cpp174
-rw-r--r--src/mbgl/style/layers/fill_extrusion_layer_impl.cpp2
-rw-r--r--src/mbgl/style/layers/fill_extrusion_layer_impl.hpp4
-rw-r--r--src/mbgl/style/layers/fill_layer.cpp174
-rw-r--r--src/mbgl/style/layers/fill_layer_impl.cpp2
-rw-r--r--src/mbgl/style/layers/fill_layer_impl.hpp4
-rw-r--r--src/mbgl/style/layers/layer.cpp.ejs100
-rw-r--r--src/mbgl/style/layers/line_layer.cpp252
-rw-r--r--src/mbgl/style/layers/line_layer_impl.cpp2
-rw-r--r--src/mbgl/style/layers/line_layer_impl.hpp4
-rw-r--r--src/mbgl/style/layers/raster_layer.cpp154
-rw-r--r--src/mbgl/style/layers/raster_layer_impl.cpp2
-rw-r--r--src/mbgl/style/layers/raster_layer_impl.hpp4
-rw-r--r--src/mbgl/style/layers/symbol_layer.cpp558
-rw-r--r--src/mbgl/style/layers/symbol_layer_impl.cpp2
-rw-r--r--src/mbgl/style/layers/symbol_layer_impl.hpp5
-rw-r--r--src/mbgl/style/light.cpp62
-rw-r--r--src/mbgl/style/light.cpp.ejs26
-rw-r--r--src/mbgl/style/light_impl.cpp4
-rw-r--r--src/mbgl/style/light_impl.hpp7
-rw-r--r--src/mbgl/style/light_observer.hpp4
-rw-r--r--src/mbgl/style/parser.cpp2
-rw-r--r--src/mbgl/style/source.cpp22
-rw-r--r--src/mbgl/style/source_impl.cpp19
-rw-r--r--src/mbgl/style/source_impl.hpp21
-rw-r--r--src/mbgl/style/sources/geojson_source.cpp69
-rw-r--r--src/mbgl/style/sources/geojson_source_impl.cpp87
-rw-r--r--src/mbgl/style/sources/geojson_source_impl.hpp15
-rw-r--r--src/mbgl/style/sources/raster_source.cpp74
-rw-r--r--src/mbgl/style/sources/raster_source_impl.cpp30
-rw-r--r--src/mbgl/style/sources/raster_source_impl.hpp15
-rw-r--r--src/mbgl/style/sources/vector_source.cpp71
-rw-r--r--src/mbgl/style/sources/vector_source_impl.cpp23
-rw-r--r--src/mbgl/style/sources/vector_source_impl.hpp13
-rw-r--r--src/mbgl/style/style.cpp277
-rw-r--r--src/mbgl/style/style.hpp22
-rw-r--r--src/mbgl/style/tile_source_impl.cpp78
-rw-r--r--src/mbgl/style/tile_source_impl.hpp47
-rw-r--r--src/mbgl/tile/geometry_tile.cpp14
-rw-r--r--src/mbgl/tile/geometry_tile.hpp2
-rw-r--r--src/mbgl/tile/geometry_tile_worker.cpp16
-rw-r--r--src/mbgl/tile/geometry_tile_worker.hpp6
-rw-r--r--src/mbgl/tile/raster_tile.cpp2
-rw-r--r--src/mbgl/tile/raster_tile.hpp2
-rw-r--r--src/mbgl/tile/tile.hpp7
-rw-r--r--src/mbgl/util/longest_common_subsequence.hpp106
-rw-r--r--test/style/conversion/layer.test.cpp8
-rw-r--r--test/style/source.test.cpp96
-rw-r--r--test/style/style_layer.test.cpp21
-rw-r--r--test/tile/geojson_tile.test.cpp2
-rw-r--r--test/tile/vector_tile.test.cpp2
124 files changed, 2590 insertions, 1485 deletions
diff --git a/cmake/core-files.cmake b/cmake/core-files.cmake
index 5383f0ed7b..f83a0413b9 100644
--- a/cmake/core-files.cmake
+++ b/cmake/core-files.cmake
@@ -224,6 +224,8 @@ set(MBGL_CORE_FILES
src/mbgl/renderer/render_symbol_layer.hpp
src/mbgl/renderer/render_tile.cpp
src/mbgl/renderer/render_tile.hpp
+ src/mbgl/renderer/style_diff.cpp
+ src/mbgl/renderer/style_diff.hpp
src/mbgl/renderer/symbol_bucket.cpp
src/mbgl/renderer/symbol_bucket.hpp
src/mbgl/renderer/tile_parameters.hpp
@@ -341,8 +343,6 @@ set(MBGL_CORE_FILES
src/mbgl/style/source_observer.hpp
src/mbgl/style/style.cpp
src/mbgl/style/style.hpp
- src/mbgl/style/tile_source_impl.cpp
- src/mbgl/style/tile_source_impl.hpp
src/mbgl/style/types.cpp
src/mbgl/style/update_batch.hpp
@@ -510,6 +510,7 @@ set(MBGL_CORE_FILES
include/mbgl/util/geometry.hpp
include/mbgl/util/ignore.hpp
include/mbgl/util/image.hpp
+ include/mbgl/util/immutable.hpp
include/mbgl/util/indexed_tuple.hpp
include/mbgl/util/interpolate.hpp
include/mbgl/util/logging.hpp
@@ -559,6 +560,7 @@ set(MBGL_CORE_FILES
src/mbgl/util/io.cpp
src/mbgl/util/io.hpp
src/mbgl/util/logging.cpp
+ src/mbgl/util/longest_common_subsequence.hpp
src/mbgl/util/mapbox.cpp
src/mbgl/util/mapbox.hpp
src/mbgl/util/mat2.cpp
diff --git a/include/mbgl/style/layer.hpp b/include/mbgl/style/layer.hpp
index 56f2c48fa7..10176879c5 100644
--- a/include/mbgl/style/layer.hpp
+++ b/include/mbgl/style/layer.hpp
@@ -2,6 +2,7 @@
#include <mbgl/util/noncopyable.hpp>
#include <mbgl/util/any.hpp>
+#include <mbgl/util/immutable.hpp>
#include <mbgl/style/layer_type.hpp>
#include <mbgl/style/types.hpp>
@@ -19,6 +20,7 @@ class RasterLayer;
class BackgroundLayer;
class CustomLayer;
class FillExtrusionLayer;
+class LayerObserver;
/**
* The runtime representation of a [layer](https://www.mapbox.com/mapbox-gl-style-spec/#layers) from the Mapbox Style
@@ -38,15 +40,6 @@ class FillExtrusionLayer;
*/
class Layer : public mbgl::util::noncopyable {
public:
- class Impl;
-
-protected:
-
- const LayerType type;
- Layer(LayerType, std::unique_ptr<Impl>);
-
-public:
-
virtual ~Layer();
// Check whether this layer is of the given subtype.
@@ -78,7 +71,7 @@ public:
//
template <class V>
auto accept(V&& visitor) {
- switch (type) {
+ switch (getType()) {
case LayerType::Fill:
return visitor(*as<FillLayer>());
case LayerType::Line:
@@ -98,20 +91,30 @@ public:
}
}
+ LayerType getType() const;
const std::string& getID() const;
// Visibility
VisibilityType getVisibility() const;
- void setVisibility(VisibilityType);
+ virtual void setVisibility(VisibilityType) = 0;
// Zoom range
float getMinZoom() const;
- void setMinZoom(float) const;
float getMaxZoom() const;
- void setMaxZoom(float) const;
+ virtual void setMinZoom(float) = 0;
+ virtual void setMaxZoom(float) = 0;
// Private implementation
- const std::unique_ptr<Impl> baseImpl;
+ class Impl;
+ Immutable<Impl> baseImpl;
+
+ Layer(Immutable<Impl>);
+
+ // Create a layer, copying all properties except id and paint properties from this layer.
+ virtual std::unique_ptr<Layer> cloneRef(const std::string& id) const = 0;
+
+ LayerObserver* observer = nullptr;
+ void setObserver(LayerObserver*);
// For use in SDK bindings, which store a reference to a platform-native peer
// object here, so that separately-obtained references to this object share
diff --git a/include/mbgl/style/layers/background_layer.hpp b/include/mbgl/style/layers/background_layer.hpp
index 6604a868f3..63708a449f 100644
--- a/include/mbgl/style/layers/background_layer.hpp
+++ b/include/mbgl/style/layers/background_layer.hpp
@@ -19,6 +19,13 @@ public:
BackgroundLayer(const std::string& layerID);
~BackgroundLayer() final;
+ // Visibility
+ void setVisibility(VisibilityType) final;
+
+ // Zoom range
+ void setMinZoom(float) final;
+ void setMaxZoom(float) final;
+
// Paint properties
static PropertyValue<Color> getDefaultBackgroundColor();
@@ -42,15 +49,16 @@ public:
// Private implementation
class Impl;
- Impl* const impl;
+ const Impl& impl() const;
- BackgroundLayer(const Impl&);
- BackgroundLayer(const BackgroundLayer&) = delete;
+ Mutable<Impl> mutableImpl() const;
+ BackgroundLayer(Immutable<Impl>);
+ std::unique_ptr<Layer> cloneRef(const std::string& id) const final;
};
template <>
inline bool Layer::is<BackgroundLayer>() const {
- return type == LayerType::Background;
+ return getType() == LayerType::Background;
}
} // namespace style
diff --git a/include/mbgl/style/layers/circle_layer.hpp b/include/mbgl/style/layers/circle_layer.hpp
index 3a3723249f..f40c507e28 100644
--- a/include/mbgl/style/layers/circle_layer.hpp
+++ b/include/mbgl/style/layers/circle_layer.hpp
@@ -27,6 +27,13 @@ public:
void setFilter(const Filter&);
const Filter& getFilter() const;
+ // Visibility
+ void setVisibility(VisibilityType) final;
+
+ // Zoom range
+ void setMinZoom(float) final;
+ void setMaxZoom(float) final;
+
// Paint properties
static DataDrivenPropertyValue<float> getDefaultCircleRadius();
@@ -92,15 +99,16 @@ public:
// Private implementation
class Impl;
- Impl* const impl;
+ const Impl& impl() const;
- CircleLayer(const Impl&);
- CircleLayer(const CircleLayer&) = delete;
+ Mutable<Impl> mutableImpl() const;
+ CircleLayer(Immutable<Impl>);
+ std::unique_ptr<Layer> cloneRef(const std::string& id) const final;
};
template <>
inline bool Layer::is<CircleLayer>() const {
- return type == LayerType::Circle;
+ return getType() == LayerType::Circle;
}
} // namespace style
diff --git a/include/mbgl/style/layers/custom_layer.hpp b/include/mbgl/style/layers/custom_layer.hpp
index edc8d43f89..79a353b047 100644
--- a/include/mbgl/style/layers/custom_layer.hpp
+++ b/include/mbgl/style/layers/custom_layer.hpp
@@ -55,12 +55,21 @@ public:
void* context);
~CustomLayer() final;
+ // Visibility
+ void setVisibility(VisibilityType) final;
+
+ // Zoom range
+ void setMinZoom(float) final;
+ void setMaxZoom(float) final;
+
// Private implementation
class Impl;
- Impl* impl;
+ const Impl& impl() const;
+
+ Mutable<Impl> mutableImpl() const;
+ std::unique_ptr<Layer> cloneRef(const std::string& id) const final;
- CustomLayer(const Impl&);
CustomLayer(const CustomLayer&) = delete;
};
diff --git a/include/mbgl/style/layers/fill_extrusion_layer.hpp b/include/mbgl/style/layers/fill_extrusion_layer.hpp
index 1f79f87fac..bc6890e82f 100644
--- a/include/mbgl/style/layers/fill_extrusion_layer.hpp
+++ b/include/mbgl/style/layers/fill_extrusion_layer.hpp
@@ -27,6 +27,13 @@ public:
void setFilter(const Filter&);
const Filter& getFilter() const;
+ // Visibility
+ void setVisibility(VisibilityType) final;
+
+ // Zoom range
+ void setMinZoom(float) final;
+ void setMaxZoom(float) final;
+
// Paint properties
static PropertyValue<float> getDefaultFillExtrusionOpacity();
@@ -74,15 +81,16 @@ public:
// Private implementation
class Impl;
- Impl* const impl;
+ const Impl& impl() const;
- FillExtrusionLayer(const Impl&);
- FillExtrusionLayer(const FillExtrusionLayer&) = delete;
+ Mutable<Impl> mutableImpl() const;
+ FillExtrusionLayer(Immutable<Impl>);
+ std::unique_ptr<Layer> cloneRef(const std::string& id) const final;
};
template <>
inline bool Layer::is<FillExtrusionLayer>() const {
- return type == LayerType::FillExtrusion;
+ return getType() == LayerType::FillExtrusion;
}
} // namespace style
diff --git a/include/mbgl/style/layers/fill_layer.hpp b/include/mbgl/style/layers/fill_layer.hpp
index 8371ff7a8f..3d08e75a1c 100644
--- a/include/mbgl/style/layers/fill_layer.hpp
+++ b/include/mbgl/style/layers/fill_layer.hpp
@@ -27,6 +27,13 @@ public:
void setFilter(const Filter&);
const Filter& getFilter() const;
+ // Visibility
+ void setVisibility(VisibilityType) final;
+
+ // Zoom range
+ void setMinZoom(float) final;
+ void setMaxZoom(float) final;
+
// Paint properties
static PropertyValue<bool> getDefaultFillAntialias();
@@ -74,15 +81,16 @@ public:
// Private implementation
class Impl;
- Impl* const impl;
+ const Impl& impl() const;
- FillLayer(const Impl&);
- FillLayer(const FillLayer&) = delete;
+ Mutable<Impl> mutableImpl() const;
+ FillLayer(Immutable<Impl>);
+ std::unique_ptr<Layer> cloneRef(const std::string& id) const final;
};
template <>
inline bool Layer::is<FillLayer>() const {
- return type == LayerType::Fill;
+ return getType() == LayerType::Fill;
}
} // namespace style
diff --git a/include/mbgl/style/layers/layer.hpp.ejs b/include/mbgl/style/layers/layer.hpp.ejs
index 59d7cd6415..033ae88956 100644
--- a/include/mbgl/style/layers/layer.hpp.ejs
+++ b/include/mbgl/style/layers/layer.hpp.ejs
@@ -44,6 +44,13 @@ public:
<% } -%>
<% } -%>
+ // Visibility
+ void setVisibility(VisibilityType) final;
+
+ // Zoom range
+ void setMinZoom(float) final;
+ void setMaxZoom(float) final;
+
<% if (layoutProperties.length) { -%>
// Layout properties
@@ -67,15 +74,16 @@ public:
// Private implementation
class Impl;
- Impl* const impl;
+ const Impl& impl() const;
- <%- camelize(type) %>Layer(const Impl&);
- <%- camelize(type) %>Layer(const <%- camelize(type) %>Layer&) = delete;
+ Mutable<Impl> mutableImpl() const;
+ <%- camelize(type) %>Layer(Immutable<Impl>);
+ std::unique_ptr<Layer> cloneRef(const std::string& id) const final;
};
template <>
inline bool Layer::is<<%- camelize(type) %>Layer>() const {
- return type == LayerType::<%- camelize(type) %>;
+ return getType() == LayerType::<%- camelize(type) %>;
}
} // namespace style
diff --git a/include/mbgl/style/layers/line_layer.hpp b/include/mbgl/style/layers/line_layer.hpp
index a5f08e553c..6000839d1c 100644
--- a/include/mbgl/style/layers/line_layer.hpp
+++ b/include/mbgl/style/layers/line_layer.hpp
@@ -29,6 +29,13 @@ public:
void setFilter(const Filter&);
const Filter& getFilter() const;
+ // Visibility
+ void setVisibility(VisibilityType) final;
+
+ // Zoom range
+ void setMinZoom(float) final;
+ void setMaxZoom(float) final;
+
// Layout properties
static PropertyValue<LineCapType> getDefaultLineCap();
@@ -112,15 +119,16 @@ public:
// Private implementation
class Impl;
- Impl* const impl;
+ const Impl& impl() const;
- LineLayer(const Impl&);
- LineLayer(const LineLayer&) = delete;
+ Mutable<Impl> mutableImpl() const;
+ LineLayer(Immutable<Impl>);
+ std::unique_ptr<Layer> cloneRef(const std::string& id) const final;
};
template <>
inline bool Layer::is<LineLayer>() const {
- return type == LayerType::Line;
+ return getType() == LayerType::Line;
}
} // namespace style
diff --git a/include/mbgl/style/layers/raster_layer.hpp b/include/mbgl/style/layers/raster_layer.hpp
index c0351da5d0..ad9a68f1b0 100644
--- a/include/mbgl/style/layers/raster_layer.hpp
+++ b/include/mbgl/style/layers/raster_layer.hpp
@@ -22,6 +22,13 @@ public:
// Source
const std::string& getSourceID() const;
+ // Visibility
+ void setVisibility(VisibilityType) final;
+
+ // Zoom range
+ void setMinZoom(float) final;
+ void setMaxZoom(float) final;
+
// Paint properties
static PropertyValue<float> getDefaultRasterOpacity();
@@ -69,15 +76,16 @@ public:
// Private implementation
class Impl;
- Impl* const impl;
+ const Impl& impl() const;
- RasterLayer(const Impl&);
- RasterLayer(const RasterLayer&) = delete;
+ Mutable<Impl> mutableImpl() const;
+ RasterLayer(Immutable<Impl>);
+ std::unique_ptr<Layer> cloneRef(const std::string& id) const final;
};
template <>
inline bool Layer::is<RasterLayer>() const {
- return type == LayerType::Raster;
+ return getType() == LayerType::Raster;
}
} // namespace style
diff --git a/include/mbgl/style/layers/symbol_layer.hpp b/include/mbgl/style/layers/symbol_layer.hpp
index ea6bda55d7..e7df5a92ae 100644
--- a/include/mbgl/style/layers/symbol_layer.hpp
+++ b/include/mbgl/style/layers/symbol_layer.hpp
@@ -29,6 +29,13 @@ public:
void setFilter(const Filter&);
const Filter& getFilter() const;
+ // Visibility
+ void setVisibility(VisibilityType) final;
+
+ // Zoom range
+ void setMinZoom(float) final;
+ void setMaxZoom(float) final;
+
// Layout properties
static PropertyValue<SymbolPlacementType> getDefaultSymbolPlacement();
@@ -256,15 +263,16 @@ public:
// Private implementation
class Impl;
- Impl* const impl;
+ const Impl& impl() const;
- SymbolLayer(const Impl&);
- SymbolLayer(const SymbolLayer&) = delete;
+ Mutable<Impl> mutableImpl() const;
+ SymbolLayer(Immutable<Impl>);
+ std::unique_ptr<Layer> cloneRef(const std::string& id) const final;
};
template <>
inline bool Layer::is<SymbolLayer>() const {
- return type == LayerType::Symbol;
+ return getType() == LayerType::Symbol;
}
} // namespace style
diff --git a/include/mbgl/style/light.hpp b/include/mbgl/style/light.hpp
index 8212a58dcc..c82792b28d 100644
--- a/include/mbgl/style/light.hpp
+++ b/include/mbgl/style/light.hpp
@@ -1,20 +1,19 @@
// This file is generated. Do not edit.
#pragma once
+
#include <mbgl/style/property_value.hpp>
#include <mbgl/style/transition_options.hpp>
#include <mbgl/style/types.hpp>
-
-#include <memory>
+#include <mbgl/util/immutable.hpp>
namespace mbgl {
namespace style {
+class LightObserver;
+
class Light {
public:
-
- class Impl;
-
Light();
~Light();
@@ -42,7 +41,12 @@ public:
void setIntensityTransition(const TransitionOptions&);
TransitionOptions getIntensityTransition() const;
- std::shared_ptr<Impl> impl;
+ class Impl;
+ Immutable<Impl> impl;
+ Mutable<Impl> mutableImpl() const;
+
+ LightObserver* observer = nullptr;
+ void setObserver(LightObserver*);
};
} // namespace style
diff --git a/include/mbgl/style/light.hpp.ejs b/include/mbgl/style/light.hpp.ejs
index 601e0bd410..adc5b651e3 100644
--- a/include/mbgl/style/light.hpp.ejs
+++ b/include/mbgl/style/light.hpp.ejs
@@ -4,20 +4,19 @@
// This file is generated. Do not edit.
#pragma once
+
#include <mbgl/style/property_value.hpp>
#include <mbgl/style/transition_options.hpp>
#include <mbgl/style/types.hpp>
-
-#include <memory>
+#include <mbgl/util/immutable.hpp>
namespace mbgl {
namespace style {
+class LightObserver;
+
class Light {
public:
-
- class Impl;
-
Light();
~Light();
@@ -29,7 +28,12 @@ public:
TransitionOptions get<%- camelize(property.name) %>Transition() const;
<% } -%>
- std::shared_ptr<Impl> impl;
+ class Impl;
+ Immutable<Impl> impl;
+ Mutable<Impl> mutableImpl() const;
+
+ LightObserver* observer = nullptr;
+ void setObserver(LightObserver*);
};
} // namespace style
diff --git a/include/mbgl/style/source.hpp b/include/mbgl/style/source.hpp
index 4c82e472a6..d19dfd4e36 100644
--- a/include/mbgl/style/source.hpp
+++ b/include/mbgl/style/source.hpp
@@ -1,19 +1,25 @@
#pragma once
-#include <mbgl/util/feature.hpp>
#include <mbgl/util/noncopyable.hpp>
#include <mbgl/util/optional.hpp>
-#include <mbgl/util/range.hpp>
#include <mbgl/util/any.hpp>
+#include <mbgl/util/immutable.hpp>
#include <mbgl/style/types.hpp>
#include <memory>
#include <string>
-#include <vector>
namespace mbgl {
+
+class FileSource;
+
namespace style {
+class VectorSource;
+class RasterSource;
+class GeoJSONSource;
+class SourceObserver;
+
/**
* The runtime representation of a [source](https://www.mapbox.com/mapbox-gl-style-spec/#sources) from the Mapbox Style
* Specification.
@@ -49,21 +55,28 @@ public:
return is<T>() ? reinterpret_cast<const T*>(this) : nullptr;
}
+ SourceType getType() const;
const std::string& getID() const;
optional<std::string> getAttribution() const;
// Private implementation
class Impl;
- const std::unique_ptr<Impl> baseImpl;
+ Immutable<Impl> baseImpl;
+
+ Source(Immutable<Impl>);
+
+ void setObserver(SourceObserver*);
+ SourceObserver* observer = nullptr;
+
+ virtual void loadDescription(FileSource&) = 0;
+ void dumpDebugLogs() const;
+
+ bool loaded = false;
// For use in SDK bindings, which store a reference to a platform-native peer
// object here, so that separately-obtained references to this object share
// identical platform-native peers.
any peer;
-
-protected:
- const SourceType type;
- Source(SourceType, std::unique_ptr<Impl>);
};
} // namespace style
diff --git a/include/mbgl/style/sources/geojson_source.hpp b/include/mbgl/style/sources/geojson_source.hpp
index 5b39d7821b..2dcfec51aa 100644
--- a/include/mbgl/style/sources/geojson_source.hpp
+++ b/include/mbgl/style/sources/geojson_source.hpp
@@ -5,6 +5,9 @@
#include <mbgl/util/optional.hpp>
namespace mbgl {
+
+class AsyncRequest;
+
namespace style {
struct GeoJSONOptions {
@@ -22,21 +25,26 @@ struct GeoJSONOptions {
class GeoJSONSource : public Source {
public:
GeoJSONSource(const std::string& id, const GeoJSONOptions& = {});
+ ~GeoJSONSource() final;
void setURL(const std::string& url);
void setGeoJSON(const GeoJSON&);
optional<std::string> getURL() const;
- // Private implementation
-
class Impl;
- Impl* const impl;
+ const Impl& impl() const;
+
+ void loadDescription(FileSource&) final;
+
+private:
+ optional<std::string> url;
+ std::unique_ptr<AsyncRequest> req;
};
template <>
inline bool Source::is<GeoJSONSource>() const {
- return type == SourceType::GeoJSON;
+ return getType() == SourceType::GeoJSON;
}
} // namespace style
diff --git a/include/mbgl/style/sources/raster_source.hpp b/include/mbgl/style/sources/raster_source.hpp
index 395f25e51d..7f23a7ca4b 100644
--- a/include/mbgl/style/sources/raster_source.hpp
+++ b/include/mbgl/style/sources/raster_source.hpp
@@ -5,23 +5,34 @@
#include <mbgl/util/variant.hpp>
namespace mbgl {
+
+class AsyncRequest;
+
namespace style {
class RasterSource : public Source {
public:
RasterSource(std::string id, variant<std::string, Tileset> urlOrTileset, uint16_t tileSize);
+ ~RasterSource() final;
+ const variant<std::string, Tileset>& getURLOrTileset() const;
optional<std::string> getURL() const;
- // Private implementation
+ uint16_t getTileSize() const;
class Impl;
- Impl* const impl;
+ const Impl& impl() const;
+
+ void loadDescription(FileSource&) final;
+
+private:
+ const variant<std::string, Tileset> urlOrTileset;
+ std::unique_ptr<AsyncRequest> req;
};
template <>
inline bool Source::is<RasterSource>() const {
- return type == SourceType::Raster;
+ return getType() == SourceType::Raster;
}
} // namespace style
diff --git a/include/mbgl/style/sources/vector_source.hpp b/include/mbgl/style/sources/vector_source.hpp
index 8626ce160a..6f16974b40 100644
--- a/include/mbgl/style/sources/vector_source.hpp
+++ b/include/mbgl/style/sources/vector_source.hpp
@@ -5,23 +5,32 @@
#include <mbgl/util/variant.hpp>
namespace mbgl {
+
+class AsyncRequest;
+
namespace style {
class VectorSource : public Source {
public:
VectorSource(std::string id, variant<std::string, Tileset> urlOrTileset);
+ ~VectorSource() final;
+ const variant<std::string, Tileset>& getURLOrTileset() const;
optional<std::string> getURL() const;
- // Private implementation
-
class Impl;
- Impl* const impl;
+ const Impl& impl() const;
+
+ void loadDescription(FileSource&) final;
+
+private:
+ const variant<std::string, Tileset> urlOrTileset;
+ std::unique_ptr<AsyncRequest> req;
};
template <>
inline bool Source::is<VectorSource>() const {
- return type == SourceType::Vector;
+ return getType() == SourceType::Vector;
}
} // namespace style
diff --git a/include/mbgl/util/immutable.hpp b/include/mbgl/util/immutable.hpp
new file mode 100644
index 0000000000..1d6ff4079a
--- /dev/null
+++ b/include/mbgl/util/immutable.hpp
@@ -0,0 +1,127 @@
+#pragma once
+
+#include <memory>
+
+namespace mbgl {
+
+/**
+ * `Mutable<T>` is a non-nullable uniquely owning reference to a `T`. It can be efficiently converted
+ * to `Immutable<T>`.
+ *
+ * The lifecycle of `Mutable<T>` and `Immutable<T>` is as follows:
+ *
+ * 1. Create a `Mutable<T>` using `makeMutable(...)`
+ * 2. Mutate it freely
+ * 3. When you're ready to freeze its state and enable safe cross-thread sharing, move assign or
+ * move construct it to `Immutable<T>`
+ *
+ * The reason that `Mutable<T>` exists, rather than simply using a `std::unique_ptr<T>`, is to take advantage
+ * of the underlying single-allocation optimization provided by `std::make_shared`.
+ */
+template <class T>
+class Mutable {
+public:
+ Mutable(Mutable&&) = default;
+ Mutable& operator=(Mutable&&) = default;
+
+ Mutable(const Mutable&) = delete;
+ Mutable& operator=(const Mutable&) = delete;
+
+ T* get() { return ptr.get(); }
+ T* operator->() { return ptr.get(); }
+ T& operator*() { return *ptr; }
+
+private:
+ Mutable(std::shared_ptr<T>&& s)
+ : ptr(std::move(s)) {}
+
+ std::shared_ptr<T> ptr;
+
+ template <class S> friend class Immutable;
+ template <class S, class... Args> friend Mutable<S> makeMutable(Args&&...);
+};
+
+template <class T, class... Args>
+Mutable<T> makeMutable(Args&&... args) {
+ return Mutable<T>(std::make_shared<T>(std::forward<Args>(args)...));
+}
+
+/**
+ * `Immutable<T>` is a non-nullable shared reference to a `const T`. Construction requires
+ * a transfer of unique ownership from a `Mutable<T>`; once constructed it has the same behavior
+ * as `std::shared_ptr<const T>` but with better indication of intent.
+ *
+ * Normally one should not share state between threads because it's difficult to verify the
+ * absence of read/write data races. `Immutable` provides a guarantee that no writes are
+ * possible, and instances therefore can be freely transferred and shared between threads.
+ */
+template <class T>
+class Immutable {
+public:
+ template <class S>
+ Immutable(Mutable<S>&& s)
+ : ptr(std::const_pointer_cast<const S>(std::move(s.ptr))) {}
+
+ template <class S>
+ Immutable(Immutable<S>&& s)
+ : ptr(std::move(s.ptr)) {}
+
+ template <class S>
+ Immutable(const Immutable<S>& s)
+ : ptr(s.ptr) {}
+
+ template <class S>
+ Immutable& operator=(Mutable<S>&& s) {
+ ptr = std::const_pointer_cast<const S>(std::move(s.ptr));
+ return *this;
+ }
+
+ template <class S>
+ Immutable& operator=(Immutable<S>&& s) {
+ ptr = std::move(s.ptr);
+ return *this;
+ }
+
+ template <class S>
+ Immutable& operator=(const Immutable<S>& s) {
+ ptr = s.ptr;
+ return *this;
+ }
+
+ const T* get() const { return ptr.get(); }
+ const T* operator->() const { return ptr.get(); }
+ const T& operator*() const { return *ptr; }
+
+ friend bool operator==(const Immutable<T>& lhs, const Immutable<T>& rhs) {
+ return lhs.ptr == rhs.ptr;
+ }
+
+ friend bool operator!=(const Immutable<T>& lhs, const Immutable<T>& rhs) {
+ return lhs.ptr != rhs.ptr;
+ }
+
+private:
+ Immutable(std::shared_ptr<const T>&& s)
+ : ptr(std::move(s)) {}
+
+ std::shared_ptr<const T> ptr;
+
+ template <class S> friend class Immutable;
+ template <class S> friend class EnableImmutableFromThis;
+ template <class S, class U> friend Immutable<S> staticImmutableCast(const Immutable<U>&);
+};
+
+template <class T>
+class EnableImmutableFromThis : public std::enable_shared_from_this<const T> {
+public:
+ Immutable<T> immutableFromThis() const {
+ return Immutable<T>(this->shared_from_this());
+ }
+};
+
+template <class S, class U>
+Immutable<S> staticImmutableCast(const Immutable<U>& u) {
+ return Immutable<S>(std::static_pointer_cast<const S>(u.ptr));
+}
+
+} // namespace mbgl
diff --git a/include/mbgl/util/tileset.hpp b/include/mbgl/util/tileset.hpp
index 1f28a5039a..1256e9fe96 100644
--- a/include/mbgl/util/tileset.hpp
+++ b/include/mbgl/util/tileset.hpp
@@ -18,6 +18,11 @@ public:
Scheme scheme = Scheme::XYZ;
// TileJSON also includes center, zoom, and bounds, but they are not used by mbgl.
+
+ friend bool operator==(const Tileset& lhs, const Tileset& rhs) {
+ return std::tie(lhs.tiles, lhs.zoomRange, lhs.attribution, lhs.scheme)
+ == std::tie(rhs.tiles, rhs.zoomRange, rhs.attribution, rhs.scheme);
+ }
};
} // namespace mbgl
diff --git a/mapbox-gl-js b/mapbox-gl-js
-Subproject 8b085a211579d417ad8b3d58bc502c4ffbdfc2e
+Subproject 94619177e52614564496c9e5bdd7751fc8ee426
diff --git a/platform/default/mbgl/storage/offline_download.cpp b/platform/default/mbgl/storage/offline_download.cpp
index 5a487b3534..235baac12c 100644
--- a/platform/default/mbgl/storage/offline_download.cpp
+++ b/platform/default/mbgl/storage/offline_download.cpp
@@ -5,8 +5,9 @@
#include <mbgl/storage/response.hpp>
#include <mbgl/storage/http_file_source.hpp>
#include <mbgl/style/parser.hpp>
-#include <mbgl/style/sources/geojson_source_impl.hpp>
-#include <mbgl/style/tile_source_impl.hpp>
+#include <mbgl/style/sources/vector_source.hpp>
+#include <mbgl/style/sources/raster_source.hpp>
+#include <mbgl/style/sources/geojson_source.hpp>
#include <mbgl/style/conversion/json.hpp>
#include <mbgl/style/conversion/tileset.hpp>
#include <mbgl/text/glyph.hpp>
@@ -19,6 +20,8 @@
namespace mbgl {
+using namespace style;
+
OfflineDownload::OfflineDownload(int64_t id_,
OfflineRegionDefinition&& definition_,
OfflineDatabase& offlineDatabase_,
@@ -71,15 +74,9 @@ OfflineRegionStatus OfflineDownload::getStatus() const {
result.requiredResourceCountIsPrecise = true;
for (const auto& source : parser.sources) {
- SourceType type = source->baseImpl->type;
-
- switch (type) {
- case SourceType::Vector:
- case SourceType::Raster: {
- auto* tileSource = static_cast<style::TileSourceImpl*>(source->baseImpl.get());
- const variant<std::string, Tileset>& urlOrTileset = tileSource->getURLOrTileset();
- const uint16_t tileSize = tileSource->getTileSize();
+ SourceType type = source->getType();
+ auto handleTiledSource = [&] (const variant<std::string, Tileset>& urlOrTileset, const uint16_t tileSize) {
if (urlOrTileset.is<Tileset>()) {
result.requiredResourceCount +=
definition.tileCover(type, tileSize, urlOrTileset.get<Tileset>().zoomRange).size();
@@ -98,11 +95,23 @@ OfflineRegionStatus OfflineDownload::getStatus() const {
result.requiredResourceCountIsPrecise = false;
}
}
+ };
+
+ switch (type) {
+ case SourceType::Vector: {
+ const auto& vectorSource = *source->as<VectorSource>();
+ handleTiledSource(vectorSource.getURLOrTileset(), util::tileSize);
+ break;
+ }
+
+ case SourceType::Raster: {
+ const auto& rasterSource = *source->as<RasterSource>();
+ handleTiledSource(rasterSource.getURLOrTileset(), rasterSource.getTileSize());
break;
}
case SourceType::GeoJSON: {
- auto* geojsonSource = source->as<style::GeoJSONSource>();
+ auto* geojsonSource = source->as<GeoJSONSource>();
if (geojsonSource->getURL()) {
result.requiredResourceCount += 1;
}
@@ -137,16 +146,9 @@ void OfflineDownload::activateDownload() {
parser.parse(*styleResponse.data);
for (const auto& source : parser.sources) {
- SourceType type = source->baseImpl->type;
-
- switch (type) {
- case SourceType::Vector:
- case SourceType::Raster: {
- const style::TileSourceImpl* tileSource =
- static_cast<style::TileSourceImpl*>(source->baseImpl.get());
- const variant<std::string, Tileset>& urlOrTileset = tileSource->getURLOrTileset();
- const uint16_t tileSize = tileSource->getTileSize();
+ SourceType type = source->getType();
+ auto handleTiledSource = [&] (const variant<std::string, Tileset>& urlOrTileset, const uint16_t tileSize) {
if (urlOrTileset.is<Tileset>()) {
queueTiles(type, tileSize, urlOrTileset.get<Tileset>());
} else {
@@ -169,12 +171,23 @@ void OfflineDownload::activateDownload() {
}
});
}
+ };
+
+ switch (type) {
+ case SourceType::Vector: {
+ const auto& vectorSource = *source->as<VectorSource>();
+ handleTiledSource(vectorSource.getURLOrTileset(), util::tileSize);
+ break;
+ }
+
+ case SourceType::Raster: {
+ const auto& rasterSource = *source->as<RasterSource>();
+ handleTiledSource(rasterSource.getURLOrTileset(), rasterSource.getTileSize());
break;
}
case SourceType::GeoJSON: {
- auto* geojsonSource =
- static_cast<style::GeoJSONSource::Impl*>(source->baseImpl.get());
+ const auto* geojsonSource = static_cast<const GeoJSONSource*>(source.get());
if (geojsonSource->getURL()) {
queueResource(Resource::source(*geojsonSource->getURL()));
diff --git a/src/mbgl/annotation/annotation_source.cpp b/src/mbgl/annotation/annotation_source.cpp
index 9956140179..b0b8bae6cc 100644
--- a/src/mbgl/annotation/annotation_source.cpp
+++ b/src/mbgl/annotation/annotation_source.cpp
@@ -7,19 +7,23 @@ namespace mbgl {
using namespace style;
AnnotationSource::AnnotationSource()
- : Source(SourceType::Annotations, std::make_unique<Impl>(*this)) {
+ : Source(makeMutable<Impl>()) {
}
-AnnotationSource::Impl::Impl(Source& base_)
- : Source::Impl(SourceType::Annotations, AnnotationManager::SourceID, base_) {
+AnnotationSource::Impl::Impl()
+ : Source::Impl(SourceType::Annotations, AnnotationManager::SourceID) {
}
-void AnnotationSource::Impl::loadDescription(FileSource&) {
+void AnnotationSource::loadDescription(FileSource&) {
loaded = true;
}
+optional<std::string> AnnotationSource::Impl::getAttribution() const {
+ return {};
+}
+
std::unique_ptr<RenderSource> AnnotationSource::Impl::createRenderSource() const {
- return std::make_unique<RenderAnnotationSource>(*this);
+ return std::make_unique<RenderAnnotationSource>(staticImmutableCast<AnnotationSource::Impl>(immutableFromThis()));
}
} // namespace mbgl
diff --git a/src/mbgl/annotation/annotation_source.hpp b/src/mbgl/annotation/annotation_source.hpp
index 46c9564443..56d91f5501 100644
--- a/src/mbgl/annotation/annotation_source.hpp
+++ b/src/mbgl/annotation/annotation_source.hpp
@@ -10,13 +10,19 @@ public:
AnnotationSource();
class Impl;
+ const Impl& impl() const;
+
+private:
+ void loadDescription(FileSource&) final;
+
+ Mutable<Impl> mutableImpl() const;
};
class AnnotationSource::Impl : public style::Source::Impl {
public:
- Impl(Source&);
+ Impl();
- void loadDescription(FileSource&) final;
+ optional<std::string> getAttribution() const final;
std::unique_ptr<RenderSource> createRenderSource() const final;
};
diff --git a/src/mbgl/annotation/render_annotation_source.cpp b/src/mbgl/annotation/render_annotation_source.cpp
index a62d2d51d3..718f7a16e6 100644
--- a/src/mbgl/annotation/render_annotation_source.cpp
+++ b/src/mbgl/annotation/render_annotation_source.cpp
@@ -9,11 +9,15 @@ namespace mbgl {
using namespace style;
-RenderAnnotationSource::RenderAnnotationSource(const AnnotationSource::Impl& impl_)
+RenderAnnotationSource::RenderAnnotationSource(Immutable<AnnotationSource::Impl> impl_)
: RenderSource(impl_) {
tilePyramid.setObserver(this);
}
+const AnnotationSource::Impl& RenderAnnotationSource::impl() const {
+ return static_cast<const AnnotationSource::Impl&>(*baseImpl);
+}
+
bool RenderAnnotationSource::isLoaded() const {
return tilePyramid.isLoaded();
}
diff --git a/src/mbgl/annotation/render_annotation_source.hpp b/src/mbgl/annotation/render_annotation_source.hpp
index 9ae9340477..539e73b57e 100644
--- a/src/mbgl/annotation/render_annotation_source.hpp
+++ b/src/mbgl/annotation/render_annotation_source.hpp
@@ -8,7 +8,7 @@ namespace mbgl {
class RenderAnnotationSource : public RenderSource {
public:
- RenderAnnotationSource(const AnnotationSource::Impl&);
+ RenderAnnotationSource(Immutable<AnnotationSource::Impl>);
bool isLoaded() const final;
@@ -47,6 +47,8 @@ public:
void dumpDebugLogs() const final;
private:
+ const AnnotationSource::Impl& impl() const;
+
TilePyramid tilePyramid;
};
diff --git a/src/mbgl/geometry/feature_index.cpp b/src/mbgl/geometry/feature_index.cpp
index 8251e4d03a..451943ff26 100644
--- a/src/mbgl/geometry/feature_index.cpp
+++ b/src/mbgl/geometry/feature_index.cpp
@@ -61,7 +61,7 @@ static int16_t getAdditionalQueryRadius(const RenderedQueryOptions& queryOptions
// Determine the additional radius needed factoring in property functions
float additionalRadius = 0;
auto getQueryRadius = [&](const RenderLayer& layer) {
- auto bucket = tile.getBucket(layer);
+ auto bucket = tile.getBucket(*layer.baseImpl);
if (bucket) {
additionalRadius = std::max(additionalRadius, bucket->getQueryRadius(layer) * pixelsToTileUnits);
}
diff --git a/src/mbgl/layout/symbol_layout.cpp b/src/mbgl/layout/symbol_layout.cpp
index aa91eb1688..fe857fec7e 100644
--- a/src/mbgl/layout/symbol_layout.cpp
+++ b/src/mbgl/layout/symbol_layout.cpp
@@ -50,11 +50,11 @@ SymbolLayout::SymbolLayout(const BucketParameters& parameters,
mode(parameters.mode),
tileSize(util::tileSize * overscaling),
tilePixelRatio(float(util::EXTENT) / tileSize),
- textSize(layers.at(0)->as<RenderSymbolLayer>()->impl->layout.unevaluated.get<TextSize>()),
- iconSize(layers.at(0)->as<RenderSymbolLayer>()->impl->layout.unevaluated.get<IconSize>())
+ textSize(layers.at(0)->as<RenderSymbolLayer>()->impl().layout.unevaluated.get<TextSize>()),
+ iconSize(layers.at(0)->as<RenderSymbolLayer>()->impl().layout.unevaluated.get<IconSize>())
{
- const SymbolLayer::Impl& leader = *layers.at(0)->as<RenderSymbolLayer>()->impl;
+ const SymbolLayer::Impl& leader = layers.at(0)->as<RenderSymbolLayer>()->impl();
layout = leader.layout.evaluate(PropertyEvaluationParameters(zoom));
diff --git a/src/mbgl/map/map.cpp b/src/mbgl/map/map.cpp
index c7daf5ac09..4ef422a2de 100644
--- a/src/mbgl/map/map.cpp
+++ b/src/mbgl/map/map.cpp
@@ -402,7 +402,7 @@ void Map::Impl::loadStyleJSON(const std::string& json) {
map.setPitch(map.getDefaultPitch());
}
- onUpdate(Update::Classes | Update::AnnotationStyle);
+ onUpdate(Update::AnnotationStyle);
}
std::string Map::getStyleURL() const {
@@ -919,7 +919,7 @@ void Map::addLayer(std::unique_ptr<Layer> layer, const optional<std::string>& be
BackendScope guard(impl->backend);
impl->style->addLayer(std::move(layer), before);
- impl->onUpdate(Update::Classes);
+ impl->onUpdate(Update::Repaint);
}
std::unique_ptr<Layer> Map::removeLayer(const std::string& id) {
diff --git a/src/mbgl/map/update.hpp b/src/mbgl/map/update.hpp
index 5e87515eac..29f2583f7c 100644
--- a/src/mbgl/map/update.hpp
+++ b/src/mbgl/map/update.hpp
@@ -8,7 +8,6 @@ enum class Update {
Nothing = 0,
Repaint = 1 << 0,
Classes = 1 << 2,
- RecalculateStyle = 1 << 3,
AnnotationStyle = 1 << 6,
AnnotationData = 1 << 7
};
diff --git a/src/mbgl/renderer/group_by_layout.cpp b/src/mbgl/renderer/group_by_layout.cpp
index df1eb7c7dd..3b02727ff8 100644
--- a/src/mbgl/renderer/group_by_layout.cpp
+++ b/src/mbgl/renderer/group_by_layout.cpp
@@ -19,13 +19,13 @@ std::string layoutKey(const RenderLayer& layer) {
writer.StartArray();
writer.Uint(static_cast<uint32_t>(layer.type));
- writer.String(layer.baseImpl.source);
- writer.String(layer.baseImpl.sourceLayer);
- writer.Double(layer.baseImpl.minZoom);
- writer.Double(layer.baseImpl.maxZoom);
- writer.Uint(static_cast<uint32_t>(layer.baseImpl.visibility));
- stringify(writer, layer.baseImpl.filter);
- layer.baseImpl.stringifyLayout(writer);
+ writer.String(layer.baseImpl->source);
+ writer.String(layer.baseImpl->sourceLayer);
+ writer.Double(layer.baseImpl->minZoom);
+ writer.Double(layer.baseImpl->maxZoom);
+ writer.Uint(static_cast<uint32_t>(layer.baseImpl->visibility));
+ stringify(writer, layer.baseImpl->filter);
+ layer.baseImpl->stringifyLayout(writer);
writer.EndArray();
return s.GetString();
diff --git a/src/mbgl/renderer/painter.cpp b/src/mbgl/renderer/painter.cpp
index eed3bfcd8b..51770b07b1 100644
--- a/src/mbgl/renderer/painter.cpp
+++ b/src/mbgl/renderer/painter.cpp
@@ -144,7 +144,7 @@ void Painter::render(const Style& style, const FrameData& frame_, View& view, Sp
spriteAtlas = style.spriteAtlas.get();
lineAtlas = style.lineAtlas.get();
- evaluatedLight = style.getRenderLight()->getEvaluated();
+ evaluatedLight = style.getRenderLight().getEvaluated();
RenderData renderData = style.getRenderData(frame.debugOptions, state.getAngle());
const std::vector<RenderItem>& order = renderData.order;
@@ -180,7 +180,7 @@ void Painter::render(const Style& style, const FrameData& frame_, View& view, Sp
for (const auto& item : order) {
for (const auto& tileRef : item.tiles) {
- const auto& bucket = tileRef.get().tile.getBucket(item.layer);
+ const auto& bucket = tileRef.get().tile.getBucket(*item.layer.baseImpl);
if (bucket && bucket->needsUpload()) {
bucket->upload(context);
}
@@ -309,7 +309,7 @@ void Painter::renderPass(PaintParameters& parameters,
MBGL_DEBUG_GROUP(context, "background");
renderBackground(parameters, *layer.as<RenderBackgroundLayer>());
} else if (layer.is<RenderCustomLayer>()) {
- MBGL_DEBUG_GROUP(context, layer.baseImpl.id + " - custom");
+ MBGL_DEBUG_GROUP(context, layer.baseImpl->id + " - custom");
// Reset GL state to a known state so the CustomLayer always has a clean slate.
context.vertexArrayObject = 0;
@@ -317,7 +317,7 @@ void Painter::renderPass(PaintParameters& parameters,
context.setStencilMode(gl::StencilMode::disabled());
context.setColorMode(colorModeForRenderPass());
- layer.as<RenderCustomLayer>()->impl->render(state);
+ layer.as<RenderCustomLayer>()->impl().render(state);
// Reset the view back to our original one, just in case the CustomLayer changed
// the viewport or Framebuffer.
@@ -339,8 +339,8 @@ void Painter::renderPass(PaintParameters& parameters,
for (auto& tileRef : item.tiles) {
auto& tile = tileRef.get();
- MBGL_DEBUG_GROUP(context, layer.baseImpl.id + " - " + util::toString(tile.id));
- auto bucket = tile.tile.getBucket(layer);
+ MBGL_DEBUG_GROUP(context, layer.baseImpl->id + " - " + util::toString(tile.id));
+ auto bucket = tile.tile.getBucket(*layer.baseImpl);
bucket->render(*this, parameters, layer, tile);
}
@@ -366,8 +366,8 @@ void Painter::renderPass(PaintParameters& parameters,
} else {
for (auto& tileRef : item.tiles) {
auto& tile = tileRef.get();
- MBGL_DEBUG_GROUP(context, layer.baseImpl.id + " - " + util::toString(tile.id));
- auto bucket = tile.tile.getBucket(layer);
+ MBGL_DEBUG_GROUP(context, layer.baseImpl->id + " - " + util::toString(tile.id));
+ auto bucket = tile.tile.getBucket(*layer.baseImpl);
bucket->render(*this, parameters, layer, tile);
}
}
diff --git a/src/mbgl/renderer/render_background_layer.cpp b/src/mbgl/renderer/render_background_layer.cpp
index 8069209c71..f2e9c0cbaf 100644
--- a/src/mbgl/renderer/render_background_layer.cpp
+++ b/src/mbgl/renderer/render_background_layer.cpp
@@ -4,9 +4,12 @@
namespace mbgl {
-RenderBackgroundLayer::RenderBackgroundLayer(const style::BackgroundLayer::Impl& _impl)
- : RenderLayer(style::LayerType::Background, _impl),
- impl(&_impl) {
+RenderBackgroundLayer::RenderBackgroundLayer(Immutable<style::BackgroundLayer::Impl> _impl)
+ : RenderLayer(style::LayerType::Background, _impl) {
+}
+
+const style::BackgroundLayer::Impl& RenderBackgroundLayer::impl() const {
+ return static_cast<const style::BackgroundLayer::Impl&>(*baseImpl);
}
std::unique_ptr<RenderLayer> RenderBackgroundLayer::clone() const {
@@ -20,7 +23,7 @@ std::unique_ptr<Bucket> RenderBackgroundLayer::createBucket(const BucketParamete
}
void RenderBackgroundLayer::cascade(const CascadeParameters &parameters) {
- unevaluated = impl->cascading.cascade(parameters, std::move(unevaluated));
+ unevaluated = impl().cascading.cascade(parameters, std::move(unevaluated));
}
void RenderBackgroundLayer::evaluate(const PropertyEvaluationParameters &parameters) {
diff --git a/src/mbgl/renderer/render_background_layer.hpp b/src/mbgl/renderer/render_background_layer.hpp
index 9174664a70..6a98ff330c 100644
--- a/src/mbgl/renderer/render_background_layer.hpp
+++ b/src/mbgl/renderer/render_background_layer.hpp
@@ -8,8 +8,7 @@ namespace mbgl {
class RenderBackgroundLayer: public RenderLayer {
public:
-
- RenderBackgroundLayer(const style::BackgroundLayer::Impl&);
+ RenderBackgroundLayer(Immutable<style::BackgroundLayer::Impl>);
~RenderBackgroundLayer() final = default;
std::unique_ptr<RenderLayer> clone() const override;
@@ -24,7 +23,7 @@ public:
style::BackgroundPaintProperties::Unevaluated unevaluated;
style::BackgroundPaintProperties::Evaluated evaluated;
- const style::BackgroundLayer::Impl* const impl;
+ const style::BackgroundLayer::Impl& impl() const;
};
template <>
diff --git a/src/mbgl/renderer/render_circle_layer.cpp b/src/mbgl/renderer/render_circle_layer.cpp
index e9ed465187..fb179082c9 100644
--- a/src/mbgl/renderer/render_circle_layer.cpp
+++ b/src/mbgl/renderer/render_circle_layer.cpp
@@ -7,9 +7,12 @@
namespace mbgl {
-RenderCircleLayer::RenderCircleLayer(const style::CircleLayer::Impl& _impl)
- : RenderLayer(style::LayerType::Circle, _impl),
- impl(&_impl) {
+RenderCircleLayer::RenderCircleLayer(Immutable<style::CircleLayer::Impl> _impl)
+ : RenderLayer(style::LayerType::Circle, _impl) {
+}
+
+const style::CircleLayer::Impl& RenderCircleLayer::impl() const {
+ return static_cast<const style::CircleLayer::Impl&>(*baseImpl);
}
std::unique_ptr<RenderLayer> RenderCircleLayer::clone() const {
@@ -21,7 +24,7 @@ std::unique_ptr<Bucket> RenderCircleLayer::createBucket(const BucketParameters&
}
void RenderCircleLayer::cascade(const CascadeParameters& parameters) {
- unevaluated = impl->cascading.cascade(parameters, std::move(unevaluated));
+ unevaluated = impl().cascading.cascade(parameters, std::move(unevaluated));
}
void RenderCircleLayer::evaluate(const PropertyEvaluationParameters& parameters) {
diff --git a/src/mbgl/renderer/render_circle_layer.hpp b/src/mbgl/renderer/render_circle_layer.hpp
index 60d600faca..7c411e80aa 100644
--- a/src/mbgl/renderer/render_circle_layer.hpp
+++ b/src/mbgl/renderer/render_circle_layer.hpp
@@ -8,8 +8,7 @@ namespace mbgl {
class RenderCircleLayer: public RenderLayer {
public:
-
- RenderCircleLayer(const style::CircleLayer::Impl&);
+ RenderCircleLayer(Immutable<style::CircleLayer::Impl>);
~RenderCircleLayer() final = default;
std::unique_ptr<RenderLayer> clone() const override;
@@ -31,7 +30,7 @@ public:
style::CirclePaintProperties::Unevaluated unevaluated;
style::CirclePaintProperties::Evaluated evaluated;
- const style::CircleLayer::Impl* const impl;
+ const style::CircleLayer::Impl& impl() const;
};
template <>
diff --git a/src/mbgl/renderer/render_custom_layer.cpp b/src/mbgl/renderer/render_custom_layer.cpp
index d89fa7bba2..0f22bc8780 100644
--- a/src/mbgl/renderer/render_custom_layer.cpp
+++ b/src/mbgl/renderer/render_custom_layer.cpp
@@ -4,9 +4,12 @@
namespace mbgl {
-RenderCustomLayer::RenderCustomLayer(const style::CustomLayer::Impl& _impl)
- : RenderLayer(style::LayerType::Custom, _impl),
- impl(&_impl) {
+RenderCustomLayer::RenderCustomLayer(Immutable<style::CustomLayer::Impl> _impl)
+ : RenderLayer(style::LayerType::Custom, _impl) {
+}
+
+const style::CustomLayer::Impl& RenderCustomLayer::impl() const {
+ return static_cast<const style::CustomLayer::Impl&>(*baseImpl);
}
std::unique_ptr<RenderLayer> RenderCustomLayer::clone() const {
diff --git a/src/mbgl/renderer/render_custom_layer.hpp b/src/mbgl/renderer/render_custom_layer.hpp
index f6ef253481..9b16928a58 100644
--- a/src/mbgl/renderer/render_custom_layer.hpp
+++ b/src/mbgl/renderer/render_custom_layer.hpp
@@ -7,8 +7,7 @@ namespace mbgl {
class RenderCustomLayer: public RenderLayer {
public:
-
- RenderCustomLayer(const style::CustomLayer::Impl&);
+ RenderCustomLayer(Immutable<style::CustomLayer::Impl>);
~RenderCustomLayer() final = default;
std::unique_ptr<RenderLayer> clone() const override;
@@ -19,7 +18,7 @@ public:
std::unique_ptr<Bucket> createBucket(const BucketParameters&, const std::vector<const RenderLayer*>&) const final;
- const style::CustomLayer::Impl* const impl;
+ const style::CustomLayer::Impl& impl() const;
};
template <>
diff --git a/src/mbgl/renderer/render_fill_extrusion_layer.cpp b/src/mbgl/renderer/render_fill_extrusion_layer.cpp
index f6ba164d8c..8dc6e93a9e 100644
--- a/src/mbgl/renderer/render_fill_extrusion_layer.cpp
+++ b/src/mbgl/renderer/render_fill_extrusion_layer.cpp
@@ -7,9 +7,12 @@
namespace mbgl {
-RenderFillExtrusionLayer::RenderFillExtrusionLayer(const style::FillExtrusionLayer::Impl& _impl)
- : RenderLayer(style::LayerType::FillExtrusion, _impl),
- impl(&_impl) {
+RenderFillExtrusionLayer::RenderFillExtrusionLayer(Immutable<style::FillExtrusionLayer::Impl> _impl)
+ : RenderLayer(style::LayerType::FillExtrusion, _impl) {
+}
+
+const style::FillExtrusionLayer::Impl& RenderFillExtrusionLayer::impl() const {
+ return static_cast<const style::FillExtrusionLayer::Impl&>(*baseImpl);
}
std::unique_ptr<RenderLayer> RenderFillExtrusionLayer::clone() const {
@@ -21,7 +24,7 @@ std::unique_ptr<Bucket> RenderFillExtrusionLayer::createBucket(const BucketParam
}
void RenderFillExtrusionLayer::cascade(const CascadeParameters& parameters) {
- unevaluated = impl->cascading.cascade(parameters, std::move(unevaluated));
+ unevaluated = impl().cascading.cascade(parameters, std::move(unevaluated));
}
void RenderFillExtrusionLayer::evaluate(const PropertyEvaluationParameters& parameters) {
diff --git a/src/mbgl/renderer/render_fill_extrusion_layer.hpp b/src/mbgl/renderer/render_fill_extrusion_layer.hpp
index bd66d8e3b1..2bfbc296c1 100644
--- a/src/mbgl/renderer/render_fill_extrusion_layer.hpp
+++ b/src/mbgl/renderer/render_fill_extrusion_layer.hpp
@@ -8,8 +8,7 @@ namespace mbgl {
class RenderFillExtrusionLayer: public RenderLayer {
public:
-
- RenderFillExtrusionLayer(const style::FillExtrusionLayer::Impl&);
+ RenderFillExtrusionLayer(Immutable<style::FillExtrusionLayer::Impl>);
~RenderFillExtrusionLayer() final = default;
std::unique_ptr<RenderLayer> clone() const override;
@@ -31,7 +30,7 @@ public:
style::FillExtrusionPaintProperties::Unevaluated unevaluated;
style::FillExtrusionPaintProperties::Evaluated evaluated;
- const style::FillExtrusionLayer::Impl* const impl;
+ const style::FillExtrusionLayer::Impl& impl() const;
};
template <>
diff --git a/src/mbgl/renderer/render_fill_layer.cpp b/src/mbgl/renderer/render_fill_layer.cpp
index 340ec85803..0de22b3ca8 100644
--- a/src/mbgl/renderer/render_fill_layer.cpp
+++ b/src/mbgl/renderer/render_fill_layer.cpp
@@ -7,9 +7,12 @@
namespace mbgl {
-RenderFillLayer::RenderFillLayer(const style::FillLayer::Impl& _impl)
- : RenderLayer(style::LayerType::Fill, _impl),
- impl(&_impl) {
+RenderFillLayer::RenderFillLayer(Immutable<style::FillLayer::Impl> _impl)
+ : RenderLayer(style::LayerType::Fill, _impl) {
+}
+
+const style::FillLayer::Impl& RenderFillLayer::impl() const {
+ return static_cast<const style::FillLayer::Impl&>(*baseImpl);
}
std::unique_ptr<RenderLayer> RenderFillLayer::clone() const {
@@ -21,7 +24,7 @@ std::unique_ptr<Bucket> RenderFillLayer::createBucket(const BucketParameters& pa
}
void RenderFillLayer::cascade(const CascadeParameters& parameters) {
- unevaluated = impl->cascading.cascade(parameters, std::move(unevaluated));
+ unevaluated = impl().cascading.cascade(parameters, std::move(unevaluated));
}
void RenderFillLayer::evaluate(const PropertyEvaluationParameters& parameters) {
diff --git a/src/mbgl/renderer/render_fill_layer.hpp b/src/mbgl/renderer/render_fill_layer.hpp
index 8080cf289b..7e23a61a00 100644
--- a/src/mbgl/renderer/render_fill_layer.hpp
+++ b/src/mbgl/renderer/render_fill_layer.hpp
@@ -8,8 +8,7 @@ namespace mbgl {
class RenderFillLayer: public RenderLayer {
public:
-
- RenderFillLayer(const style::FillLayer::Impl&);
+ RenderFillLayer(Immutable<style::FillLayer::Impl>);
~RenderFillLayer() final = default;
std::unique_ptr<RenderLayer> clone() const override;
@@ -31,7 +30,7 @@ public:
style::FillPaintProperties::Unevaluated unevaluated;
style::FillPaintProperties::Evaluated evaluated;
- const style::FillLayer::Impl* const impl;
+ const style::FillLayer::Impl& impl() const;
};
template <>
diff --git a/src/mbgl/renderer/render_layer.cpp b/src/mbgl/renderer/render_layer.cpp
index ed8864149b..2f30b2ce21 100644
--- a/src/mbgl/renderer/render_layer.cpp
+++ b/src/mbgl/renderer/render_layer.cpp
@@ -3,12 +3,17 @@
namespace mbgl {
-RenderLayer::RenderLayer(style::LayerType type_, const style::Layer::Impl& baseImpl_)
- : type(type_), baseImpl(baseImpl_) {
+RenderLayer::RenderLayer(style::LayerType type_, Immutable<style::Layer::Impl> baseImpl_)
+ : type(type_),
+ baseImpl(baseImpl_) {
+}
+
+void RenderLayer::setImpl(Immutable<style::Layer::Impl> impl) {
+ baseImpl = impl;
}
const std::string& RenderLayer::getID() const {
- return baseImpl.id;
+ return baseImpl->id;
}
bool RenderLayer::hasRenderPass(RenderPass pass) const {
@@ -17,9 +22,9 @@ bool RenderLayer::hasRenderPass(RenderPass pass) const {
bool RenderLayer::needsRendering(float zoom) const {
return passes != RenderPass::None
- && baseImpl.visibility != style::VisibilityType::None
- && baseImpl.minZoom <= zoom
- && baseImpl.maxZoom >= zoom;
+ && baseImpl->visibility != style::VisibilityType::None
+ && baseImpl->minZoom <= zoom
+ && baseImpl->maxZoom >= zoom;
}
} // namespace mbgl \ No newline at end of file
diff --git a/src/mbgl/renderer/render_layer.hpp b/src/mbgl/renderer/render_layer.hpp
index eea2ec1f61..a877405564 100644
--- a/src/mbgl/renderer/render_layer.hpp
+++ b/src/mbgl/renderer/render_layer.hpp
@@ -16,14 +16,12 @@ class CascadeParameters;
class PropertyEvaluationParameters;
class RenderLayer {
-
protected:
- RenderLayer(style::LayerType, const style::Layer::Impl&);
+ RenderLayer(style::LayerType, Immutable<style::Layer::Impl>);
const style::LayerType type;
public:
-
virtual ~RenderLayer() = default;
// Create an identical copy of this layer.
@@ -73,11 +71,12 @@ public:
virtual std::unique_ptr<Bucket> createBucket(const BucketParameters&, const std::vector<const RenderLayer*>&) const = 0;
// Private implementation
- const style::Layer::Impl& baseImpl;
+ Immutable<style::Layer::Impl> baseImpl;
+ void setImpl(Immutable<style::Layer::Impl>);
friend std::string layoutKey(const RenderLayer&);
-protected:
+protected:
// Stores what render passes this layer is currently enabled for. This depends on the
// evaluated StyleProperties object and is updated accordingly.
RenderPass passes = RenderPass::None;
diff --git a/src/mbgl/renderer/render_light.cpp b/src/mbgl/renderer/render_light.cpp
index 134e1829e0..1fc346fd26 100644
--- a/src/mbgl/renderer/render_light.cpp
+++ b/src/mbgl/renderer/render_light.cpp
@@ -2,17 +2,8 @@
namespace mbgl {
-RenderLight::RenderLight(std::shared_ptr<const style::Light::Impl> impl_)
- : impl(std::move(impl_)) {
-}
-
-RenderLight::RenderLight(std::shared_ptr<const style::Light::Impl> impl_, const TransitioningLight transitioning_)
- : impl(std::move(impl_))
- , transitioning(transitioning_) {
-}
-
-std::unique_ptr<RenderLight> RenderLight::copy(std::shared_ptr<const style::Light::Impl> impl_) const {
- return std::make_unique<RenderLight>(std::move(impl_), transitioning);
+RenderLight::RenderLight(Immutable<style::Light::Impl> impl_)
+ : impl(std::move(impl_)) {
}
void RenderLight::transition(const CascadeParameters& parameters) {
diff --git a/src/mbgl/renderer/render_light.hpp b/src/mbgl/renderer/render_light.hpp
index 275f3ae8ba..ed8d8bf59c 100644
--- a/src/mbgl/renderer/render_light.hpp
+++ b/src/mbgl/renderer/render_light.hpp
@@ -74,14 +74,7 @@ using EvaluatedLight = Evaluated<style::LightProperties>;
class RenderLight {
public:
- RenderLight(std::shared_ptr<const style::Light::Impl>);
-
- // Creates a copy intitalized with previous transitioning light
- RenderLight(std::shared_ptr<const style::Light::Impl>, const TransitioningLight);
-
- // creates a copy initialized with previous transitioning
- // values
- std::unique_ptr<RenderLight> copy(std::shared_ptr<const style::Light::Impl>) const;
+ RenderLight(Immutable<style::Light::Impl>);
void transition(const CascadeParameters&);
void evaluate(const PropertyEvaluationParameters&);
@@ -89,10 +82,9 @@ public:
const EvaluatedLight& getEvaluated() const;
- const std::shared_ptr<const style::Light::Impl> impl;
+ Immutable<style::Light::Impl> impl;
private:
-
TransitioningLight transitioning;
EvaluatedLight evaluated;
};
diff --git a/src/mbgl/renderer/render_line_layer.cpp b/src/mbgl/renderer/render_line_layer.cpp
index 06c2564516..6573118c3b 100644
--- a/src/mbgl/renderer/render_line_layer.cpp
+++ b/src/mbgl/renderer/render_line_layer.cpp
@@ -7,9 +7,12 @@
namespace mbgl {
-RenderLineLayer::RenderLineLayer(const style::LineLayer::Impl& _impl)
- : RenderLayer(style::LayerType::Line, _impl),
- impl(&_impl) {
+RenderLineLayer::RenderLineLayer(Immutable<style::LineLayer::Impl> _impl)
+ : RenderLayer(style::LayerType::Line, _impl) {
+}
+
+const style::LineLayer::Impl& RenderLineLayer::impl() const {
+ return static_cast<const style::LineLayer::Impl&>(*baseImpl);
}
std::unique_ptr<RenderLayer> RenderLineLayer::clone() const {
@@ -17,11 +20,11 @@ std::unique_ptr<RenderLayer> RenderLineLayer::clone() const {
}
std::unique_ptr<Bucket> RenderLineLayer::createBucket(const BucketParameters& parameters, const std::vector<const RenderLayer*>& layers) const {
- return std::make_unique<LineBucket>(parameters, layers, impl->layout);
+ return std::make_unique<LineBucket>(parameters, layers, impl().layout);
}
void RenderLineLayer::cascade(const CascadeParameters& parameters) {
- unevaluated = impl->cascading.cascade(parameters, std::move(unevaluated));
+ unevaluated = impl().cascading.cascade(parameters, std::move(unevaluated));
}
void RenderLineLayer::evaluate(const PropertyEvaluationParameters& parameters) {
diff --git a/src/mbgl/renderer/render_line_layer.hpp b/src/mbgl/renderer/render_line_layer.hpp
index 6d6fecc227..dce4d07f18 100644
--- a/src/mbgl/renderer/render_line_layer.hpp
+++ b/src/mbgl/renderer/render_line_layer.hpp
@@ -8,8 +8,7 @@ namespace mbgl {
class RenderLineLayer: public RenderLayer {
public:
-
- RenderLineLayer(const style::LineLayer::Impl&);
+ RenderLineLayer(Immutable<style::LineLayer::Impl>);
~RenderLineLayer() final = default;
std::unique_ptr<RenderLayer> clone() const override;
@@ -31,14 +30,13 @@ public:
style::LinePaintProperties::Unevaluated unevaluated;
style::LinePaintProperties::Evaluated evaluated;
- const style::LineLayer::Impl* const impl;
+ const style::LineLayer::Impl& impl() const;
// Special case
float dashLineWidth = 1;
private:
float getLineWidth(const GeometryTileFeature&, const float) const;
-
};
template <>
diff --git a/src/mbgl/renderer/render_raster_layer.cpp b/src/mbgl/renderer/render_raster_layer.cpp
index 5e664e6f58..2e79a785bc 100644
--- a/src/mbgl/renderer/render_raster_layer.cpp
+++ b/src/mbgl/renderer/render_raster_layer.cpp
@@ -4,9 +4,12 @@
namespace mbgl {
-RenderRasterLayer::RenderRasterLayer(const style::RasterLayer::Impl& _impl)
- : RenderLayer(style::LayerType::Raster, _impl),
- impl(&_impl) {
+RenderRasterLayer::RenderRasterLayer(Immutable<style::RasterLayer::Impl> _impl)
+ : RenderLayer(style::LayerType::Raster, _impl) {
+}
+
+const style::RasterLayer::Impl& RenderRasterLayer::impl() const {
+ return static_cast<const style::RasterLayer::Impl&>(*baseImpl);
}
std::unique_ptr<RenderLayer> RenderRasterLayer::clone() const {
@@ -19,7 +22,7 @@ std::unique_ptr<Bucket> RenderRasterLayer::createBucket(const BucketParameters&,
}
void RenderRasterLayer::cascade(const CascadeParameters& parameters) {
- unevaluated = impl->cascading.cascade(parameters, std::move(unevaluated));
+ unevaluated = impl().cascading.cascade(parameters, std::move(unevaluated));
}
void RenderRasterLayer::evaluate(const PropertyEvaluationParameters& parameters) {
diff --git a/src/mbgl/renderer/render_raster_layer.hpp b/src/mbgl/renderer/render_raster_layer.hpp
index 3ffeb8febf..f51d042d5f 100644
--- a/src/mbgl/renderer/render_raster_layer.hpp
+++ b/src/mbgl/renderer/render_raster_layer.hpp
@@ -8,8 +8,7 @@ namespace mbgl {
class RenderRasterLayer: public RenderLayer {
public:
-
- RenderRasterLayer(const style::RasterLayer::Impl&);
+ RenderRasterLayer(Immutable<style::RasterLayer::Impl>);
~RenderRasterLayer() final = default;
std::unique_ptr<RenderLayer> clone() const override;
@@ -24,7 +23,7 @@ public:
style::RasterPaintProperties::Unevaluated unevaluated;
style::RasterPaintProperties::Evaluated evaluated;
- const style::RasterLayer::Impl* const impl;
+ const style::RasterLayer::Impl& impl() const;
};
template <>
diff --git a/src/mbgl/renderer/render_source.cpp b/src/mbgl/renderer/render_source.cpp
index 22043f9f3c..9eca54795a 100644
--- a/src/mbgl/renderer/render_source.cpp
+++ b/src/mbgl/renderer/render_source.cpp
@@ -6,7 +6,7 @@ namespace mbgl {
static RenderSourceObserver nullObserver;
-RenderSource::RenderSource(const style::Source::Impl& impl)
+RenderSource::RenderSource(Immutable<style::Source::Impl> impl)
: baseImpl(impl),
observer(&nullObserver) {
}
@@ -15,6 +15,10 @@ void RenderSource::setObserver(RenderSourceObserver* observer_) {
observer = observer_;
}
+void RenderSource::setImpl(Immutable<style::Source::Impl> impl) {
+ baseImpl = impl;
+}
+
void RenderSource::onTileChanged(Tile& tile) {
observer->onTileChanged(*this, tile.id);
}
diff --git a/src/mbgl/renderer/render_source.hpp b/src/mbgl/renderer/render_source.hpp
index e682e4cd1a..178ee92f93 100644
--- a/src/mbgl/renderer/render_source.hpp
+++ b/src/mbgl/renderer/render_source.hpp
@@ -29,7 +29,7 @@ class ClipIDGenerator;
class RenderSource : protected TileObserver {
public:
- RenderSource(const style::Source::Impl&);
+ RenderSource(Immutable<style::Source::Impl>);
~RenderSource() override = default;
virtual bool isLoaded() const = 0;
@@ -71,7 +71,9 @@ public:
void setObserver(RenderSourceObserver*);
- const style::Source::Impl& baseImpl;
+ Immutable<style::Source::Impl> baseImpl;
+ void setImpl(Immutable<style::Source::Impl>);
+
bool enabled = false;
protected:
diff --git a/src/mbgl/renderer/render_symbol_layer.cpp b/src/mbgl/renderer/render_symbol_layer.cpp
index 30d769e032..7ea6190cb1 100644
--- a/src/mbgl/renderer/render_symbol_layer.cpp
+++ b/src/mbgl/renderer/render_symbol_layer.cpp
@@ -8,9 +8,12 @@
namespace mbgl {
-RenderSymbolLayer::RenderSymbolLayer(const style::SymbolLayer::Impl& _impl)
- : RenderLayer(style::LayerType::Symbol, _impl),
- impl(&_impl) {
+RenderSymbolLayer::RenderSymbolLayer(Immutable<style::SymbolLayer::Impl> _impl)
+ : RenderLayer(style::LayerType::Symbol, _impl) {
+}
+
+const style::SymbolLayer::Impl& RenderSymbolLayer::impl() const {
+ return static_cast<const style::SymbolLayer::Impl&>(*baseImpl);
}
std::unique_ptr<RenderLayer> RenderSymbolLayer::clone() const {
@@ -35,7 +38,7 @@ std::unique_ptr<SymbolLayout> RenderSymbolLayer::createLayout(const BucketParame
}
void RenderSymbolLayer::cascade(const CascadeParameters& parameters) {
- unevaluated = impl->cascading.cascade(parameters, std::move(unevaluated));
+ unevaluated = impl().cascading.cascade(parameters, std::move(unevaluated));
}
void RenderSymbolLayer::evaluate(const PropertyEvaluationParameters& parameters) {
diff --git a/src/mbgl/renderer/render_symbol_layer.hpp b/src/mbgl/renderer/render_symbol_layer.hpp
index 80ffd95a06..553deb8259 100644
--- a/src/mbgl/renderer/render_symbol_layer.hpp
+++ b/src/mbgl/renderer/render_symbol_layer.hpp
@@ -61,7 +61,7 @@ class GeometryTileLayer;
class RenderSymbolLayer: public RenderLayer {
public:
- RenderSymbolLayer(const style::SymbolLayer::Impl&);
+ RenderSymbolLayer(Immutable<style::SymbolLayer::Impl>);
~RenderSymbolLayer() final = default;
std::unique_ptr<RenderLayer> clone() const override;
@@ -87,7 +87,7 @@ public:
float iconSize = 1.0f;
float textSize = 16.0f;
- const style::SymbolLayer::Impl* const impl;
+ const style::SymbolLayer::Impl& impl() const;
};
template <>
diff --git a/src/mbgl/renderer/sources/render_geojson_source.cpp b/src/mbgl/renderer/sources/render_geojson_source.cpp
index 2b1eeea73b..893f6a2ac6 100644
--- a/src/mbgl/renderer/sources/render_geojson_source.cpp
+++ b/src/mbgl/renderer/sources/render_geojson_source.cpp
@@ -9,12 +9,15 @@ namespace mbgl {
using namespace style;
-RenderGeoJSONSource::RenderGeoJSONSource(const style::GeoJSONSource::Impl& impl_)
- : RenderSource(impl_),
- impl(impl_) {
+RenderGeoJSONSource::RenderGeoJSONSource(Immutable<style::GeoJSONSource::Impl> impl_)
+ : RenderSource(impl_) {
tilePyramid.setObserver(this);
}
+const style::GeoJSONSource::Impl& RenderGeoJSONSource::impl() const {
+ return static_cast<const style::GeoJSONSource::Impl&>(*baseImpl);
+}
+
bool RenderGeoJSONSource::isLoaded() const {
return tilePyramid.isLoaded();
}
@@ -37,7 +40,7 @@ std::map<UnwrappedTileID, RenderTile>& RenderGeoJSONSource::getRenderTiles() {
}
void RenderGeoJSONSource::updateTiles(const TileParameters& parameters) {
- GeoJSONData* data_ = impl.getData();
+ GeoJSONData* data_ = impl().getData();
if (!data_) {
return;
@@ -55,9 +58,9 @@ void RenderGeoJSONSource::updateTiles(const TileParameters& parameters) {
tilePyramid.updateTiles(parameters,
SourceType::GeoJSON,
util::tileSize,
- impl.getZoomRange(),
+ impl().getZoomRange(),
[&] (const OverscaledTileID& tileID) {
- return std::make_unique<GeoJSONTile>(tileID, impl.id, parameters, data->getTile(tileID.canonical));
+ return std::make_unique<GeoJSONTile>(tileID, impl().id, parameters, data->getTile(tileID.canonical));
});
}
diff --git a/src/mbgl/renderer/sources/render_geojson_source.hpp b/src/mbgl/renderer/sources/render_geojson_source.hpp
index 262ab29276..0f9379b9b6 100644
--- a/src/mbgl/renderer/sources/render_geojson_source.hpp
+++ b/src/mbgl/renderer/sources/render_geojson_source.hpp
@@ -12,7 +12,7 @@ class GeoJSONData;
class RenderGeoJSONSource : public RenderSource {
public:
- RenderGeoJSONSource(const style::GeoJSONSource::Impl&);
+ RenderGeoJSONSource(Immutable<style::GeoJSONSource::Impl>);
bool isLoaded() const final;
@@ -51,7 +51,8 @@ public:
void dumpDebugLogs() const final;
private:
- const style::GeoJSONSource::Impl& impl;
+ const style::GeoJSONSource::Impl& impl() const;
+
TilePyramid tilePyramid;
style::GeoJSONData* data;
};
diff --git a/src/mbgl/renderer/sources/render_raster_source.cpp b/src/mbgl/renderer/sources/render_raster_source.cpp
index c5a29eebf5..e2d641c4e4 100644
--- a/src/mbgl/renderer/sources/render_raster_source.cpp
+++ b/src/mbgl/renderer/sources/render_raster_source.cpp
@@ -6,12 +6,15 @@ namespace mbgl {
using namespace style;
-RenderRasterSource::RenderRasterSource(const style::RasterSource::Impl& impl_)
- : RenderSource(impl_),
- impl(impl_) {
+RenderRasterSource::RenderRasterSource(Immutable<style::RasterSource::Impl> impl_)
+ : RenderSource(impl_) {
tilePyramid.setObserver(this);
}
+const style::RasterSource::Impl& RenderRasterSource::impl() const {
+ return static_cast<const style::RasterSource::Impl&>(*baseImpl);
+}
+
bool RenderRasterSource::isLoaded() const {
return tilePyramid.isLoaded();
}
@@ -33,7 +36,7 @@ std::map<UnwrappedTileID, RenderTile>& RenderRasterSource::getRenderTiles() {
}
void RenderRasterSource::updateTiles(const TileParameters& parameters) {
- optional<Tileset> tileset = impl.getTileset();
+ optional<Tileset> tileset = impl().getTileset();
if (!tileset) {
return;
@@ -46,7 +49,7 @@ void RenderRasterSource::updateTiles(const TileParameters& parameters) {
tilePyramid.updateTiles(parameters,
SourceType::Raster,
- impl.getTileSize(),
+ impl().getTileSize(),
tileset->zoomRange,
[&] (const OverscaledTileID& tileID) {
return std::make_unique<RasterTile>(tileID, parameters, *tileset);
diff --git a/src/mbgl/renderer/sources/render_raster_source.hpp b/src/mbgl/renderer/sources/render_raster_source.hpp
index 5690ba80ea..9bf4436bc7 100644
--- a/src/mbgl/renderer/sources/render_raster_source.hpp
+++ b/src/mbgl/renderer/sources/render_raster_source.hpp
@@ -8,7 +8,7 @@ namespace mbgl {
class RenderRasterSource : public RenderSource {
public:
- RenderRasterSource(const style::RasterSource::Impl&);
+ RenderRasterSource(Immutable<style::RasterSource::Impl>);
bool isLoaded() const final;
@@ -47,7 +47,8 @@ public:
void dumpDebugLogs() const final;
private:
- const style::RasterSource::Impl& impl;
+ const style::RasterSource::Impl& impl() const;
+
TilePyramid tilePyramid;
optional<std::vector<std::string>> tileURLTemplates;
};
diff --git a/src/mbgl/renderer/sources/render_vector_source.cpp b/src/mbgl/renderer/sources/render_vector_source.cpp
index 0db4698a81..f88ca2beea 100644
--- a/src/mbgl/renderer/sources/render_vector_source.cpp
+++ b/src/mbgl/renderer/sources/render_vector_source.cpp
@@ -9,12 +9,15 @@ namespace mbgl {
using namespace style;
-RenderVectorSource::RenderVectorSource(const style::VectorSource::Impl& impl_)
- : RenderSource(impl_),
- impl(impl_) {
+RenderVectorSource::RenderVectorSource(Immutable<style::VectorSource::Impl> impl_)
+ : RenderSource(impl_) {
tilePyramid.setObserver(this);
}
+const style::VectorSource::Impl& RenderVectorSource::impl() const {
+ return static_cast<const style::VectorSource::Impl&>(*baseImpl);
+}
+
bool RenderVectorSource::isLoaded() const {
return tilePyramid.isLoaded();
}
@@ -37,7 +40,7 @@ std::map<UnwrappedTileID, RenderTile>& RenderVectorSource::getRenderTiles() {
}
void RenderVectorSource::updateTiles(const TileParameters& parameters) {
- optional<Tileset> tileset = impl.getTileset();
+ optional<Tileset> tileset = impl().getTileset();
if (!tileset) {
return;
@@ -53,7 +56,7 @@ void RenderVectorSource::updateTiles(const TileParameters& parameters) {
util::tileSize,
tileset->zoomRange,
[&] (const OverscaledTileID& tileID) {
- return std::make_unique<VectorTile>(tileID, impl.id, parameters, *tileset);
+ return std::make_unique<VectorTile>(tileID, impl().id, parameters, *tileset);
});
}
diff --git a/src/mbgl/renderer/sources/render_vector_source.hpp b/src/mbgl/renderer/sources/render_vector_source.hpp
index 36d75e0982..b3704a1274 100644
--- a/src/mbgl/renderer/sources/render_vector_source.hpp
+++ b/src/mbgl/renderer/sources/render_vector_source.hpp
@@ -8,7 +8,7 @@ namespace mbgl {
class RenderVectorSource : public RenderSource {
public:
- RenderVectorSource(const style::VectorSource::Impl&);
+ RenderVectorSource(Immutable<style::VectorSource::Impl>);
bool isLoaded() const final;
@@ -47,7 +47,8 @@ public:
void dumpDebugLogs() const final;
private:
- const style::VectorSource::Impl& impl;
+ const style::VectorSource::Impl& impl() const;
+
TilePyramid tilePyramid;
optional<std::vector<std::string>> tileURLTemplates;
};
diff --git a/src/mbgl/renderer/style_diff.cpp b/src/mbgl/renderer/style_diff.cpp
new file mode 100644
index 0000000000..12000069ea
--- /dev/null
+++ b/src/mbgl/renderer/style_diff.cpp
@@ -0,0 +1,56 @@
+#include <mbgl/renderer/style_diff.hpp>
+#include <mbgl/style/layer_impl.hpp>
+#include <mbgl/util/immutable.hpp>
+#include <mbgl/util/variant.hpp>
+#include <mbgl/util/longest_common_subsequence.hpp>
+
+namespace mbgl {
+
+template <class T>
+StyleDifference<T> diff(const std::vector<T>& a, const std::vector<T>& b) {
+ std::vector<T> lcs;
+
+ auto eq = [] (const T& lhs, const T& rhs) {
+ return std::tie(lhs->id, lhs->type)
+ == std::tie(rhs->id, rhs->type);
+ };
+
+ longest_common_subsequence(a.begin(), a.end(), b.begin(), b.end(), std::back_inserter(lcs), eq);
+
+ auto aIt = a.begin();
+ auto bIt = b.begin();
+ auto lIt = lcs.begin();
+
+ StyleDifference<T> result;
+
+ while (aIt != a.end() || bIt != b.end()) {
+ if (aIt != a.end() && (lIt == lcs.end() || !eq(*lIt, *aIt))) {
+ result.removed.emplace((*aIt)->id, *aIt);
+ aIt++;
+ } else if (bIt != b.end() && (lIt == lcs.end() || !eq(*lIt, *bIt))) {
+ result.added.emplace((*bIt)->id, *bIt);
+ bIt++;
+ } else {
+ if (aIt->get() != bIt->get()) {
+ result.changed.emplace((*bIt)->id, *bIt);
+ }
+ aIt++;
+ bIt++;
+ lIt++;
+ }
+ }
+
+ return result;
+}
+
+SourceDifference diffSources(const std::vector<ImmutableSource>& a,
+ const std::vector<ImmutableSource>& b) {
+ return diff(a, b);
+}
+
+LayerDifference diffLayers(const std::vector<ImmutableLayer>& a,
+ const std::vector<ImmutableLayer>& b) {
+ return diff(a, b);
+}
+
+} // namespace mbgl
diff --git a/src/mbgl/renderer/style_diff.hpp b/src/mbgl/renderer/style_diff.hpp
new file mode 100644
index 0000000000..dc2ef95c6c
--- /dev/null
+++ b/src/mbgl/renderer/style_diff.hpp
@@ -0,0 +1,30 @@
+#include <mbgl/style/source_impl.hpp>
+#include <mbgl/style/layer_impl.hpp>
+#include <mbgl/util/immutable.hpp>
+#include <mbgl/util/variant.hpp>
+
+#include <unordered_map>
+
+namespace mbgl {
+
+template <class T>
+class StyleDifference {
+public:
+ std::unordered_map<std::string, T> added;
+ std::unordered_map<std::string, T> removed;
+ std::unordered_map<std::string, T> changed;
+};
+
+using ImmutableSource = Immutable<style::Source::Impl>;
+using SourceDifference = StyleDifference<ImmutableSource>;
+
+SourceDifference diffSources(const std::vector<ImmutableSource>&,
+ const std::vector<ImmutableSource>&);
+
+using ImmutableLayer = Immutable<style::Layer::Impl>;
+using LayerDifference = StyleDifference<ImmutableLayer>;
+
+LayerDifference diffLayers(const std::vector<ImmutableLayer>&,
+ const std::vector<ImmutableLayer>&);
+
+} // namespace mbgl
diff --git a/src/mbgl/style/layer.cpp b/src/mbgl/style/layer.cpp
index e2eba0e2e0..fe51dd09ca 100644
--- a/src/mbgl/style/layer.cpp
+++ b/src/mbgl/style/layer.cpp
@@ -1,16 +1,23 @@
#include <mbgl/style/layer.hpp>
#include <mbgl/style/layer_impl.hpp>
-#include <mbgl/style/layer_type.hpp>
+#include <mbgl/style/layer_observer.hpp>
namespace mbgl {
namespace style {
-Layer::Layer(LayerType type_, std::unique_ptr<Impl> baseImpl_)
- : type(type_), baseImpl(std::move(baseImpl_)) {
+static LayerObserver nullObserver;
+
+Layer::Layer(Immutable<Impl> impl)
+ : baseImpl(std::move(impl)),
+ observer(&nullObserver) {
}
Layer::~Layer() = default;
+LayerType Layer::getType() const {
+ return baseImpl->type;
+}
+
const std::string& Layer::getID() const {
return baseImpl->id;
}
@@ -19,27 +26,16 @@ VisibilityType Layer::getVisibility() const {
return baseImpl->visibility;
}
-void Layer::setVisibility(VisibilityType value) {
- if (value == getVisibility())
- return;
- baseImpl->visibility = value;
- baseImpl->observer->onLayerVisibilityChanged(*this);
-}
-
float Layer::getMinZoom() const {
return baseImpl->minZoom;
}
-void Layer::setMinZoom(float minZoom) const {
- baseImpl->minZoom = minZoom;
-}
-
float Layer::getMaxZoom() const {
return baseImpl->maxZoom;
}
-void Layer::setMaxZoom(float maxZoom) const {
- baseImpl->maxZoom = maxZoom;
+void Layer::setObserver(LayerObserver* observer_) {
+ observer = observer_ ? observer_ : &nullObserver;
}
} // namespace style
diff --git a/src/mbgl/style/layer_impl.cpp b/src/mbgl/style/layer_impl.cpp
index 725064a9a2..a9a3941f3e 100644
--- a/src/mbgl/style/layer_impl.cpp
+++ b/src/mbgl/style/layer_impl.cpp
@@ -3,8 +3,10 @@
namespace mbgl {
namespace style {
-void Layer::Impl::setObserver(LayerObserver* observer_) {
- observer = observer_ ? observer_ : &nullObserver;
+Layer::Impl::Impl(LayerType type_, std::string layerID, std::string sourceID)
+ : type(type_),
+ id(std::move(layerID)),
+ source(std::move(sourceID)) {
}
} // namespace style
diff --git a/src/mbgl/style/layer_impl.hpp b/src/mbgl/style/layer_impl.hpp
index 914203f804..fe7259a11a 100644
--- a/src/mbgl/style/layer_impl.hpp
+++ b/src/mbgl/style/layer_impl.hpp
@@ -3,13 +3,10 @@
#include <mbgl/style/layer.hpp>
#include <mbgl/style/types.hpp>
#include <mbgl/style/filter.hpp>
-#include <mbgl/style/layer_observer.hpp>
-#include <mbgl/util/noncopyable.hpp>
#include <rapidjson/writer.h>
#include <rapidjson/stringbuffer.h>
-#include <memory>
#include <string>
#include <limits>
@@ -30,24 +27,19 @@ namespace style {
* Members that are public in `FooLayer::Impl` are part of the internal API for "foo" layers.
* Members that are private in `FooLayer::Impl` are internal to "foo" layers.
*/
-class Layer::Impl {
+class Layer::Impl : public EnableImmutableFromThis<Layer::Impl> {
public:
+ Impl(LayerType, std::string layerID, std::string sourceID);
virtual ~Impl() = default;
- // Create an identical copy of this layer.
- virtual std::unique_ptr<Layer> clone() const = 0;
-
- // Create a layer, copying all properties except id and paint properties from this layer.
- virtual std::unique_ptr<Layer> cloneRef(const std::string& id) const = 0;
+ Impl& operator=(const Impl&) = delete;
// Utility function for automatic layer grouping.
virtual void stringifyLayout(rapidjson::Writer<rapidjson::StringBuffer>&) const = 0;
virtual std::unique_ptr<RenderLayer> createRenderLayer() const = 0;
- void setObserver(LayerObserver*);
-
-public:
+ const LayerType type;
std::string id;
std::string source;
std::string sourceLayer;
@@ -56,13 +48,8 @@ public:
float maxZoom = std::numeric_limits<float>::infinity();
VisibilityType visibility = VisibilityType::Visible;
- LayerObserver nullObserver;
- LayerObserver* observer = &nullObserver;
-
protected:
- Impl() = default;
Impl(const Impl&) = default;
- Impl& operator=(const Impl&) = delete;
};
} // namespace style
diff --git a/src/mbgl/style/layers/background_layer.cpp b/src/mbgl/style/layers/background_layer.cpp
index b4ffea138b..3d29b9819c 100644
--- a/src/mbgl/style/layers/background_layer.cpp
+++ b/src/mbgl/style/layers/background_layer.cpp
@@ -3,38 +3,65 @@
#include <mbgl/style/layers/background_layer.hpp>
#include <mbgl/style/layers/background_layer_impl.hpp>
#include <mbgl/style/conversion/stringify.hpp>
+#include <mbgl/style/layer_observer.hpp>
namespace mbgl {
namespace style {
BackgroundLayer::BackgroundLayer(const std::string& layerID)
- : Layer(LayerType::Background, std::make_unique<Impl>())
- , impl(static_cast<Impl*>(baseImpl.get())) {
- impl->id = layerID;
+ : Layer(makeMutable<Impl>(LayerType::Background, layerID, std::string())) {
}
-BackgroundLayer::BackgroundLayer(const Impl& other)
- : Layer(LayerType::Background, std::make_unique<Impl>(other))
- , impl(static_cast<Impl*>(baseImpl.get())) {
+BackgroundLayer::BackgroundLayer(Immutable<Impl> impl_)
+ : Layer(std::move(impl_)) {
}
BackgroundLayer::~BackgroundLayer() = default;
-std::unique_ptr<Layer> BackgroundLayer::Impl::clone() const {
- return std::make_unique<BackgroundLayer>(*this);
+const BackgroundLayer::Impl& BackgroundLayer::impl() const {
+ return static_cast<const Impl&>(*baseImpl);
}
-std::unique_ptr<Layer> BackgroundLayer::Impl::cloneRef(const std::string& id_) const {
- auto result = std::make_unique<BackgroundLayer>(*this);
- result->impl->id = id_;
- result->impl->cascading = BackgroundPaintProperties::Cascading();
- return std::move(result);
+Mutable<BackgroundLayer::Impl> BackgroundLayer::mutableImpl() const {
+ return makeMutable<Impl>(impl());
+}
+
+std::unique_ptr<Layer> BackgroundLayer::cloneRef(const std::string& id_) const {
+ auto impl_ = mutableImpl();
+ impl_->id = id_;
+ impl_->cascading = BackgroundPaintProperties::Cascading();
+ return std::make_unique<BackgroundLayer>(std::move(impl_));
}
void BackgroundLayer::Impl::stringifyLayout(rapidjson::Writer<rapidjson::StringBuffer>&) const {
}
+// Visibility
+
+void BackgroundLayer::setVisibility(VisibilityType value) {
+ if (value == getVisibility())
+ return;
+ auto impl_ = mutableImpl();
+ impl_->visibility = value;
+ baseImpl = std::move(impl_);
+ observer->onLayerVisibilityChanged(*this);
+}
+
+// Zoom range
+
+void BackgroundLayer::setMinZoom(float minZoom) {
+ auto impl_ = mutableImpl();
+ impl_->minZoom = minZoom;
+ baseImpl = std::move(impl_);
+}
+
+void BackgroundLayer::setMaxZoom(float maxZoom) {
+ auto impl_ = mutableImpl();
+ impl_->maxZoom = maxZoom;
+ baseImpl = std::move(impl_);
+}
+
// Layout properties
@@ -45,22 +72,26 @@ PropertyValue<Color> BackgroundLayer::getDefaultBackgroundColor() {
}
PropertyValue<Color> BackgroundLayer::getBackgroundColor(const optional<std::string>& klass) const {
- return impl->cascading.template get<BackgroundColor>().get(klass);
+ return impl().cascading.template get<BackgroundColor>().get(klass);
}
void BackgroundLayer::setBackgroundColor(PropertyValue<Color> value, const optional<std::string>& klass) {
if (value == getBackgroundColor(klass))
return;
- impl->cascading.template get<BackgroundColor>().set(value, klass);
- impl->observer->onLayerPaintPropertyChanged(*this);
+ auto impl_ = mutableImpl();
+ impl_->cascading.template get<BackgroundColor>().set(value, klass);
+ baseImpl = std::move(impl_);
+ observer->onLayerPaintPropertyChanged(*this);
}
void BackgroundLayer::setBackgroundColorTransition(const TransitionOptions& value, const optional<std::string>& klass) {
- impl->cascading.template get<BackgroundColor>().setTransition(value, klass);
+ auto impl_ = mutableImpl();
+ impl_->cascading.template get<BackgroundColor>().setTransition(value, klass);
+ baseImpl = std::move(impl_);
}
TransitionOptions BackgroundLayer::getBackgroundColorTransition(const optional<std::string>& klass) const {
- return impl->cascading.template get<BackgroundColor>().getTransition(klass);
+ return impl().cascading.template get<BackgroundColor>().getTransition(klass);
}
PropertyValue<std::string> BackgroundLayer::getDefaultBackgroundPattern() {
@@ -68,22 +99,26 @@ PropertyValue<std::string> BackgroundLayer::getDefaultBackgroundPattern() {
}
PropertyValue<std::string> BackgroundLayer::getBackgroundPattern(const optional<std::string>& klass) const {
- return impl->cascading.template get<BackgroundPattern>().get(klass);
+ return impl().cascading.template get<BackgroundPattern>().get(klass);
}
void BackgroundLayer::setBackgroundPattern(PropertyValue<std::string> value, const optional<std::string>& klass) {
if (value == getBackgroundPattern(klass))
return;
- impl->cascading.template get<BackgroundPattern>().set(value, klass);
- impl->observer->onLayerPaintPropertyChanged(*this);
+ auto impl_ = mutableImpl();
+ impl_->cascading.template get<BackgroundPattern>().set(value, klass);
+ baseImpl = std::move(impl_);
+ observer->onLayerPaintPropertyChanged(*this);
}
void BackgroundLayer::setBackgroundPatternTransition(const TransitionOptions& value, const optional<std::string>& klass) {
- impl->cascading.template get<BackgroundPattern>().setTransition(value, klass);
+ auto impl_ = mutableImpl();
+ impl_->cascading.template get<BackgroundPattern>().setTransition(value, klass);
+ baseImpl = std::move(impl_);
}
TransitionOptions BackgroundLayer::getBackgroundPatternTransition(const optional<std::string>& klass) const {
- return impl->cascading.template get<BackgroundPattern>().getTransition(klass);
+ return impl().cascading.template get<BackgroundPattern>().getTransition(klass);
}
PropertyValue<float> BackgroundLayer::getDefaultBackgroundOpacity() {
@@ -91,22 +126,26 @@ PropertyValue<float> BackgroundLayer::getDefaultBackgroundOpacity() {
}
PropertyValue<float> BackgroundLayer::getBackgroundOpacity(const optional<std::string>& klass) const {
- return impl->cascading.template get<BackgroundOpacity>().get(klass);
+ return impl().cascading.template get<BackgroundOpacity>().get(klass);
}
void BackgroundLayer::setBackgroundOpacity(PropertyValue<float> value, const optional<std::string>& klass) {
if (value == getBackgroundOpacity(klass))
return;
- impl->cascading.template get<BackgroundOpacity>().set(value, klass);
- impl->observer->onLayerPaintPropertyChanged(*this);
+ auto impl_ = mutableImpl();
+ impl_->cascading.template get<BackgroundOpacity>().set(value, klass);
+ baseImpl = std::move(impl_);
+ observer->onLayerPaintPropertyChanged(*this);
}
void BackgroundLayer::setBackgroundOpacityTransition(const TransitionOptions& value, const optional<std::string>& klass) {
- impl->cascading.template get<BackgroundOpacity>().setTransition(value, klass);
+ auto impl_ = mutableImpl();
+ impl_->cascading.template get<BackgroundOpacity>().setTransition(value, klass);
+ baseImpl = std::move(impl_);
}
TransitionOptions BackgroundLayer::getBackgroundOpacityTransition(const optional<std::string>& klass) const {
- return impl->cascading.template get<BackgroundOpacity>().getTransition(klass);
+ return impl().cascading.template get<BackgroundOpacity>().getTransition(klass);
}
} // namespace style
diff --git a/src/mbgl/style/layers/background_layer_impl.cpp b/src/mbgl/style/layers/background_layer_impl.cpp
index 6c4a4c26d9..07249ec5a4 100644
--- a/src/mbgl/style/layers/background_layer_impl.cpp
+++ b/src/mbgl/style/layers/background_layer_impl.cpp
@@ -5,7 +5,7 @@ namespace mbgl {
namespace style {
std::unique_ptr<RenderLayer> BackgroundLayer::Impl::createRenderLayer() const {
- return std::make_unique<RenderBackgroundLayer>(*this);
+ return std::make_unique<RenderBackgroundLayer>(staticImmutableCast<BackgroundLayer::Impl>(immutableFromThis()));
}
} // namespace style
diff --git a/src/mbgl/style/layers/background_layer_impl.hpp b/src/mbgl/style/layers/background_layer_impl.hpp
index 85152da4ec..41eee7bdf3 100644
--- a/src/mbgl/style/layers/background_layer_impl.hpp
+++ b/src/mbgl/style/layers/background_layer_impl.hpp
@@ -9,8 +9,8 @@ namespace style {
class BackgroundLayer::Impl : public Layer::Impl {
public:
- std::unique_ptr<Layer> clone() const override;
- std::unique_ptr<Layer> cloneRef(const std::string& id) const override;
+ using Layer::Impl::Impl;
+
void stringifyLayout(rapidjson::Writer<rapidjson::StringBuffer>&) const override;
std::unique_ptr<RenderLayer> createRenderLayer() const override;
diff --git a/src/mbgl/style/layers/circle_layer.cpp b/src/mbgl/style/layers/circle_layer.cpp
index 8b3431a9a1..6fcfe445a5 100644
--- a/src/mbgl/style/layers/circle_layer.cpp
+++ b/src/mbgl/style/layers/circle_layer.cpp
@@ -3,33 +3,34 @@
#include <mbgl/style/layers/circle_layer.hpp>
#include <mbgl/style/layers/circle_layer_impl.hpp>
#include <mbgl/style/conversion/stringify.hpp>
+#include <mbgl/style/layer_observer.hpp>
namespace mbgl {
namespace style {
CircleLayer::CircleLayer(const std::string& layerID, const std::string& sourceID)
- : Layer(LayerType::Circle, std::make_unique<Impl>())
- , impl(static_cast<Impl*>(baseImpl.get())) {
- impl->id = layerID;
- impl->source = sourceID;
+ : Layer(makeMutable<Impl>(LayerType::Circle, layerID, sourceID)) {
}
-CircleLayer::CircleLayer(const Impl& other)
- : Layer(LayerType::Circle, std::make_unique<Impl>(other))
- , impl(static_cast<Impl*>(baseImpl.get())) {
+CircleLayer::CircleLayer(Immutable<Impl> impl_)
+ : Layer(std::move(impl_)) {
}
CircleLayer::~CircleLayer() = default;
-std::unique_ptr<Layer> CircleLayer::Impl::clone() const {
- return std::make_unique<CircleLayer>(*this);
+const CircleLayer::Impl& CircleLayer::impl() const {
+ return static_cast<const Impl&>(*baseImpl);
}
-std::unique_ptr<Layer> CircleLayer::Impl::cloneRef(const std::string& id_) const {
- auto result = std::make_unique<CircleLayer>(*this);
- result->impl->id = id_;
- result->impl->cascading = CirclePaintProperties::Cascading();
- return std::move(result);
+Mutable<CircleLayer::Impl> CircleLayer::mutableImpl() const {
+ return makeMutable<Impl>(impl());
+}
+
+std::unique_ptr<Layer> CircleLayer::cloneRef(const std::string& id_) const {
+ auto impl_ = mutableImpl();
+ impl_->id = id_;
+ impl_->cascading = CirclePaintProperties::Cascading();
+ return std::make_unique<CircleLayer>(std::move(impl_));
}
void CircleLayer::Impl::stringifyLayout(rapidjson::Writer<rapidjson::StringBuffer>&) const {
@@ -38,26 +39,55 @@ void CircleLayer::Impl::stringifyLayout(rapidjson::Writer<rapidjson::StringBuffe
// Source
const std::string& CircleLayer::getSourceID() const {
- return impl->source;
+ return impl().source;
}
void CircleLayer::setSourceLayer(const std::string& sourceLayer) {
- impl->sourceLayer = sourceLayer;
+ auto impl_ = mutableImpl();
+ impl_->sourceLayer = sourceLayer;
+ baseImpl = std::move(impl_);
}
const std::string& CircleLayer::getSourceLayer() const {
- return impl->sourceLayer;
+ return impl().sourceLayer;
}
// Filter
void CircleLayer::setFilter(const Filter& filter) {
- impl->filter = filter;
- impl->observer->onLayerFilterChanged(*this);
+ auto impl_ = mutableImpl();
+ impl_->filter = filter;
+ baseImpl = std::move(impl_);
+ observer->onLayerFilterChanged(*this);
}
const Filter& CircleLayer::getFilter() const {
- return impl->filter;
+ return impl().filter;
+}
+
+// Visibility
+
+void CircleLayer::setVisibility(VisibilityType value) {
+ if (value == getVisibility())
+ return;
+ auto impl_ = mutableImpl();
+ impl_->visibility = value;
+ baseImpl = std::move(impl_);
+ observer->onLayerVisibilityChanged(*this);
+}
+
+// Zoom range
+
+void CircleLayer::setMinZoom(float minZoom) {
+ auto impl_ = mutableImpl();
+ impl_->minZoom = minZoom;
+ baseImpl = std::move(impl_);
+}
+
+void CircleLayer::setMaxZoom(float maxZoom) {
+ auto impl_ = mutableImpl();
+ impl_->maxZoom = maxZoom;
+ baseImpl = std::move(impl_);
}
// Layout properties
@@ -70,26 +100,30 @@ DataDrivenPropertyValue<float> CircleLayer::getDefaultCircleRadius() {
}
DataDrivenPropertyValue<float> CircleLayer::getCircleRadius(const optional<std::string>& klass) const {
- return impl->cascading.template get<CircleRadius>().get(klass);
+ return impl().cascading.template get<CircleRadius>().get(klass);
}
void CircleLayer::setCircleRadius(DataDrivenPropertyValue<float> value, const optional<std::string>& klass) {
if (value == getCircleRadius(klass))
return;
- impl->cascading.template get<CircleRadius>().set(value, klass);
+ auto impl_ = mutableImpl();
+ impl_->cascading.template get<CircleRadius>().set(value, klass);
+ baseImpl = std::move(impl_);
if (value.isDataDriven()) {
- impl->observer->onLayerDataDrivenPaintPropertyChanged(*this);
+ observer->onLayerDataDrivenPaintPropertyChanged(*this);
} else {
- impl->observer->onLayerPaintPropertyChanged(*this);
+ observer->onLayerPaintPropertyChanged(*this);
}
}
void CircleLayer::setCircleRadiusTransition(const TransitionOptions& value, const optional<std::string>& klass) {
- impl->cascading.template get<CircleRadius>().setTransition(value, klass);
+ auto impl_ = mutableImpl();
+ impl_->cascading.template get<CircleRadius>().setTransition(value, klass);
+ baseImpl = std::move(impl_);
}
TransitionOptions CircleLayer::getCircleRadiusTransition(const optional<std::string>& klass) const {
- return impl->cascading.template get<CircleRadius>().getTransition(klass);
+ return impl().cascading.template get<CircleRadius>().getTransition(klass);
}
DataDrivenPropertyValue<Color> CircleLayer::getDefaultCircleColor() {
@@ -97,26 +131,30 @@ DataDrivenPropertyValue<Color> CircleLayer::getDefaultCircleColor() {
}
DataDrivenPropertyValue<Color> CircleLayer::getCircleColor(const optional<std::string>& klass) const {
- return impl->cascading.template get<CircleColor>().get(klass);
+ return impl().cascading.template get<CircleColor>().get(klass);
}
void CircleLayer::setCircleColor(DataDrivenPropertyValue<Color> value, const optional<std::string>& klass) {
if (value == getCircleColor(klass))
return;
- impl->cascading.template get<CircleColor>().set(value, klass);
+ auto impl_ = mutableImpl();
+ impl_->cascading.template get<CircleColor>().set(value, klass);
+ baseImpl = std::move(impl_);
if (value.isDataDriven()) {
- impl->observer->onLayerDataDrivenPaintPropertyChanged(*this);
+ observer->onLayerDataDrivenPaintPropertyChanged(*this);
} else {
- impl->observer->onLayerPaintPropertyChanged(*this);
+ observer->onLayerPaintPropertyChanged(*this);
}
}
void CircleLayer::setCircleColorTransition(const TransitionOptions& value, const optional<std::string>& klass) {
- impl->cascading.template get<CircleColor>().setTransition(value, klass);
+ auto impl_ = mutableImpl();
+ impl_->cascading.template get<CircleColor>().setTransition(value, klass);
+ baseImpl = std::move(impl_);
}
TransitionOptions CircleLayer::getCircleColorTransition(const optional<std::string>& klass) const {
- return impl->cascading.template get<CircleColor>().getTransition(klass);
+ return impl().cascading.template get<CircleColor>().getTransition(klass);
}
DataDrivenPropertyValue<float> CircleLayer::getDefaultCircleBlur() {
@@ -124,26 +162,30 @@ DataDrivenPropertyValue<float> CircleLayer::getDefaultCircleBlur() {
}
DataDrivenPropertyValue<float> CircleLayer::getCircleBlur(const optional<std::string>& klass) const {
- return impl->cascading.template get<CircleBlur>().get(klass);
+ return impl().cascading.template get<CircleBlur>().get(klass);
}
void CircleLayer::setCircleBlur(DataDrivenPropertyValue<float> value, const optional<std::string>& klass) {
if (value == getCircleBlur(klass))
return;
- impl->cascading.template get<CircleBlur>().set(value, klass);
+ auto impl_ = mutableImpl();
+ impl_->cascading.template get<CircleBlur>().set(value, klass);
+ baseImpl = std::move(impl_);
if (value.isDataDriven()) {
- impl->observer->onLayerDataDrivenPaintPropertyChanged(*this);
+ observer->onLayerDataDrivenPaintPropertyChanged(*this);
} else {
- impl->observer->onLayerPaintPropertyChanged(*this);
+ observer->onLayerPaintPropertyChanged(*this);
}
}
void CircleLayer::setCircleBlurTransition(const TransitionOptions& value, const optional<std::string>& klass) {
- impl->cascading.template get<CircleBlur>().setTransition(value, klass);
+ auto impl_ = mutableImpl();
+ impl_->cascading.template get<CircleBlur>().setTransition(value, klass);
+ baseImpl = std::move(impl_);
}
TransitionOptions CircleLayer::getCircleBlurTransition(const optional<std::string>& klass) const {
- return impl->cascading.template get<CircleBlur>().getTransition(klass);
+ return impl().cascading.template get<CircleBlur>().getTransition(klass);
}
DataDrivenPropertyValue<float> CircleLayer::getDefaultCircleOpacity() {
@@ -151,26 +193,30 @@ DataDrivenPropertyValue<float> CircleLayer::getDefaultCircleOpacity() {
}
DataDrivenPropertyValue<float> CircleLayer::getCircleOpacity(const optional<std::string>& klass) const {
- return impl->cascading.template get<CircleOpacity>().get(klass);
+ return impl().cascading.template get<CircleOpacity>().get(klass);
}
void CircleLayer::setCircleOpacity(DataDrivenPropertyValue<float> value, const optional<std::string>& klass) {
if (value == getCircleOpacity(klass))
return;
- impl->cascading.template get<CircleOpacity>().set(value, klass);
+ auto impl_ = mutableImpl();
+ impl_->cascading.template get<CircleOpacity>().set(value, klass);
+ baseImpl = std::move(impl_);
if (value.isDataDriven()) {
- impl->observer->onLayerDataDrivenPaintPropertyChanged(*this);
+ observer->onLayerDataDrivenPaintPropertyChanged(*this);
} else {
- impl->observer->onLayerPaintPropertyChanged(*this);
+ observer->onLayerPaintPropertyChanged(*this);
}
}
void CircleLayer::setCircleOpacityTransition(const TransitionOptions& value, const optional<std::string>& klass) {
- impl->cascading.template get<CircleOpacity>().setTransition(value, klass);
+ auto impl_ = mutableImpl();
+ impl_->cascading.template get<CircleOpacity>().setTransition(value, klass);
+ baseImpl = std::move(impl_);
}
TransitionOptions CircleLayer::getCircleOpacityTransition(const optional<std::string>& klass) const {
- return impl->cascading.template get<CircleOpacity>().getTransition(klass);
+ return impl().cascading.template get<CircleOpacity>().getTransition(klass);
}
PropertyValue<std::array<float, 2>> CircleLayer::getDefaultCircleTranslate() {
@@ -178,22 +224,26 @@ PropertyValue<std::array<float, 2>> CircleLayer::getDefaultCircleTranslate() {
}
PropertyValue<std::array<float, 2>> CircleLayer::getCircleTranslate(const optional<std::string>& klass) const {
- return impl->cascading.template get<CircleTranslate>().get(klass);
+ return impl().cascading.template get<CircleTranslate>().get(klass);
}
void CircleLayer::setCircleTranslate(PropertyValue<std::array<float, 2>> value, const optional<std::string>& klass) {
if (value == getCircleTranslate(klass))
return;
- impl->cascading.template get<CircleTranslate>().set(value, klass);
- impl->observer->onLayerPaintPropertyChanged(*this);
+ auto impl_ = mutableImpl();
+ impl_->cascading.template get<CircleTranslate>().set(value, klass);
+ baseImpl = std::move(impl_);
+ observer->onLayerPaintPropertyChanged(*this);
}
void CircleLayer::setCircleTranslateTransition(const TransitionOptions& value, const optional<std::string>& klass) {
- impl->cascading.template get<CircleTranslate>().setTransition(value, klass);
+ auto impl_ = mutableImpl();
+ impl_->cascading.template get<CircleTranslate>().setTransition(value, klass);
+ baseImpl = std::move(impl_);
}
TransitionOptions CircleLayer::getCircleTranslateTransition(const optional<std::string>& klass) const {
- return impl->cascading.template get<CircleTranslate>().getTransition(klass);
+ return impl().cascading.template get<CircleTranslate>().getTransition(klass);
}
PropertyValue<TranslateAnchorType> CircleLayer::getDefaultCircleTranslateAnchor() {
@@ -201,22 +251,26 @@ PropertyValue<TranslateAnchorType> CircleLayer::getDefaultCircleTranslateAnchor(
}
PropertyValue<TranslateAnchorType> CircleLayer::getCircleTranslateAnchor(const optional<std::string>& klass) const {
- return impl->cascading.template get<CircleTranslateAnchor>().get(klass);
+ return impl().cascading.template get<CircleTranslateAnchor>().get(klass);
}
void CircleLayer::setCircleTranslateAnchor(PropertyValue<TranslateAnchorType> value, const optional<std::string>& klass) {
if (value == getCircleTranslateAnchor(klass))
return;
- impl->cascading.template get<CircleTranslateAnchor>().set(value, klass);
- impl->observer->onLayerPaintPropertyChanged(*this);
+ auto impl_ = mutableImpl();
+ impl_->cascading.template get<CircleTranslateAnchor>().set(value, klass);
+ baseImpl = std::move(impl_);
+ observer->onLayerPaintPropertyChanged(*this);
}
void CircleLayer::setCircleTranslateAnchorTransition(const TransitionOptions& value, const optional<std::string>& klass) {
- impl->cascading.template get<CircleTranslateAnchor>().setTransition(value, klass);
+ auto impl_ = mutableImpl();
+ impl_->cascading.template get<CircleTranslateAnchor>().setTransition(value, klass);
+ baseImpl = std::move(impl_);
}
TransitionOptions CircleLayer::getCircleTranslateAnchorTransition(const optional<std::string>& klass) const {
- return impl->cascading.template get<CircleTranslateAnchor>().getTransition(klass);
+ return impl().cascading.template get<CircleTranslateAnchor>().getTransition(klass);
}
PropertyValue<CirclePitchScaleType> CircleLayer::getDefaultCirclePitchScale() {
@@ -224,22 +278,26 @@ PropertyValue<CirclePitchScaleType> CircleLayer::getDefaultCirclePitchScale() {
}
PropertyValue<CirclePitchScaleType> CircleLayer::getCirclePitchScale(const optional<std::string>& klass) const {
- return impl->cascading.template get<CirclePitchScale>().get(klass);
+ return impl().cascading.template get<CirclePitchScale>().get(klass);
}
void CircleLayer::setCirclePitchScale(PropertyValue<CirclePitchScaleType> value, const optional<std::string>& klass) {
if (value == getCirclePitchScale(klass))
return;
- impl->cascading.template get<CirclePitchScale>().set(value, klass);
- impl->observer->onLayerPaintPropertyChanged(*this);
+ auto impl_ = mutableImpl();
+ impl_->cascading.template get<CirclePitchScale>().set(value, klass);
+ baseImpl = std::move(impl_);
+ observer->onLayerPaintPropertyChanged(*this);
}
void CircleLayer::setCirclePitchScaleTransition(const TransitionOptions& value, const optional<std::string>& klass) {
- impl->cascading.template get<CirclePitchScale>().setTransition(value, klass);
+ auto impl_ = mutableImpl();
+ impl_->cascading.template get<CirclePitchScale>().setTransition(value, klass);
+ baseImpl = std::move(impl_);
}
TransitionOptions CircleLayer::getCirclePitchScaleTransition(const optional<std::string>& klass) const {
- return impl->cascading.template get<CirclePitchScale>().getTransition(klass);
+ return impl().cascading.template get<CirclePitchScale>().getTransition(klass);
}
DataDrivenPropertyValue<float> CircleLayer::getDefaultCircleStrokeWidth() {
@@ -247,26 +305,30 @@ DataDrivenPropertyValue<float> CircleLayer::getDefaultCircleStrokeWidth() {
}
DataDrivenPropertyValue<float> CircleLayer::getCircleStrokeWidth(const optional<std::string>& klass) const {
- return impl->cascading.template get<CircleStrokeWidth>().get(klass);
+ return impl().cascading.template get<CircleStrokeWidth>().get(klass);
}
void CircleLayer::setCircleStrokeWidth(DataDrivenPropertyValue<float> value, const optional<std::string>& klass) {
if (value == getCircleStrokeWidth(klass))
return;
- impl->cascading.template get<CircleStrokeWidth>().set(value, klass);
+ auto impl_ = mutableImpl();
+ impl_->cascading.template get<CircleStrokeWidth>().set(value, klass);
+ baseImpl = std::move(impl_);
if (value.isDataDriven()) {
- impl->observer->onLayerDataDrivenPaintPropertyChanged(*this);
+ observer->onLayerDataDrivenPaintPropertyChanged(*this);
} else {
- impl->observer->onLayerPaintPropertyChanged(*this);
+ observer->onLayerPaintPropertyChanged(*this);
}
}
void CircleLayer::setCircleStrokeWidthTransition(const TransitionOptions& value, const optional<std::string>& klass) {
- impl->cascading.template get<CircleStrokeWidth>().setTransition(value, klass);
+ auto impl_ = mutableImpl();
+ impl_->cascading.template get<CircleStrokeWidth>().setTransition(value, klass);
+ baseImpl = std::move(impl_);
}
TransitionOptions CircleLayer::getCircleStrokeWidthTransition(const optional<std::string>& klass) const {
- return impl->cascading.template get<CircleStrokeWidth>().getTransition(klass);
+ return impl().cascading.template get<CircleStrokeWidth>().getTransition(klass);
}
DataDrivenPropertyValue<Color> CircleLayer::getDefaultCircleStrokeColor() {
@@ -274,26 +336,30 @@ DataDrivenPropertyValue<Color> CircleLayer::getDefaultCircleStrokeColor() {
}
DataDrivenPropertyValue<Color> CircleLayer::getCircleStrokeColor(const optional<std::string>& klass) const {
- return impl->cascading.template get<CircleStrokeColor>().get(klass);
+ return impl().cascading.template get<CircleStrokeColor>().get(klass);
}
void CircleLayer::setCircleStrokeColor(DataDrivenPropertyValue<Color> value, const optional<std::string>& klass) {
if (value == getCircleStrokeColor(klass))
return;
- impl->cascading.template get<CircleStrokeColor>().set(value, klass);
+ auto impl_ = mutableImpl();
+ impl_->cascading.template get<CircleStrokeColor>().set(value, klass);
+ baseImpl = std::move(impl_);
if (value.isDataDriven()) {
- impl->observer->onLayerDataDrivenPaintPropertyChanged(*this);
+ observer->onLayerDataDrivenPaintPropertyChanged(*this);
} else {
- impl->observer->onLayerPaintPropertyChanged(*this);
+ observer->onLayerPaintPropertyChanged(*this);
}
}
void CircleLayer::setCircleStrokeColorTransition(const TransitionOptions& value, const optional<std::string>& klass) {
- impl->cascading.template get<CircleStrokeColor>().setTransition(value, klass);
+ auto impl_ = mutableImpl();
+ impl_->cascading.template get<CircleStrokeColor>().setTransition(value, klass);
+ baseImpl = std::move(impl_);
}
TransitionOptions CircleLayer::getCircleStrokeColorTransition(const optional<std::string>& klass) const {
- return impl->cascading.template get<CircleStrokeColor>().getTransition(klass);
+ return impl().cascading.template get<CircleStrokeColor>().getTransition(klass);
}
DataDrivenPropertyValue<float> CircleLayer::getDefaultCircleStrokeOpacity() {
@@ -301,26 +367,30 @@ DataDrivenPropertyValue<float> CircleLayer::getDefaultCircleStrokeOpacity() {
}
DataDrivenPropertyValue<float> CircleLayer::getCircleStrokeOpacity(const optional<std::string>& klass) const {
- return impl->cascading.template get<CircleStrokeOpacity>().get(klass);
+ return impl().cascading.template get<CircleStrokeOpacity>().get(klass);
}
void CircleLayer::setCircleStrokeOpacity(DataDrivenPropertyValue<float> value, const optional<std::string>& klass) {
if (value == getCircleStrokeOpacity(klass))
return;
- impl->cascading.template get<CircleStrokeOpacity>().set(value, klass);
+ auto impl_ = mutableImpl();
+ impl_->cascading.template get<CircleStrokeOpacity>().set(value, klass);
+ baseImpl = std::move(impl_);
if (value.isDataDriven()) {
- impl->observer->onLayerDataDrivenPaintPropertyChanged(*this);
+ observer->onLayerDataDrivenPaintPropertyChanged(*this);
} else {
- impl->observer->onLayerPaintPropertyChanged(*this);
+ observer->onLayerPaintPropertyChanged(*this);
}
}
void CircleLayer::setCircleStrokeOpacityTransition(const TransitionOptions& value, const optional<std::string>& klass) {
- impl->cascading.template get<CircleStrokeOpacity>().setTransition(value, klass);
+ auto impl_ = mutableImpl();
+ impl_->cascading.template get<CircleStrokeOpacity>().setTransition(value, klass);
+ baseImpl = std::move(impl_);
}
TransitionOptions CircleLayer::getCircleStrokeOpacityTransition(const optional<std::string>& klass) const {
- return impl->cascading.template get<CircleStrokeOpacity>().getTransition(klass);
+ return impl().cascading.template get<CircleStrokeOpacity>().getTransition(klass);
}
} // namespace style
diff --git a/src/mbgl/style/layers/circle_layer_impl.cpp b/src/mbgl/style/layers/circle_layer_impl.cpp
index 31b286f273..8df79507bf 100644
--- a/src/mbgl/style/layers/circle_layer_impl.cpp
+++ b/src/mbgl/style/layers/circle_layer_impl.cpp
@@ -5,7 +5,7 @@ namespace mbgl {
namespace style {
std::unique_ptr<RenderLayer> CircleLayer::Impl::createRenderLayer() const {
- return std::make_unique<RenderCircleLayer>(*this);
+ return std::make_unique<RenderCircleLayer>(staticImmutableCast<CircleLayer::Impl>(immutableFromThis()));
}
} // namespace style
diff --git a/src/mbgl/style/layers/circle_layer_impl.hpp b/src/mbgl/style/layers/circle_layer_impl.hpp
index 886815f0d1..94fa24b811 100644
--- a/src/mbgl/style/layers/circle_layer_impl.hpp
+++ b/src/mbgl/style/layers/circle_layer_impl.hpp
@@ -9,8 +9,8 @@ namespace style {
class CircleLayer::Impl : public Layer::Impl {
public:
- std::unique_ptr<Layer> clone() const override;
- std::unique_ptr<Layer> cloneRef(const std::string& id) const override;
+ using Layer::Impl::Impl;
+
void stringifyLayout(rapidjson::Writer<rapidjson::StringBuffer>&) const override;
std::unique_ptr<RenderLayer> createRenderLayer() const override;
diff --git a/src/mbgl/style/layers/custom_layer.cpp b/src/mbgl/style/layers/custom_layer.cpp
index cda8a157f0..f7c349b3d8 100644
--- a/src/mbgl/style/layers/custom_layer.cpp
+++ b/src/mbgl/style/layers/custom_layer.cpp
@@ -1,6 +1,6 @@
#include <mbgl/style/layers/custom_layer.hpp>
#include <mbgl/style/layers/custom_layer_impl.hpp>
-#include <mbgl/util/logging.hpp>
+#include <mbgl/style/layer_observer.hpp>
namespace mbgl {
namespace style {
@@ -10,21 +10,52 @@ CustomLayer::CustomLayer(const std::string& layerID,
CustomLayerRenderFunction render,
CustomLayerDeinitializeFunction deinit,
void* context)
- : Layer(LayerType::Custom, std::make_unique<Impl>(layerID, init, render, deinit, context))
- , impl(static_cast<Impl*>(baseImpl.get())) {
- Log::Info(Event::General, "New custom layer: %s", layerID.c_str());
+ : Layer(makeMutable<Impl>(layerID, init, render, deinit, context)) {
}
-CustomLayer::CustomLayer(const Impl& other)
- : Layer(LayerType::Custom, std::make_unique<Impl>(other))
- , impl(static_cast<Impl*>(baseImpl.get())) {
+CustomLayer::~CustomLayer() = default;
+
+const CustomLayer::Impl& CustomLayer::impl() const {
+ return static_cast<const Impl&>(*baseImpl);
}
-CustomLayer::~CustomLayer() = default;
+Mutable<CustomLayer::Impl> CustomLayer::mutableImpl() const {
+ return makeMutable<Impl>(impl());
+}
+
+std::unique_ptr<Layer> CustomLayer::cloneRef(const std::string&) const {
+ assert(false);
+ return nullptr;
+}
+
+// Visibility
+
+void CustomLayer::setVisibility(VisibilityType value) {
+ if (value == getVisibility())
+ return;
+ auto impl_ = mutableImpl();
+ impl_->visibility = value;
+ baseImpl = std::move(impl_);
+ observer->onLayerVisibilityChanged(*this);
+}
+
+// Zoom range
+
+void CustomLayer::setMinZoom(float minZoom) {
+ auto impl_ = mutableImpl();
+ impl_->minZoom = minZoom;
+ baseImpl = std::move(impl_);
+}
+
+void CustomLayer::setMaxZoom(float maxZoom) {
+ auto impl_ = mutableImpl();
+ impl_->maxZoom = maxZoom;
+ baseImpl = std::move(impl_);
+}
template <>
bool Layer::is<CustomLayer>() const {
- return type == LayerType::Custom;
+ return getType() == LayerType::Custom;
}
} // namespace style
diff --git a/src/mbgl/style/layers/custom_layer_impl.cpp b/src/mbgl/style/layers/custom_layer_impl.cpp
index 1d3e9af8d6..e459b57171 100644
--- a/src/mbgl/style/layers/custom_layer_impl.cpp
+++ b/src/mbgl/style/layers/custom_layer_impl.cpp
@@ -2,52 +2,36 @@
#include <mbgl/renderer/render_custom_layer.hpp>
#include <mbgl/map/transform_state.hpp>
#include <mbgl/util/logging.hpp>
+
namespace mbgl {
namespace style {
std::unique_ptr<RenderLayer> CustomLayer::Impl::createRenderLayer() const {
- return std::make_unique<RenderCustomLayer>(*this);
+ return std::make_unique<RenderCustomLayer>(staticImmutableCast<CustomLayer::Impl>(immutableFromThis()));
}
CustomLayer::Impl::Impl(const std::string& id_,
CustomLayerInitializeFunction initializeFn_,
CustomLayerRenderFunction renderFn_,
CustomLayerDeinitializeFunction deinitializeFn_,
- void* context_) {
+ void* context_)
+ : Layer::Impl(LayerType::Custom, id_, std::string()) {
Log::Info(Event::General, "New custom layer Impl: %s", id_.c_str());
- id = id_;
initializeFn = initializeFn_;
renderFn = renderFn_;
deinitializeFn = deinitializeFn_;
context = context_;
}
-CustomLayer::Impl::Impl(const CustomLayer::Impl &other)
- : Layer::Impl(other) {
- id = other.id;
- // Don't copy anything else.
-}
-
-CustomLayer::Impl::~Impl() = default;
-
-std::unique_ptr<Layer> CustomLayer::Impl::clone() const {
- return std::make_unique<CustomLayer>(*this);
-}
-
-std::unique_ptr<Layer> CustomLayer::Impl::cloneRef(const std::string&) const {
- assert(false);
- return std::make_unique<CustomLayer>(*this);
-}
-
void CustomLayer::Impl::stringifyLayout(rapidjson::Writer<rapidjson::StringBuffer>&) const {
}
-void CustomLayer::Impl::initialize() {
+void CustomLayer::Impl::initialize() const {
assert(initializeFn);
initializeFn(context);
}
-void CustomLayer::Impl::deinitialize() {
+void CustomLayer::Impl::deinitialize() const {
if (deinitializeFn) {
deinitializeFn(context);
}
diff --git a/src/mbgl/style/layers/custom_layer_impl.hpp b/src/mbgl/style/layers/custom_layer_impl.hpp
index e612d17f14..f921f47d59 100644
--- a/src/mbgl/style/layers/custom_layer_impl.hpp
+++ b/src/mbgl/style/layers/custom_layer_impl.hpp
@@ -17,16 +17,11 @@ public:
CustomLayerDeinitializeFunction,
void* context);
- Impl(const Impl&);
- ~Impl() final;
-
- void initialize();
- void deinitialize();
+ void initialize() const;
+ void deinitialize() const;
void render(const TransformState&) const;
private:
- std::unique_ptr<Layer> clone() const override;
- std::unique_ptr<Layer> cloneRef(const std::string& id) const override;
void stringifyLayout(rapidjson::Writer<rapidjson::StringBuffer>&) const override;
std::unique_ptr<RenderLayer> createRenderLayer() const final;
diff --git a/src/mbgl/style/layers/fill_extrusion_layer.cpp b/src/mbgl/style/layers/fill_extrusion_layer.cpp
index 6f11d6052c..78a348f5c4 100644
--- a/src/mbgl/style/layers/fill_extrusion_layer.cpp
+++ b/src/mbgl/style/layers/fill_extrusion_layer.cpp
@@ -3,33 +3,34 @@
#include <mbgl/style/layers/fill_extrusion_layer.hpp>
#include <mbgl/style/layers/fill_extrusion_layer_impl.hpp>
#include <mbgl/style/conversion/stringify.hpp>
+#include <mbgl/style/layer_observer.hpp>
namespace mbgl {
namespace style {
FillExtrusionLayer::FillExtrusionLayer(const std::string& layerID, const std::string& sourceID)
- : Layer(LayerType::FillExtrusion, std::make_unique<Impl>())
- , impl(static_cast<Impl*>(baseImpl.get())) {
- impl->id = layerID;
- impl->source = sourceID;
+ : Layer(makeMutable<Impl>(LayerType::FillExtrusion, layerID, sourceID)) {
}
-FillExtrusionLayer::FillExtrusionLayer(const Impl& other)
- : Layer(LayerType::FillExtrusion, std::make_unique<Impl>(other))
- , impl(static_cast<Impl*>(baseImpl.get())) {
+FillExtrusionLayer::FillExtrusionLayer(Immutable<Impl> impl_)
+ : Layer(std::move(impl_)) {
}
FillExtrusionLayer::~FillExtrusionLayer() = default;
-std::unique_ptr<Layer> FillExtrusionLayer::Impl::clone() const {
- return std::make_unique<FillExtrusionLayer>(*this);
+const FillExtrusionLayer::Impl& FillExtrusionLayer::impl() const {
+ return static_cast<const Impl&>(*baseImpl);
}
-std::unique_ptr<Layer> FillExtrusionLayer::Impl::cloneRef(const std::string& id_) const {
- auto result = std::make_unique<FillExtrusionLayer>(*this);
- result->impl->id = id_;
- result->impl->cascading = FillExtrusionPaintProperties::Cascading();
- return std::move(result);
+Mutable<FillExtrusionLayer::Impl> FillExtrusionLayer::mutableImpl() const {
+ return makeMutable<Impl>(impl());
+}
+
+std::unique_ptr<Layer> FillExtrusionLayer::cloneRef(const std::string& id_) const {
+ auto impl_ = mutableImpl();
+ impl_->id = id_;
+ impl_->cascading = FillExtrusionPaintProperties::Cascading();
+ return std::make_unique<FillExtrusionLayer>(std::move(impl_));
}
void FillExtrusionLayer::Impl::stringifyLayout(rapidjson::Writer<rapidjson::StringBuffer>&) const {
@@ -38,26 +39,55 @@ void FillExtrusionLayer::Impl::stringifyLayout(rapidjson::Writer<rapidjson::Stri
// Source
const std::string& FillExtrusionLayer::getSourceID() const {
- return impl->source;
+ return impl().source;
}
void FillExtrusionLayer::setSourceLayer(const std::string& sourceLayer) {
- impl->sourceLayer = sourceLayer;
+ auto impl_ = mutableImpl();
+ impl_->sourceLayer = sourceLayer;
+ baseImpl = std::move(impl_);
}
const std::string& FillExtrusionLayer::getSourceLayer() const {
- return impl->sourceLayer;
+ return impl().sourceLayer;
}
// Filter
void FillExtrusionLayer::setFilter(const Filter& filter) {
- impl->filter = filter;
- impl->observer->onLayerFilterChanged(*this);
+ auto impl_ = mutableImpl();
+ impl_->filter = filter;
+ baseImpl = std::move(impl_);
+ observer->onLayerFilterChanged(*this);
}
const Filter& FillExtrusionLayer::getFilter() const {
- return impl->filter;
+ return impl().filter;
+}
+
+// Visibility
+
+void FillExtrusionLayer::setVisibility(VisibilityType value) {
+ if (value == getVisibility())
+ return;
+ auto impl_ = mutableImpl();
+ impl_->visibility = value;
+ baseImpl = std::move(impl_);
+ observer->onLayerVisibilityChanged(*this);
+}
+
+// Zoom range
+
+void FillExtrusionLayer::setMinZoom(float minZoom) {
+ auto impl_ = mutableImpl();
+ impl_->minZoom = minZoom;
+ baseImpl = std::move(impl_);
+}
+
+void FillExtrusionLayer::setMaxZoom(float maxZoom) {
+ auto impl_ = mutableImpl();
+ impl_->maxZoom = maxZoom;
+ baseImpl = std::move(impl_);
}
// Layout properties
@@ -70,22 +100,26 @@ PropertyValue<float> FillExtrusionLayer::getDefaultFillExtrusionOpacity() {
}
PropertyValue<float> FillExtrusionLayer::getFillExtrusionOpacity(const optional<std::string>& klass) const {
- return impl->cascading.template get<FillExtrusionOpacity>().get(klass);
+ return impl().cascading.template get<FillExtrusionOpacity>().get(klass);
}
void FillExtrusionLayer::setFillExtrusionOpacity(PropertyValue<float> value, const optional<std::string>& klass) {
if (value == getFillExtrusionOpacity(klass))
return;
- impl->cascading.template get<FillExtrusionOpacity>().set(value, klass);
- impl->observer->onLayerPaintPropertyChanged(*this);
+ auto impl_ = mutableImpl();
+ impl_->cascading.template get<FillExtrusionOpacity>().set(value, klass);
+ baseImpl = std::move(impl_);
+ observer->onLayerPaintPropertyChanged(*this);
}
void FillExtrusionLayer::setFillExtrusionOpacityTransition(const TransitionOptions& value, const optional<std::string>& klass) {
- impl->cascading.template get<FillExtrusionOpacity>().setTransition(value, klass);
+ auto impl_ = mutableImpl();
+ impl_->cascading.template get<FillExtrusionOpacity>().setTransition(value, klass);
+ baseImpl = std::move(impl_);
}
TransitionOptions FillExtrusionLayer::getFillExtrusionOpacityTransition(const optional<std::string>& klass) const {
- return impl->cascading.template get<FillExtrusionOpacity>().getTransition(klass);
+ return impl().cascading.template get<FillExtrusionOpacity>().getTransition(klass);
}
DataDrivenPropertyValue<Color> FillExtrusionLayer::getDefaultFillExtrusionColor() {
@@ -93,26 +127,30 @@ DataDrivenPropertyValue<Color> FillExtrusionLayer::getDefaultFillExtrusionColor(
}
DataDrivenPropertyValue<Color> FillExtrusionLayer::getFillExtrusionColor(const optional<std::string>& klass) const {
- return impl->cascading.template get<FillExtrusionColor>().get(klass);
+ return impl().cascading.template get<FillExtrusionColor>().get(klass);
}
void FillExtrusionLayer::setFillExtrusionColor(DataDrivenPropertyValue<Color> value, const optional<std::string>& klass) {
if (value == getFillExtrusionColor(klass))
return;
- impl->cascading.template get<FillExtrusionColor>().set(value, klass);
+ auto impl_ = mutableImpl();
+ impl_->cascading.template get<FillExtrusionColor>().set(value, klass);
+ baseImpl = std::move(impl_);
if (value.isDataDriven()) {
- impl->observer->onLayerDataDrivenPaintPropertyChanged(*this);
+ observer->onLayerDataDrivenPaintPropertyChanged(*this);
} else {
- impl->observer->onLayerPaintPropertyChanged(*this);
+ observer->onLayerPaintPropertyChanged(*this);
}
}
void FillExtrusionLayer::setFillExtrusionColorTransition(const TransitionOptions& value, const optional<std::string>& klass) {
- impl->cascading.template get<FillExtrusionColor>().setTransition(value, klass);
+ auto impl_ = mutableImpl();
+ impl_->cascading.template get<FillExtrusionColor>().setTransition(value, klass);
+ baseImpl = std::move(impl_);
}
TransitionOptions FillExtrusionLayer::getFillExtrusionColorTransition(const optional<std::string>& klass) const {
- return impl->cascading.template get<FillExtrusionColor>().getTransition(klass);
+ return impl().cascading.template get<FillExtrusionColor>().getTransition(klass);
}
PropertyValue<std::array<float, 2>> FillExtrusionLayer::getDefaultFillExtrusionTranslate() {
@@ -120,22 +158,26 @@ PropertyValue<std::array<float, 2>> FillExtrusionLayer::getDefaultFillExtrusionT
}
PropertyValue<std::array<float, 2>> FillExtrusionLayer::getFillExtrusionTranslate(const optional<std::string>& klass) const {
- return impl->cascading.template get<FillExtrusionTranslate>().get(klass);
+ return impl().cascading.template get<FillExtrusionTranslate>().get(klass);
}
void FillExtrusionLayer::setFillExtrusionTranslate(PropertyValue<std::array<float, 2>> value, const optional<std::string>& klass) {
if (value == getFillExtrusionTranslate(klass))
return;
- impl->cascading.template get<FillExtrusionTranslate>().set(value, klass);
- impl->observer->onLayerPaintPropertyChanged(*this);
+ auto impl_ = mutableImpl();
+ impl_->cascading.template get<FillExtrusionTranslate>().set(value, klass);
+ baseImpl = std::move(impl_);
+ observer->onLayerPaintPropertyChanged(*this);
}
void FillExtrusionLayer::setFillExtrusionTranslateTransition(const TransitionOptions& value, const optional<std::string>& klass) {
- impl->cascading.template get<FillExtrusionTranslate>().setTransition(value, klass);
+ auto impl_ = mutableImpl();
+ impl_->cascading.template get<FillExtrusionTranslate>().setTransition(value, klass);
+ baseImpl = std::move(impl_);
}
TransitionOptions FillExtrusionLayer::getFillExtrusionTranslateTransition(const optional<std::string>& klass) const {
- return impl->cascading.template get<FillExtrusionTranslate>().getTransition(klass);
+ return impl().cascading.template get<FillExtrusionTranslate>().getTransition(klass);
}
PropertyValue<TranslateAnchorType> FillExtrusionLayer::getDefaultFillExtrusionTranslateAnchor() {
@@ -143,22 +185,26 @@ PropertyValue<TranslateAnchorType> FillExtrusionLayer::getDefaultFillExtrusionTr
}
PropertyValue<TranslateAnchorType> FillExtrusionLayer::getFillExtrusionTranslateAnchor(const optional<std::string>& klass) const {
- return impl->cascading.template get<FillExtrusionTranslateAnchor>().get(klass);
+ return impl().cascading.template get<FillExtrusionTranslateAnchor>().get(klass);
}
void FillExtrusionLayer::setFillExtrusionTranslateAnchor(PropertyValue<TranslateAnchorType> value, const optional<std::string>& klass) {
if (value == getFillExtrusionTranslateAnchor(klass))
return;
- impl->cascading.template get<FillExtrusionTranslateAnchor>().set(value, klass);
- impl->observer->onLayerPaintPropertyChanged(*this);
+ auto impl_ = mutableImpl();
+ impl_->cascading.template get<FillExtrusionTranslateAnchor>().set(value, klass);
+ baseImpl = std::move(impl_);
+ observer->onLayerPaintPropertyChanged(*this);
}
void FillExtrusionLayer::setFillExtrusionTranslateAnchorTransition(const TransitionOptions& value, const optional<std::string>& klass) {
- impl->cascading.template get<FillExtrusionTranslateAnchor>().setTransition(value, klass);
+ auto impl_ = mutableImpl();
+ impl_->cascading.template get<FillExtrusionTranslateAnchor>().setTransition(value, klass);
+ baseImpl = std::move(impl_);
}
TransitionOptions FillExtrusionLayer::getFillExtrusionTranslateAnchorTransition(const optional<std::string>& klass) const {
- return impl->cascading.template get<FillExtrusionTranslateAnchor>().getTransition(klass);
+ return impl().cascading.template get<FillExtrusionTranslateAnchor>().getTransition(klass);
}
PropertyValue<std::string> FillExtrusionLayer::getDefaultFillExtrusionPattern() {
@@ -166,22 +212,26 @@ PropertyValue<std::string> FillExtrusionLayer::getDefaultFillExtrusionPattern()
}
PropertyValue<std::string> FillExtrusionLayer::getFillExtrusionPattern(const optional<std::string>& klass) const {
- return impl->cascading.template get<FillExtrusionPattern>().get(klass);
+ return impl().cascading.template get<FillExtrusionPattern>().get(klass);
}
void FillExtrusionLayer::setFillExtrusionPattern(PropertyValue<std::string> value, const optional<std::string>& klass) {
if (value == getFillExtrusionPattern(klass))
return;
- impl->cascading.template get<FillExtrusionPattern>().set(value, klass);
- impl->observer->onLayerPaintPropertyChanged(*this);
+ auto impl_ = mutableImpl();
+ impl_->cascading.template get<FillExtrusionPattern>().set(value, klass);
+ baseImpl = std::move(impl_);
+ observer->onLayerPaintPropertyChanged(*this);
}
void FillExtrusionLayer::setFillExtrusionPatternTransition(const TransitionOptions& value, const optional<std::string>& klass) {
- impl->cascading.template get<FillExtrusionPattern>().setTransition(value, klass);
+ auto impl_ = mutableImpl();
+ impl_->cascading.template get<FillExtrusionPattern>().setTransition(value, klass);
+ baseImpl = std::move(impl_);
}
TransitionOptions FillExtrusionLayer::getFillExtrusionPatternTransition(const optional<std::string>& klass) const {
- return impl->cascading.template get<FillExtrusionPattern>().getTransition(klass);
+ return impl().cascading.template get<FillExtrusionPattern>().getTransition(klass);
}
DataDrivenPropertyValue<float> FillExtrusionLayer::getDefaultFillExtrusionHeight() {
@@ -189,26 +239,30 @@ DataDrivenPropertyValue<float> FillExtrusionLayer::getDefaultFillExtrusionHeight
}
DataDrivenPropertyValue<float> FillExtrusionLayer::getFillExtrusionHeight(const optional<std::string>& klass) const {
- return impl->cascading.template get<FillExtrusionHeight>().get(klass);
+ return impl().cascading.template get<FillExtrusionHeight>().get(klass);
}
void FillExtrusionLayer::setFillExtrusionHeight(DataDrivenPropertyValue<float> value, const optional<std::string>& klass) {
if (value == getFillExtrusionHeight(klass))
return;
- impl->cascading.template get<FillExtrusionHeight>().set(value, klass);
+ auto impl_ = mutableImpl();
+ impl_->cascading.template get<FillExtrusionHeight>().set(value, klass);
+ baseImpl = std::move(impl_);
if (value.isDataDriven()) {
- impl->observer->onLayerDataDrivenPaintPropertyChanged(*this);
+ observer->onLayerDataDrivenPaintPropertyChanged(*this);
} else {
- impl->observer->onLayerPaintPropertyChanged(*this);
+ observer->onLayerPaintPropertyChanged(*this);
}
}
void FillExtrusionLayer::setFillExtrusionHeightTransition(const TransitionOptions& value, const optional<std::string>& klass) {
- impl->cascading.template get<FillExtrusionHeight>().setTransition(value, klass);
+ auto impl_ = mutableImpl();
+ impl_->cascading.template get<FillExtrusionHeight>().setTransition(value, klass);
+ baseImpl = std::move(impl_);
}
TransitionOptions FillExtrusionLayer::getFillExtrusionHeightTransition(const optional<std::string>& klass) const {
- return impl->cascading.template get<FillExtrusionHeight>().getTransition(klass);
+ return impl().cascading.template get<FillExtrusionHeight>().getTransition(klass);
}
DataDrivenPropertyValue<float> FillExtrusionLayer::getDefaultFillExtrusionBase() {
@@ -216,26 +270,30 @@ DataDrivenPropertyValue<float> FillExtrusionLayer::getDefaultFillExtrusionBase()
}
DataDrivenPropertyValue<float> FillExtrusionLayer::getFillExtrusionBase(const optional<std::string>& klass) const {
- return impl->cascading.template get<FillExtrusionBase>().get(klass);
+ return impl().cascading.template get<FillExtrusionBase>().get(klass);
}
void FillExtrusionLayer::setFillExtrusionBase(DataDrivenPropertyValue<float> value, const optional<std::string>& klass) {
if (value == getFillExtrusionBase(klass))
return;
- impl->cascading.template get<FillExtrusionBase>().set(value, klass);
+ auto impl_ = mutableImpl();
+ impl_->cascading.template get<FillExtrusionBase>().set(value, klass);
+ baseImpl = std::move(impl_);
if (value.isDataDriven()) {
- impl->observer->onLayerDataDrivenPaintPropertyChanged(*this);
+ observer->onLayerDataDrivenPaintPropertyChanged(*this);
} else {
- impl->observer->onLayerPaintPropertyChanged(*this);
+ observer->onLayerPaintPropertyChanged(*this);
}
}
void FillExtrusionLayer::setFillExtrusionBaseTransition(const TransitionOptions& value, const optional<std::string>& klass) {
- impl->cascading.template get<FillExtrusionBase>().setTransition(value, klass);
+ auto impl_ = mutableImpl();
+ impl_->cascading.template get<FillExtrusionBase>().setTransition(value, klass);
+ baseImpl = std::move(impl_);
}
TransitionOptions FillExtrusionLayer::getFillExtrusionBaseTransition(const optional<std::string>& klass) const {
- return impl->cascading.template get<FillExtrusionBase>().getTransition(klass);
+ return impl().cascading.template get<FillExtrusionBase>().getTransition(klass);
}
} // namespace style
diff --git a/src/mbgl/style/layers/fill_extrusion_layer_impl.cpp b/src/mbgl/style/layers/fill_extrusion_layer_impl.cpp
index 5340541221..9530e45b7f 100644
--- a/src/mbgl/style/layers/fill_extrusion_layer_impl.cpp
+++ b/src/mbgl/style/layers/fill_extrusion_layer_impl.cpp
@@ -5,7 +5,7 @@ namespace mbgl {
namespace style {
std::unique_ptr<RenderLayer> FillExtrusionLayer::Impl::createRenderLayer() const {
- return std::make_unique<RenderFillExtrusionLayer>(*this);
+ return std::make_unique<RenderFillExtrusionLayer>(staticImmutableCast<FillExtrusionLayer::Impl>(immutableFromThis()));
}
} // namespace style
diff --git a/src/mbgl/style/layers/fill_extrusion_layer_impl.hpp b/src/mbgl/style/layers/fill_extrusion_layer_impl.hpp
index 2353bd99fe..167d28e973 100644
--- a/src/mbgl/style/layers/fill_extrusion_layer_impl.hpp
+++ b/src/mbgl/style/layers/fill_extrusion_layer_impl.hpp
@@ -9,8 +9,8 @@ namespace style {
class FillExtrusionLayer::Impl : public Layer::Impl {
public:
- std::unique_ptr<Layer> clone() const override;
- std::unique_ptr<Layer> cloneRef(const std::string& id) const override;
+ using Layer::Impl::Impl;
+
void stringifyLayout(rapidjson::Writer<rapidjson::StringBuffer>&) const override;
std::unique_ptr<RenderLayer> createRenderLayer() const override;
diff --git a/src/mbgl/style/layers/fill_layer.cpp b/src/mbgl/style/layers/fill_layer.cpp
index 9fd9d33af3..39f476c974 100644
--- a/src/mbgl/style/layers/fill_layer.cpp
+++ b/src/mbgl/style/layers/fill_layer.cpp
@@ -3,33 +3,34 @@
#include <mbgl/style/layers/fill_layer.hpp>
#include <mbgl/style/layers/fill_layer_impl.hpp>
#include <mbgl/style/conversion/stringify.hpp>
+#include <mbgl/style/layer_observer.hpp>
namespace mbgl {
namespace style {
FillLayer::FillLayer(const std::string& layerID, const std::string& sourceID)
- : Layer(LayerType::Fill, std::make_unique<Impl>())
- , impl(static_cast<Impl*>(baseImpl.get())) {
- impl->id = layerID;
- impl->source = sourceID;
+ : Layer(makeMutable<Impl>(LayerType::Fill, layerID, sourceID)) {
}
-FillLayer::FillLayer(const Impl& other)
- : Layer(LayerType::Fill, std::make_unique<Impl>(other))
- , impl(static_cast<Impl*>(baseImpl.get())) {
+FillLayer::FillLayer(Immutable<Impl> impl_)
+ : Layer(std::move(impl_)) {
}
FillLayer::~FillLayer() = default;
-std::unique_ptr<Layer> FillLayer::Impl::clone() const {
- return std::make_unique<FillLayer>(*this);
+const FillLayer::Impl& FillLayer::impl() const {
+ return static_cast<const Impl&>(*baseImpl);
}
-std::unique_ptr<Layer> FillLayer::Impl::cloneRef(const std::string& id_) const {
- auto result = std::make_unique<FillLayer>(*this);
- result->impl->id = id_;
- result->impl->cascading = FillPaintProperties::Cascading();
- return std::move(result);
+Mutable<FillLayer::Impl> FillLayer::mutableImpl() const {
+ return makeMutable<Impl>(impl());
+}
+
+std::unique_ptr<Layer> FillLayer::cloneRef(const std::string& id_) const {
+ auto impl_ = mutableImpl();
+ impl_->id = id_;
+ impl_->cascading = FillPaintProperties::Cascading();
+ return std::make_unique<FillLayer>(std::move(impl_));
}
void FillLayer::Impl::stringifyLayout(rapidjson::Writer<rapidjson::StringBuffer>&) const {
@@ -38,26 +39,55 @@ void FillLayer::Impl::stringifyLayout(rapidjson::Writer<rapidjson::StringBuffer>
// Source
const std::string& FillLayer::getSourceID() const {
- return impl->source;
+ return impl().source;
}
void FillLayer::setSourceLayer(const std::string& sourceLayer) {
- impl->sourceLayer = sourceLayer;
+ auto impl_ = mutableImpl();
+ impl_->sourceLayer = sourceLayer;
+ baseImpl = std::move(impl_);
}
const std::string& FillLayer::getSourceLayer() const {
- return impl->sourceLayer;
+ return impl().sourceLayer;
}
// Filter
void FillLayer::setFilter(const Filter& filter) {
- impl->filter = filter;
- impl->observer->onLayerFilterChanged(*this);
+ auto impl_ = mutableImpl();
+ impl_->filter = filter;
+ baseImpl = std::move(impl_);
+ observer->onLayerFilterChanged(*this);
}
const Filter& FillLayer::getFilter() const {
- return impl->filter;
+ return impl().filter;
+}
+
+// Visibility
+
+void FillLayer::setVisibility(VisibilityType value) {
+ if (value == getVisibility())
+ return;
+ auto impl_ = mutableImpl();
+ impl_->visibility = value;
+ baseImpl = std::move(impl_);
+ observer->onLayerVisibilityChanged(*this);
+}
+
+// Zoom range
+
+void FillLayer::setMinZoom(float minZoom) {
+ auto impl_ = mutableImpl();
+ impl_->minZoom = minZoom;
+ baseImpl = std::move(impl_);
+}
+
+void FillLayer::setMaxZoom(float maxZoom) {
+ auto impl_ = mutableImpl();
+ impl_->maxZoom = maxZoom;
+ baseImpl = std::move(impl_);
}
// Layout properties
@@ -70,22 +100,26 @@ PropertyValue<bool> FillLayer::getDefaultFillAntialias() {
}
PropertyValue<bool> FillLayer::getFillAntialias(const optional<std::string>& klass) const {
- return impl->cascading.template get<FillAntialias>().get(klass);
+ return impl().cascading.template get<FillAntialias>().get(klass);
}
void FillLayer::setFillAntialias(PropertyValue<bool> value, const optional<std::string>& klass) {
if (value == getFillAntialias(klass))
return;
- impl->cascading.template get<FillAntialias>().set(value, klass);
- impl->observer->onLayerPaintPropertyChanged(*this);
+ auto impl_ = mutableImpl();
+ impl_->cascading.template get<FillAntialias>().set(value, klass);
+ baseImpl = std::move(impl_);
+ observer->onLayerPaintPropertyChanged(*this);
}
void FillLayer::setFillAntialiasTransition(const TransitionOptions& value, const optional<std::string>& klass) {
- impl->cascading.template get<FillAntialias>().setTransition(value, klass);
+ auto impl_ = mutableImpl();
+ impl_->cascading.template get<FillAntialias>().setTransition(value, klass);
+ baseImpl = std::move(impl_);
}
TransitionOptions FillLayer::getFillAntialiasTransition(const optional<std::string>& klass) const {
- return impl->cascading.template get<FillAntialias>().getTransition(klass);
+ return impl().cascading.template get<FillAntialias>().getTransition(klass);
}
DataDrivenPropertyValue<float> FillLayer::getDefaultFillOpacity() {
@@ -93,26 +127,30 @@ DataDrivenPropertyValue<float> FillLayer::getDefaultFillOpacity() {
}
DataDrivenPropertyValue<float> FillLayer::getFillOpacity(const optional<std::string>& klass) const {
- return impl->cascading.template get<FillOpacity>().get(klass);
+ return impl().cascading.template get<FillOpacity>().get(klass);
}
void FillLayer::setFillOpacity(DataDrivenPropertyValue<float> value, const optional<std::string>& klass) {
if (value == getFillOpacity(klass))
return;
- impl->cascading.template get<FillOpacity>().set(value, klass);
+ auto impl_ = mutableImpl();
+ impl_->cascading.template get<FillOpacity>().set(value, klass);
+ baseImpl = std::move(impl_);
if (value.isDataDriven()) {
- impl->observer->onLayerDataDrivenPaintPropertyChanged(*this);
+ observer->onLayerDataDrivenPaintPropertyChanged(*this);
} else {
- impl->observer->onLayerPaintPropertyChanged(*this);
+ observer->onLayerPaintPropertyChanged(*this);
}
}
void FillLayer::setFillOpacityTransition(const TransitionOptions& value, const optional<std::string>& klass) {
- impl->cascading.template get<FillOpacity>().setTransition(value, klass);
+ auto impl_ = mutableImpl();
+ impl_->cascading.template get<FillOpacity>().setTransition(value, klass);
+ baseImpl = std::move(impl_);
}
TransitionOptions FillLayer::getFillOpacityTransition(const optional<std::string>& klass) const {
- return impl->cascading.template get<FillOpacity>().getTransition(klass);
+ return impl().cascading.template get<FillOpacity>().getTransition(klass);
}
DataDrivenPropertyValue<Color> FillLayer::getDefaultFillColor() {
@@ -120,26 +158,30 @@ DataDrivenPropertyValue<Color> FillLayer::getDefaultFillColor() {
}
DataDrivenPropertyValue<Color> FillLayer::getFillColor(const optional<std::string>& klass) const {
- return impl->cascading.template get<FillColor>().get(klass);
+ return impl().cascading.template get<FillColor>().get(klass);
}
void FillLayer::setFillColor(DataDrivenPropertyValue<Color> value, const optional<std::string>& klass) {
if (value == getFillColor(klass))
return;
- impl->cascading.template get<FillColor>().set(value, klass);
+ auto impl_ = mutableImpl();
+ impl_->cascading.template get<FillColor>().set(value, klass);
+ baseImpl = std::move(impl_);
if (value.isDataDriven()) {
- impl->observer->onLayerDataDrivenPaintPropertyChanged(*this);
+ observer->onLayerDataDrivenPaintPropertyChanged(*this);
} else {
- impl->observer->onLayerPaintPropertyChanged(*this);
+ observer->onLayerPaintPropertyChanged(*this);
}
}
void FillLayer::setFillColorTransition(const TransitionOptions& value, const optional<std::string>& klass) {
- impl->cascading.template get<FillColor>().setTransition(value, klass);
+ auto impl_ = mutableImpl();
+ impl_->cascading.template get<FillColor>().setTransition(value, klass);
+ baseImpl = std::move(impl_);
}
TransitionOptions FillLayer::getFillColorTransition(const optional<std::string>& klass) const {
- return impl->cascading.template get<FillColor>().getTransition(klass);
+ return impl().cascading.template get<FillColor>().getTransition(klass);
}
DataDrivenPropertyValue<Color> FillLayer::getDefaultFillOutlineColor() {
@@ -147,26 +189,30 @@ DataDrivenPropertyValue<Color> FillLayer::getDefaultFillOutlineColor() {
}
DataDrivenPropertyValue<Color> FillLayer::getFillOutlineColor(const optional<std::string>& klass) const {
- return impl->cascading.template get<FillOutlineColor>().get(klass);
+ return impl().cascading.template get<FillOutlineColor>().get(klass);
}
void FillLayer::setFillOutlineColor(DataDrivenPropertyValue<Color> value, const optional<std::string>& klass) {
if (value == getFillOutlineColor(klass))
return;
- impl->cascading.template get<FillOutlineColor>().set(value, klass);
+ auto impl_ = mutableImpl();
+ impl_->cascading.template get<FillOutlineColor>().set(value, klass);
+ baseImpl = std::move(impl_);
if (value.isDataDriven()) {
- impl->observer->onLayerDataDrivenPaintPropertyChanged(*this);
+ observer->onLayerDataDrivenPaintPropertyChanged(*this);
} else {
- impl->observer->onLayerPaintPropertyChanged(*this);
+ observer->onLayerPaintPropertyChanged(*this);
}
}
void FillLayer::setFillOutlineColorTransition(const TransitionOptions& value, const optional<std::string>& klass) {
- impl->cascading.template get<FillOutlineColor>().setTransition(value, klass);
+ auto impl_ = mutableImpl();
+ impl_->cascading.template get<FillOutlineColor>().setTransition(value, klass);
+ baseImpl = std::move(impl_);
}
TransitionOptions FillLayer::getFillOutlineColorTransition(const optional<std::string>& klass) const {
- return impl->cascading.template get<FillOutlineColor>().getTransition(klass);
+ return impl().cascading.template get<FillOutlineColor>().getTransition(klass);
}
PropertyValue<std::array<float, 2>> FillLayer::getDefaultFillTranslate() {
@@ -174,22 +220,26 @@ PropertyValue<std::array<float, 2>> FillLayer::getDefaultFillTranslate() {
}
PropertyValue<std::array<float, 2>> FillLayer::getFillTranslate(const optional<std::string>& klass) const {
- return impl->cascading.template get<FillTranslate>().get(klass);
+ return impl().cascading.template get<FillTranslate>().get(klass);
}
void FillLayer::setFillTranslate(PropertyValue<std::array<float, 2>> value, const optional<std::string>& klass) {
if (value == getFillTranslate(klass))
return;
- impl->cascading.template get<FillTranslate>().set(value, klass);
- impl->observer->onLayerPaintPropertyChanged(*this);
+ auto impl_ = mutableImpl();
+ impl_->cascading.template get<FillTranslate>().set(value, klass);
+ baseImpl = std::move(impl_);
+ observer->onLayerPaintPropertyChanged(*this);
}
void FillLayer::setFillTranslateTransition(const TransitionOptions& value, const optional<std::string>& klass) {
- impl->cascading.template get<FillTranslate>().setTransition(value, klass);
+ auto impl_ = mutableImpl();
+ impl_->cascading.template get<FillTranslate>().setTransition(value, klass);
+ baseImpl = std::move(impl_);
}
TransitionOptions FillLayer::getFillTranslateTransition(const optional<std::string>& klass) const {
- return impl->cascading.template get<FillTranslate>().getTransition(klass);
+ return impl().cascading.template get<FillTranslate>().getTransition(klass);
}
PropertyValue<TranslateAnchorType> FillLayer::getDefaultFillTranslateAnchor() {
@@ -197,22 +247,26 @@ PropertyValue<TranslateAnchorType> FillLayer::getDefaultFillTranslateAnchor() {
}
PropertyValue<TranslateAnchorType> FillLayer::getFillTranslateAnchor(const optional<std::string>& klass) const {
- return impl->cascading.template get<FillTranslateAnchor>().get(klass);
+ return impl().cascading.template get<FillTranslateAnchor>().get(klass);
}
void FillLayer::setFillTranslateAnchor(PropertyValue<TranslateAnchorType> value, const optional<std::string>& klass) {
if (value == getFillTranslateAnchor(klass))
return;
- impl->cascading.template get<FillTranslateAnchor>().set(value, klass);
- impl->observer->onLayerPaintPropertyChanged(*this);
+ auto impl_ = mutableImpl();
+ impl_->cascading.template get<FillTranslateAnchor>().set(value, klass);
+ baseImpl = std::move(impl_);
+ observer->onLayerPaintPropertyChanged(*this);
}
void FillLayer::setFillTranslateAnchorTransition(const TransitionOptions& value, const optional<std::string>& klass) {
- impl->cascading.template get<FillTranslateAnchor>().setTransition(value, klass);
+ auto impl_ = mutableImpl();
+ impl_->cascading.template get<FillTranslateAnchor>().setTransition(value, klass);
+ baseImpl = std::move(impl_);
}
TransitionOptions FillLayer::getFillTranslateAnchorTransition(const optional<std::string>& klass) const {
- return impl->cascading.template get<FillTranslateAnchor>().getTransition(klass);
+ return impl().cascading.template get<FillTranslateAnchor>().getTransition(klass);
}
PropertyValue<std::string> FillLayer::getDefaultFillPattern() {
@@ -220,22 +274,26 @@ PropertyValue<std::string> FillLayer::getDefaultFillPattern() {
}
PropertyValue<std::string> FillLayer::getFillPattern(const optional<std::string>& klass) const {
- return impl->cascading.template get<FillPattern>().get(klass);
+ return impl().cascading.template get<FillPattern>().get(klass);
}
void FillLayer::setFillPattern(PropertyValue<std::string> value, const optional<std::string>& klass) {
if (value == getFillPattern(klass))
return;
- impl->cascading.template get<FillPattern>().set(value, klass);
- impl->observer->onLayerPaintPropertyChanged(*this);
+ auto impl_ = mutableImpl();
+ impl_->cascading.template get<FillPattern>().set(value, klass);
+ baseImpl = std::move(impl_);
+ observer->onLayerPaintPropertyChanged(*this);
}
void FillLayer::setFillPatternTransition(const TransitionOptions& value, const optional<std::string>& klass) {
- impl->cascading.template get<FillPattern>().setTransition(value, klass);
+ auto impl_ = mutableImpl();
+ impl_->cascading.template get<FillPattern>().setTransition(value, klass);
+ baseImpl = std::move(impl_);
}
TransitionOptions FillLayer::getFillPatternTransition(const optional<std::string>& klass) const {
- return impl->cascading.template get<FillPattern>().getTransition(klass);
+ return impl().cascading.template get<FillPattern>().getTransition(klass);
}
} // namespace style
diff --git a/src/mbgl/style/layers/fill_layer_impl.cpp b/src/mbgl/style/layers/fill_layer_impl.cpp
index 6ec55a58e3..3bddedbdfb 100644
--- a/src/mbgl/style/layers/fill_layer_impl.cpp
+++ b/src/mbgl/style/layers/fill_layer_impl.cpp
@@ -5,7 +5,7 @@ namespace mbgl {
namespace style {
std::unique_ptr<RenderLayer> FillLayer::Impl::createRenderLayer() const {
- return std::make_unique<RenderFillLayer>(*this);
+ return std::make_unique<RenderFillLayer>(staticImmutableCast<FillLayer::Impl>(immutableFromThis()));
}
} // namespace style
diff --git a/src/mbgl/style/layers/fill_layer_impl.hpp b/src/mbgl/style/layers/fill_layer_impl.hpp
index 215558962e..0e911c86cf 100644
--- a/src/mbgl/style/layers/fill_layer_impl.hpp
+++ b/src/mbgl/style/layers/fill_layer_impl.hpp
@@ -9,8 +9,8 @@ namespace style {
class FillLayer::Impl : public Layer::Impl {
public:
- std::unique_ptr<Layer> clone() const override;
- std::unique_ptr<Layer> cloneRef(const std::string& id) const override;
+ using Layer::Impl::Impl;
+
void stringifyLayout(rapidjson::Writer<rapidjson::StringBuffer>&) const override;
std::unique_ptr<RenderLayer> createRenderLayer() const override;
diff --git a/src/mbgl/style/layers/layer.cpp.ejs b/src/mbgl/style/layers/layer.cpp.ejs
index 2f690c3158..31a4332400 100644
--- a/src/mbgl/style/layers/layer.cpp.ejs
+++ b/src/mbgl/style/layers/layer.cpp.ejs
@@ -8,41 +8,40 @@
#include <mbgl/style/layers/<%- type.replace('-', '_') %>_layer.hpp>
#include <mbgl/style/layers/<%- type.replace('-', '_') %>_layer_impl.hpp>
#include <mbgl/style/conversion/stringify.hpp>
+#include <mbgl/style/layer_observer.hpp>
namespace mbgl {
namespace style {
<% if (type === 'background') { -%>
<%- camelize(type) %>Layer::<%- camelize(type) %>Layer(const std::string& layerID)
- : Layer(LayerType::<%- camelize(type) %>, std::make_unique<Impl>())
- , impl(static_cast<Impl*>(baseImpl.get())) {
- impl->id = layerID;
+ : Layer(makeMutable<Impl>(LayerType::<%- camelize(type) %>, layerID, std::string())) {
}
<% } else { -%>
<%- camelize(type) %>Layer::<%- camelize(type) %>Layer(const std::string& layerID, const std::string& sourceID)
- : Layer(LayerType::<%- camelize(type) %>, std::make_unique<Impl>())
- , impl(static_cast<Impl*>(baseImpl.get())) {
- impl->id = layerID;
- impl->source = sourceID;
+ : Layer(makeMutable<Impl>(LayerType::<%- camelize(type) %>, layerID, sourceID)) {
}
<% } -%>
-<%- camelize(type) %>Layer::<%- camelize(type) %>Layer(const Impl& other)
- : Layer(LayerType::<%- camelize(type) %>, std::make_unique<Impl>(other))
- , impl(static_cast<Impl*>(baseImpl.get())) {
+<%- camelize(type) %>Layer::<%- camelize(type) %>Layer(Immutable<Impl> impl_)
+ : Layer(std::move(impl_)) {
}
<%- camelize(type) %>Layer::~<%- camelize(type) %>Layer() = default;
-std::unique_ptr<Layer> <%- camelize(type) %>Layer::Impl::clone() const {
- return std::make_unique<<%- camelize(type) %>Layer>(*this);
+const <%- camelize(type) %>Layer::Impl& <%- camelize(type) %>Layer::impl() const {
+ return static_cast<const Impl&>(*baseImpl);
}
-std::unique_ptr<Layer> <%- camelize(type) %>Layer::Impl::cloneRef(const std::string& id_) const {
- auto result = std::make_unique<<%- camelize(type) %>Layer>(*this);
- result->impl->id = id_;
- result->impl->cascading = <%- camelize(type) %>PaintProperties::Cascading();
- return std::move(result);
+Mutable<<%- camelize(type) %>Layer::Impl> <%- camelize(type) %>Layer::mutableImpl() const {
+ return makeMutable<Impl>(impl());
+}
+
+std::unique_ptr<Layer> <%- camelize(type) %>Layer::cloneRef(const std::string& id_) const {
+ auto impl_ = mutableImpl();
+ impl_->id = id_;
+ impl_->cascading = <%- camelize(type) %>PaintProperties::Cascading();
+ return std::make_unique<<%- camelize(type) %>Layer>(std::move(impl_));
}
<% if (layoutProperties.length) { -%>
@@ -58,31 +57,60 @@ void <%- camelize(type) %>Layer::Impl::stringifyLayout(rapidjson::Writer<rapidjs
// Source
const std::string& <%- camelize(type) %>Layer::getSourceID() const {
- return impl->source;
+ return impl().source;
}
<% if (type !== 'raster') { -%>
void <%- camelize(type) %>Layer::setSourceLayer(const std::string& sourceLayer) {
- impl->sourceLayer = sourceLayer;
+ auto impl_ = mutableImpl();
+ impl_->sourceLayer = sourceLayer;
+ baseImpl = std::move(impl_);
}
const std::string& <%- camelize(type) %>Layer::getSourceLayer() const {
- return impl->sourceLayer;
+ return impl().sourceLayer;
}
// Filter
void <%- camelize(type) %>Layer::setFilter(const Filter& filter) {
- impl->filter = filter;
- impl->observer->onLayerFilterChanged(*this);
+ auto impl_ = mutableImpl();
+ impl_->filter = filter;
+ baseImpl = std::move(impl_);
+ observer->onLayerFilterChanged(*this);
}
const Filter& <%- camelize(type) %>Layer::getFilter() const {
- return impl->filter;
+ return impl().filter;
}
<% } -%>
<% } -%>
+// Visibility
+
+void <%- camelize(type) %>Layer::setVisibility(VisibilityType value) {
+ if (value == getVisibility())
+ return;
+ auto impl_ = mutableImpl();
+ impl_->visibility = value;
+ baseImpl = std::move(impl_);
+ observer->onLayerVisibilityChanged(*this);
+}
+
+// Zoom range
+
+void <%- camelize(type) %>Layer::setMinZoom(float minZoom) {
+ auto impl_ = mutableImpl();
+ impl_->minZoom = minZoom;
+ baseImpl = std::move(impl_);
+}
+
+void <%- camelize(type) %>Layer::setMaxZoom(float maxZoom) {
+ auto impl_ = mutableImpl();
+ impl_->maxZoom = maxZoom;
+ baseImpl = std::move(impl_);
+}
+
// Layout properties
<% for (const property of layoutProperties) { -%>
@@ -91,14 +119,16 @@ const Filter& <%- camelize(type) %>Layer::getFilter() const {
}
<%- propertyValueType(property) %> <%- camelize(type) %>Layer::get<%- camelize(property.name) %>() const {
- return impl->layout.unevaluated.get<<%- camelize(property.name) %>>();
+ return impl().layout.unevaluated.get<<%- camelize(property.name) %>>();
}
void <%- camelize(type) %>Layer::set<%- camelize(property.name) %>(<%- propertyValueType(property) %> value) {
if (value == get<%- camelize(property.name) %>())
return;
- impl->layout.unevaluated.get<<%- camelize(property.name) %>>() = value;
- impl->observer->onLayerLayoutPropertyChanged(*this, "<%- property.name %>");
+ auto impl_ = mutableImpl();
+ impl_->layout.unevaluated.get<<%- camelize(property.name) %>>() = value;
+ baseImpl = std::move(impl_);
+ observer->onLayerLayoutPropertyChanged(*this, "<%- property.name %>");
}
<% } -%>
@@ -109,30 +139,34 @@ void <%- camelize(type) %>Layer::set<%- camelize(property.name) %>(<%- propertyV
}
<%- propertyValueType(property) %> <%- camelize(type) %>Layer::get<%- camelize(property.name) %>(const optional<std::string>& klass) const {
- return impl->cascading.template get<<%- camelize(property.name) %>>().get(klass);
+ return impl().cascading.template get<<%- camelize(property.name) %>>().get(klass);
}
void <%- camelize(type) %>Layer::set<%- camelize(property.name) %>(<%- propertyValueType(property) %> value, const optional<std::string>& klass) {
if (value == get<%- camelize(property.name) %>(klass))
return;
- impl->cascading.template get<<%- camelize(property.name) %>>().set(value, klass);
+ auto impl_ = mutableImpl();
+ impl_->cascading.template get<<%- camelize(property.name) %>>().set(value, klass);
+ baseImpl = std::move(impl_);
<% if (isDataDriven(property)) { -%>
if (value.isDataDriven()) {
- impl->observer->onLayerDataDrivenPaintPropertyChanged(*this);
+ observer->onLayerDataDrivenPaintPropertyChanged(*this);
} else {
- impl->observer->onLayerPaintPropertyChanged(*this);
+ observer->onLayerPaintPropertyChanged(*this);
}
<% } else { -%>
- impl->observer->onLayerPaintPropertyChanged(*this);
+ observer->onLayerPaintPropertyChanged(*this);
<% } -%>
}
void <%- camelize(type) %>Layer::set<%- camelize(property.name) %>Transition(const TransitionOptions& value, const optional<std::string>& klass) {
- impl->cascading.template get<<%- camelize(property.name) %>>().setTransition(value, klass);
+ auto impl_ = mutableImpl();
+ impl_->cascading.template get<<%- camelize(property.name) %>>().setTransition(value, klass);
+ baseImpl = std::move(impl_);
}
TransitionOptions <%- camelize(type) %>Layer::get<%- camelize(property.name) %>Transition(const optional<std::string>& klass) const {
- return impl->cascading.template get<<%- camelize(property.name) %>>().getTransition(klass);
+ return impl().cascading.template get<<%- camelize(property.name) %>>().getTransition(klass);
}
<% } -%>
diff --git a/src/mbgl/style/layers/line_layer.cpp b/src/mbgl/style/layers/line_layer.cpp
index 7f1575aad5..8b9085b48c 100644
--- a/src/mbgl/style/layers/line_layer.cpp
+++ b/src/mbgl/style/layers/line_layer.cpp
@@ -3,33 +3,34 @@
#include <mbgl/style/layers/line_layer.hpp>
#include <mbgl/style/layers/line_layer_impl.hpp>
#include <mbgl/style/conversion/stringify.hpp>
+#include <mbgl/style/layer_observer.hpp>
namespace mbgl {
namespace style {
LineLayer::LineLayer(const std::string& layerID, const std::string& sourceID)
- : Layer(LayerType::Line, std::make_unique<Impl>())
- , impl(static_cast<Impl*>(baseImpl.get())) {
- impl->id = layerID;
- impl->source = sourceID;
+ : Layer(makeMutable<Impl>(LayerType::Line, layerID, sourceID)) {
}
-LineLayer::LineLayer(const Impl& other)
- : Layer(LayerType::Line, std::make_unique<Impl>(other))
- , impl(static_cast<Impl*>(baseImpl.get())) {
+LineLayer::LineLayer(Immutable<Impl> impl_)
+ : Layer(std::move(impl_)) {
}
LineLayer::~LineLayer() = default;
-std::unique_ptr<Layer> LineLayer::Impl::clone() const {
- return std::make_unique<LineLayer>(*this);
+const LineLayer::Impl& LineLayer::impl() const {
+ return static_cast<const Impl&>(*baseImpl);
}
-std::unique_ptr<Layer> LineLayer::Impl::cloneRef(const std::string& id_) const {
- auto result = std::make_unique<LineLayer>(*this);
- result->impl->id = id_;
- result->impl->cascading = LinePaintProperties::Cascading();
- return std::move(result);
+Mutable<LineLayer::Impl> LineLayer::mutableImpl() const {
+ return makeMutable<Impl>(impl());
+}
+
+std::unique_ptr<Layer> LineLayer::cloneRef(const std::string& id_) const {
+ auto impl_ = mutableImpl();
+ impl_->id = id_;
+ impl_->cascading = LinePaintProperties::Cascading();
+ return std::make_unique<LineLayer>(std::move(impl_));
}
void LineLayer::Impl::stringifyLayout(rapidjson::Writer<rapidjson::StringBuffer>& writer) const {
@@ -39,26 +40,55 @@ void LineLayer::Impl::stringifyLayout(rapidjson::Writer<rapidjson::StringBuffer>
// Source
const std::string& LineLayer::getSourceID() const {
- return impl->source;
+ return impl().source;
}
void LineLayer::setSourceLayer(const std::string& sourceLayer) {
- impl->sourceLayer = sourceLayer;
+ auto impl_ = mutableImpl();
+ impl_->sourceLayer = sourceLayer;
+ baseImpl = std::move(impl_);
}
const std::string& LineLayer::getSourceLayer() const {
- return impl->sourceLayer;
+ return impl().sourceLayer;
}
// Filter
void LineLayer::setFilter(const Filter& filter) {
- impl->filter = filter;
- impl->observer->onLayerFilterChanged(*this);
+ auto impl_ = mutableImpl();
+ impl_->filter = filter;
+ baseImpl = std::move(impl_);
+ observer->onLayerFilterChanged(*this);
}
const Filter& LineLayer::getFilter() const {
- return impl->filter;
+ return impl().filter;
+}
+
+// Visibility
+
+void LineLayer::setVisibility(VisibilityType value) {
+ if (value == getVisibility())
+ return;
+ auto impl_ = mutableImpl();
+ impl_->visibility = value;
+ baseImpl = std::move(impl_);
+ observer->onLayerVisibilityChanged(*this);
+}
+
+// Zoom range
+
+void LineLayer::setMinZoom(float minZoom) {
+ auto impl_ = mutableImpl();
+ impl_->minZoom = minZoom;
+ baseImpl = std::move(impl_);
+}
+
+void LineLayer::setMaxZoom(float maxZoom) {
+ auto impl_ = mutableImpl();
+ impl_->maxZoom = maxZoom;
+ baseImpl = std::move(impl_);
}
// Layout properties
@@ -68,56 +98,64 @@ PropertyValue<LineCapType> LineLayer::getDefaultLineCap() {
}
PropertyValue<LineCapType> LineLayer::getLineCap() const {
- return impl->layout.unevaluated.get<LineCap>();
+ return impl().layout.unevaluated.get<LineCap>();
}
void LineLayer::setLineCap(PropertyValue<LineCapType> value) {
if (value == getLineCap())
return;
- impl->layout.unevaluated.get<LineCap>() = value;
- impl->observer->onLayerLayoutPropertyChanged(*this, "line-cap");
+ auto impl_ = mutableImpl();
+ impl_->layout.unevaluated.get<LineCap>() = value;
+ baseImpl = std::move(impl_);
+ observer->onLayerLayoutPropertyChanged(*this, "line-cap");
}
PropertyValue<LineJoinType> LineLayer::getDefaultLineJoin() {
return LineJoin::defaultValue();
}
PropertyValue<LineJoinType> LineLayer::getLineJoin() const {
- return impl->layout.unevaluated.get<LineJoin>();
+ return impl().layout.unevaluated.get<LineJoin>();
}
void LineLayer::setLineJoin(PropertyValue<LineJoinType> value) {
if (value == getLineJoin())
return;
- impl->layout.unevaluated.get<LineJoin>() = value;
- impl->observer->onLayerLayoutPropertyChanged(*this, "line-join");
+ auto impl_ = mutableImpl();
+ impl_->layout.unevaluated.get<LineJoin>() = value;
+ baseImpl = std::move(impl_);
+ observer->onLayerLayoutPropertyChanged(*this, "line-join");
}
PropertyValue<float> LineLayer::getDefaultLineMiterLimit() {
return LineMiterLimit::defaultValue();
}
PropertyValue<float> LineLayer::getLineMiterLimit() const {
- return impl->layout.unevaluated.get<LineMiterLimit>();
+ return impl().layout.unevaluated.get<LineMiterLimit>();
}
void LineLayer::setLineMiterLimit(PropertyValue<float> value) {
if (value == getLineMiterLimit())
return;
- impl->layout.unevaluated.get<LineMiterLimit>() = value;
- impl->observer->onLayerLayoutPropertyChanged(*this, "line-miter-limit");
+ auto impl_ = mutableImpl();
+ impl_->layout.unevaluated.get<LineMiterLimit>() = value;
+ baseImpl = std::move(impl_);
+ observer->onLayerLayoutPropertyChanged(*this, "line-miter-limit");
}
PropertyValue<float> LineLayer::getDefaultLineRoundLimit() {
return LineRoundLimit::defaultValue();
}
PropertyValue<float> LineLayer::getLineRoundLimit() const {
- return impl->layout.unevaluated.get<LineRoundLimit>();
+ return impl().layout.unevaluated.get<LineRoundLimit>();
}
void LineLayer::setLineRoundLimit(PropertyValue<float> value) {
if (value == getLineRoundLimit())
return;
- impl->layout.unevaluated.get<LineRoundLimit>() = value;
- impl->observer->onLayerLayoutPropertyChanged(*this, "line-round-limit");
+ auto impl_ = mutableImpl();
+ impl_->layout.unevaluated.get<LineRoundLimit>() = value;
+ baseImpl = std::move(impl_);
+ observer->onLayerLayoutPropertyChanged(*this, "line-round-limit");
}
// Paint properties
@@ -127,26 +165,30 @@ DataDrivenPropertyValue<float> LineLayer::getDefaultLineOpacity() {
}
DataDrivenPropertyValue<float> LineLayer::getLineOpacity(const optional<std::string>& klass) const {
- return impl->cascading.template get<LineOpacity>().get(klass);
+ return impl().cascading.template get<LineOpacity>().get(klass);
}
void LineLayer::setLineOpacity(DataDrivenPropertyValue<float> value, const optional<std::string>& klass) {
if (value == getLineOpacity(klass))
return;
- impl->cascading.template get<LineOpacity>().set(value, klass);
+ auto impl_ = mutableImpl();
+ impl_->cascading.template get<LineOpacity>().set(value, klass);
+ baseImpl = std::move(impl_);
if (value.isDataDriven()) {
- impl->observer->onLayerDataDrivenPaintPropertyChanged(*this);
+ observer->onLayerDataDrivenPaintPropertyChanged(*this);
} else {
- impl->observer->onLayerPaintPropertyChanged(*this);
+ observer->onLayerPaintPropertyChanged(*this);
}
}
void LineLayer::setLineOpacityTransition(const TransitionOptions& value, const optional<std::string>& klass) {
- impl->cascading.template get<LineOpacity>().setTransition(value, klass);
+ auto impl_ = mutableImpl();
+ impl_->cascading.template get<LineOpacity>().setTransition(value, klass);
+ baseImpl = std::move(impl_);
}
TransitionOptions LineLayer::getLineOpacityTransition(const optional<std::string>& klass) const {
- return impl->cascading.template get<LineOpacity>().getTransition(klass);
+ return impl().cascading.template get<LineOpacity>().getTransition(klass);
}
DataDrivenPropertyValue<Color> LineLayer::getDefaultLineColor() {
@@ -154,26 +196,30 @@ DataDrivenPropertyValue<Color> LineLayer::getDefaultLineColor() {
}
DataDrivenPropertyValue<Color> LineLayer::getLineColor(const optional<std::string>& klass) const {
- return impl->cascading.template get<LineColor>().get(klass);
+ return impl().cascading.template get<LineColor>().get(klass);
}
void LineLayer::setLineColor(DataDrivenPropertyValue<Color> value, const optional<std::string>& klass) {
if (value == getLineColor(klass))
return;
- impl->cascading.template get<LineColor>().set(value, klass);
+ auto impl_ = mutableImpl();
+ impl_->cascading.template get<LineColor>().set(value, klass);
+ baseImpl = std::move(impl_);
if (value.isDataDriven()) {
- impl->observer->onLayerDataDrivenPaintPropertyChanged(*this);
+ observer->onLayerDataDrivenPaintPropertyChanged(*this);
} else {
- impl->observer->onLayerPaintPropertyChanged(*this);
+ observer->onLayerPaintPropertyChanged(*this);
}
}
void LineLayer::setLineColorTransition(const TransitionOptions& value, const optional<std::string>& klass) {
- impl->cascading.template get<LineColor>().setTransition(value, klass);
+ auto impl_ = mutableImpl();
+ impl_->cascading.template get<LineColor>().setTransition(value, klass);
+ baseImpl = std::move(impl_);
}
TransitionOptions LineLayer::getLineColorTransition(const optional<std::string>& klass) const {
- return impl->cascading.template get<LineColor>().getTransition(klass);
+ return impl().cascading.template get<LineColor>().getTransition(klass);
}
PropertyValue<std::array<float, 2>> LineLayer::getDefaultLineTranslate() {
@@ -181,22 +227,26 @@ PropertyValue<std::array<float, 2>> LineLayer::getDefaultLineTranslate() {
}
PropertyValue<std::array<float, 2>> LineLayer::getLineTranslate(const optional<std::string>& klass) const {
- return impl->cascading.template get<LineTranslate>().get(klass);
+ return impl().cascading.template get<LineTranslate>().get(klass);
}
void LineLayer::setLineTranslate(PropertyValue<std::array<float, 2>> value, const optional<std::string>& klass) {
if (value == getLineTranslate(klass))
return;
- impl->cascading.template get<LineTranslate>().set(value, klass);
- impl->observer->onLayerPaintPropertyChanged(*this);
+ auto impl_ = mutableImpl();
+ impl_->cascading.template get<LineTranslate>().set(value, klass);
+ baseImpl = std::move(impl_);
+ observer->onLayerPaintPropertyChanged(*this);
}
void LineLayer::setLineTranslateTransition(const TransitionOptions& value, const optional<std::string>& klass) {
- impl->cascading.template get<LineTranslate>().setTransition(value, klass);
+ auto impl_ = mutableImpl();
+ impl_->cascading.template get<LineTranslate>().setTransition(value, klass);
+ baseImpl = std::move(impl_);
}
TransitionOptions LineLayer::getLineTranslateTransition(const optional<std::string>& klass) const {
- return impl->cascading.template get<LineTranslate>().getTransition(klass);
+ return impl().cascading.template get<LineTranslate>().getTransition(klass);
}
PropertyValue<TranslateAnchorType> LineLayer::getDefaultLineTranslateAnchor() {
@@ -204,22 +254,26 @@ PropertyValue<TranslateAnchorType> LineLayer::getDefaultLineTranslateAnchor() {
}
PropertyValue<TranslateAnchorType> LineLayer::getLineTranslateAnchor(const optional<std::string>& klass) const {
- return impl->cascading.template get<LineTranslateAnchor>().get(klass);
+ return impl().cascading.template get<LineTranslateAnchor>().get(klass);
}
void LineLayer::setLineTranslateAnchor(PropertyValue<TranslateAnchorType> value, const optional<std::string>& klass) {
if (value == getLineTranslateAnchor(klass))
return;
- impl->cascading.template get<LineTranslateAnchor>().set(value, klass);
- impl->observer->onLayerPaintPropertyChanged(*this);
+ auto impl_ = mutableImpl();
+ impl_->cascading.template get<LineTranslateAnchor>().set(value, klass);
+ baseImpl = std::move(impl_);
+ observer->onLayerPaintPropertyChanged(*this);
}
void LineLayer::setLineTranslateAnchorTransition(const TransitionOptions& value, const optional<std::string>& klass) {
- impl->cascading.template get<LineTranslateAnchor>().setTransition(value, klass);
+ auto impl_ = mutableImpl();
+ impl_->cascading.template get<LineTranslateAnchor>().setTransition(value, klass);
+ baseImpl = std::move(impl_);
}
TransitionOptions LineLayer::getLineTranslateAnchorTransition(const optional<std::string>& klass) const {
- return impl->cascading.template get<LineTranslateAnchor>().getTransition(klass);
+ return impl().cascading.template get<LineTranslateAnchor>().getTransition(klass);
}
PropertyValue<float> LineLayer::getDefaultLineWidth() {
@@ -227,22 +281,26 @@ PropertyValue<float> LineLayer::getDefaultLineWidth() {
}
PropertyValue<float> LineLayer::getLineWidth(const optional<std::string>& klass) const {
- return impl->cascading.template get<LineWidth>().get(klass);
+ return impl().cascading.template get<LineWidth>().get(klass);
}
void LineLayer::setLineWidth(PropertyValue<float> value, const optional<std::string>& klass) {
if (value == getLineWidth(klass))
return;
- impl->cascading.template get<LineWidth>().set(value, klass);
- impl->observer->onLayerPaintPropertyChanged(*this);
+ auto impl_ = mutableImpl();
+ impl_->cascading.template get<LineWidth>().set(value, klass);
+ baseImpl = std::move(impl_);
+ observer->onLayerPaintPropertyChanged(*this);
}
void LineLayer::setLineWidthTransition(const TransitionOptions& value, const optional<std::string>& klass) {
- impl->cascading.template get<LineWidth>().setTransition(value, klass);
+ auto impl_ = mutableImpl();
+ impl_->cascading.template get<LineWidth>().setTransition(value, klass);
+ baseImpl = std::move(impl_);
}
TransitionOptions LineLayer::getLineWidthTransition(const optional<std::string>& klass) const {
- return impl->cascading.template get<LineWidth>().getTransition(klass);
+ return impl().cascading.template get<LineWidth>().getTransition(klass);
}
DataDrivenPropertyValue<float> LineLayer::getDefaultLineGapWidth() {
@@ -250,26 +308,30 @@ DataDrivenPropertyValue<float> LineLayer::getDefaultLineGapWidth() {
}
DataDrivenPropertyValue<float> LineLayer::getLineGapWidth(const optional<std::string>& klass) const {
- return impl->cascading.template get<LineGapWidth>().get(klass);
+ return impl().cascading.template get<LineGapWidth>().get(klass);
}
void LineLayer::setLineGapWidth(DataDrivenPropertyValue<float> value, const optional<std::string>& klass) {
if (value == getLineGapWidth(klass))
return;
- impl->cascading.template get<LineGapWidth>().set(value, klass);
+ auto impl_ = mutableImpl();
+ impl_->cascading.template get<LineGapWidth>().set(value, klass);
+ baseImpl = std::move(impl_);
if (value.isDataDriven()) {
- impl->observer->onLayerDataDrivenPaintPropertyChanged(*this);
+ observer->onLayerDataDrivenPaintPropertyChanged(*this);
} else {
- impl->observer->onLayerPaintPropertyChanged(*this);
+ observer->onLayerPaintPropertyChanged(*this);
}
}
void LineLayer::setLineGapWidthTransition(const TransitionOptions& value, const optional<std::string>& klass) {
- impl->cascading.template get<LineGapWidth>().setTransition(value, klass);
+ auto impl_ = mutableImpl();
+ impl_->cascading.template get<LineGapWidth>().setTransition(value, klass);
+ baseImpl = std::move(impl_);
}
TransitionOptions LineLayer::getLineGapWidthTransition(const optional<std::string>& klass) const {
- return impl->cascading.template get<LineGapWidth>().getTransition(klass);
+ return impl().cascading.template get<LineGapWidth>().getTransition(klass);
}
DataDrivenPropertyValue<float> LineLayer::getDefaultLineOffset() {
@@ -277,26 +339,30 @@ DataDrivenPropertyValue<float> LineLayer::getDefaultLineOffset() {
}
DataDrivenPropertyValue<float> LineLayer::getLineOffset(const optional<std::string>& klass) const {
- return impl->cascading.template get<LineOffset>().get(klass);
+ return impl().cascading.template get<LineOffset>().get(klass);
}
void LineLayer::setLineOffset(DataDrivenPropertyValue<float> value, const optional<std::string>& klass) {
if (value == getLineOffset(klass))
return;
- impl->cascading.template get<LineOffset>().set(value, klass);
+ auto impl_ = mutableImpl();
+ impl_->cascading.template get<LineOffset>().set(value, klass);
+ baseImpl = std::move(impl_);
if (value.isDataDriven()) {
- impl->observer->onLayerDataDrivenPaintPropertyChanged(*this);
+ observer->onLayerDataDrivenPaintPropertyChanged(*this);
} else {
- impl->observer->onLayerPaintPropertyChanged(*this);
+ observer->onLayerPaintPropertyChanged(*this);
}
}
void LineLayer::setLineOffsetTransition(const TransitionOptions& value, const optional<std::string>& klass) {
- impl->cascading.template get<LineOffset>().setTransition(value, klass);
+ auto impl_ = mutableImpl();
+ impl_->cascading.template get<LineOffset>().setTransition(value, klass);
+ baseImpl = std::move(impl_);
}
TransitionOptions LineLayer::getLineOffsetTransition(const optional<std::string>& klass) const {
- return impl->cascading.template get<LineOffset>().getTransition(klass);
+ return impl().cascading.template get<LineOffset>().getTransition(klass);
}
DataDrivenPropertyValue<float> LineLayer::getDefaultLineBlur() {
@@ -304,26 +370,30 @@ DataDrivenPropertyValue<float> LineLayer::getDefaultLineBlur() {
}
DataDrivenPropertyValue<float> LineLayer::getLineBlur(const optional<std::string>& klass) const {
- return impl->cascading.template get<LineBlur>().get(klass);
+ return impl().cascading.template get<LineBlur>().get(klass);
}
void LineLayer::setLineBlur(DataDrivenPropertyValue<float> value, const optional<std::string>& klass) {
if (value == getLineBlur(klass))
return;
- impl->cascading.template get<LineBlur>().set(value, klass);
+ auto impl_ = mutableImpl();
+ impl_->cascading.template get<LineBlur>().set(value, klass);
+ baseImpl = std::move(impl_);
if (value.isDataDriven()) {
- impl->observer->onLayerDataDrivenPaintPropertyChanged(*this);
+ observer->onLayerDataDrivenPaintPropertyChanged(*this);
} else {
- impl->observer->onLayerPaintPropertyChanged(*this);
+ observer->onLayerPaintPropertyChanged(*this);
}
}
void LineLayer::setLineBlurTransition(const TransitionOptions& value, const optional<std::string>& klass) {
- impl->cascading.template get<LineBlur>().setTransition(value, klass);
+ auto impl_ = mutableImpl();
+ impl_->cascading.template get<LineBlur>().setTransition(value, klass);
+ baseImpl = std::move(impl_);
}
TransitionOptions LineLayer::getLineBlurTransition(const optional<std::string>& klass) const {
- return impl->cascading.template get<LineBlur>().getTransition(klass);
+ return impl().cascading.template get<LineBlur>().getTransition(klass);
}
PropertyValue<std::vector<float>> LineLayer::getDefaultLineDasharray() {
@@ -331,22 +401,26 @@ PropertyValue<std::vector<float>> LineLayer::getDefaultLineDasharray() {
}
PropertyValue<std::vector<float>> LineLayer::getLineDasharray(const optional<std::string>& klass) const {
- return impl->cascading.template get<LineDasharray>().get(klass);
+ return impl().cascading.template get<LineDasharray>().get(klass);
}
void LineLayer::setLineDasharray(PropertyValue<std::vector<float>> value, const optional<std::string>& klass) {
if (value == getLineDasharray(klass))
return;
- impl->cascading.template get<LineDasharray>().set(value, klass);
- impl->observer->onLayerPaintPropertyChanged(*this);
+ auto impl_ = mutableImpl();
+ impl_->cascading.template get<LineDasharray>().set(value, klass);
+ baseImpl = std::move(impl_);
+ observer->onLayerPaintPropertyChanged(*this);
}
void LineLayer::setLineDasharrayTransition(const TransitionOptions& value, const optional<std::string>& klass) {
- impl->cascading.template get<LineDasharray>().setTransition(value, klass);
+ auto impl_ = mutableImpl();
+ impl_->cascading.template get<LineDasharray>().setTransition(value, klass);
+ baseImpl = std::move(impl_);
}
TransitionOptions LineLayer::getLineDasharrayTransition(const optional<std::string>& klass) const {
- return impl->cascading.template get<LineDasharray>().getTransition(klass);
+ return impl().cascading.template get<LineDasharray>().getTransition(klass);
}
PropertyValue<std::string> LineLayer::getDefaultLinePattern() {
@@ -354,22 +428,26 @@ PropertyValue<std::string> LineLayer::getDefaultLinePattern() {
}
PropertyValue<std::string> LineLayer::getLinePattern(const optional<std::string>& klass) const {
- return impl->cascading.template get<LinePattern>().get(klass);
+ return impl().cascading.template get<LinePattern>().get(klass);
}
void LineLayer::setLinePattern(PropertyValue<std::string> value, const optional<std::string>& klass) {
if (value == getLinePattern(klass))
return;
- impl->cascading.template get<LinePattern>().set(value, klass);
- impl->observer->onLayerPaintPropertyChanged(*this);
+ auto impl_ = mutableImpl();
+ impl_->cascading.template get<LinePattern>().set(value, klass);
+ baseImpl = std::move(impl_);
+ observer->onLayerPaintPropertyChanged(*this);
}
void LineLayer::setLinePatternTransition(const TransitionOptions& value, const optional<std::string>& klass) {
- impl->cascading.template get<LinePattern>().setTransition(value, klass);
+ auto impl_ = mutableImpl();
+ impl_->cascading.template get<LinePattern>().setTransition(value, klass);
+ baseImpl = std::move(impl_);
}
TransitionOptions LineLayer::getLinePatternTransition(const optional<std::string>& klass) const {
- return impl->cascading.template get<LinePattern>().getTransition(klass);
+ return impl().cascading.template get<LinePattern>().getTransition(klass);
}
} // namespace style
diff --git a/src/mbgl/style/layers/line_layer_impl.cpp b/src/mbgl/style/layers/line_layer_impl.cpp
index 973a77abf4..0158ba7a96 100644
--- a/src/mbgl/style/layers/line_layer_impl.cpp
+++ b/src/mbgl/style/layers/line_layer_impl.cpp
@@ -5,7 +5,7 @@ namespace mbgl {
namespace style {
std::unique_ptr<RenderLayer> LineLayer::Impl::createRenderLayer() const {
- return std::make_unique<RenderLineLayer>(*this);
+ return std::make_unique<RenderLineLayer>(staticImmutableCast<LineLayer::Impl>(immutableFromThis()));
}
} // namespace style
diff --git a/src/mbgl/style/layers/line_layer_impl.hpp b/src/mbgl/style/layers/line_layer_impl.hpp
index 02c9c85f00..70d357c592 100644
--- a/src/mbgl/style/layers/line_layer_impl.hpp
+++ b/src/mbgl/style/layers/line_layer_impl.hpp
@@ -9,8 +9,8 @@ namespace style {
class LineLayer::Impl : public Layer::Impl {
public:
- std::unique_ptr<Layer> clone() const override;
- std::unique_ptr<Layer> cloneRef(const std::string& id) const override;
+ using Layer::Impl::Impl;
+
void stringifyLayout(rapidjson::Writer<rapidjson::StringBuffer>&) const override;
std::unique_ptr<RenderLayer> createRenderLayer() const override;
diff --git a/src/mbgl/style/layers/raster_layer.cpp b/src/mbgl/style/layers/raster_layer.cpp
index b525f9eaa4..13c2d214ce 100644
--- a/src/mbgl/style/layers/raster_layer.cpp
+++ b/src/mbgl/style/layers/raster_layer.cpp
@@ -3,33 +3,34 @@
#include <mbgl/style/layers/raster_layer.hpp>
#include <mbgl/style/layers/raster_layer_impl.hpp>
#include <mbgl/style/conversion/stringify.hpp>
+#include <mbgl/style/layer_observer.hpp>
namespace mbgl {
namespace style {
RasterLayer::RasterLayer(const std::string& layerID, const std::string& sourceID)
- : Layer(LayerType::Raster, std::make_unique<Impl>())
- , impl(static_cast<Impl*>(baseImpl.get())) {
- impl->id = layerID;
- impl->source = sourceID;
+ : Layer(makeMutable<Impl>(LayerType::Raster, layerID, sourceID)) {
}
-RasterLayer::RasterLayer(const Impl& other)
- : Layer(LayerType::Raster, std::make_unique<Impl>(other))
- , impl(static_cast<Impl*>(baseImpl.get())) {
+RasterLayer::RasterLayer(Immutable<Impl> impl_)
+ : Layer(std::move(impl_)) {
}
RasterLayer::~RasterLayer() = default;
-std::unique_ptr<Layer> RasterLayer::Impl::clone() const {
- return std::make_unique<RasterLayer>(*this);
+const RasterLayer::Impl& RasterLayer::impl() const {
+ return static_cast<const Impl&>(*baseImpl);
}
-std::unique_ptr<Layer> RasterLayer::Impl::cloneRef(const std::string& id_) const {
- auto result = std::make_unique<RasterLayer>(*this);
- result->impl->id = id_;
- result->impl->cascading = RasterPaintProperties::Cascading();
- return std::move(result);
+Mutable<RasterLayer::Impl> RasterLayer::mutableImpl() const {
+ return makeMutable<Impl>(impl());
+}
+
+std::unique_ptr<Layer> RasterLayer::cloneRef(const std::string& id_) const {
+ auto impl_ = mutableImpl();
+ impl_->id = id_;
+ impl_->cascading = RasterPaintProperties::Cascading();
+ return std::make_unique<RasterLayer>(std::move(impl_));
}
void RasterLayer::Impl::stringifyLayout(rapidjson::Writer<rapidjson::StringBuffer>&) const {
@@ -38,10 +39,35 @@ void RasterLayer::Impl::stringifyLayout(rapidjson::Writer<rapidjson::StringBuffe
// Source
const std::string& RasterLayer::getSourceID() const {
- return impl->source;
+ return impl().source;
}
+// Visibility
+
+void RasterLayer::setVisibility(VisibilityType value) {
+ if (value == getVisibility())
+ return;
+ auto impl_ = mutableImpl();
+ impl_->visibility = value;
+ baseImpl = std::move(impl_);
+ observer->onLayerVisibilityChanged(*this);
+}
+
+// Zoom range
+
+void RasterLayer::setMinZoom(float minZoom) {
+ auto impl_ = mutableImpl();
+ impl_->minZoom = minZoom;
+ baseImpl = std::move(impl_);
+}
+
+void RasterLayer::setMaxZoom(float maxZoom) {
+ auto impl_ = mutableImpl();
+ impl_->maxZoom = maxZoom;
+ baseImpl = std::move(impl_);
+}
+
// Layout properties
@@ -52,22 +78,26 @@ PropertyValue<float> RasterLayer::getDefaultRasterOpacity() {
}
PropertyValue<float> RasterLayer::getRasterOpacity(const optional<std::string>& klass) const {
- return impl->cascading.template get<RasterOpacity>().get(klass);
+ return impl().cascading.template get<RasterOpacity>().get(klass);
}
void RasterLayer::setRasterOpacity(PropertyValue<float> value, const optional<std::string>& klass) {
if (value == getRasterOpacity(klass))
return;
- impl->cascading.template get<RasterOpacity>().set(value, klass);
- impl->observer->onLayerPaintPropertyChanged(*this);
+ auto impl_ = mutableImpl();
+ impl_->cascading.template get<RasterOpacity>().set(value, klass);
+ baseImpl = std::move(impl_);
+ observer->onLayerPaintPropertyChanged(*this);
}
void RasterLayer::setRasterOpacityTransition(const TransitionOptions& value, const optional<std::string>& klass) {
- impl->cascading.template get<RasterOpacity>().setTransition(value, klass);
+ auto impl_ = mutableImpl();
+ impl_->cascading.template get<RasterOpacity>().setTransition(value, klass);
+ baseImpl = std::move(impl_);
}
TransitionOptions RasterLayer::getRasterOpacityTransition(const optional<std::string>& klass) const {
- return impl->cascading.template get<RasterOpacity>().getTransition(klass);
+ return impl().cascading.template get<RasterOpacity>().getTransition(klass);
}
PropertyValue<float> RasterLayer::getDefaultRasterHueRotate() {
@@ -75,22 +105,26 @@ PropertyValue<float> RasterLayer::getDefaultRasterHueRotate() {
}
PropertyValue<float> RasterLayer::getRasterHueRotate(const optional<std::string>& klass) const {
- return impl->cascading.template get<RasterHueRotate>().get(klass);
+ return impl().cascading.template get<RasterHueRotate>().get(klass);
}
void RasterLayer::setRasterHueRotate(PropertyValue<float> value, const optional<std::string>& klass) {
if (value == getRasterHueRotate(klass))
return;
- impl->cascading.template get<RasterHueRotate>().set(value, klass);
- impl->observer->onLayerPaintPropertyChanged(*this);
+ auto impl_ = mutableImpl();
+ impl_->cascading.template get<RasterHueRotate>().set(value, klass);
+ baseImpl = std::move(impl_);
+ observer->onLayerPaintPropertyChanged(*this);
}
void RasterLayer::setRasterHueRotateTransition(const TransitionOptions& value, const optional<std::string>& klass) {
- impl->cascading.template get<RasterHueRotate>().setTransition(value, klass);
+ auto impl_ = mutableImpl();
+ impl_->cascading.template get<RasterHueRotate>().setTransition(value, klass);
+ baseImpl = std::move(impl_);
}
TransitionOptions RasterLayer::getRasterHueRotateTransition(const optional<std::string>& klass) const {
- return impl->cascading.template get<RasterHueRotate>().getTransition(klass);
+ return impl().cascading.template get<RasterHueRotate>().getTransition(klass);
}
PropertyValue<float> RasterLayer::getDefaultRasterBrightnessMin() {
@@ -98,22 +132,26 @@ PropertyValue<float> RasterLayer::getDefaultRasterBrightnessMin() {
}
PropertyValue<float> RasterLayer::getRasterBrightnessMin(const optional<std::string>& klass) const {
- return impl->cascading.template get<RasterBrightnessMin>().get(klass);
+ return impl().cascading.template get<RasterBrightnessMin>().get(klass);
}
void RasterLayer::setRasterBrightnessMin(PropertyValue<float> value, const optional<std::string>& klass) {
if (value == getRasterBrightnessMin(klass))
return;
- impl->cascading.template get<RasterBrightnessMin>().set(value, klass);
- impl->observer->onLayerPaintPropertyChanged(*this);
+ auto impl_ = mutableImpl();
+ impl_->cascading.template get<RasterBrightnessMin>().set(value, klass);
+ baseImpl = std::move(impl_);
+ observer->onLayerPaintPropertyChanged(*this);
}
void RasterLayer::setRasterBrightnessMinTransition(const TransitionOptions& value, const optional<std::string>& klass) {
- impl->cascading.template get<RasterBrightnessMin>().setTransition(value, klass);
+ auto impl_ = mutableImpl();
+ impl_->cascading.template get<RasterBrightnessMin>().setTransition(value, klass);
+ baseImpl = std::move(impl_);
}
TransitionOptions RasterLayer::getRasterBrightnessMinTransition(const optional<std::string>& klass) const {
- return impl->cascading.template get<RasterBrightnessMin>().getTransition(klass);
+ return impl().cascading.template get<RasterBrightnessMin>().getTransition(klass);
}
PropertyValue<float> RasterLayer::getDefaultRasterBrightnessMax() {
@@ -121,22 +159,26 @@ PropertyValue<float> RasterLayer::getDefaultRasterBrightnessMax() {
}
PropertyValue<float> RasterLayer::getRasterBrightnessMax(const optional<std::string>& klass) const {
- return impl->cascading.template get<RasterBrightnessMax>().get(klass);
+ return impl().cascading.template get<RasterBrightnessMax>().get(klass);
}
void RasterLayer::setRasterBrightnessMax(PropertyValue<float> value, const optional<std::string>& klass) {
if (value == getRasterBrightnessMax(klass))
return;
- impl->cascading.template get<RasterBrightnessMax>().set(value, klass);
- impl->observer->onLayerPaintPropertyChanged(*this);
+ auto impl_ = mutableImpl();
+ impl_->cascading.template get<RasterBrightnessMax>().set(value, klass);
+ baseImpl = std::move(impl_);
+ observer->onLayerPaintPropertyChanged(*this);
}
void RasterLayer::setRasterBrightnessMaxTransition(const TransitionOptions& value, const optional<std::string>& klass) {
- impl->cascading.template get<RasterBrightnessMax>().setTransition(value, klass);
+ auto impl_ = mutableImpl();
+ impl_->cascading.template get<RasterBrightnessMax>().setTransition(value, klass);
+ baseImpl = std::move(impl_);
}
TransitionOptions RasterLayer::getRasterBrightnessMaxTransition(const optional<std::string>& klass) const {
- return impl->cascading.template get<RasterBrightnessMax>().getTransition(klass);
+ return impl().cascading.template get<RasterBrightnessMax>().getTransition(klass);
}
PropertyValue<float> RasterLayer::getDefaultRasterSaturation() {
@@ -144,22 +186,26 @@ PropertyValue<float> RasterLayer::getDefaultRasterSaturation() {
}
PropertyValue<float> RasterLayer::getRasterSaturation(const optional<std::string>& klass) const {
- return impl->cascading.template get<RasterSaturation>().get(klass);
+ return impl().cascading.template get<RasterSaturation>().get(klass);
}
void RasterLayer::setRasterSaturation(PropertyValue<float> value, const optional<std::string>& klass) {
if (value == getRasterSaturation(klass))
return;
- impl->cascading.template get<RasterSaturation>().set(value, klass);
- impl->observer->onLayerPaintPropertyChanged(*this);
+ auto impl_ = mutableImpl();
+ impl_->cascading.template get<RasterSaturation>().set(value, klass);
+ baseImpl = std::move(impl_);
+ observer->onLayerPaintPropertyChanged(*this);
}
void RasterLayer::setRasterSaturationTransition(const TransitionOptions& value, const optional<std::string>& klass) {
- impl->cascading.template get<RasterSaturation>().setTransition(value, klass);
+ auto impl_ = mutableImpl();
+ impl_->cascading.template get<RasterSaturation>().setTransition(value, klass);
+ baseImpl = std::move(impl_);
}
TransitionOptions RasterLayer::getRasterSaturationTransition(const optional<std::string>& klass) const {
- return impl->cascading.template get<RasterSaturation>().getTransition(klass);
+ return impl().cascading.template get<RasterSaturation>().getTransition(klass);
}
PropertyValue<float> RasterLayer::getDefaultRasterContrast() {
@@ -167,22 +213,26 @@ PropertyValue<float> RasterLayer::getDefaultRasterContrast() {
}
PropertyValue<float> RasterLayer::getRasterContrast(const optional<std::string>& klass) const {
- return impl->cascading.template get<RasterContrast>().get(klass);
+ return impl().cascading.template get<RasterContrast>().get(klass);
}
void RasterLayer::setRasterContrast(PropertyValue<float> value, const optional<std::string>& klass) {
if (value == getRasterContrast(klass))
return;
- impl->cascading.template get<RasterContrast>().set(value, klass);
- impl->observer->onLayerPaintPropertyChanged(*this);
+ auto impl_ = mutableImpl();
+ impl_->cascading.template get<RasterContrast>().set(value, klass);
+ baseImpl = std::move(impl_);
+ observer->onLayerPaintPropertyChanged(*this);
}
void RasterLayer::setRasterContrastTransition(const TransitionOptions& value, const optional<std::string>& klass) {
- impl->cascading.template get<RasterContrast>().setTransition(value, klass);
+ auto impl_ = mutableImpl();
+ impl_->cascading.template get<RasterContrast>().setTransition(value, klass);
+ baseImpl = std::move(impl_);
}
TransitionOptions RasterLayer::getRasterContrastTransition(const optional<std::string>& klass) const {
- return impl->cascading.template get<RasterContrast>().getTransition(klass);
+ return impl().cascading.template get<RasterContrast>().getTransition(klass);
}
PropertyValue<float> RasterLayer::getDefaultRasterFadeDuration() {
@@ -190,22 +240,26 @@ PropertyValue<float> RasterLayer::getDefaultRasterFadeDuration() {
}
PropertyValue<float> RasterLayer::getRasterFadeDuration(const optional<std::string>& klass) const {
- return impl->cascading.template get<RasterFadeDuration>().get(klass);
+ return impl().cascading.template get<RasterFadeDuration>().get(klass);
}
void RasterLayer::setRasterFadeDuration(PropertyValue<float> value, const optional<std::string>& klass) {
if (value == getRasterFadeDuration(klass))
return;
- impl->cascading.template get<RasterFadeDuration>().set(value, klass);
- impl->observer->onLayerPaintPropertyChanged(*this);
+ auto impl_ = mutableImpl();
+ impl_->cascading.template get<RasterFadeDuration>().set(value, klass);
+ baseImpl = std::move(impl_);
+ observer->onLayerPaintPropertyChanged(*this);
}
void RasterLayer::setRasterFadeDurationTransition(const TransitionOptions& value, const optional<std::string>& klass) {
- impl->cascading.template get<RasterFadeDuration>().setTransition(value, klass);
+ auto impl_ = mutableImpl();
+ impl_->cascading.template get<RasterFadeDuration>().setTransition(value, klass);
+ baseImpl = std::move(impl_);
}
TransitionOptions RasterLayer::getRasterFadeDurationTransition(const optional<std::string>& klass) const {
- return impl->cascading.template get<RasterFadeDuration>().getTransition(klass);
+ return impl().cascading.template get<RasterFadeDuration>().getTransition(klass);
}
} // namespace style
diff --git a/src/mbgl/style/layers/raster_layer_impl.cpp b/src/mbgl/style/layers/raster_layer_impl.cpp
index fa9f80dac6..f7e908a5cf 100644
--- a/src/mbgl/style/layers/raster_layer_impl.cpp
+++ b/src/mbgl/style/layers/raster_layer_impl.cpp
@@ -5,7 +5,7 @@ namespace mbgl {
namespace style {
std::unique_ptr<RenderLayer> RasterLayer::Impl::createRenderLayer() const {
- return std::make_unique<RenderRasterLayer>(*this);
+ return std::make_unique<RenderRasterLayer>(staticImmutableCast<RasterLayer::Impl>(immutableFromThis()));
}
} // namespace style
diff --git a/src/mbgl/style/layers/raster_layer_impl.hpp b/src/mbgl/style/layers/raster_layer_impl.hpp
index edf5f9111b..451619807a 100644
--- a/src/mbgl/style/layers/raster_layer_impl.hpp
+++ b/src/mbgl/style/layers/raster_layer_impl.hpp
@@ -9,8 +9,8 @@ namespace style {
class RasterLayer::Impl : public Layer::Impl {
public:
- std::unique_ptr<Layer> clone() const override;
- std::unique_ptr<Layer> cloneRef(const std::string& id) const override;
+ using Layer::Impl::Impl;
+
void stringifyLayout(rapidjson::Writer<rapidjson::StringBuffer>&) const override;
std::unique_ptr<RenderLayer> createRenderLayer() const override;
diff --git a/src/mbgl/style/layers/symbol_layer.cpp b/src/mbgl/style/layers/symbol_layer.cpp
index 273a9fd24e..5a062997c4 100644
--- a/src/mbgl/style/layers/symbol_layer.cpp
+++ b/src/mbgl/style/layers/symbol_layer.cpp
@@ -3,33 +3,34 @@
#include <mbgl/style/layers/symbol_layer.hpp>
#include <mbgl/style/layers/symbol_layer_impl.hpp>
#include <mbgl/style/conversion/stringify.hpp>
+#include <mbgl/style/layer_observer.hpp>
namespace mbgl {
namespace style {
SymbolLayer::SymbolLayer(const std::string& layerID, const std::string& sourceID)
- : Layer(LayerType::Symbol, std::make_unique<Impl>())
- , impl(static_cast<Impl*>(baseImpl.get())) {
- impl->id = layerID;
- impl->source = sourceID;
+ : Layer(makeMutable<Impl>(LayerType::Symbol, layerID, sourceID)) {
}
-SymbolLayer::SymbolLayer(const Impl& other)
- : Layer(LayerType::Symbol, std::make_unique<Impl>(other))
- , impl(static_cast<Impl*>(baseImpl.get())) {
+SymbolLayer::SymbolLayer(Immutable<Impl> impl_)
+ : Layer(std::move(impl_)) {
}
SymbolLayer::~SymbolLayer() = default;
-std::unique_ptr<Layer> SymbolLayer::Impl::clone() const {
- return std::make_unique<SymbolLayer>(*this);
+const SymbolLayer::Impl& SymbolLayer::impl() const {
+ return static_cast<const Impl&>(*baseImpl);
}
-std::unique_ptr<Layer> SymbolLayer::Impl::cloneRef(const std::string& id_) const {
- auto result = std::make_unique<SymbolLayer>(*this);
- result->impl->id = id_;
- result->impl->cascading = SymbolPaintProperties::Cascading();
- return std::move(result);
+Mutable<SymbolLayer::Impl> SymbolLayer::mutableImpl() const {
+ return makeMutable<Impl>(impl());
+}
+
+std::unique_ptr<Layer> SymbolLayer::cloneRef(const std::string& id_) const {
+ auto impl_ = mutableImpl();
+ impl_->id = id_;
+ impl_->cascading = SymbolPaintProperties::Cascading();
+ return std::make_unique<SymbolLayer>(std::move(impl_));
}
void SymbolLayer::Impl::stringifyLayout(rapidjson::Writer<rapidjson::StringBuffer>& writer) const {
@@ -39,26 +40,55 @@ void SymbolLayer::Impl::stringifyLayout(rapidjson::Writer<rapidjson::StringBuffe
// Source
const std::string& SymbolLayer::getSourceID() const {
- return impl->source;
+ return impl().source;
}
void SymbolLayer::setSourceLayer(const std::string& sourceLayer) {
- impl->sourceLayer = sourceLayer;
+ auto impl_ = mutableImpl();
+ impl_->sourceLayer = sourceLayer;
+ baseImpl = std::move(impl_);
}
const std::string& SymbolLayer::getSourceLayer() const {
- return impl->sourceLayer;
+ return impl().sourceLayer;
}
// Filter
void SymbolLayer::setFilter(const Filter& filter) {
- impl->filter = filter;
- impl->observer->onLayerFilterChanged(*this);
+ auto impl_ = mutableImpl();
+ impl_->filter = filter;
+ baseImpl = std::move(impl_);
+ observer->onLayerFilterChanged(*this);
}
const Filter& SymbolLayer::getFilter() const {
- return impl->filter;
+ return impl().filter;
+}
+
+// Visibility
+
+void SymbolLayer::setVisibility(VisibilityType value) {
+ if (value == getVisibility())
+ return;
+ auto impl_ = mutableImpl();
+ impl_->visibility = value;
+ baseImpl = std::move(impl_);
+ observer->onLayerVisibilityChanged(*this);
+}
+
+// Zoom range
+
+void SymbolLayer::setMinZoom(float minZoom) {
+ auto impl_ = mutableImpl();
+ impl_->minZoom = minZoom;
+ baseImpl = std::move(impl_);
+}
+
+void SymbolLayer::setMaxZoom(float maxZoom) {
+ auto impl_ = mutableImpl();
+ impl_->maxZoom = maxZoom;
+ baseImpl = std::move(impl_);
}
// Layout properties
@@ -68,476 +98,544 @@ PropertyValue<SymbolPlacementType> SymbolLayer::getDefaultSymbolPlacement() {
}
PropertyValue<SymbolPlacementType> SymbolLayer::getSymbolPlacement() const {
- return impl->layout.unevaluated.get<SymbolPlacement>();
+ return impl().layout.unevaluated.get<SymbolPlacement>();
}
void SymbolLayer::setSymbolPlacement(PropertyValue<SymbolPlacementType> value) {
if (value == getSymbolPlacement())
return;
- impl->layout.unevaluated.get<SymbolPlacement>() = value;
- impl->observer->onLayerLayoutPropertyChanged(*this, "symbol-placement");
+ auto impl_ = mutableImpl();
+ impl_->layout.unevaluated.get<SymbolPlacement>() = value;
+ baseImpl = std::move(impl_);
+ observer->onLayerLayoutPropertyChanged(*this, "symbol-placement");
}
PropertyValue<float> SymbolLayer::getDefaultSymbolSpacing() {
return SymbolSpacing::defaultValue();
}
PropertyValue<float> SymbolLayer::getSymbolSpacing() const {
- return impl->layout.unevaluated.get<SymbolSpacing>();
+ return impl().layout.unevaluated.get<SymbolSpacing>();
}
void SymbolLayer::setSymbolSpacing(PropertyValue<float> value) {
if (value == getSymbolSpacing())
return;
- impl->layout.unevaluated.get<SymbolSpacing>() = value;
- impl->observer->onLayerLayoutPropertyChanged(*this, "symbol-spacing");
+ auto impl_ = mutableImpl();
+ impl_->layout.unevaluated.get<SymbolSpacing>() = value;
+ baseImpl = std::move(impl_);
+ observer->onLayerLayoutPropertyChanged(*this, "symbol-spacing");
}
PropertyValue<bool> SymbolLayer::getDefaultSymbolAvoidEdges() {
return SymbolAvoidEdges::defaultValue();
}
PropertyValue<bool> SymbolLayer::getSymbolAvoidEdges() const {
- return impl->layout.unevaluated.get<SymbolAvoidEdges>();
+ return impl().layout.unevaluated.get<SymbolAvoidEdges>();
}
void SymbolLayer::setSymbolAvoidEdges(PropertyValue<bool> value) {
if (value == getSymbolAvoidEdges())
return;
- impl->layout.unevaluated.get<SymbolAvoidEdges>() = value;
- impl->observer->onLayerLayoutPropertyChanged(*this, "symbol-avoid-edges");
+ auto impl_ = mutableImpl();
+ impl_->layout.unevaluated.get<SymbolAvoidEdges>() = value;
+ baseImpl = std::move(impl_);
+ observer->onLayerLayoutPropertyChanged(*this, "symbol-avoid-edges");
}
PropertyValue<bool> SymbolLayer::getDefaultIconAllowOverlap() {
return IconAllowOverlap::defaultValue();
}
PropertyValue<bool> SymbolLayer::getIconAllowOverlap() const {
- return impl->layout.unevaluated.get<IconAllowOverlap>();
+ return impl().layout.unevaluated.get<IconAllowOverlap>();
}
void SymbolLayer::setIconAllowOverlap(PropertyValue<bool> value) {
if (value == getIconAllowOverlap())
return;
- impl->layout.unevaluated.get<IconAllowOverlap>() = value;
- impl->observer->onLayerLayoutPropertyChanged(*this, "icon-allow-overlap");
+ auto impl_ = mutableImpl();
+ impl_->layout.unevaluated.get<IconAllowOverlap>() = value;
+ baseImpl = std::move(impl_);
+ observer->onLayerLayoutPropertyChanged(*this, "icon-allow-overlap");
}
PropertyValue<bool> SymbolLayer::getDefaultIconIgnorePlacement() {
return IconIgnorePlacement::defaultValue();
}
PropertyValue<bool> SymbolLayer::getIconIgnorePlacement() const {
- return impl->layout.unevaluated.get<IconIgnorePlacement>();
+ return impl().layout.unevaluated.get<IconIgnorePlacement>();
}
void SymbolLayer::setIconIgnorePlacement(PropertyValue<bool> value) {
if (value == getIconIgnorePlacement())
return;
- impl->layout.unevaluated.get<IconIgnorePlacement>() = value;
- impl->observer->onLayerLayoutPropertyChanged(*this, "icon-ignore-placement");
+ auto impl_ = mutableImpl();
+ impl_->layout.unevaluated.get<IconIgnorePlacement>() = value;
+ baseImpl = std::move(impl_);
+ observer->onLayerLayoutPropertyChanged(*this, "icon-ignore-placement");
}
PropertyValue<bool> SymbolLayer::getDefaultIconOptional() {
return IconOptional::defaultValue();
}
PropertyValue<bool> SymbolLayer::getIconOptional() const {
- return impl->layout.unevaluated.get<IconOptional>();
+ return impl().layout.unevaluated.get<IconOptional>();
}
void SymbolLayer::setIconOptional(PropertyValue<bool> value) {
if (value == getIconOptional())
return;
- impl->layout.unevaluated.get<IconOptional>() = value;
- impl->observer->onLayerLayoutPropertyChanged(*this, "icon-optional");
+ auto impl_ = mutableImpl();
+ impl_->layout.unevaluated.get<IconOptional>() = value;
+ baseImpl = std::move(impl_);
+ observer->onLayerLayoutPropertyChanged(*this, "icon-optional");
}
PropertyValue<AlignmentType> SymbolLayer::getDefaultIconRotationAlignment() {
return IconRotationAlignment::defaultValue();
}
PropertyValue<AlignmentType> SymbolLayer::getIconRotationAlignment() const {
- return impl->layout.unevaluated.get<IconRotationAlignment>();
+ return impl().layout.unevaluated.get<IconRotationAlignment>();
}
void SymbolLayer::setIconRotationAlignment(PropertyValue<AlignmentType> value) {
if (value == getIconRotationAlignment())
return;
- impl->layout.unevaluated.get<IconRotationAlignment>() = value;
- impl->observer->onLayerLayoutPropertyChanged(*this, "icon-rotation-alignment");
+ auto impl_ = mutableImpl();
+ impl_->layout.unevaluated.get<IconRotationAlignment>() = value;
+ baseImpl = std::move(impl_);
+ observer->onLayerLayoutPropertyChanged(*this, "icon-rotation-alignment");
}
DataDrivenPropertyValue<float> SymbolLayer::getDefaultIconSize() {
return IconSize::defaultValue();
}
DataDrivenPropertyValue<float> SymbolLayer::getIconSize() const {
- return impl->layout.unevaluated.get<IconSize>();
+ return impl().layout.unevaluated.get<IconSize>();
}
void SymbolLayer::setIconSize(DataDrivenPropertyValue<float> value) {
if (value == getIconSize())
return;
- impl->layout.unevaluated.get<IconSize>() = value;
- impl->observer->onLayerLayoutPropertyChanged(*this, "icon-size");
+ auto impl_ = mutableImpl();
+ impl_->layout.unevaluated.get<IconSize>() = value;
+ baseImpl = std::move(impl_);
+ observer->onLayerLayoutPropertyChanged(*this, "icon-size");
}
PropertyValue<IconTextFitType> SymbolLayer::getDefaultIconTextFit() {
return IconTextFit::defaultValue();
}
PropertyValue<IconTextFitType> SymbolLayer::getIconTextFit() const {
- return impl->layout.unevaluated.get<IconTextFit>();
+ return impl().layout.unevaluated.get<IconTextFit>();
}
void SymbolLayer::setIconTextFit(PropertyValue<IconTextFitType> value) {
if (value == getIconTextFit())
return;
- impl->layout.unevaluated.get<IconTextFit>() = value;
- impl->observer->onLayerLayoutPropertyChanged(*this, "icon-text-fit");
+ auto impl_ = mutableImpl();
+ impl_->layout.unevaluated.get<IconTextFit>() = value;
+ baseImpl = std::move(impl_);
+ observer->onLayerLayoutPropertyChanged(*this, "icon-text-fit");
}
PropertyValue<std::array<float, 4>> SymbolLayer::getDefaultIconTextFitPadding() {
return IconTextFitPadding::defaultValue();
}
PropertyValue<std::array<float, 4>> SymbolLayer::getIconTextFitPadding() const {
- return impl->layout.unevaluated.get<IconTextFitPadding>();
+ return impl().layout.unevaluated.get<IconTextFitPadding>();
}
void SymbolLayer::setIconTextFitPadding(PropertyValue<std::array<float, 4>> value) {
if (value == getIconTextFitPadding())
return;
- impl->layout.unevaluated.get<IconTextFitPadding>() = value;
- impl->observer->onLayerLayoutPropertyChanged(*this, "icon-text-fit-padding");
+ auto impl_ = mutableImpl();
+ impl_->layout.unevaluated.get<IconTextFitPadding>() = value;
+ baseImpl = std::move(impl_);
+ observer->onLayerLayoutPropertyChanged(*this, "icon-text-fit-padding");
}
DataDrivenPropertyValue<std::string> SymbolLayer::getDefaultIconImage() {
return IconImage::defaultValue();
}
DataDrivenPropertyValue<std::string> SymbolLayer::getIconImage() const {
- return impl->layout.unevaluated.get<IconImage>();
+ return impl().layout.unevaluated.get<IconImage>();
}
void SymbolLayer::setIconImage(DataDrivenPropertyValue<std::string> value) {
if (value == getIconImage())
return;
- impl->layout.unevaluated.get<IconImage>() = value;
- impl->observer->onLayerLayoutPropertyChanged(*this, "icon-image");
+ auto impl_ = mutableImpl();
+ impl_->layout.unevaluated.get<IconImage>() = value;
+ baseImpl = std::move(impl_);
+ observer->onLayerLayoutPropertyChanged(*this, "icon-image");
}
DataDrivenPropertyValue<float> SymbolLayer::getDefaultIconRotate() {
return IconRotate::defaultValue();
}
DataDrivenPropertyValue<float> SymbolLayer::getIconRotate() const {
- return impl->layout.unevaluated.get<IconRotate>();
+ return impl().layout.unevaluated.get<IconRotate>();
}
void SymbolLayer::setIconRotate(DataDrivenPropertyValue<float> value) {
if (value == getIconRotate())
return;
- impl->layout.unevaluated.get<IconRotate>() = value;
- impl->observer->onLayerLayoutPropertyChanged(*this, "icon-rotate");
+ auto impl_ = mutableImpl();
+ impl_->layout.unevaluated.get<IconRotate>() = value;
+ baseImpl = std::move(impl_);
+ observer->onLayerLayoutPropertyChanged(*this, "icon-rotate");
}
PropertyValue<float> SymbolLayer::getDefaultIconPadding() {
return IconPadding::defaultValue();
}
PropertyValue<float> SymbolLayer::getIconPadding() const {
- return impl->layout.unevaluated.get<IconPadding>();
+ return impl().layout.unevaluated.get<IconPadding>();
}
void SymbolLayer::setIconPadding(PropertyValue<float> value) {
if (value == getIconPadding())
return;
- impl->layout.unevaluated.get<IconPadding>() = value;
- impl->observer->onLayerLayoutPropertyChanged(*this, "icon-padding");
+ auto impl_ = mutableImpl();
+ impl_->layout.unevaluated.get<IconPadding>() = value;
+ baseImpl = std::move(impl_);
+ observer->onLayerLayoutPropertyChanged(*this, "icon-padding");
}
PropertyValue<bool> SymbolLayer::getDefaultIconKeepUpright() {
return IconKeepUpright::defaultValue();
}
PropertyValue<bool> SymbolLayer::getIconKeepUpright() const {
- return impl->layout.unevaluated.get<IconKeepUpright>();
+ return impl().layout.unevaluated.get<IconKeepUpright>();
}
void SymbolLayer::setIconKeepUpright(PropertyValue<bool> value) {
if (value == getIconKeepUpright())
return;
- impl->layout.unevaluated.get<IconKeepUpright>() = value;
- impl->observer->onLayerLayoutPropertyChanged(*this, "icon-keep-upright");
+ auto impl_ = mutableImpl();
+ impl_->layout.unevaluated.get<IconKeepUpright>() = value;
+ baseImpl = std::move(impl_);
+ observer->onLayerLayoutPropertyChanged(*this, "icon-keep-upright");
}
DataDrivenPropertyValue<std::array<float, 2>> SymbolLayer::getDefaultIconOffset() {
return IconOffset::defaultValue();
}
DataDrivenPropertyValue<std::array<float, 2>> SymbolLayer::getIconOffset() const {
- return impl->layout.unevaluated.get<IconOffset>();
+ return impl().layout.unevaluated.get<IconOffset>();
}
void SymbolLayer::setIconOffset(DataDrivenPropertyValue<std::array<float, 2>> value) {
if (value == getIconOffset())
return;
- impl->layout.unevaluated.get<IconOffset>() = value;
- impl->observer->onLayerLayoutPropertyChanged(*this, "icon-offset");
+ auto impl_ = mutableImpl();
+ impl_->layout.unevaluated.get<IconOffset>() = value;
+ baseImpl = std::move(impl_);
+ observer->onLayerLayoutPropertyChanged(*this, "icon-offset");
}
PropertyValue<AlignmentType> SymbolLayer::getDefaultTextPitchAlignment() {
return TextPitchAlignment::defaultValue();
}
PropertyValue<AlignmentType> SymbolLayer::getTextPitchAlignment() const {
- return impl->layout.unevaluated.get<TextPitchAlignment>();
+ return impl().layout.unevaluated.get<TextPitchAlignment>();
}
void SymbolLayer::setTextPitchAlignment(PropertyValue<AlignmentType> value) {
if (value == getTextPitchAlignment())
return;
- impl->layout.unevaluated.get<TextPitchAlignment>() = value;
- impl->observer->onLayerLayoutPropertyChanged(*this, "text-pitch-alignment");
+ auto impl_ = mutableImpl();
+ impl_->layout.unevaluated.get<TextPitchAlignment>() = value;
+ baseImpl = std::move(impl_);
+ observer->onLayerLayoutPropertyChanged(*this, "text-pitch-alignment");
}
PropertyValue<AlignmentType> SymbolLayer::getDefaultTextRotationAlignment() {
return TextRotationAlignment::defaultValue();
}
PropertyValue<AlignmentType> SymbolLayer::getTextRotationAlignment() const {
- return impl->layout.unevaluated.get<TextRotationAlignment>();
+ return impl().layout.unevaluated.get<TextRotationAlignment>();
}
void SymbolLayer::setTextRotationAlignment(PropertyValue<AlignmentType> value) {
if (value == getTextRotationAlignment())
return;
- impl->layout.unevaluated.get<TextRotationAlignment>() = value;
- impl->observer->onLayerLayoutPropertyChanged(*this, "text-rotation-alignment");
+ auto impl_ = mutableImpl();
+ impl_->layout.unevaluated.get<TextRotationAlignment>() = value;
+ baseImpl = std::move(impl_);
+ observer->onLayerLayoutPropertyChanged(*this, "text-rotation-alignment");
}
DataDrivenPropertyValue<std::string> SymbolLayer::getDefaultTextField() {
return TextField::defaultValue();
}
DataDrivenPropertyValue<std::string> SymbolLayer::getTextField() const {
- return impl->layout.unevaluated.get<TextField>();
+ return impl().layout.unevaluated.get<TextField>();
}
void SymbolLayer::setTextField(DataDrivenPropertyValue<std::string> value) {
if (value == getTextField())
return;
- impl->layout.unevaluated.get<TextField>() = value;
- impl->observer->onLayerLayoutPropertyChanged(*this, "text-field");
+ auto impl_ = mutableImpl();
+ impl_->layout.unevaluated.get<TextField>() = value;
+ baseImpl = std::move(impl_);
+ observer->onLayerLayoutPropertyChanged(*this, "text-field");
}
PropertyValue<std::vector<std::string>> SymbolLayer::getDefaultTextFont() {
return TextFont::defaultValue();
}
PropertyValue<std::vector<std::string>> SymbolLayer::getTextFont() const {
- return impl->layout.unevaluated.get<TextFont>();
+ return impl().layout.unevaluated.get<TextFont>();
}
void SymbolLayer::setTextFont(PropertyValue<std::vector<std::string>> value) {
if (value == getTextFont())
return;
- impl->layout.unevaluated.get<TextFont>() = value;
- impl->observer->onLayerLayoutPropertyChanged(*this, "text-font");
+ auto impl_ = mutableImpl();
+ impl_->layout.unevaluated.get<TextFont>() = value;
+ baseImpl = std::move(impl_);
+ observer->onLayerLayoutPropertyChanged(*this, "text-font");
}
DataDrivenPropertyValue<float> SymbolLayer::getDefaultTextSize() {
return TextSize::defaultValue();
}
DataDrivenPropertyValue<float> SymbolLayer::getTextSize() const {
- return impl->layout.unevaluated.get<TextSize>();
+ return impl().layout.unevaluated.get<TextSize>();
}
void SymbolLayer::setTextSize(DataDrivenPropertyValue<float> value) {
if (value == getTextSize())
return;
- impl->layout.unevaluated.get<TextSize>() = value;
- impl->observer->onLayerLayoutPropertyChanged(*this, "text-size");
+ auto impl_ = mutableImpl();
+ impl_->layout.unevaluated.get<TextSize>() = value;
+ baseImpl = std::move(impl_);
+ observer->onLayerLayoutPropertyChanged(*this, "text-size");
}
PropertyValue<float> SymbolLayer::getDefaultTextMaxWidth() {
return TextMaxWidth::defaultValue();
}
PropertyValue<float> SymbolLayer::getTextMaxWidth() const {
- return impl->layout.unevaluated.get<TextMaxWidth>();
+ return impl().layout.unevaluated.get<TextMaxWidth>();
}
void SymbolLayer::setTextMaxWidth(PropertyValue<float> value) {
if (value == getTextMaxWidth())
return;
- impl->layout.unevaluated.get<TextMaxWidth>() = value;
- impl->observer->onLayerLayoutPropertyChanged(*this, "text-max-width");
+ auto impl_ = mutableImpl();
+ impl_->layout.unevaluated.get<TextMaxWidth>() = value;
+ baseImpl = std::move(impl_);
+ observer->onLayerLayoutPropertyChanged(*this, "text-max-width");
}
PropertyValue<float> SymbolLayer::getDefaultTextLineHeight() {
return TextLineHeight::defaultValue();
}
PropertyValue<float> SymbolLayer::getTextLineHeight() const {
- return impl->layout.unevaluated.get<TextLineHeight>();
+ return impl().layout.unevaluated.get<TextLineHeight>();
}
void SymbolLayer::setTextLineHeight(PropertyValue<float> value) {
if (value == getTextLineHeight())
return;
- impl->layout.unevaluated.get<TextLineHeight>() = value;
- impl->observer->onLayerLayoutPropertyChanged(*this, "text-line-height");
+ auto impl_ = mutableImpl();
+ impl_->layout.unevaluated.get<TextLineHeight>() = value;
+ baseImpl = std::move(impl_);
+ observer->onLayerLayoutPropertyChanged(*this, "text-line-height");
}
PropertyValue<float> SymbolLayer::getDefaultTextLetterSpacing() {
return TextLetterSpacing::defaultValue();
}
PropertyValue<float> SymbolLayer::getTextLetterSpacing() const {
- return impl->layout.unevaluated.get<TextLetterSpacing>();
+ return impl().layout.unevaluated.get<TextLetterSpacing>();
}
void SymbolLayer::setTextLetterSpacing(PropertyValue<float> value) {
if (value == getTextLetterSpacing())
return;
- impl->layout.unevaluated.get<TextLetterSpacing>() = value;
- impl->observer->onLayerLayoutPropertyChanged(*this, "text-letter-spacing");
+ auto impl_ = mutableImpl();
+ impl_->layout.unevaluated.get<TextLetterSpacing>() = value;
+ baseImpl = std::move(impl_);
+ observer->onLayerLayoutPropertyChanged(*this, "text-letter-spacing");
}
PropertyValue<TextJustifyType> SymbolLayer::getDefaultTextJustify() {
return TextJustify::defaultValue();
}
PropertyValue<TextJustifyType> SymbolLayer::getTextJustify() const {
- return impl->layout.unevaluated.get<TextJustify>();
+ return impl().layout.unevaluated.get<TextJustify>();
}
void SymbolLayer::setTextJustify(PropertyValue<TextJustifyType> value) {
if (value == getTextJustify())
return;
- impl->layout.unevaluated.get<TextJustify>() = value;
- impl->observer->onLayerLayoutPropertyChanged(*this, "text-justify");
+ auto impl_ = mutableImpl();
+ impl_->layout.unevaluated.get<TextJustify>() = value;
+ baseImpl = std::move(impl_);
+ observer->onLayerLayoutPropertyChanged(*this, "text-justify");
}
PropertyValue<TextAnchorType> SymbolLayer::getDefaultTextAnchor() {
return TextAnchor::defaultValue();
}
PropertyValue<TextAnchorType> SymbolLayer::getTextAnchor() const {
- return impl->layout.unevaluated.get<TextAnchor>();
+ return impl().layout.unevaluated.get<TextAnchor>();
}
void SymbolLayer::setTextAnchor(PropertyValue<TextAnchorType> value) {
if (value == getTextAnchor())
return;
- impl->layout.unevaluated.get<TextAnchor>() = value;
- impl->observer->onLayerLayoutPropertyChanged(*this, "text-anchor");
+ auto impl_ = mutableImpl();
+ impl_->layout.unevaluated.get<TextAnchor>() = value;
+ baseImpl = std::move(impl_);
+ observer->onLayerLayoutPropertyChanged(*this, "text-anchor");
}
PropertyValue<float> SymbolLayer::getDefaultTextMaxAngle() {
return TextMaxAngle::defaultValue();
}
PropertyValue<float> SymbolLayer::getTextMaxAngle() const {
- return impl->layout.unevaluated.get<TextMaxAngle>();
+ return impl().layout.unevaluated.get<TextMaxAngle>();
}
void SymbolLayer::setTextMaxAngle(PropertyValue<float> value) {
if (value == getTextMaxAngle())
return;
- impl->layout.unevaluated.get<TextMaxAngle>() = value;
- impl->observer->onLayerLayoutPropertyChanged(*this, "text-max-angle");
+ auto impl_ = mutableImpl();
+ impl_->layout.unevaluated.get<TextMaxAngle>() = value;
+ baseImpl = std::move(impl_);
+ observer->onLayerLayoutPropertyChanged(*this, "text-max-angle");
}
DataDrivenPropertyValue<float> SymbolLayer::getDefaultTextRotate() {
return TextRotate::defaultValue();
}
DataDrivenPropertyValue<float> SymbolLayer::getTextRotate() const {
- return impl->layout.unevaluated.get<TextRotate>();
+ return impl().layout.unevaluated.get<TextRotate>();
}
void SymbolLayer::setTextRotate(DataDrivenPropertyValue<float> value) {
if (value == getTextRotate())
return;
- impl->layout.unevaluated.get<TextRotate>() = value;
- impl->observer->onLayerLayoutPropertyChanged(*this, "text-rotate");
+ auto impl_ = mutableImpl();
+ impl_->layout.unevaluated.get<TextRotate>() = value;
+ baseImpl = std::move(impl_);
+ observer->onLayerLayoutPropertyChanged(*this, "text-rotate");
}
PropertyValue<float> SymbolLayer::getDefaultTextPadding() {
return TextPadding::defaultValue();
}
PropertyValue<float> SymbolLayer::getTextPadding() const {
- return impl->layout.unevaluated.get<TextPadding>();
+ return impl().layout.unevaluated.get<TextPadding>();
}
void SymbolLayer::setTextPadding(PropertyValue<float> value) {
if (value == getTextPadding())
return;
- impl->layout.unevaluated.get<TextPadding>() = value;
- impl->observer->onLayerLayoutPropertyChanged(*this, "text-padding");
+ auto impl_ = mutableImpl();
+ impl_->layout.unevaluated.get<TextPadding>() = value;
+ baseImpl = std::move(impl_);
+ observer->onLayerLayoutPropertyChanged(*this, "text-padding");
}
PropertyValue<bool> SymbolLayer::getDefaultTextKeepUpright() {
return TextKeepUpright::defaultValue();
}
PropertyValue<bool> SymbolLayer::getTextKeepUpright() const {
- return impl->layout.unevaluated.get<TextKeepUpright>();
+ return impl().layout.unevaluated.get<TextKeepUpright>();
}
void SymbolLayer::setTextKeepUpright(PropertyValue<bool> value) {
if (value == getTextKeepUpright())
return;
- impl->layout.unevaluated.get<TextKeepUpright>() = value;
- impl->observer->onLayerLayoutPropertyChanged(*this, "text-keep-upright");
+ auto impl_ = mutableImpl();
+ impl_->layout.unevaluated.get<TextKeepUpright>() = value;
+ baseImpl = std::move(impl_);
+ observer->onLayerLayoutPropertyChanged(*this, "text-keep-upright");
}
DataDrivenPropertyValue<TextTransformType> SymbolLayer::getDefaultTextTransform() {
return TextTransform::defaultValue();
}
DataDrivenPropertyValue<TextTransformType> SymbolLayer::getTextTransform() const {
- return impl->layout.unevaluated.get<TextTransform>();
+ return impl().layout.unevaluated.get<TextTransform>();
}
void SymbolLayer::setTextTransform(DataDrivenPropertyValue<TextTransformType> value) {
if (value == getTextTransform())
return;
- impl->layout.unevaluated.get<TextTransform>() = value;
- impl->observer->onLayerLayoutPropertyChanged(*this, "text-transform");
+ auto impl_ = mutableImpl();
+ impl_->layout.unevaluated.get<TextTransform>() = value;
+ baseImpl = std::move(impl_);
+ observer->onLayerLayoutPropertyChanged(*this, "text-transform");
}
DataDrivenPropertyValue<std::array<float, 2>> SymbolLayer::getDefaultTextOffset() {
return TextOffset::defaultValue();
}
DataDrivenPropertyValue<std::array<float, 2>> SymbolLayer::getTextOffset() const {
- return impl->layout.unevaluated.get<TextOffset>();
+ return impl().layout.unevaluated.get<TextOffset>();
}
void SymbolLayer::setTextOffset(DataDrivenPropertyValue<std::array<float, 2>> value) {
if (value == getTextOffset())
return;
- impl->layout.unevaluated.get<TextOffset>() = value;
- impl->observer->onLayerLayoutPropertyChanged(*this, "text-offset");
+ auto impl_ = mutableImpl();
+ impl_->layout.unevaluated.get<TextOffset>() = value;
+ baseImpl = std::move(impl_);
+ observer->onLayerLayoutPropertyChanged(*this, "text-offset");
}
PropertyValue<bool> SymbolLayer::getDefaultTextAllowOverlap() {
return TextAllowOverlap::defaultValue();
}
PropertyValue<bool> SymbolLayer::getTextAllowOverlap() const {
- return impl->layout.unevaluated.get<TextAllowOverlap>();
+ return impl().layout.unevaluated.get<TextAllowOverlap>();
}
void SymbolLayer::setTextAllowOverlap(PropertyValue<bool> value) {
if (value == getTextAllowOverlap())
return;
- impl->layout.unevaluated.get<TextAllowOverlap>() = value;
- impl->observer->onLayerLayoutPropertyChanged(*this, "text-allow-overlap");
+ auto impl_ = mutableImpl();
+ impl_->layout.unevaluated.get<TextAllowOverlap>() = value;
+ baseImpl = std::move(impl_);
+ observer->onLayerLayoutPropertyChanged(*this, "text-allow-overlap");
}
PropertyValue<bool> SymbolLayer::getDefaultTextIgnorePlacement() {
return TextIgnorePlacement::defaultValue();
}
PropertyValue<bool> SymbolLayer::getTextIgnorePlacement() const {
- return impl->layout.unevaluated.get<TextIgnorePlacement>();
+ return impl().layout.unevaluated.get<TextIgnorePlacement>();
}
void SymbolLayer::setTextIgnorePlacement(PropertyValue<bool> value) {
if (value == getTextIgnorePlacement())
return;
- impl->layout.unevaluated.get<TextIgnorePlacement>() = value;
- impl->observer->onLayerLayoutPropertyChanged(*this, "text-ignore-placement");
+ auto impl_ = mutableImpl();
+ impl_->layout.unevaluated.get<TextIgnorePlacement>() = value;
+ baseImpl = std::move(impl_);
+ observer->onLayerLayoutPropertyChanged(*this, "text-ignore-placement");
}
PropertyValue<bool> SymbolLayer::getDefaultTextOptional() {
return TextOptional::defaultValue();
}
PropertyValue<bool> SymbolLayer::getTextOptional() const {
- return impl->layout.unevaluated.get<TextOptional>();
+ return impl().layout.unevaluated.get<TextOptional>();
}
void SymbolLayer::setTextOptional(PropertyValue<bool> value) {
if (value == getTextOptional())
return;
- impl->layout.unevaluated.get<TextOptional>() = value;
- impl->observer->onLayerLayoutPropertyChanged(*this, "text-optional");
+ auto impl_ = mutableImpl();
+ impl_->layout.unevaluated.get<TextOptional>() = value;
+ baseImpl = std::move(impl_);
+ observer->onLayerLayoutPropertyChanged(*this, "text-optional");
}
// Paint properties
@@ -547,26 +645,30 @@ DataDrivenPropertyValue<float> SymbolLayer::getDefaultIconOpacity() {
}
DataDrivenPropertyValue<float> SymbolLayer::getIconOpacity(const optional<std::string>& klass) const {
- return impl->cascading.template get<IconOpacity>().get(klass);
+ return impl().cascading.template get<IconOpacity>().get(klass);
}
void SymbolLayer::setIconOpacity(DataDrivenPropertyValue<float> value, const optional<std::string>& klass) {
if (value == getIconOpacity(klass))
return;
- impl->cascading.template get<IconOpacity>().set(value, klass);
+ auto impl_ = mutableImpl();
+ impl_->cascading.template get<IconOpacity>().set(value, klass);
+ baseImpl = std::move(impl_);
if (value.isDataDriven()) {
- impl->observer->onLayerDataDrivenPaintPropertyChanged(*this);
+ observer->onLayerDataDrivenPaintPropertyChanged(*this);
} else {
- impl->observer->onLayerPaintPropertyChanged(*this);
+ observer->onLayerPaintPropertyChanged(*this);
}
}
void SymbolLayer::setIconOpacityTransition(const TransitionOptions& value, const optional<std::string>& klass) {
- impl->cascading.template get<IconOpacity>().setTransition(value, klass);
+ auto impl_ = mutableImpl();
+ impl_->cascading.template get<IconOpacity>().setTransition(value, klass);
+ baseImpl = std::move(impl_);
}
TransitionOptions SymbolLayer::getIconOpacityTransition(const optional<std::string>& klass) const {
- return impl->cascading.template get<IconOpacity>().getTransition(klass);
+ return impl().cascading.template get<IconOpacity>().getTransition(klass);
}
DataDrivenPropertyValue<Color> SymbolLayer::getDefaultIconColor() {
@@ -574,26 +676,30 @@ DataDrivenPropertyValue<Color> SymbolLayer::getDefaultIconColor() {
}
DataDrivenPropertyValue<Color> SymbolLayer::getIconColor(const optional<std::string>& klass) const {
- return impl->cascading.template get<IconColor>().get(klass);
+ return impl().cascading.template get<IconColor>().get(klass);
}
void SymbolLayer::setIconColor(DataDrivenPropertyValue<Color> value, const optional<std::string>& klass) {
if (value == getIconColor(klass))
return;
- impl->cascading.template get<IconColor>().set(value, klass);
+ auto impl_ = mutableImpl();
+ impl_->cascading.template get<IconColor>().set(value, klass);
+ baseImpl = std::move(impl_);
if (value.isDataDriven()) {
- impl->observer->onLayerDataDrivenPaintPropertyChanged(*this);
+ observer->onLayerDataDrivenPaintPropertyChanged(*this);
} else {
- impl->observer->onLayerPaintPropertyChanged(*this);
+ observer->onLayerPaintPropertyChanged(*this);
}
}
void SymbolLayer::setIconColorTransition(const TransitionOptions& value, const optional<std::string>& klass) {
- impl->cascading.template get<IconColor>().setTransition(value, klass);
+ auto impl_ = mutableImpl();
+ impl_->cascading.template get<IconColor>().setTransition(value, klass);
+ baseImpl = std::move(impl_);
}
TransitionOptions SymbolLayer::getIconColorTransition(const optional<std::string>& klass) const {
- return impl->cascading.template get<IconColor>().getTransition(klass);
+ return impl().cascading.template get<IconColor>().getTransition(klass);
}
DataDrivenPropertyValue<Color> SymbolLayer::getDefaultIconHaloColor() {
@@ -601,26 +707,30 @@ DataDrivenPropertyValue<Color> SymbolLayer::getDefaultIconHaloColor() {
}
DataDrivenPropertyValue<Color> SymbolLayer::getIconHaloColor(const optional<std::string>& klass) const {
- return impl->cascading.template get<IconHaloColor>().get(klass);
+ return impl().cascading.template get<IconHaloColor>().get(klass);
}
void SymbolLayer::setIconHaloColor(DataDrivenPropertyValue<Color> value, const optional<std::string>& klass) {
if (value == getIconHaloColor(klass))
return;
- impl->cascading.template get<IconHaloColor>().set(value, klass);
+ auto impl_ = mutableImpl();
+ impl_->cascading.template get<IconHaloColor>().set(value, klass);
+ baseImpl = std::move(impl_);
if (value.isDataDriven()) {
- impl->observer->onLayerDataDrivenPaintPropertyChanged(*this);
+ observer->onLayerDataDrivenPaintPropertyChanged(*this);
} else {
- impl->observer->onLayerPaintPropertyChanged(*this);
+ observer->onLayerPaintPropertyChanged(*this);
}
}
void SymbolLayer::setIconHaloColorTransition(const TransitionOptions& value, const optional<std::string>& klass) {
- impl->cascading.template get<IconHaloColor>().setTransition(value, klass);
+ auto impl_ = mutableImpl();
+ impl_->cascading.template get<IconHaloColor>().setTransition(value, klass);
+ baseImpl = std::move(impl_);
}
TransitionOptions SymbolLayer::getIconHaloColorTransition(const optional<std::string>& klass) const {
- return impl->cascading.template get<IconHaloColor>().getTransition(klass);
+ return impl().cascading.template get<IconHaloColor>().getTransition(klass);
}
DataDrivenPropertyValue<float> SymbolLayer::getDefaultIconHaloWidth() {
@@ -628,26 +738,30 @@ DataDrivenPropertyValue<float> SymbolLayer::getDefaultIconHaloWidth() {
}
DataDrivenPropertyValue<float> SymbolLayer::getIconHaloWidth(const optional<std::string>& klass) const {
- return impl->cascading.template get<IconHaloWidth>().get(klass);
+ return impl().cascading.template get<IconHaloWidth>().get(klass);
}
void SymbolLayer::setIconHaloWidth(DataDrivenPropertyValue<float> value, const optional<std::string>& klass) {
if (value == getIconHaloWidth(klass))
return;
- impl->cascading.template get<IconHaloWidth>().set(value, klass);
+ auto impl_ = mutableImpl();
+ impl_->cascading.template get<IconHaloWidth>().set(value, klass);
+ baseImpl = std::move(impl_);
if (value.isDataDriven()) {
- impl->observer->onLayerDataDrivenPaintPropertyChanged(*this);
+ observer->onLayerDataDrivenPaintPropertyChanged(*this);
} else {
- impl->observer->onLayerPaintPropertyChanged(*this);
+ observer->onLayerPaintPropertyChanged(*this);
}
}
void SymbolLayer::setIconHaloWidthTransition(const TransitionOptions& value, const optional<std::string>& klass) {
- impl->cascading.template get<IconHaloWidth>().setTransition(value, klass);
+ auto impl_ = mutableImpl();
+ impl_->cascading.template get<IconHaloWidth>().setTransition(value, klass);
+ baseImpl = std::move(impl_);
}
TransitionOptions SymbolLayer::getIconHaloWidthTransition(const optional<std::string>& klass) const {
- return impl->cascading.template get<IconHaloWidth>().getTransition(klass);
+ return impl().cascading.template get<IconHaloWidth>().getTransition(klass);
}
DataDrivenPropertyValue<float> SymbolLayer::getDefaultIconHaloBlur() {
@@ -655,26 +769,30 @@ DataDrivenPropertyValue<float> SymbolLayer::getDefaultIconHaloBlur() {
}
DataDrivenPropertyValue<float> SymbolLayer::getIconHaloBlur(const optional<std::string>& klass) const {
- return impl->cascading.template get<IconHaloBlur>().get(klass);
+ return impl().cascading.template get<IconHaloBlur>().get(klass);
}
void SymbolLayer::setIconHaloBlur(DataDrivenPropertyValue<float> value, const optional<std::string>& klass) {
if (value == getIconHaloBlur(klass))
return;
- impl->cascading.template get<IconHaloBlur>().set(value, klass);
+ auto impl_ = mutableImpl();
+ impl_->cascading.template get<IconHaloBlur>().set(value, klass);
+ baseImpl = std::move(impl_);
if (value.isDataDriven()) {
- impl->observer->onLayerDataDrivenPaintPropertyChanged(*this);
+ observer->onLayerDataDrivenPaintPropertyChanged(*this);
} else {
- impl->observer->onLayerPaintPropertyChanged(*this);
+ observer->onLayerPaintPropertyChanged(*this);
}
}
void SymbolLayer::setIconHaloBlurTransition(const TransitionOptions& value, const optional<std::string>& klass) {
- impl->cascading.template get<IconHaloBlur>().setTransition(value, klass);
+ auto impl_ = mutableImpl();
+ impl_->cascading.template get<IconHaloBlur>().setTransition(value, klass);
+ baseImpl = std::move(impl_);
}
TransitionOptions SymbolLayer::getIconHaloBlurTransition(const optional<std::string>& klass) const {
- return impl->cascading.template get<IconHaloBlur>().getTransition(klass);
+ return impl().cascading.template get<IconHaloBlur>().getTransition(klass);
}
PropertyValue<std::array<float, 2>> SymbolLayer::getDefaultIconTranslate() {
@@ -682,22 +800,26 @@ PropertyValue<std::array<float, 2>> SymbolLayer::getDefaultIconTranslate() {
}
PropertyValue<std::array<float, 2>> SymbolLayer::getIconTranslate(const optional<std::string>& klass) const {
- return impl->cascading.template get<IconTranslate>().get(klass);
+ return impl().cascading.template get<IconTranslate>().get(klass);
}
void SymbolLayer::setIconTranslate(PropertyValue<std::array<float, 2>> value, const optional<std::string>& klass) {
if (value == getIconTranslate(klass))
return;
- impl->cascading.template get<IconTranslate>().set(value, klass);
- impl->observer->onLayerPaintPropertyChanged(*this);
+ auto impl_ = mutableImpl();
+ impl_->cascading.template get<IconTranslate>().set(value, klass);
+ baseImpl = std::move(impl_);
+ observer->onLayerPaintPropertyChanged(*this);
}
void SymbolLayer::setIconTranslateTransition(const TransitionOptions& value, const optional<std::string>& klass) {
- impl->cascading.template get<IconTranslate>().setTransition(value, klass);
+ auto impl_ = mutableImpl();
+ impl_->cascading.template get<IconTranslate>().setTransition(value, klass);
+ baseImpl = std::move(impl_);
}
TransitionOptions SymbolLayer::getIconTranslateTransition(const optional<std::string>& klass) const {
- return impl->cascading.template get<IconTranslate>().getTransition(klass);
+ return impl().cascading.template get<IconTranslate>().getTransition(klass);
}
PropertyValue<TranslateAnchorType> SymbolLayer::getDefaultIconTranslateAnchor() {
@@ -705,22 +827,26 @@ PropertyValue<TranslateAnchorType> SymbolLayer::getDefaultIconTranslateAnchor()
}
PropertyValue<TranslateAnchorType> SymbolLayer::getIconTranslateAnchor(const optional<std::string>& klass) const {
- return impl->cascading.template get<IconTranslateAnchor>().get(klass);
+ return impl().cascading.template get<IconTranslateAnchor>().get(klass);
}
void SymbolLayer::setIconTranslateAnchor(PropertyValue<TranslateAnchorType> value, const optional<std::string>& klass) {
if (value == getIconTranslateAnchor(klass))
return;
- impl->cascading.template get<IconTranslateAnchor>().set(value, klass);
- impl->observer->onLayerPaintPropertyChanged(*this);
+ auto impl_ = mutableImpl();
+ impl_->cascading.template get<IconTranslateAnchor>().set(value, klass);
+ baseImpl = std::move(impl_);
+ observer->onLayerPaintPropertyChanged(*this);
}
void SymbolLayer::setIconTranslateAnchorTransition(const TransitionOptions& value, const optional<std::string>& klass) {
- impl->cascading.template get<IconTranslateAnchor>().setTransition(value, klass);
+ auto impl_ = mutableImpl();
+ impl_->cascading.template get<IconTranslateAnchor>().setTransition(value, klass);
+ baseImpl = std::move(impl_);
}
TransitionOptions SymbolLayer::getIconTranslateAnchorTransition(const optional<std::string>& klass) const {
- return impl->cascading.template get<IconTranslateAnchor>().getTransition(klass);
+ return impl().cascading.template get<IconTranslateAnchor>().getTransition(klass);
}
DataDrivenPropertyValue<float> SymbolLayer::getDefaultTextOpacity() {
@@ -728,26 +854,30 @@ DataDrivenPropertyValue<float> SymbolLayer::getDefaultTextOpacity() {
}
DataDrivenPropertyValue<float> SymbolLayer::getTextOpacity(const optional<std::string>& klass) const {
- return impl->cascading.template get<TextOpacity>().get(klass);
+ return impl().cascading.template get<TextOpacity>().get(klass);
}
void SymbolLayer::setTextOpacity(DataDrivenPropertyValue<float> value, const optional<std::string>& klass) {
if (value == getTextOpacity(klass))
return;
- impl->cascading.template get<TextOpacity>().set(value, klass);
+ auto impl_ = mutableImpl();
+ impl_->cascading.template get<TextOpacity>().set(value, klass);
+ baseImpl = std::move(impl_);
if (value.isDataDriven()) {
- impl->observer->onLayerDataDrivenPaintPropertyChanged(*this);
+ observer->onLayerDataDrivenPaintPropertyChanged(*this);
} else {
- impl->observer->onLayerPaintPropertyChanged(*this);
+ observer->onLayerPaintPropertyChanged(*this);
}
}
void SymbolLayer::setTextOpacityTransition(const TransitionOptions& value, const optional<std::string>& klass) {
- impl->cascading.template get<TextOpacity>().setTransition(value, klass);
+ auto impl_ = mutableImpl();
+ impl_->cascading.template get<TextOpacity>().setTransition(value, klass);
+ baseImpl = std::move(impl_);
}
TransitionOptions SymbolLayer::getTextOpacityTransition(const optional<std::string>& klass) const {
- return impl->cascading.template get<TextOpacity>().getTransition(klass);
+ return impl().cascading.template get<TextOpacity>().getTransition(klass);
}
DataDrivenPropertyValue<Color> SymbolLayer::getDefaultTextColor() {
@@ -755,26 +885,30 @@ DataDrivenPropertyValue<Color> SymbolLayer::getDefaultTextColor() {
}
DataDrivenPropertyValue<Color> SymbolLayer::getTextColor(const optional<std::string>& klass) const {
- return impl->cascading.template get<TextColor>().get(klass);
+ return impl().cascading.template get<TextColor>().get(klass);
}
void SymbolLayer::setTextColor(DataDrivenPropertyValue<Color> value, const optional<std::string>& klass) {
if (value == getTextColor(klass))
return;
- impl->cascading.template get<TextColor>().set(value, klass);
+ auto impl_ = mutableImpl();
+ impl_->cascading.template get<TextColor>().set(value, klass);
+ baseImpl = std::move(impl_);
if (value.isDataDriven()) {
- impl->observer->onLayerDataDrivenPaintPropertyChanged(*this);
+ observer->onLayerDataDrivenPaintPropertyChanged(*this);
} else {
- impl->observer->onLayerPaintPropertyChanged(*this);
+ observer->onLayerPaintPropertyChanged(*this);
}
}
void SymbolLayer::setTextColorTransition(const TransitionOptions& value, const optional<std::string>& klass) {
- impl->cascading.template get<TextColor>().setTransition(value, klass);
+ auto impl_ = mutableImpl();
+ impl_->cascading.template get<TextColor>().setTransition(value, klass);
+ baseImpl = std::move(impl_);
}
TransitionOptions SymbolLayer::getTextColorTransition(const optional<std::string>& klass) const {
- return impl->cascading.template get<TextColor>().getTransition(klass);
+ return impl().cascading.template get<TextColor>().getTransition(klass);
}
DataDrivenPropertyValue<Color> SymbolLayer::getDefaultTextHaloColor() {
@@ -782,26 +916,30 @@ DataDrivenPropertyValue<Color> SymbolLayer::getDefaultTextHaloColor() {
}
DataDrivenPropertyValue<Color> SymbolLayer::getTextHaloColor(const optional<std::string>& klass) const {
- return impl->cascading.template get<TextHaloColor>().get(klass);
+ return impl().cascading.template get<TextHaloColor>().get(klass);
}
void SymbolLayer::setTextHaloColor(DataDrivenPropertyValue<Color> value, const optional<std::string>& klass) {
if (value == getTextHaloColor(klass))
return;
- impl->cascading.template get<TextHaloColor>().set(value, klass);
+ auto impl_ = mutableImpl();
+ impl_->cascading.template get<TextHaloColor>().set(value, klass);
+ baseImpl = std::move(impl_);
if (value.isDataDriven()) {
- impl->observer->onLayerDataDrivenPaintPropertyChanged(*this);
+ observer->onLayerDataDrivenPaintPropertyChanged(*this);
} else {
- impl->observer->onLayerPaintPropertyChanged(*this);
+ observer->onLayerPaintPropertyChanged(*this);
}
}
void SymbolLayer::setTextHaloColorTransition(const TransitionOptions& value, const optional<std::string>& klass) {
- impl->cascading.template get<TextHaloColor>().setTransition(value, klass);
+ auto impl_ = mutableImpl();
+ impl_->cascading.template get<TextHaloColor>().setTransition(value, klass);
+ baseImpl = std::move(impl_);
}
TransitionOptions SymbolLayer::getTextHaloColorTransition(const optional<std::string>& klass) const {
- return impl->cascading.template get<TextHaloColor>().getTransition(klass);
+ return impl().cascading.template get<TextHaloColor>().getTransition(klass);
}
DataDrivenPropertyValue<float> SymbolLayer::getDefaultTextHaloWidth() {
@@ -809,26 +947,30 @@ DataDrivenPropertyValue<float> SymbolLayer::getDefaultTextHaloWidth() {
}
DataDrivenPropertyValue<float> SymbolLayer::getTextHaloWidth(const optional<std::string>& klass) const {
- return impl->cascading.template get<TextHaloWidth>().get(klass);
+ return impl().cascading.template get<TextHaloWidth>().get(klass);
}
void SymbolLayer::setTextHaloWidth(DataDrivenPropertyValue<float> value, const optional<std::string>& klass) {
if (value == getTextHaloWidth(klass))
return;
- impl->cascading.template get<TextHaloWidth>().set(value, klass);
+ auto impl_ = mutableImpl();
+ impl_->cascading.template get<TextHaloWidth>().set(value, klass);
+ baseImpl = std::move(impl_);
if (value.isDataDriven()) {
- impl->observer->onLayerDataDrivenPaintPropertyChanged(*this);
+ observer->onLayerDataDrivenPaintPropertyChanged(*this);
} else {
- impl->observer->onLayerPaintPropertyChanged(*this);
+ observer->onLayerPaintPropertyChanged(*this);
}
}
void SymbolLayer::setTextHaloWidthTransition(const TransitionOptions& value, const optional<std::string>& klass) {
- impl->cascading.template get<TextHaloWidth>().setTransition(value, klass);
+ auto impl_ = mutableImpl();
+ impl_->cascading.template get<TextHaloWidth>().setTransition(value, klass);
+ baseImpl = std::move(impl_);
}
TransitionOptions SymbolLayer::getTextHaloWidthTransition(const optional<std::string>& klass) const {
- return impl->cascading.template get<TextHaloWidth>().getTransition(klass);
+ return impl().cascading.template get<TextHaloWidth>().getTransition(klass);
}
DataDrivenPropertyValue<float> SymbolLayer::getDefaultTextHaloBlur() {
@@ -836,26 +978,30 @@ DataDrivenPropertyValue<float> SymbolLayer::getDefaultTextHaloBlur() {
}
DataDrivenPropertyValue<float> SymbolLayer::getTextHaloBlur(const optional<std::string>& klass) const {
- return impl->cascading.template get<TextHaloBlur>().get(klass);
+ return impl().cascading.template get<TextHaloBlur>().get(klass);
}
void SymbolLayer::setTextHaloBlur(DataDrivenPropertyValue<float> value, const optional<std::string>& klass) {
if (value == getTextHaloBlur(klass))
return;
- impl->cascading.template get<TextHaloBlur>().set(value, klass);
+ auto impl_ = mutableImpl();
+ impl_->cascading.template get<TextHaloBlur>().set(value, klass);
+ baseImpl = std::move(impl_);
if (value.isDataDriven()) {
- impl->observer->onLayerDataDrivenPaintPropertyChanged(*this);
+ observer->onLayerDataDrivenPaintPropertyChanged(*this);
} else {
- impl->observer->onLayerPaintPropertyChanged(*this);
+ observer->onLayerPaintPropertyChanged(*this);
}
}
void SymbolLayer::setTextHaloBlurTransition(const TransitionOptions& value, const optional<std::string>& klass) {
- impl->cascading.template get<TextHaloBlur>().setTransition(value, klass);
+ auto impl_ = mutableImpl();
+ impl_->cascading.template get<TextHaloBlur>().setTransition(value, klass);
+ baseImpl = std::move(impl_);
}
TransitionOptions SymbolLayer::getTextHaloBlurTransition(const optional<std::string>& klass) const {
- return impl->cascading.template get<TextHaloBlur>().getTransition(klass);
+ return impl().cascading.template get<TextHaloBlur>().getTransition(klass);
}
PropertyValue<std::array<float, 2>> SymbolLayer::getDefaultTextTranslate() {
@@ -863,22 +1009,26 @@ PropertyValue<std::array<float, 2>> SymbolLayer::getDefaultTextTranslate() {
}
PropertyValue<std::array<float, 2>> SymbolLayer::getTextTranslate(const optional<std::string>& klass) const {
- return impl->cascading.template get<TextTranslate>().get(klass);
+ return impl().cascading.template get<TextTranslate>().get(klass);
}
void SymbolLayer::setTextTranslate(PropertyValue<std::array<float, 2>> value, const optional<std::string>& klass) {
if (value == getTextTranslate(klass))
return;
- impl->cascading.template get<TextTranslate>().set(value, klass);
- impl->observer->onLayerPaintPropertyChanged(*this);
+ auto impl_ = mutableImpl();
+ impl_->cascading.template get<TextTranslate>().set(value, klass);
+ baseImpl = std::move(impl_);
+ observer->onLayerPaintPropertyChanged(*this);
}
void SymbolLayer::setTextTranslateTransition(const TransitionOptions& value, const optional<std::string>& klass) {
- impl->cascading.template get<TextTranslate>().setTransition(value, klass);
+ auto impl_ = mutableImpl();
+ impl_->cascading.template get<TextTranslate>().setTransition(value, klass);
+ baseImpl = std::move(impl_);
}
TransitionOptions SymbolLayer::getTextTranslateTransition(const optional<std::string>& klass) const {
- return impl->cascading.template get<TextTranslate>().getTransition(klass);
+ return impl().cascading.template get<TextTranslate>().getTransition(klass);
}
PropertyValue<TranslateAnchorType> SymbolLayer::getDefaultTextTranslateAnchor() {
@@ -886,22 +1036,26 @@ PropertyValue<TranslateAnchorType> SymbolLayer::getDefaultTextTranslateAnchor()
}
PropertyValue<TranslateAnchorType> SymbolLayer::getTextTranslateAnchor(const optional<std::string>& klass) const {
- return impl->cascading.template get<TextTranslateAnchor>().get(klass);
+ return impl().cascading.template get<TextTranslateAnchor>().get(klass);
}
void SymbolLayer::setTextTranslateAnchor(PropertyValue<TranslateAnchorType> value, const optional<std::string>& klass) {
if (value == getTextTranslateAnchor(klass))
return;
- impl->cascading.template get<TextTranslateAnchor>().set(value, klass);
- impl->observer->onLayerPaintPropertyChanged(*this);
+ auto impl_ = mutableImpl();
+ impl_->cascading.template get<TextTranslateAnchor>().set(value, klass);
+ baseImpl = std::move(impl_);
+ observer->onLayerPaintPropertyChanged(*this);
}
void SymbolLayer::setTextTranslateAnchorTransition(const TransitionOptions& value, const optional<std::string>& klass) {
- impl->cascading.template get<TextTranslateAnchor>().setTransition(value, klass);
+ auto impl_ = mutableImpl();
+ impl_->cascading.template get<TextTranslateAnchor>().setTransition(value, klass);
+ baseImpl = std::move(impl_);
}
TransitionOptions SymbolLayer::getTextTranslateAnchorTransition(const optional<std::string>& klass) const {
- return impl->cascading.template get<TextTranslateAnchor>().getTransition(klass);
+ return impl().cascading.template get<TextTranslateAnchor>().getTransition(klass);
}
} // namespace style
diff --git a/src/mbgl/style/layers/symbol_layer_impl.cpp b/src/mbgl/style/layers/symbol_layer_impl.cpp
index c99dd8ad70..220a17fd36 100644
--- a/src/mbgl/style/layers/symbol_layer_impl.cpp
+++ b/src/mbgl/style/layers/symbol_layer_impl.cpp
@@ -5,7 +5,7 @@ namespace mbgl {
namespace style {
std::unique_ptr<RenderLayer> SymbolLayer::Impl::createRenderLayer() const {
- return std::make_unique<RenderSymbolLayer>(*this);
+ return std::make_unique<RenderSymbolLayer>(staticImmutableCast<SymbolLayer::Impl>(immutableFromThis()));
}
} // namespace style
diff --git a/src/mbgl/style/layers/symbol_layer_impl.hpp b/src/mbgl/style/layers/symbol_layer_impl.hpp
index df145647a0..4937ee8721 100644
--- a/src/mbgl/style/layers/symbol_layer_impl.hpp
+++ b/src/mbgl/style/layers/symbol_layer_impl.hpp
@@ -6,13 +6,12 @@
#include <mbgl/style/layers/symbol_layer_properties.hpp>
namespace mbgl {
-
namespace style {
class SymbolLayer::Impl : public Layer::Impl {
public:
- std::unique_ptr<Layer> clone() const override;
- std::unique_ptr<Layer> cloneRef(const std::string& id) const override;
+ using Layer::Impl::Impl;
+
void stringifyLayout(rapidjson::Writer<rapidjson::StringBuffer>&) const override;
std::unique_ptr<RenderLayer> createRenderLayer() const override;
diff --git a/src/mbgl/style/light.cpp b/src/mbgl/style/light.cpp
index b54920713c..d2f91c73af 100644
--- a/src/mbgl/style/light.cpp
+++ b/src/mbgl/style/light.cpp
@@ -2,17 +2,29 @@
#include <mbgl/style/light.hpp>
#include <mbgl/style/light_impl.hpp>
+#include <mbgl/style/light_observer.hpp>
#include <mbgl/style/light_properties.hpp>
namespace mbgl {
namespace style {
+static LightObserver nullObserver;
+
Light::Light()
- : impl(std::make_unique<Impl>()) {
+ : impl(makeMutable<Impl>()),
+ observer(&nullObserver) {
}
Light::~Light() = default;
+void Light::setObserver(LightObserver* observer_) {
+ observer = observer_ ? observer_ : &nullObserver;
+}
+
+Mutable<Light::Impl> Light::mutableImpl() const {
+ return makeMutable<Impl>(*impl);
+}
+
LightAnchorType Light::getDefaultAnchor() {
return LightAnchor::defaultValue();
}
@@ -22,13 +34,17 @@ PropertyValue<LightAnchorType> Light::getAnchor() const {
}
void Light::setAnchor(PropertyValue<LightAnchorType> property) {
- impl->properties.template get<LightAnchor>().value = property;
- impl->observer->onLightChanged(*this);
+ auto impl_ = mutableImpl();
+ impl_->properties.template get<LightAnchor>().value = property;
+ impl = std::move(impl_);
+ observer->onLightChanged(*this);
}
void Light::setAnchorTransition(const TransitionOptions& transition) {
- impl->properties.template get<LightAnchor>().transition = transition;
- impl->observer->onLightChanged(*this);
+ auto impl_ = mutableImpl();
+ impl_->properties.template get<LightAnchor>().transition = transition;
+ impl = std::move(impl_);
+ observer->onLightChanged(*this);
}
TransitionOptions Light::getAnchorTransition() const {
@@ -44,13 +60,17 @@ PropertyValue<Position> Light::getPosition() const {
}
void Light::setPosition(PropertyValue<Position> property) {
- impl->properties.template get<LightPosition>().value = property;
- impl->observer->onLightChanged(*this);
+ auto impl_ = mutableImpl();
+ impl_->properties.template get<LightPosition>().value = property;
+ impl = std::move(impl_);
+ observer->onLightChanged(*this);
}
void Light::setPositionTransition(const TransitionOptions& transition) {
- impl->properties.template get<LightPosition>().transition = transition;
- impl->observer->onLightChanged(*this);
+ auto impl_ = mutableImpl();
+ impl_->properties.template get<LightPosition>().transition = transition;
+ impl = std::move(impl_);
+ observer->onLightChanged(*this);
}
TransitionOptions Light::getPositionTransition() const {
@@ -66,13 +86,17 @@ PropertyValue<Color> Light::getColor() const {
}
void Light::setColor(PropertyValue<Color> property) {
- impl->properties.template get<LightColor>().value = property;
- impl->observer->onLightChanged(*this);
+ auto impl_ = mutableImpl();
+ impl_->properties.template get<LightColor>().value = property;
+ impl = std::move(impl_);
+ observer->onLightChanged(*this);
}
void Light::setColorTransition(const TransitionOptions& transition) {
- impl->properties.template get<LightColor>().transition = transition;
- impl->observer->onLightChanged(*this);
+ auto impl_ = mutableImpl();
+ impl_->properties.template get<LightColor>().transition = transition;
+ impl = std::move(impl_);
+ observer->onLightChanged(*this);
}
TransitionOptions Light::getColorTransition() const {
@@ -88,13 +112,17 @@ PropertyValue<float> Light::getIntensity() const {
}
void Light::setIntensity(PropertyValue<float> property) {
- impl->properties.template get<LightIntensity>().value = property;
- impl->observer->onLightChanged(*this);
+ auto impl_ = mutableImpl();
+ impl_->properties.template get<LightIntensity>().value = property;
+ impl = std::move(impl_);
+ observer->onLightChanged(*this);
}
void Light::setIntensityTransition(const TransitionOptions& transition) {
- impl->properties.template get<LightIntensity>().transition = transition;
- impl->observer->onLightChanged(*this);
+ auto impl_ = mutableImpl();
+ impl_->properties.template get<LightIntensity>().transition = transition;
+ impl = std::move(impl_);
+ observer->onLightChanged(*this);
}
TransitionOptions Light::getIntensityTransition() const {
diff --git a/src/mbgl/style/light.cpp.ejs b/src/mbgl/style/light.cpp.ejs
index c82c65c10c..454bad49d8 100644
--- a/src/mbgl/style/light.cpp.ejs
+++ b/src/mbgl/style/light.cpp.ejs
@@ -5,17 +5,29 @@
#include <mbgl/style/light.hpp>
#include <mbgl/style/light_impl.hpp>
+#include <mbgl/style/light_observer.hpp>
#include <mbgl/style/light_properties.hpp>
namespace mbgl {
namespace style {
+static LightObserver nullObserver;
+
Light::Light()
- : impl(std::make_unique<Impl>()) {
+ : impl(makeMutable<Impl>()),
+ observer(&nullObserver) {
}
Light::~Light() = default;
+void Light::setObserver(LightObserver* observer_) {
+ observer = observer_ ? observer_ : &nullObserver;
+}
+
+Mutable<Light::Impl> Light::mutableImpl() const {
+ return makeMutable<Impl>(*impl);
+}
+
<% for (const property of properties) { -%>
<%- evaluatedType(property) %> Light::getDefault<%- camelize(property.name) %>() {
return Light<%- camelize(property.name) %>::defaultValue();
@@ -26,13 +38,17 @@ Light::~Light() = default;
}
void Light::set<%- camelize(property.name) %>(<%- propertyValueType(property) %> property) {
- impl->properties.template get<Light<%- camelize(property.name) %>>().value = property;
- impl->observer->onLightChanged(*this);
+ auto impl_ = mutableImpl();
+ impl_->properties.template get<Light<%- camelize(property.name) %>>().value = property;
+ impl = std::move(impl_);
+ observer->onLightChanged(*this);
}
void Light::set<%- camelize(property.name) %>Transition(const TransitionOptions& transition) {
- impl->properties.template get<Light<%- camelize(property.name) %>>().transition = transition;
- impl->observer->onLightChanged(*this);
+ auto impl_ = mutableImpl();
+ impl_->properties.template get<Light<%- camelize(property.name) %>>().transition = transition;
+ impl = std::move(impl_);
+ observer->onLightChanged(*this);
}
TransitionOptions Light::get<%- camelize(property.name) %>Transition() const {
diff --git a/src/mbgl/style/light_impl.cpp b/src/mbgl/style/light_impl.cpp
index e0ab1176ed..619d115f02 100644
--- a/src/mbgl/style/light_impl.cpp
+++ b/src/mbgl/style/light_impl.cpp
@@ -3,9 +3,5 @@
namespace mbgl {
namespace style {
-void Light::Impl::setObserver(LightObserver* observer_) {
- observer = observer_;
-}
-
} // namespace style
} // namespace mbgl
diff --git a/src/mbgl/style/light_impl.hpp b/src/mbgl/style/light_impl.hpp
index b4fd886742..d607cf00e5 100644
--- a/src/mbgl/style/light_impl.hpp
+++ b/src/mbgl/style/light_impl.hpp
@@ -1,18 +1,13 @@
#pragma once
+#include <mbgl/style/light.hpp>
#include <mbgl/style/light_properties.hpp>
-#include <mbgl/style/light_observer.hpp>
namespace mbgl {
namespace style {
class Light::Impl {
public:
-
- LightObserver nullObserver;
- LightObserver* observer = &nullObserver;
- void setObserver(LightObserver*);
-
IndexedTuple<LightProperties, LightProperties> properties;
};
diff --git a/src/mbgl/style/light_observer.hpp b/src/mbgl/style/light_observer.hpp
index 751a84850d..45beb64928 100644
--- a/src/mbgl/style/light_observer.hpp
+++ b/src/mbgl/style/light_observer.hpp
@@ -1,10 +1,10 @@
#pragma once
-#include <mbgl/style/light.hpp>
-
namespace mbgl {
namespace style {
+class Light;
+
class LightObserver {
public:
virtual ~LightObserver() = default;
diff --git a/src/mbgl/style/parser.cpp b/src/mbgl/style/parser.cpp
index fc3ccf410b..ea96bda502 100644
--- a/src/mbgl/style/parser.cpp
+++ b/src/mbgl/style/parser.cpp
@@ -236,7 +236,7 @@ void Parser::parseLayer(const std::string& id, const JSValue& value, std::unique
return;
}
- layer = reference->baseImpl->cloneRef(id);
+ layer = reference->cloneRef(id);
conversion::setPaintProperties(*layer, value);
} else {
conversion::Error error;
diff --git a/src/mbgl/style/source.cpp b/src/mbgl/style/source.cpp
index cfb268006b..4fcebc8377 100644
--- a/src/mbgl/style/source.cpp
+++ b/src/mbgl/style/source.cpp
@@ -1,15 +1,24 @@
#include <mbgl/style/source.hpp>
#include <mbgl/style/source_impl.hpp>
+#include <mbgl/style/source_observer.hpp>
+#include <mbgl/util/logging.hpp>
namespace mbgl {
namespace style {
-Source::Source(SourceType type_, std::unique_ptr<Impl> baseImpl_)
- : baseImpl(std::move(baseImpl_)), type(type_) {
+static SourceObserver nullObserver;
+
+Source::Source(Immutable<Impl> impl)
+ : baseImpl(std::move(impl)),
+ observer(&nullObserver) {
}
Source::~Source() = default;
+SourceType Source::getType() const {
+ return baseImpl->type;
+}
+
const std::string& Source::getID() const {
return baseImpl->id;
}
@@ -18,5 +27,14 @@ optional<std::string> Source::getAttribution() const {
return baseImpl->getAttribution();
}
+void Source::setObserver(SourceObserver* observer_) {
+ observer = observer_ ? observer_ : &nullObserver;
+}
+
+void Source::dumpDebugLogs() const {
+ Log::Info(Event::General, "Source::id: %s", getID().c_str());
+ Log::Info(Event::General, "Source::loaded: %d", loaded);
+}
+
} // namespace style
} // namespace mbgl
diff --git a/src/mbgl/style/source_impl.cpp b/src/mbgl/style/source_impl.cpp
index 1e9405abbb..0683f847cb 100644
--- a/src/mbgl/style/source_impl.cpp
+++ b/src/mbgl/style/source_impl.cpp
@@ -1,26 +1,11 @@
#include <mbgl/style/source_impl.hpp>
-#include <mbgl/style/source_observer.hpp>
-#include <mbgl/util/logging.hpp>
namespace mbgl {
namespace style {
-static SourceObserver nullObserver;
-
-Source::Impl::Impl(SourceType type_, std::string id_, Source& base_)
+Source::Impl::Impl(SourceType type_, std::string id_)
: type(type_),
- id(std::move(id_)),
- base(base_),
- observer(&nullObserver) {
-}
-
-void Source::Impl::dumpDebugLogs() const {
- Log::Info(Event::General, "Source::id: %s", base.getID().c_str());
- Log::Info(Event::General, "Source::loaded: %d", loaded);
-}
-
-void Source::Impl::setObserver(SourceObserver* observer_) {
- observer = observer_ ? observer_ : &nullObserver;
+ id(std::move(id_)) {
}
} // namespace style
diff --git a/src/mbgl/style/source_impl.hpp b/src/mbgl/style/source_impl.hpp
index 2514ec5120..3620ec4e50 100644
--- a/src/mbgl/style/source_impl.hpp
+++ b/src/mbgl/style/source_impl.hpp
@@ -3,35 +3,30 @@
#include <mbgl/style/source.hpp>
#include <mbgl/util/noncopyable.hpp>
+#include <string>
+
namespace mbgl {
-class FileSource;
class RenderSource;
namespace style {
class SourceObserver;
-class Source::Impl : private util::noncopyable {
+class Source::Impl : public EnableImmutableFromThis<Source::Impl> {
public:
- Impl(SourceType, std::string id, Source&);
virtual ~Impl() = default;
- virtual void loadDescription(FileSource&) = 0;
+ virtual optional<std::string> getAttribution() const = 0;
virtual std::unique_ptr<RenderSource> createRenderSource() const = 0;
- virtual optional<std::string> getAttribution() const { return {}; };
-
const SourceType type;
const std::string id;
- bool loaded = false;
- Source& base;
-
- void setObserver(SourceObserver*);
- SourceObserver* observer = nullptr;
-
- void dumpDebugLogs() const;
+protected:
+ Impl(SourceType, std::string);
+ Impl(const Impl&) = default;
+ Impl& operator=(const Impl&) = delete;
};
} // namespace style
diff --git a/src/mbgl/style/sources/geojson_source.cpp b/src/mbgl/style/sources/geojson_source.cpp
index 110c1cd63c..d04c8ffce4 100644
--- a/src/mbgl/style/sources/geojson_source.cpp
+++ b/src/mbgl/style/sources/geojson_source.cpp
@@ -1,25 +1,80 @@
#include <mbgl/style/sources/geojson_source.hpp>
#include <mbgl/style/sources/geojson_source_impl.hpp>
+#include <mbgl/style/source_observer.hpp>
+#include <mbgl/style/conversion/json.hpp>
+#include <mbgl/style/conversion/geojson.hpp>
+#include <mbgl/storage/file_source.hpp>
+#include <mbgl/util/logging.hpp>
namespace mbgl {
namespace style {
GeoJSONSource::GeoJSONSource(const std::string& id, const GeoJSONOptions& options)
- : Source(SourceType::GeoJSON,
- std::make_unique<GeoJSONSource::Impl>(std::move(id), *this, options)),
- impl(static_cast<Impl*>(baseImpl.get())) {
+ : Source(makeMutable<Impl>(std::move(id), options)) {
}
-void GeoJSONSource::setURL(const std::string& url) {
- impl->setURL(url);
+GeoJSONSource::~GeoJSONSource() = default;
+
+const GeoJSONSource::Impl& GeoJSONSource::impl() const {
+ return static_cast<const Impl&>(*baseImpl);
+}
+
+void GeoJSONSource::setURL(const std::string& url_) {
+ url = std::move(url_);
+
+ // Signal that the source description needs a reload
+ if (loaded || req) {
+ loaded = false;
+ req.reset();
+ observer->onSourceDescriptionChanged(*this);
+ }
}
void GeoJSONSource::setGeoJSON(const mapbox::geojson::geojson& geoJSON) {
- impl->setGeoJSON(geoJSON);
+ req.reset();
+ baseImpl = makeMutable<Impl>(impl(), geoJSON);
}
optional<std::string> GeoJSONSource::getURL() const {
- return impl->getURL();
+ return url;
+}
+
+void GeoJSONSource::loadDescription(FileSource& fileSource) {
+ if (!url) {
+ loaded = true;
+ return;
+ }
+
+ if (req) {
+ return;
+ }
+
+ req = fileSource.request(Resource::source(*url), [this](Response res) {
+ if (res.error) {
+ observer->onSourceError(
+ *this, std::make_exception_ptr(std::runtime_error(res.error->message)));
+ } else if (res.notModified) {
+ return;
+ } else if (res.noContent) {
+ observer->onSourceError(
+ *this, std::make_exception_ptr(std::runtime_error("unexpectedly empty GeoJSON")));
+ } else {
+ conversion::Error error;
+ optional<GeoJSON> geoJSON = conversion::convertJSON<GeoJSON>(*res.data, error);
+ if (!geoJSON) {
+ Log::Error(Event::ParseStyle, "Failed to parse GeoJSON data: %s",
+ error.message.c_str());
+ // Create an empty GeoJSON VT object to make sure we're not infinitely waiting for
+ // tiles to load.
+ baseImpl = makeMutable<Impl>(impl(), GeoJSON{ FeatureCollection{} });
+ } else {
+ baseImpl = makeMutable<Impl>(impl(), *geoJSON);
+ }
+
+ loaded = true;
+ observer->onSourceLoaded(*this);
+ }
+ });
}
} // namespace style
diff --git a/src/mbgl/style/sources/geojson_source_impl.cpp b/src/mbgl/style/sources/geojson_source_impl.cpp
index 1a686ff9bc..17d05aaa5a 100644
--- a/src/mbgl/style/sources/geojson_source_impl.cpp
+++ b/src/mbgl/style/sources/geojson_source_impl.cpp
@@ -1,12 +1,6 @@
#include <mbgl/style/sources/geojson_source_impl.hpp>
-#include <mbgl/style/conversion/json.hpp>
-#include <mbgl/style/conversion/geojson.hpp>
-#include <mbgl/style/source_observer.hpp>
-#include <mbgl/tile/tile_id.hpp>
-#include <mbgl/storage/file_source.hpp>
#include <mbgl/renderer/sources/render_geojson_source.hpp>
#include <mbgl/util/constants.cpp>
-#include <mbgl/util/logging.hpp>
#include <mapbox/geojsonvt.hpp>
#include <supercluster.hpp>
@@ -42,33 +36,14 @@ private:
mapbox::supercluster::Supercluster impl;
};
-GeoJSONSource::Impl::Impl(std::string id_, Source& base_, const GeoJSONOptions options_)
- : Source::Impl(SourceType::GeoJSON, std::move(id_), base_), options(options_) {
+GeoJSONSource::Impl::Impl(std::string id_, GeoJSONOptions options_)
+ : Source::Impl(SourceType::GeoJSON, std::move(id_)),
+ options(std::move(options_)) {
}
-GeoJSONSource::Impl::~Impl() = default;
-
-void GeoJSONSource::Impl::setURL(std::string url_) {
- url = std::move(url_);
-
- // Signal that the source description needs a reload
- if (loaded || req) {
- loaded = false;
- req.reset();
- observer->onSourceDescriptionChanged(base);
- }
-}
-
-optional<std::string> GeoJSONSource::Impl::getURL() const {
- return url;
-}
-
-void GeoJSONSource::Impl::setGeoJSON(const GeoJSON& geoJSON) {
- req.reset();
- _setGeoJSON(geoJSON);
-}
-
-void GeoJSONSource::Impl::_setGeoJSON(const GeoJSON& geoJSON) {
+GeoJSONSource::Impl::Impl(const Impl& other, const GeoJSON& geoJSON)
+ : Source::Impl(other),
+ options(other.options) {
double scale = util::EXTENT / util::tileSize;
if (options.cluster
@@ -90,47 +65,7 @@ void GeoJSONSource::Impl::_setGeoJSON(const GeoJSON& geoJSON) {
}
}
-void GeoJSONSource::Impl::loadDescription(FileSource& fileSource) {
- if (!url) {
- loaded = true;
- return;
- }
-
- if (req) {
- return;
- }
-
- req = fileSource.request(Resource::source(*url), [this](Response res) {
- if (res.error) {
- observer->onSourceError(
- base, std::make_exception_ptr(std::runtime_error(res.error->message)));
- } else if (res.notModified) {
- return;
- } else if (res.noContent) {
- observer->onSourceError(
- base, std::make_exception_ptr(std::runtime_error("unexpectedly empty GeoJSON")));
- } else {
- conversion::Error error;
- optional<GeoJSON> geoJSON = conversion::convertJSON<GeoJSON>(*res.data, error);
- if (!geoJSON) {
- Log::Error(Event::ParseStyle, "Failed to parse GeoJSON data: %s",
- error.message.c_str());
- // Create an empty GeoJSON VT object to make sure we're not infinitely waiting for
- // tiles to load.
- _setGeoJSON(GeoJSON{ FeatureCollection{} });
- } else {
- _setGeoJSON(*geoJSON);
- }
-
- loaded = true;
- observer->onSourceLoaded(base);
- }
- });
-}
-
-std::unique_ptr<RenderSource> GeoJSONSource::Impl::createRenderSource() const {
- return std::make_unique<RenderGeoJSONSource>(*this);
-}
+GeoJSONSource::Impl::~Impl() = default;
Range<uint8_t> GeoJSONSource::Impl::getZoomRange() const {
return { 0, options.maxzoom };
@@ -140,5 +75,13 @@ GeoJSONData* GeoJSONSource::Impl::getData() const {
return data.get();
}
+optional<std::string> GeoJSONSource::Impl::getAttribution() const {
+ return {};
+}
+
+std::unique_ptr<RenderSource> GeoJSONSource::Impl::createRenderSource() const {
+ return std::make_unique<RenderGeoJSONSource>(staticImmutableCast<GeoJSONSource::Impl>(immutableFromThis()));
+}
+
} // namespace style
} // namespace mbgl
diff --git a/src/mbgl/style/sources/geojson_source_impl.hpp b/src/mbgl/style/sources/geojson_source_impl.hpp
index e8b881d05e..65580700e7 100644
--- a/src/mbgl/style/sources/geojson_source_impl.hpp
+++ b/src/mbgl/style/sources/geojson_source_impl.hpp
@@ -2,7 +2,7 @@
#include <mbgl/style/source_impl.hpp>
#include <mbgl/style/sources/geojson_source.hpp>
-#include <mbgl/util/variant.hpp>
+#include <mbgl/util/range.hpp>
namespace mbgl {
@@ -18,25 +18,18 @@ public:
class GeoJSONSource::Impl : public Source::Impl {
public:
- Impl(std::string id, Source&, const GeoJSONOptions);
+ Impl(std::string id, GeoJSONOptions);
+ Impl(const GeoJSONSource::Impl&, const GeoJSON&);
~Impl() final;
- void setURL(std::string);
- optional<std::string> getURL() const;
Range<uint8_t> getZoomRange() const;
-
- void setGeoJSON(const GeoJSON&);
GeoJSONData* getData() const;
- void loadDescription(FileSource&) final;
+ optional<std::string> getAttribution() const final;
std::unique_ptr<RenderSource> createRenderSource() const final;
private:
- void _setGeoJSON(const GeoJSON&);
-
GeoJSONOptions options;
- optional<std::string> url;
- std::unique_ptr<AsyncRequest> req;
std::unique_ptr<GeoJSONData> data;
};
diff --git a/src/mbgl/style/sources/raster_source.cpp b/src/mbgl/style/sources/raster_source.cpp
index 94fdbcef12..0a0412a4ed 100644
--- a/src/mbgl/style/sources/raster_source.cpp
+++ b/src/mbgl/style/sources/raster_source.cpp
@@ -1,21 +1,81 @@
#include <mbgl/style/sources/raster_source.hpp>
#include <mbgl/style/sources/raster_source_impl.hpp>
+#include <mbgl/style/source_observer.hpp>
+#include <mbgl/style/conversion/json.hpp>
+#include <mbgl/style/conversion/tileset.hpp>
+#include <mbgl/storage/file_source.hpp>
+#include <mbgl/util/mapbox.hpp>
namespace mbgl {
namespace style {
-RasterSource::RasterSource(std::string id, variant<std::string, Tileset> urlOrTileset, uint16_t tileSize)
- : Source(SourceType::Raster, std::make_unique<RasterSource::Impl>(std::move(id), *this, std::move(urlOrTileset), tileSize)),
- impl(static_cast<Impl*>(baseImpl.get())) {
+RasterSource::RasterSource(std::string id, variant<std::string, Tileset> urlOrTileset_, uint16_t tileSize)
+ : Source(makeMutable<Impl>(std::move(id), tileSize)),
+ urlOrTileset(std::move(urlOrTileset_)) {
+}
+
+RasterSource::~RasterSource() = default;
+
+const RasterSource::Impl& RasterSource::impl() const {
+ return static_cast<const Impl&>(*baseImpl);
+}
+
+const variant<std::string, Tileset>& RasterSource::getURLOrTileset() const {
+ return urlOrTileset;
}
optional<std::string> RasterSource::getURL() const {
- auto urlOrTileset = impl->getURLOrTileset();
- if (urlOrTileset.is<std::string>()) {
- return urlOrTileset.get<std::string>();
- } else {
+ if (urlOrTileset.is<Tileset>()) {
return {};
}
+
+ return urlOrTileset.get<std::string>();
+}
+
+uint16_t RasterSource::getTileSize() const {
+ return impl().getTileSize();
+}
+
+void RasterSource::loadDescription(FileSource& fileSource) {
+ if (urlOrTileset.is<Tileset>()) {
+ baseImpl = makeMutable<Impl>(impl(), urlOrTileset.get<Tileset>());
+ loaded = true;
+ return;
+ }
+
+ if (req) {
+ return;
+ }
+
+ const std::string& url = urlOrTileset.get<std::string>();
+ req = fileSource.request(Resource::source(url), [this, url](Response res) {
+ if (res.error) {
+ observer->onSourceError(*this, std::make_exception_ptr(std::runtime_error(res.error->message)));
+ } else if (res.notModified) {
+ return;
+ } else if (res.noContent) {
+ observer->onSourceError(*this, std::make_exception_ptr(std::runtime_error("unexpectedly empty TileJSON")));
+ } else {
+ conversion::Error error;
+ optional<Tileset> tileset = conversion::convertJSON<Tileset>(*res.data, error);
+ if (!tileset) {
+ observer->onSourceError(*this, std::make_exception_ptr(std::runtime_error(error.message)));
+ return;
+ }
+
+ util::mapbox::canonicalizeTileset(*tileset, url, getType(), getTileSize());
+ bool changed = impl().getTileset() != *tileset;
+
+ baseImpl = makeMutable<Impl>(impl(), *tileset);
+ loaded = true;
+
+ observer->onSourceLoaded(*this);
+
+ if (changed) {
+ observer->onSourceChanged(*this);
+ }
+ }
+ });
}
} // namespace style
diff --git a/src/mbgl/style/sources/raster_source_impl.cpp b/src/mbgl/style/sources/raster_source_impl.cpp
index b85d221f2e..1d684524c7 100644
--- a/src/mbgl/style/sources/raster_source_impl.cpp
+++ b/src/mbgl/style/sources/raster_source_impl.cpp
@@ -4,14 +4,34 @@
namespace mbgl {
namespace style {
-RasterSource::Impl::Impl(std::string id_, Source& base_,
- variant<std::string, Tileset> urlOrTileset_,
- uint16_t tileSize_)
- : TileSourceImpl(SourceType::Raster, std::move(id_), base_, std::move(urlOrTileset_), tileSize_) {
+RasterSource::Impl::Impl(std::string id_, uint16_t tileSize_)
+ : Source::Impl(SourceType::Raster, std::move(id_)),
+ tileSize(tileSize_) {
+}
+
+RasterSource::Impl::Impl(const Impl& other, Tileset tileset_)
+ : Source::Impl(other),
+ tileSize(other.tileSize),
+ tileset(std::move(tileset_)) {
+}
+
+uint16_t RasterSource::Impl::getTileSize() const {
+ return tileSize;
+}
+
+optional<Tileset> RasterSource::Impl::getTileset() const {
+ return tileset;
+}
+
+optional<std::string> RasterSource::Impl::getAttribution() const {
+ if (!tileset) {
+ return {};
+ }
+ return tileset->attribution;
}
std::unique_ptr<RenderSource> RasterSource::Impl::createRenderSource() const {
- return std::make_unique<RenderRasterSource>(*this);
+ return std::make_unique<RenderRasterSource>(staticImmutableCast<RasterSource::Impl>(immutableFromThis()));
}
} // namespace style
diff --git a/src/mbgl/style/sources/raster_source_impl.hpp b/src/mbgl/style/sources/raster_source_impl.hpp
index 4bc76560f8..0a58953ab7 100644
--- a/src/mbgl/style/sources/raster_source_impl.hpp
+++ b/src/mbgl/style/sources/raster_source_impl.hpp
@@ -1,16 +1,25 @@
#pragma once
#include <mbgl/style/sources/raster_source.hpp>
-#include <mbgl/style/tile_source_impl.hpp>
+#include <mbgl/style/source_impl.hpp>
namespace mbgl {
namespace style {
-class RasterSource::Impl : public TileSourceImpl {
+class RasterSource::Impl : public Source::Impl {
public:
- Impl(std::string id, Source&, variant<std::string, Tileset>, uint16_t tileSize);
+ Impl(std::string id, uint16_t tileSize);
+ Impl(const Impl&, Tileset);
+ optional<Tileset> getTileset() const;
+ uint16_t getTileSize() const;
+
+ optional<std::string> getAttribution() const final;
std::unique_ptr<RenderSource> createRenderSource() const final;
+
+private:
+ uint16_t tileSize;
+ optional<Tileset> tileset;
};
} // namespace style
diff --git a/src/mbgl/style/sources/vector_source.cpp b/src/mbgl/style/sources/vector_source.cpp
index 4bcd3b8985..ccdd453c75 100644
--- a/src/mbgl/style/sources/vector_source.cpp
+++ b/src/mbgl/style/sources/vector_source.cpp
@@ -1,21 +1,78 @@
#include <mbgl/style/sources/vector_source.hpp>
#include <mbgl/style/sources/vector_source_impl.hpp>
+#include <mbgl/style/source_observer.hpp>
+#include <mbgl/style/conversion/json.hpp>
+#include <mbgl/style/conversion/tileset.hpp>
+#include <mbgl/storage/file_source.hpp>
+#include <mbgl/util/mapbox.hpp>
+#include <mbgl/util/constants.hpp>
namespace mbgl {
namespace style {
-VectorSource::VectorSource(std::string id, variant<std::string, Tileset> urlOrTileset)
- : Source(SourceType::Vector, std::make_unique<VectorSource::Impl>(std::move(id), *this, std::move(urlOrTileset))),
- impl(static_cast<Impl*>(baseImpl.get())) {
+VectorSource::VectorSource(std::string id, variant<std::string, Tileset> urlOrTileset_)
+ : Source(makeMutable<Impl>(std::move(id))),
+ urlOrTileset(std::move(urlOrTileset_)) {
+}
+
+VectorSource::~VectorSource() = default;
+
+const VectorSource::Impl& VectorSource::impl() const {
+ return static_cast<const Impl&>(*baseImpl);
+}
+
+const variant<std::string, Tileset>& VectorSource::getURLOrTileset() const {
+ return urlOrTileset;
}
optional<std::string> VectorSource::getURL() const {
- auto urlOrTileset = impl->getURLOrTileset();
- if (urlOrTileset.is<std::string>()) {
- return urlOrTileset.get<std::string>();
- } else {
+ if (urlOrTileset.is<Tileset>()) {
return {};
}
+
+ return urlOrTileset.get<std::string>();
+}
+
+void VectorSource::loadDescription(FileSource& fileSource) {
+ if (urlOrTileset.is<Tileset>()) {
+ baseImpl = makeMutable<Impl>(impl(), urlOrTileset.get<Tileset>());
+ loaded = true;
+ return;
+ }
+
+ if (req) {
+ return;
+ }
+
+ const std::string& url = urlOrTileset.get<std::string>();
+ req = fileSource.request(Resource::source(url), [this, url](Response res) {
+ if (res.error) {
+ observer->onSourceError(*this, std::make_exception_ptr(std::runtime_error(res.error->message)));
+ } else if (res.notModified) {
+ return;
+ } else if (res.noContent) {
+ observer->onSourceError(*this, std::make_exception_ptr(std::runtime_error("unexpectedly empty TileJSON")));
+ } else {
+ conversion::Error error;
+ optional<Tileset> tileset = conversion::convertJSON<Tileset>(*res.data, error);
+ if (!tileset) {
+ observer->onSourceError(*this, std::make_exception_ptr(std::runtime_error(error.message)));
+ return;
+ }
+
+ util::mapbox::canonicalizeTileset(*tileset, url, getType(), util::tileSize);
+ bool changed = impl().getTileset() != *tileset;
+
+ baseImpl = makeMutable<Impl>(impl(), *tileset);
+ loaded = true;
+
+ observer->onSourceLoaded(*this);
+
+ if (changed) {
+ observer->onSourceChanged(*this);
+ }
+ }
+ });
}
} // namespace style
diff --git a/src/mbgl/style/sources/vector_source_impl.cpp b/src/mbgl/style/sources/vector_source_impl.cpp
index 158abf8575..aab62acf3f 100644
--- a/src/mbgl/style/sources/vector_source_impl.cpp
+++ b/src/mbgl/style/sources/vector_source_impl.cpp
@@ -1,16 +1,31 @@
#include <mbgl/style/sources/vector_source_impl.hpp>
#include <mbgl/renderer/sources/render_vector_source.hpp>
-#include <mbgl/util/constants.hpp>
namespace mbgl {
namespace style {
-VectorSource::Impl::Impl(std::string id_, Source& base_, variant<std::string, Tileset> urlOrTileset_)
- : TileSourceImpl(SourceType::Vector, std::move(id_), base_, std::move(urlOrTileset_), util::tileSize) {
+VectorSource::Impl::Impl(std::string id_)
+ : Source::Impl(SourceType::Vector, std::move(id_)) {
+}
+
+VectorSource::Impl::Impl(const Impl& other, Tileset tileset_)
+ : Source::Impl(other),
+ tileset(std::move(tileset_)) {
+}
+
+optional<Tileset> VectorSource::Impl::getTileset() const {
+ return tileset;
+}
+
+optional<std::string> VectorSource::Impl::getAttribution() const {
+ if (!tileset) {
+ return {};
+ }
+ return tileset->attribution;
}
std::unique_ptr<RenderSource> VectorSource::Impl::createRenderSource() const {
- return std::make_unique<RenderVectorSource>(*this);
+ return std::make_unique<RenderVectorSource>(staticImmutableCast<VectorSource::Impl>(immutableFromThis()));
}
} // namespace style
diff --git a/src/mbgl/style/sources/vector_source_impl.hpp b/src/mbgl/style/sources/vector_source_impl.hpp
index 844739948c..602d0e5bbb 100644
--- a/src/mbgl/style/sources/vector_source_impl.hpp
+++ b/src/mbgl/style/sources/vector_source_impl.hpp
@@ -1,16 +1,23 @@
#pragma once
#include <mbgl/style/sources/vector_source.hpp>
-#include <mbgl/style/tile_source_impl.hpp>
+#include <mbgl/style/source_impl.hpp>
namespace mbgl {
namespace style {
-class VectorSource::Impl : public TileSourceImpl {
+class VectorSource::Impl : public Source::Impl {
public:
- Impl(std::string id, Source&, variant<std::string, Tileset>);
+ Impl(std::string id);
+ Impl(const Impl&, Tileset);
+ optional<Tileset> getTileset() const;
+
+ optional<std::string> getAttribution() const final;
std::unique_ptr<RenderSource> createRenderSource() const final;
+
+private:
+ optional<Tileset> tileset;
};
} // namespace style
diff --git a/src/mbgl/style/style.cpp b/src/mbgl/style/style.cpp
index 9cd8cda1ec..2042bc1225 100644
--- a/src/mbgl/style/style.cpp
+++ b/src/mbgl/style/style.cpp
@@ -34,6 +34,7 @@
#include <mbgl/renderer/render_line_layer.hpp>
#include <mbgl/renderer/render_raster_layer.hpp>
#include <mbgl/renderer/render_symbol_layer.hpp>
+#include <mbgl/renderer/style_diff.hpp>
#include <mbgl/tile/tile.hpp>
#include <mbgl/util/constants.hpp>
#include <mbgl/util/exception.hpp>
@@ -74,27 +75,19 @@ Style::Style(Scheduler& scheduler_, FileSource& fileSource_, float pixelRatio)
spriteAtlas(std::make_unique<SpriteAtlas>(Size{ 1024, 1024 }, pixelRatio)),
lineAtlas(std::make_unique<LineAtlas>(Size{ 256, 512 })),
light(std::make_unique<Light>()),
- renderLight(std::make_unique<RenderLight>(light->impl)),
+ renderLight(light->impl),
observer(&nullObserver) {
glyphAtlas->setObserver(this);
spriteAtlas->setObserver(this);
- light->impl->setObserver(this);
+ light->setObserver(this);
}
Style::~Style() {
- for (const auto& source : sources) {
- source->baseImpl->setObserver(nullptr);
- }
-
for (const auto& layer : layers) {
if (auto* customLayer = layer->as<CustomLayer>()) {
- customLayer->impl->deinitialize();
+ customLayer->impl().deinitialize();
}
}
-
- glyphAtlas->setObserver(nullptr);
- spriteAtlas->setObserver(nullptr);
- light->impl->setObserver(nullptr);
}
bool Style::addClass(const std::string& className) {
@@ -136,7 +129,6 @@ void Style::setJSON(const std::string& json) {
sources.clear();
renderSources.clear();
layers.clear();
- renderLayers.clear();
classes.clear();
transitionOptions = {};
updateBatch = {};
@@ -186,12 +178,8 @@ void Style::addSource(std::unique_ptr<Source> source) {
throw std::runtime_error(msg.c_str());
}
- source->baseImpl->setObserver(this);
- source->baseImpl->loadDescription(fileSource);
-
- std::unique_ptr<RenderSource> renderSource = source->baseImpl->createRenderSource();
- renderSource->setObserver(this);
- renderSources.emplace_back(std::move(renderSource));
+ source->setObserver(this);
+ source->loadDescription(fileSource);
sources.emplace_back(std::move(source));
}
@@ -205,12 +193,8 @@ std::unique_ptr<Source> Style::removeSource(const std::string& id) {
return nullptr;
}
- util::erase_if(renderSources, [&](const auto& source) {
- return source->baseImpl.id == id;
- });
-
auto source = std::move(*it);
- source->baseImpl->setObserver(nullptr);
+ source->setObserver(nullptr);
sources.erase(it);
updateBatch.sourceIDs.erase(id);
@@ -259,15 +243,13 @@ Layer* Style::addLayer(std::unique_ptr<Layer> layer, optional<std::string> befor
}
if (auto* customLayer = layer->as<CustomLayer>()) {
- customLayer->impl->initialize();
+ customLayer->impl().initialize();
}
- layer->baseImpl->setObserver(this);
+ layer->setObserver(this);
layer->accept(QueueSourceReloadVisitor { updateBatch });
- auto added = layers.emplace(before ? findLayer(*before) : layers.end(), std::move(layer))->get();
- renderLayers.emplace(before ? findRenderLayer(*before) : renderLayers.end(), added->baseImpl->createRenderLayer());
- return std::move(added);
+ return layers.emplace(before ? findLayer(*before) : layers.end(), std::move(layer))->get();
}
std::unique_ptr<Layer> Style::removeLayer(const std::string& id) {
@@ -281,20 +263,19 @@ std::unique_ptr<Layer> Style::removeLayer(const std::string& id) {
auto layer = std::move(*it);
if (auto* customLayer = layer->as<CustomLayer>()) {
- customLayer->impl->deinitialize();
+ customLayer->impl().deinitialize();
}
- layer->baseImpl->setObserver(nullptr);
+ layer->setObserver(nullptr);
layers.erase(it);
- removeRenderLayer(id);
return layer;
}
std::vector<const RenderLayer*> Style::getRenderLayers() const {
std::vector<const RenderLayer*> result;
result.reserve(renderLayers.size());
- for (const auto& layer : renderLayers) {
- result.push_back(layer.get());
+ for (const auto& entry : renderLayers) {
+ result.push_back(entry.second.get());
}
return result;
}
@@ -302,41 +283,20 @@ std::vector<const RenderLayer*> Style::getRenderLayers() const {
std::vector<RenderLayer*> Style::getRenderLayers() {
std::vector<RenderLayer*> result;
result.reserve(renderLayers.size());
- for (auto& layer : renderLayers) {
- result.push_back(layer.get());
+ for (auto& entry : renderLayers) {
+ result.push_back(entry.second.get());
}
return result;
}
-std::vector<std::unique_ptr<RenderLayer>>::const_iterator Style::findRenderLayer(const std::string& id) const {
- return std::find_if(renderLayers.begin(), renderLayers.end(), [&](const auto& layer) {
- return layer->baseImpl.id == id;
- });
-}
-
RenderLayer* Style::getRenderLayer(const std::string& id) const {
- auto it = findRenderLayer(id);
- return it != renderLayers.end() ? it->get() : nullptr;
-}
-
-void Style::removeRenderLayer(const std::string& id) {
- auto it = std::find_if(renderLayers.begin(), renderLayers.end(), [&](const auto& layer) {
- return layer->baseImpl.id == id;
- });
-
- if (it != renderLayers.end()) {
- renderLayers.erase(it);
- }
+ auto it = renderLayers.find(id);
+ return it != renderLayers.end() ? it->second.get() : nullptr;
}
void Style::setLight(std::unique_ptr<Light> light_) {
light = std::move(light_);
- light->impl->setObserver(this);
-
- // Copy renderlight to preserve the initialised
- // transitioning light properties
- renderLight = renderLight->copy(light->impl);
-
+ light->setObserver(this);
onLightChanged(*light);
}
@@ -344,8 +304,8 @@ Light* Style::getLight() const {
return light.get();
}
-RenderLight* Style::getRenderLight() const {
- return renderLight.get();
+const RenderLight& Style::getRenderLight() const {
+ return renderLight;
}
std::string Style::getName() const {
@@ -369,7 +329,8 @@ double Style::getDefaultPitch() const {
}
void Style::update(const UpdateParameters& parameters) {
- bool zoomChanged = zoomHistory.update(parameters.transformState.getZoom(), parameters.timePoint);
+ const bool zoomChanged = zoomHistory.update(parameters.transformState.getZoom(), parameters.timePoint);
+ const bool classesChanged = parameters.updateFlags & Update::Classes;
std::vector<ClassID> classIDs;
for (const auto& className : classes) {
@@ -398,48 +359,111 @@ void Style::update(const UpdateParameters& parameters) {
parameters.annotationManager,
*this);
- const bool cascade = parameters.updateFlags & Update::Classes;
- const bool evaluate = cascade || zoomChanged || parameters.updateFlags & Update::RecalculateStyle;
+ // Update light.
+ const bool lightChanged = renderLight.impl != light->impl;
- if (cascade) {
- renderLight->transition(cascadeParameters);
+ if (lightChanged) {
+ renderLight.impl = light->impl;
+ renderLight.transition(cascadeParameters);
}
- if (evaluate || renderLight->hasTransition()) {
- renderLight->evaluate(evaluationParameters);
+ if (lightChanged || zoomChanged || renderLight.hasTransition()) {
+ renderLight.evaluate(evaluationParameters);
}
- for (const auto& renderSource : renderSources) {
- renderSource->enabled = false;
+
+ std::vector<Immutable<Source::Impl>> newSourceImpls;
+ newSourceImpls.reserve(sources.size());
+ for (const auto& source : sources) {
+ newSourceImpls.push_back(source->baseImpl);
}
- for (const auto& layer : renderLayers) {
- if (cascade) {
- layer->cascade(cascadeParameters);
+ const SourceDifference sourceDiff = diffSources(sourceImpls, newSourceImpls);
+ sourceImpls = std::move(newSourceImpls);
+
+ // Remove render layers for removed sources.
+ for (const auto& entry : sourceDiff.removed) {
+ renderLayers.erase(entry.first);
+ }
+
+ // Create render sources for newly added sources.
+ for (const auto& entry : sourceDiff.added) {
+ std::unique_ptr<RenderSource> renderSource = entry.second->createRenderSource();
+ renderSource->setObserver(this);
+ renderSources.emplace(entry.first, std::move(renderSource));
+ }
+
+ // Update render sources for changed sources.
+ for (const auto& entry : sourceDiff.changed) {
+ renderSources.at(entry.first)->setImpl(entry.second);
+ }
+
+
+ std::vector<Immutable<Layer::Impl>> newLayerImpls;
+ newLayerImpls.reserve(layers.size());
+ for (const auto& layer : layers) {
+ newLayerImpls.push_back(layer->baseImpl);
+ }
+
+ const LayerDifference layerDiff = diffLayers(layerImpls, newLayerImpls);
+ layerImpls = std::move(newLayerImpls);
+
+ // Remove render layers for removed layers.
+ for (const auto& entry : layerDiff.removed) {
+ renderLayers.erase(entry.first);
+ }
+
+ // Create render layers for newly added layers.
+ for (const auto& entry : layerDiff.added) {
+ renderLayers.emplace(entry.first, entry.second->createRenderLayer());
+ }
+
+ // Update render layers for changed layers.
+ for (const auto& entry : layerDiff.changed) {
+ renderLayers.at(entry.first)->setImpl(entry.second);
+ }
+
+ // Update layers for class and zoom changes.
+ for (const auto& entry : renderLayers) {
+ RenderLayer& layer = *entry.second;
+ const bool layerAdded = layerDiff.added.count(entry.first);
+ const bool layerChanged = layerDiff.changed.count(entry.first);
+
+ if (classesChanged || layerAdded || layerChanged) {
+ layer.cascade(cascadeParameters);
}
- if (evaluate || layer->hasTransition()) {
- layer->evaluate(evaluationParameters);
+ if (classesChanged || layerAdded || layerChanged || zoomChanged || layer.hasTransition()) {
+ layer.evaluate(evaluationParameters);
}
+ }
+
+
+ // Update tiles for each source.
+ for (const auto& entry : renderSources) {
+ entry.second->enabled = false;
+ }
- if (layer->needsRendering(zoomHistory.lastZoom)) {
- if (RenderSource* renderSource = getRenderSource(layer->baseImpl.source)) {
- renderSource->enabled = true;
+ for (const auto& entry : renderLayers) {
+ RenderLayer& layer = *entry.second;
+ if (layer.needsRendering(zoomHistory.lastZoom)) {
+ if (RenderSource* source = getRenderSource(layer.baseImpl->source)) {
+ source->enabled = true;
}
}
}
- for (const auto& renderSource : renderSources) {
- bool updated = updateBatch.sourceIDs.count(renderSource->baseImpl.id);
- if (renderSource->enabled) {
+ for (const auto& entry : renderSources) {
+ bool updated = updateBatch.sourceIDs.count(entry.first);
+ if (entry.second->enabled) {
if (updated) {
- renderSource->reloadTiles();
+ entry.second->reloadTiles();
}
- renderSource->updateTiles(tileParameters);
+ entry.second->updateTiles(tileParameters);
} else if (updated) {
- renderSource->invalidateTiles();
+ entry.second->invalidateTiles();
} else {
- renderSource->removeTiles();
+ entry.second->removeTiles();
}
}
@@ -473,20 +497,17 @@ Source* Style::getSource(const std::string& id) const {
}
RenderSource* Style::getRenderSource(const std::string& id) const {
- const auto it = std::find_if(renderSources.begin(), renderSources.end(), [&](const auto& source) {
- return source->baseImpl.id == id;
- });
-
- return it != renderSources.end() ? it->get() : nullptr;
+ auto it = renderSources.find(id);
+ return it != renderSources.end() ? it->second.get() : nullptr;
}
bool Style::hasTransitions() const {
- if (renderLight->hasTransition()) {
+ if (renderLight.hasTransition()) {
return true;
}
- for (const auto& layer : renderLayers) {
- if (layer->hasTransition()) {
+ for (const auto& entry : renderLayers) {
+ if (entry.second->hasTransition()) {
return true;
}
}
@@ -500,13 +521,13 @@ bool Style::isLoaded() const {
}
for (const auto& source: sources) {
- if (!source->baseImpl->loaded) {
+ if (!source->loaded) {
return false;
}
}
- for (const auto& renderSource: renderSources) {
- if (!renderSource->isLoaded()) {
+ for (const auto& entry: renderSources) {
+ if (!entry.second->isLoaded()) {
return false;
}
}
@@ -521,13 +542,16 @@ bool Style::isLoaded() const {
RenderData Style::getRenderData(MapDebugOptions debugOptions, float angle) const {
RenderData result;
- for (const auto& renderSource: renderSources) {
- if (renderSource->enabled) {
- result.sources.insert(renderSource.get());
+ for (const auto& entry : renderSources) {
+ if (entry.second->enabled) {
+ result.sources.insert(entry.second.get());
}
}
- for (const auto& layer : renderLayers) {
+ for (const auto& layerImpl : layerImpls) {
+ const RenderLayer* layer = getRenderLayer(layerImpl->id);
+ assert(layer);
+
if (!layer->needsRendering(zoomHistory.lastZoom)) {
continue;
}
@@ -539,7 +563,7 @@ RenderData Style::getRenderData(MapDebugOptions debugOptions, float angle) const
continue;
}
const BackgroundPaintProperties::Evaluated& paint = background->evaluated;
- if (layer.get() == renderLayers[0].get() && paint.get<BackgroundPattern>().from.empty()) {
+ if (layerImpl.get() == layerImpls[0].get() && paint.get<BackgroundPattern>().from.empty()) {
// This is a solid background. We can use glClear().
result.backgroundColor = paint.get<BackgroundColor>() * paint.get<BackgroundOpacity>();
} else {
@@ -554,9 +578,9 @@ RenderData Style::getRenderData(MapDebugOptions debugOptions, float angle) const
continue;
}
- RenderSource* source = getRenderSource(layer->baseImpl.source);
+ RenderSource* source = getRenderSource(layer->baseImpl->source);
if (!source) {
- Log::Warning(Event::Render, "can't find source for layer '%s'", layer->baseImpl.id.c_str());
+ Log::Warning(Event::Render, "can't find source for layer '%s'", layer->baseImpl->id.c_str());
continue;
}
@@ -609,7 +633,7 @@ RenderData Style::getRenderData(MapDebugOptions debugOptions, float angle) const
}
}
- auto bucket = tile.tile.getBucket(*layer);
+ auto bucket = tile.tile.getBucket(*layer->baseImpl);
if (bucket) {
sortedTilesForInsertion.emplace_back(tile);
tile.used = true;
@@ -641,8 +665,8 @@ std::vector<Feature> Style::queryRenderedFeatures(const ScreenLineString& geomet
}
}
} else {
- for (const auto& renderSource : renderSources) {
- auto sourceResults = renderSource->queryRenderedFeatures(geometry, transformState, options);
+ for (const auto& entry : renderSources) {
+ auto sourceResults = entry.second->queryRenderedFeatures(geometry, transformState, options);
std::move(sourceResults.begin(), sourceResults.end(), std::inserter(resultsByLayer, resultsByLayer.begin()));
}
}
@@ -654,11 +678,12 @@ std::vector<Feature> Style::queryRenderedFeatures(const ScreenLineString& geomet
}
// Combine all results based on the style layer order.
- for (const auto& layer : renderLayers) {
+ for (const auto& layerImpl : layerImpls) {
+ const RenderLayer* layer = getRenderLayer(layerImpl->id);
if (!layer->needsRendering(zoomHistory.lastZoom)) {
continue;
}
- auto it = resultsByLayer.find(layer->baseImpl.id);
+ auto it = resultsByLayer.find(layer->baseImpl->id);
if (it != resultsByLayer.end()) {
std::move(it->second.begin(), it->second.end(), std::back_inserter(result));
}
@@ -668,14 +693,14 @@ std::vector<Feature> Style::queryRenderedFeatures(const ScreenLineString& geomet
}
void Style::setSourceTileCacheSize(size_t size) {
- for (const auto& renderSource : renderSources) {
- renderSource->setCacheSize(size);
+ for (const auto& entry : renderSources) {
+ entry.second->setCacheSize(size);
}
}
void Style::onLowMemory() {
- for (const auto& renderSource : renderSources) {
- renderSource->onLowMemory();
+ for (const auto& entry : renderSources) {
+ entry.second->onLowMemory();
}
}
@@ -714,8 +739,8 @@ void Style::onSourceError(Source& source, std::exception_ptr error) {
void Style::onSourceDescriptionChanged(Source& source) {
observer->onSourceDescriptionChanged(source);
- if (!source.baseImpl->loaded) {
- source.baseImpl->loadDescription(fileSource);
+ if (!source.loaded) {
+ source.loadDescription(fileSource);
}
}
@@ -726,7 +751,7 @@ void Style::onTileChanged(RenderSource&, const OverscaledTileID&) {
void Style::onTileError(RenderSource& source, const OverscaledTileID& tileID, std::exception_ptr error) {
lastError = error;
Log::Error(Event::Style, "Failed to load tile %s for source %s: %s",
- util::toString(tileID).c_str(), source.baseImpl.id.c_str(), util::toString(error).c_str());
+ util::toString(tileID).c_str(), source.baseImpl->id.c_str(), util::toString(error).c_str());
observer->onResourceError(error);
}
@@ -749,38 +774,34 @@ void Style::onLayerFilterChanged(Layer& layer) {
void Style::onLayerVisibilityChanged(Layer& layer) {
layer.accept(QueueSourceReloadVisitor { updateBatch });
- observer->onUpdate(Update::RecalculateStyle);
+ observer->onUpdate(Update::Repaint);
}
void Style::onLayerPaintPropertyChanged(Layer&) {
- observer->onUpdate(Update::RecalculateStyle | Update::Classes);
+ observer->onUpdate(Update::Repaint);
}
void Style::onLayerDataDrivenPaintPropertyChanged(Layer& layer) {
layer.accept(QueueSourceReloadVisitor { updateBatch });
- observer->onUpdate(Update::RecalculateStyle | Update::Classes);
+ observer->onUpdate(Update::Repaint);
}
-void Style::onLayerLayoutPropertyChanged(Layer& layer, const char * property) {
+void Style::onLayerLayoutPropertyChanged(Layer& layer, const char *) {
layer.accept(QueueSourceReloadVisitor { updateBatch });
-
- // Recalculate the style for certain properties
- observer->onUpdate((strcmp(property, "icon-size") == 0 || strcmp(property, "text-size") == 0)
- ? Update::RecalculateStyle
- : Update::Repaint);
+ observer->onUpdate(Update::Repaint);
}
void Style::onLightChanged(const Light&) {
- observer->onUpdate(Update::Classes | Update::RecalculateStyle);
+ observer->onUpdate(Update::Repaint);
}
void Style::dumpDebugLogs() const {
for (const auto& source : sources) {
- source->baseImpl->dumpDebugLogs();
+ source->dumpDebugLogs();
}
- for (const auto& renderSource : renderSources) {
- renderSource->dumpDebugLogs();
+ for (const auto& entry : renderSources) {
+ entry.second->dumpDebugLogs();
}
spriteAtlas->dumpDebugLogs();
diff --git a/src/mbgl/style/style.hpp b/src/mbgl/style/style.hpp
index 7d235dc665..04d3a11d55 100644
--- a/src/mbgl/style/style.hpp
+++ b/src/mbgl/style/style.hpp
@@ -3,10 +3,11 @@
#include <mbgl/style/transition_options.hpp>
#include <mbgl/style/observer.hpp>
#include <mbgl/style/source_observer.hpp>
-#include <mbgl/renderer/render_source_observer.hpp>
#include <mbgl/style/layer_observer.hpp>
#include <mbgl/style/light_observer.hpp>
#include <mbgl/style/update_batch.hpp>
+#include <mbgl/renderer/render_source.hpp>
+#include <mbgl/renderer/render_source_observer.hpp>
#include <mbgl/renderer/render_layer.hpp>
#include <mbgl/renderer/render_light.hpp>
#include <mbgl/text/glyph_atlas_observer.hpp>
@@ -35,8 +36,6 @@ class RenderData;
class TransformState;
class RenderedQueryOptions;
class Scheduler;
-class RenderLayer;
-class RenderSource;
class UpdateParameters;
namespace style {
@@ -105,7 +104,7 @@ public:
void setLight(std::unique_ptr<Light>);
Light* getLight() const;
- RenderLight* getRenderLight() const;
+ const RenderLight& getRenderLight() const;
RenderData getRenderData(MapDebugOptions, float angle) const;
@@ -128,15 +127,10 @@ public:
private:
std::vector<std::unique_ptr<Source>> sources;
- std::vector<std::unique_ptr<RenderSource>> renderSources;
-
std::vector<std::unique_ptr<Layer>> layers;
- std::vector<std::unique_ptr<RenderLayer>> renderLayers;
std::vector<std::string> classes;
TransitionOptions transitionOptions;
-
std::unique_ptr<Light> light;
- std::unique_ptr<RenderLight> renderLight;
// Defaults
std::string name;
@@ -145,8 +139,14 @@ private:
double defaultBearing = 0;
double defaultPitch = 0;
+ std::vector<Immutable<Source::Impl>> sourceImpls;
+ std::vector<Immutable<Layer::Impl>> layerImpls;
+
+ std::unordered_map<std::string, std::unique_ptr<RenderSource>> renderSources;
+ std::unordered_map<std::string, std::unique_ptr<RenderLayer>> renderLayers;
+ RenderLight renderLight;
+
std::vector<std::unique_ptr<Layer>>::const_iterator findLayer(const std::string& layerID) const;
- std::vector<std::unique_ptr<RenderLayer>>::const_iterator findRenderLayer(const std::string&) const;
// GlyphStoreObserver implementation.
void onGlyphsLoaded(const FontStack&, const GlyphRange&) override;
@@ -182,8 +182,6 @@ private:
UpdateBatch updateBatch;
ZoomHistory zoomHistory;
- void removeRenderLayer(const std::string& layerID);
-
public:
bool loaded = false;
};
diff --git a/src/mbgl/style/tile_source_impl.cpp b/src/mbgl/style/tile_source_impl.cpp
deleted file mode 100644
index 4d47221da9..0000000000
--- a/src/mbgl/style/tile_source_impl.cpp
+++ /dev/null
@@ -1,78 +0,0 @@
-#include <mbgl/style/tile_source_impl.hpp>
-#include <mbgl/style/source_observer.hpp>
-#include <mbgl/style/conversion/json.hpp>
-#include <mbgl/style/conversion/tileset.hpp>
-#include <mbgl/util/mapbox.hpp>
-#include <mbgl/storage/file_source.hpp>
-
-namespace mbgl {
-namespace style {
-
-TileSourceImpl::TileSourceImpl(SourceType type_, std::string id_, Source& base_,
- variant<std::string, Tileset> urlOrTileset_,
- uint16_t tileSize_)
- : Impl(type_, std::move(id_), base_),
- urlOrTileset(std::move(urlOrTileset_)),
- tileSize(tileSize_) {
-}
-
-TileSourceImpl::~TileSourceImpl() = default;
-
-void TileSourceImpl::loadDescription(FileSource& fileSource) {
- if (urlOrTileset.is<Tileset>()) {
- tileset = urlOrTileset.get<Tileset>();
- loaded = true;
- return;
- }
-
- if (req) {
- return;
- }
-
- const auto& url = urlOrTileset.get<std::string>();
- req = fileSource.request(Resource::source(url), [this, url](Response res) {
- if (res.error) {
- observer->onSourceError(base, std::make_exception_ptr(std::runtime_error(res.error->message)));
- } else if (res.notModified) {
- return;
- } else if (res.noContent) {
- observer->onSourceError(base, std::make_exception_ptr(std::runtime_error("unexpectedly empty TileJSON")));
- } else {
- conversion::Error error;
- optional<Tileset> newTileset = conversion::convertJSON<Tileset>(*res.data, error);
- if (!newTileset) {
- observer->onSourceError(base, std::make_exception_ptr(std::runtime_error(error.message)));
- return;
- }
-
- util::mapbox::canonicalizeTileset(*newTileset, url, type, tileSize);
- bool attributionChanged = tileset.attribution != (*newTileset).attribution;
-
- tileset = *newTileset;
- loaded = true;
-
- observer->onSourceLoaded(base);
- if (attributionChanged) {
- observer->onSourceChanged(base);
- }
- }
- });
-}
-
-optional<Tileset> TileSourceImpl::getTileset() const {
- if (loaded) {
- return tileset;
- }
- return {};
-}
-
-optional<std::string> TileSourceImpl::getAttribution() const {
- if (loaded && !tileset.attribution.empty()) {
- return tileset.attribution;
- } else {
- return {};
- }
-}
-
-} // namespace style
-} // namespace mbgl
diff --git a/src/mbgl/style/tile_source_impl.hpp b/src/mbgl/style/tile_source_impl.hpp
deleted file mode 100644
index 0e5a53add7..0000000000
--- a/src/mbgl/style/tile_source_impl.hpp
+++ /dev/null
@@ -1,47 +0,0 @@
-#pragma once
-
-#include <mbgl/style/source_impl.hpp>
-#include <mbgl/util/tileset.hpp>
-#include <mbgl/util/variant.hpp>
-#include <mbgl/util/optional.hpp>
-
-namespace mbgl {
-
-class AsyncRequest;
-
-namespace style {
-
-/*
- Shared implementation for VectorSource and RasterSource. Should eventually
- be refactored to use composition rather than inheritance.
-*/
-class TileSourceImpl : public Source::Impl {
-public:
- TileSourceImpl(SourceType, std::string id, Source&,
- variant<std::string, Tileset> urlOrTileset,
- uint16_t tileSize);
- ~TileSourceImpl() override;
-
- void loadDescription(FileSource&) final;
-
- uint16_t getTileSize() const {
- return tileSize;
- }
-
- const variant<std::string, Tileset>& getURLOrTileset() const {
- return urlOrTileset;
- }
-
- optional<std::string> getAttribution() const override;
- optional<Tileset> getTileset() const;
-
-protected:
- const variant<std::string, Tileset> urlOrTileset;
- const uint16_t tileSize;
-
- Tileset tileset;
- std::unique_ptr<AsyncRequest> req;
-};
-
-} // namespace style
-} // namespace mbgl
diff --git a/src/mbgl/tile/geometry_tile.cpp b/src/mbgl/tile/geometry_tile.cpp
index 5079a33340..b8dc86555b 100644
--- a/src/mbgl/tile/geometry_tile.cpp
+++ b/src/mbgl/tile/geometry_tile.cpp
@@ -93,10 +93,10 @@ void GeometryTile::redoLayout() {
// state despite pending parse operations.
pending = true;
- std::vector<std::unique_ptr<Layer>> copy;
+ std::vector<Immutable<Layer::Impl>> impls;
for (const Layer* layer : style.getLayers()) {
- // Avoid cloning and including irrelevant layers.
+ // Skip irrelevant layers.
if (layer->is<BackgroundLayer>() ||
layer->is<CustomLayer>() ||
layer->baseImpl->source != sourceID ||
@@ -106,11 +106,11 @@ void GeometryTile::redoLayout() {
continue;
}
- copy.push_back(layer->baseImpl->clone());
+ impls.push_back(layer->baseImpl);
}
++correlationID;
- worker.invoke(&GeometryTileWorker::setLayers, std::move(copy), correlationID);
+ worker.invoke(&GeometryTileWorker::setLayers, std::move(impls), correlationID);
}
void GeometryTile::onLayout(LayoutResult result) {
@@ -160,9 +160,9 @@ void GeometryTile::getIcons(IconDependencies) {
spriteAtlas.getIcons(*this);
}
-Bucket* GeometryTile::getBucket(const RenderLayer& layer) const {
- const auto& buckets = layer.is<RenderSymbolLayer>() ? symbolBuckets : nonSymbolBuckets;
- const auto it = buckets.find(layer.baseImpl.id);
+Bucket* GeometryTile::getBucket(const Layer::Impl& layer) const {
+ const auto& buckets = layer.type == LayerType::Symbol ? symbolBuckets : nonSymbolBuckets;
+ const auto it = buckets.find(layer.id);
if (it == buckets.end()) {
return nullptr;
}
diff --git a/src/mbgl/tile/geometry_tile.hpp b/src/mbgl/tile/geometry_tile.hpp
index 08965b6389..7d275fc72c 100644
--- a/src/mbgl/tile/geometry_tile.hpp
+++ b/src/mbgl/tile/geometry_tile.hpp
@@ -48,7 +48,7 @@ public:
void getGlyphs(GlyphDependencies);
void getIcons(IconDependencies);
- Bucket* getBucket(const RenderLayer&) const override;
+ Bucket* getBucket(const style::Layer::Impl&) const override;
void queryRenderedFeatures(
std::unordered_map<std::string, std::vector<Feature>>& result,
diff --git a/src/mbgl/tile/geometry_tile_worker.cpp b/src/mbgl/tile/geometry_tile_worker.cpp
index 29bfe8d472..788534531d 100644
--- a/src/mbgl/tile/geometry_tile_worker.cpp
+++ b/src/mbgl/tile/geometry_tile_worker.cpp
@@ -91,7 +91,7 @@ void GeometryTileWorker::setData(std::unique_ptr<const GeometryTileData> data_,
}
}
-void GeometryTileWorker::setLayers(std::vector<std::unique_ptr<Layer>> layers_, uint64_t correlationID_) {
+void GeometryTileWorker::setLayers(std::vector<Immutable<Layer::Impl>> layers_, uint64_t correlationID_) {
try {
layers = std::move(layers_);
correlationID = correlationID_;
@@ -242,11 +242,11 @@ void GeometryTileWorker::requestNewIcons(const IconDependencies& iconDependencie
}
}
-static std::vector<std::unique_ptr<RenderLayer>> toRenderLayers(const std::vector<std::unique_ptr<style::Layer>>& layers, float zoom) {
+static std::vector<std::unique_ptr<RenderLayer>> toRenderLayers(const std::vector<Immutable<style::Layer::Impl>>& layers, float zoom) {
std::vector<std::unique_ptr<RenderLayer>> renderLayers;
renderLayers.reserve(layers.size());
for (auto& layer : layers) {
- renderLayers.push_back(layer->baseImpl->createRenderLayer());
+ renderLayers.push_back(layer->createRenderLayer());
renderLayers.back()->cascade(CascadeParameters {
{ ClassID::Default },
@@ -268,8 +268,8 @@ void GeometryTileWorker::redoLayout() {
std::vector<std::string> symbolOrder;
for (auto it = layers->rbegin(); it != layers->rend(); it++) {
- if ((*it)->is<SymbolLayer>()) {
- symbolOrder.push_back((*it)->getID());
+ if ((*it)->type == LayerType::Symbol) {
+ symbolOrder.push_back((*it)->id);
}
}
@@ -296,7 +296,7 @@ void GeometryTileWorker::redoLayout() {
const RenderLayer& leader = *group.at(0);
- auto geometryLayer = (*data)->getLayer(leader.baseImpl.sourceLayer);
+ auto geometryLayer = (*data)->getLayer(leader.baseImpl->sourceLayer);
if (!geometryLayer) {
continue;
}
@@ -312,8 +312,8 @@ void GeometryTileWorker::redoLayout() {
symbolLayoutMap.emplace(leader.getID(),
leader.as<RenderSymbolLayer>()->createLayout(parameters, group, *geometryLayer, glyphDependencies, iconDependencies));
} else {
- const Filter& filter = leader.baseImpl.filter;
- const std::string& sourceLayerID = leader.baseImpl.sourceLayer;
+ const Filter& filter = leader.baseImpl->filter;
+ const std::string& sourceLayerID = leader.baseImpl->sourceLayer;
std::shared_ptr<Bucket> bucket = leader.createBucket(parameters, group);
for (std::size_t i = 0; !obsolete && i < geometryLayer->featureCount(); i++) {
diff --git a/src/mbgl/tile/geometry_tile_worker.hpp b/src/mbgl/tile/geometry_tile_worker.hpp
index 1df1ef43c4..0d4cba04b3 100644
--- a/src/mbgl/tile/geometry_tile_worker.hpp
+++ b/src/mbgl/tile/geometry_tile_worker.hpp
@@ -7,6 +7,8 @@
#include <mbgl/text/placement_config.hpp>
#include <mbgl/actor/actor_ref.hpp>
#include <mbgl/util/optional.hpp>
+#include <mbgl/util/immutable.hpp>
+#include <mbgl/style/layer_impl.hpp>
#include <atomic>
#include <memory>
@@ -32,7 +34,7 @@ public:
const MapMode);
~GeometryTileWorker();
- void setLayers(std::vector<std::unique_ptr<style::Layer>>, uint64_t correlationID);
+ void setLayers(std::vector<Immutable<style::Layer::Impl>>, uint64_t correlationID);
void setData(std::unique_ptr<const GeometryTileData>, uint64_t correlationID);
void setPlacementConfig(PlacementConfig, uint64_t correlationID);
@@ -71,7 +73,7 @@ private:
uint64_t correlationID = 0;
// Outer optional indicates whether we've received it or not.
- optional<std::vector<std::unique_ptr<style::Layer>>> layers;
+ optional<std::vector<Immutable<style::Layer::Impl>>> layers;
optional<std::unique_ptr<const GeometryTileData>> data;
optional<PlacementConfig> placementConfig;
diff --git a/src/mbgl/tile/raster_tile.cpp b/src/mbgl/tile/raster_tile.cpp
index b1a901e565..796517b8fa 100644
--- a/src/mbgl/tile/raster_tile.cpp
+++ b/src/mbgl/tile/raster_tile.cpp
@@ -55,7 +55,7 @@ void RasterTile::onError(std::exception_ptr err) {
observer->onTileError(*this, err);
}
-Bucket* RasterTile::getBucket(const RenderLayer&) const {
+Bucket* RasterTile::getBucket(const style::Layer::Impl&) const {
return bucket.get();
}
diff --git a/src/mbgl/tile/raster_tile.hpp b/src/mbgl/tile/raster_tile.hpp
index e047430485..b4804bdb7d 100644
--- a/src/mbgl/tile/raster_tile.hpp
+++ b/src/mbgl/tile/raster_tile.hpp
@@ -29,7 +29,7 @@ public:
optional<Timestamp> expires_);
void cancel() override;
- Bucket* getBucket(const RenderLayer&) const override;
+ Bucket* getBucket(const style::Layer::Impl&) const override;
void onParsed(std::unique_ptr<Bucket> result);
void onError(std::exception_ptr);
diff --git a/src/mbgl/tile/tile.hpp b/src/mbgl/tile/tile.hpp
index 795fd62140..544717e2b8 100644
--- a/src/mbgl/tile/tile.hpp
+++ b/src/mbgl/tile/tile.hpp
@@ -9,6 +9,7 @@
#include <mbgl/renderer/bucket.hpp>
#include <mbgl/tile/geometry_tile_data.hpp>
#include <mbgl/storage/resource.hpp>
+#include <mbgl/style/layer_impl.hpp>
#include <string>
#include <memory>
@@ -23,10 +24,6 @@ class TileObserver;
class PlacementConfig;
class RenderedQueryOptions;
class SourceQueryOptions;
-class RenderLayer;
-
-namespace style {
-} // namespace style
class Tile : private util::noncopyable {
public:
@@ -47,7 +44,7 @@ public:
// Mark this tile as no longer needed and cancel any pending work.
virtual void cancel() = 0;
- virtual Bucket* getBucket(const RenderLayer&) const = 0;
+ virtual Bucket* getBucket(const style::Layer::Impl&) const = 0;
virtual void setPlacementConfig(const PlacementConfig&) {}
virtual void redoLayout() {}
diff --git a/src/mbgl/util/longest_common_subsequence.hpp b/src/mbgl/util/longest_common_subsequence.hpp
new file mode 100644
index 0000000000..ac127c6356
--- /dev/null
+++ b/src/mbgl/util/longest_common_subsequence.hpp
@@ -0,0 +1,106 @@
+#pragma once
+
+#include <cstddef>
+#include <functional>
+#include <iterator>
+#include <vector>
+
+namespace mbgl {
+
+/*
+ Computes the longest common subsequence (LCS) of sequences A and B, represented
+ by pairs of random access iterators. The result is output to the provided output
+ iterator. Equality of elements is determined by the provided comparator, defaulting
+ to ==.
+
+ The algorithm used is the O(ND) time and space algorithm from:
+
+ Myers, Eugene W. An O(ND) Difference Algorithm and Its Variations. Algorithmica
+ (1986) 1: 251. http://xmailserver.org/diff2.pdf
+
+ For understanding this algorithm, http://simplygenius.net/Article/DiffTutorial1 is
+ also helpful.
+
+ TODO: implement the O(N) space refinement presented in the paper.
+*/
+template <class InIt, class OutIt, class Equal>
+OutIt longest_common_subsequence(InIt a, InIt endA,
+ InIt b, InIt endB,
+ OutIt outIt,
+ Equal eq) {
+ const std::ptrdiff_t N = endA - a;
+ const std::ptrdiff_t M = endB - b;
+ const std::ptrdiff_t D = N + M;
+
+ if (D == 0) {
+ return outIt;
+ }
+
+ std::vector<std::vector<std::ptrdiff_t>> vs;
+
+ // Self-executing lambda to allow `return` to break from inner loop, and avoid shadowing `v`.
+ [&] () {
+ std::vector<std::ptrdiff_t> v;
+ v.resize(2 * D + 1);
+ v[1] = 0;
+
+ // Core of the algorithm: greedily find farthest-reaching D-paths for increasing
+ // values of D. Store the farthest-reaching endpoints found in each iteration for
+ // later reconstructing the LCS.
+ for (std::ptrdiff_t d = 0; d <= D; ++d) {
+ for (std::ptrdiff_t k = -d; k <= d; k += 2) {
+ std::ptrdiff_t x = (k == -d || (k != d && v.at(k - 1 + D) < v.at(k + 1 + D)))
+ ? v.at(k + 1 + D) // moving down
+ : v.at(k - 1 + D) + 1; // moving right
+
+ std::ptrdiff_t y = x - k;
+
+ while (x < N && y < M && eq(a[x], b[y])) {
+ x++;
+ y++;
+ }
+
+ v[k + D] = x;
+
+ if (x >= N && y >= M) {
+ vs.push_back(v);
+ return;
+ }
+ }
+
+ vs.push_back(v);
+ }
+ }();
+
+ std::ptrdiff_t x = N;
+ std::ptrdiff_t y = M;
+
+ using E = typename std::iterator_traits<InIt>::value_type;
+ std::vector<E> lcsReverse;
+
+ // Reconstruct the LCS using the farthest-reaching endpoints stored above.
+ for (std::ptrdiff_t d = vs.size() - 1; x > 0 || y > 0; --d) {
+ const std::vector<std::ptrdiff_t>& v = vs.at(d);
+ const std::ptrdiff_t k = x - y;
+ const bool down = (k == -d || (k != d && v.at(k - 1 + D) < v.at(k + 1 + D)));
+ const std::ptrdiff_t kPrev = down ? k + 1 : k - 1;
+
+ x = v.at(kPrev + D);
+ y = x - kPrev;
+
+ for (std::ptrdiff_t c = v[k + D]; c != (down ? x : x + 1); --c) {
+ lcsReverse.push_back(a[c - 1]);
+ }
+ }
+
+ return std::copy(lcsReverse.rbegin(), lcsReverse.rend(), outIt);
+}
+
+template < typename InIt, typename OutIt >
+OutIt longest_common_subsequence(InIt a, InIt endA,
+ InIt b, InIt endB,
+ OutIt outIt) {
+ return longest_common_subsequence(a, endA, b, endB, outIt, std::equal_to<>());
+}
+
+}
diff --git a/test/style/conversion/layer.test.cpp b/test/style/conversion/layer.test.cpp
index ae8d4058ab..8ca5ed7e2b 100644
--- a/test/style/conversion/layer.test.cpp
+++ b/test/style/conversion/layer.test.cpp
@@ -35,13 +35,13 @@ TEST(StyleConversion, LayerTransition) {
}
})JSON");
- ASSERT_EQ(400ms, *layer->as<BackgroundLayer>()->impl->cascading
+ ASSERT_EQ(400ms, *layer->as<BackgroundLayer>()->impl().cascading
.get<BackgroundColor>().getTransition({}).duration);
- ASSERT_EQ(500ms, *layer->as<BackgroundLayer>()->impl->cascading
+ ASSERT_EQ(500ms, *layer->as<BackgroundLayer>()->impl().cascading
.get<BackgroundColor>().getTransition({}).delay);
- ASSERT_EQ(100ms, *layer->as<BackgroundLayer>()->impl->cascading
+ ASSERT_EQ(100ms, *layer->as<BackgroundLayer>()->impl().cascading
.get<BackgroundColor>().getTransition({"class"}).duration);
- ASSERT_FALSE(bool(layer->as<BackgroundLayer>()->impl->cascading
+ ASSERT_FALSE(bool(layer->as<BackgroundLayer>()->impl().cascading
.get<BackgroundColor>().getTransition({"class"}).delay));
}
diff --git a/test/style/source.test.cpp b/test/style/source.test.cpp
index 9c0d914543..ad28db7c19 100644
--- a/test/style/source.test.cpp
+++ b/test/style/source.test.cpp
@@ -95,8 +95,8 @@ TEST(Source, LoadingFail) {
};
VectorSource source("source", "url");
- source.baseImpl->setObserver(&test.styleObserver);
- source.baseImpl->loadDescription(test.fileSource);
+ source.setObserver(&test.styleObserver);
+ source.loadDescription(test.fileSource);
test.run();
}
@@ -118,8 +118,8 @@ TEST(Source, LoadingCorrupt) {
};
VectorSource source("source", "url");
- source.baseImpl->setObserver(&test.styleObserver);
- source.baseImpl->loadDescription(test.fileSource);
+ source.setObserver(&test.styleObserver);
+ source.loadDescription(test.fileSource);
test.run();
}
@@ -137,10 +137,10 @@ TEST(Source, RasterTileEmpty) {
tileset.tiles = { "tiles" };
RasterSource source("source", tileset, 512);
- source.baseImpl->loadDescription(test.fileSource);
+ source.loadDescription(test.fileSource);
test.renderSourceObserver.tileChanged = [&] (RenderSource& source_, const OverscaledTileID&) {
- EXPECT_EQ("source", source_.baseImpl.id);
+ EXPECT_EQ("source", source_.baseImpl->id);
test.end();
};
@@ -148,9 +148,9 @@ TEST(Source, RasterTileEmpty) {
FAIL() << "Should never be called";
};
- RenderRasterSource renderSource(*source.impl);
- renderSource.setObserver(&test.renderSourceObserver);
- renderSource.updateTiles(test.tileParameters);
+ auto renderSource = source.baseImpl->createRenderSource();
+ renderSource->setObserver(&test.renderSourceObserver);
+ renderSource->updateTiles(test.tileParameters);
test.run();
}
@@ -168,10 +168,10 @@ TEST(Source, VectorTileEmpty) {
tileset.tiles = { "tiles" };
VectorSource source("source", tileset);
- source.baseImpl->loadDescription(test.fileSource);
+ source.loadDescription(test.fileSource);
test.renderSourceObserver.tileChanged = [&] (RenderSource& source_, const OverscaledTileID&) {
- EXPECT_EQ("source", source_.baseImpl.id);
+ EXPECT_EQ("source", source_.baseImpl->id);
test.end();
};
@@ -179,9 +179,9 @@ TEST(Source, VectorTileEmpty) {
FAIL() << "Should never be called";
};
- RenderVectorSource renderSource(*source.impl);
- renderSource.setObserver(&test.renderSourceObserver);
- renderSource.updateTiles(test.tileParameters);
+ auto renderSource = source.baseImpl->createRenderSource();
+ renderSource->setObserver(&test.renderSourceObserver);
+ renderSource->updateTiles(test.tileParameters);
test.run();
}
@@ -201,18 +201,18 @@ TEST(Source, RasterTileFail) {
tileset.tiles = { "tiles" };
RasterSource source("source", tileset, 512);
- source.baseImpl->loadDescription(test.fileSource);
+ source.loadDescription(test.fileSource);
test.renderSourceObserver.tileError = [&] (RenderSource& source_, const OverscaledTileID& tileID, std::exception_ptr error) {
- EXPECT_EQ(SourceType::Raster, source_.baseImpl.type);
+ EXPECT_EQ(SourceType::Raster, source_.baseImpl->type);
EXPECT_EQ(OverscaledTileID(0, 0, 0), tileID);
EXPECT_EQ("Failed by the test case", util::toString(error));
test.end();
};
- RenderRasterSource renderSource(*source.impl);
- renderSource.setObserver(&test.renderSourceObserver);
- renderSource.updateTiles(test.tileParameters);
+ auto renderSource = source.baseImpl->createRenderSource();
+ renderSource->setObserver(&test.renderSourceObserver);
+ renderSource->updateTiles(test.tileParameters);
test.run();
}
@@ -232,18 +232,18 @@ TEST(Source, VectorTileFail) {
tileset.tiles = { "tiles" };
VectorSource source("source", tileset);
- source.baseImpl->loadDescription(test.fileSource);
+ source.loadDescription(test.fileSource);
test.renderSourceObserver.tileError = [&] (RenderSource& source_, const OverscaledTileID& tileID, std::exception_ptr error) {
- EXPECT_EQ(SourceType::Vector, source_.baseImpl.type);
+ EXPECT_EQ(SourceType::Vector, source_.baseImpl->type);
EXPECT_EQ(OverscaledTileID(0, 0, 0), tileID);
EXPECT_EQ("Failed by the test case", util::toString(error));
test.end();
};
- RenderVectorSource renderSource(*source.impl);
- renderSource.setObserver(&test.renderSourceObserver);
- renderSource.updateTiles(test.tileParameters);
+ auto renderSource = source.baseImpl->createRenderSource();
+ renderSource->setObserver(&test.renderSourceObserver);
+ renderSource->updateTiles(test.tileParameters);
test.run();
}
@@ -261,19 +261,19 @@ TEST(Source, RasterTileCorrupt) {
tileset.tiles = { "tiles" };
RasterSource source("source", tileset, 512);
- source.baseImpl->loadDescription(test.fileSource);
+ source.loadDescription(test.fileSource);
test.renderSourceObserver.tileError = [&] (RenderSource& source_, const OverscaledTileID& tileID, std::exception_ptr error) {
- EXPECT_EQ(source_.baseImpl.type, SourceType::Raster);
+ EXPECT_EQ(source_.baseImpl->type, SourceType::Raster);
EXPECT_EQ(OverscaledTileID(0, 0, 0), tileID);
EXPECT_TRUE(bool(error));
// Not asserting on platform-specific error text.
test.end();
};
- RenderRasterSource renderSource(*source.impl);
- renderSource.setObserver(&test.renderSourceObserver);
- renderSource.updateTiles(test.tileParameters);
+ auto renderSource = source.baseImpl->createRenderSource();
+ renderSource->setObserver(&test.renderSourceObserver);
+ renderSource->updateTiles(test.tileParameters);
test.run();
}
@@ -296,18 +296,18 @@ TEST(Source, VectorTileCorrupt) {
tileset.tiles = { "tiles" };
VectorSource source("source", tileset);
- source.baseImpl->loadDescription(test.fileSource);
+ source.loadDescription(test.fileSource);
test.renderSourceObserver.tileError = [&] (RenderSource& source_, const OverscaledTileID& tileID, std::exception_ptr error) {
- EXPECT_EQ(source_.baseImpl.type, SourceType::Vector);
+ EXPECT_EQ(source_.baseImpl->type, SourceType::Vector);
EXPECT_EQ(OverscaledTileID(0, 0, 0), tileID);
EXPECT_EQ(util::toString(error), "unknown pbf field type exception");
test.end();
};
- RenderVectorSource renderSource(*source.impl);
- renderSource.setObserver(&test.renderSourceObserver);
- renderSource.updateTiles(test.tileParameters);
+ auto renderSource = source.baseImpl->createRenderSource();
+ renderSource->setObserver(&test.renderSourceObserver);
+ renderSource->updateTiles(test.tileParameters);
test.run();
}
@@ -324,7 +324,7 @@ TEST(Source, RasterTileCancel) {
tileset.tiles = { "tiles" };
RasterSource source("source", tileset, 512);
- source.baseImpl->loadDescription(test.fileSource);
+ source.loadDescription(test.fileSource);
test.renderSourceObserver.tileChanged = [&] (RenderSource&, const OverscaledTileID&) {
FAIL() << "Should never be called";
@@ -334,9 +334,9 @@ TEST(Source, RasterTileCancel) {
FAIL() << "Should never be called";
};
- RenderRasterSource renderSource(*source.impl);
- renderSource.setObserver(&test.renderSourceObserver);
- renderSource.updateTiles(test.tileParameters);
+ auto renderSource = source.baseImpl->createRenderSource();
+ renderSource->setObserver(&test.renderSourceObserver);
+ renderSource->updateTiles(test.tileParameters);
test.run();
}
@@ -353,7 +353,7 @@ TEST(Source, VectorTileCancel) {
tileset.tiles = { "tiles" };
VectorSource source("source", tileset);
- source.baseImpl->loadDescription(test.fileSource);
+ source.loadDescription(test.fileSource);
test.renderSourceObserver.tileChanged = [&] (RenderSource&, const OverscaledTileID&) {
FAIL() << "Should never be called";
@@ -363,9 +363,9 @@ TEST(Source, VectorTileCancel) {
FAIL() << "Should never be called";
};
- RenderVectorSource renderSource(*source.impl);
- renderSource.setObserver(&test.renderSourceObserver);
- renderSource.updateTiles(test.tileParameters);
+ auto renderSource = source.baseImpl->createRenderSource();
+ renderSource->setObserver(&test.renderSourceObserver);
+ renderSource->updateTiles(test.tileParameters);
test.run();
}
@@ -398,11 +398,11 @@ TEST(Source, RasterTileAttribution) {
};
RasterSource source("source", "url", 512);
- source.baseImpl->setObserver(&test.styleObserver);
- source.baseImpl->loadDescription(test.fileSource);
+ source.setObserver(&test.styleObserver);
+ source.loadDescription(test.fileSource);
- RenderRasterSource renderSource(*source.impl);
- renderSource.updateTiles(test.tileParameters);
+ auto renderSource = source.baseImpl->createRenderSource();
+ renderSource->updateTiles(test.tileParameters);
test.run();
}
@@ -423,10 +423,10 @@ TEST(Source, GeoJSonSourceUrlUpdate) {
};
GeoJSONSource source("source");
- source.baseImpl->setObserver(&test.styleObserver);
+ source.setObserver(&test.styleObserver);
// Load initial, so the source state will be loaded=true
- source.baseImpl->loadDescription(test.fileSource);
+ source.loadDescription(test.fileSource);
// Schedule an update
test.loop.invoke([&] () {
diff --git a/test/style/style_layer.test.cpp b/test/style/style_layer.test.cpp
index 657dc24a70..2a8379bf20 100644
--- a/test/style/style_layer.test.cpp
+++ b/test/style/style_layer.test.cpp
@@ -28,15 +28,6 @@ using namespace mbgl::style;
namespace {
-template <class T, class... Params> void testClone(Params... params) {
- auto layer = std::make_unique<T>(std::forward<Params>(params)...);
- auto clone = layer->baseImpl->clone();
- EXPECT_NE(layer.get(), clone.get());
- EXPECT_TRUE(reinterpret_cast<typename T::Impl*>(clone->baseImpl.get()));
- layer->impl->id = "test";
- EXPECT_EQ("test", layer->baseImpl->clone()->getID());
-}
-
const auto color = Color { 1, 0, 0, 1 };
const auto opacity = 1.0f;
const auto radius = 1.0f;
@@ -61,16 +52,6 @@ const auto duration = 1.0f;
} // namespace
-TEST(Layer, Clone) {
- testClone<BackgroundLayer>("background");
- testClone<CircleLayer>("circle", "source");
- testClone<CustomLayer>("custom", [](void*){}, [](void*, const CustomLayerRenderParameters&){}, [](void*){}, nullptr),
- testClone<FillLayer>("fill", "source");
- testClone<LineLayer>("line", "source");
- testClone<RasterLayer>("raster", "source");
- testClone<SymbolLayer>("symbol", "source");
-}
-
TEST(Layer, BackgroundProperties) {
auto layer = std::make_unique<BackgroundLayer>("background");
EXPECT_TRUE(layer->is<BackgroundLayer>());
@@ -222,7 +203,7 @@ TEST(Layer, RasterProperties) {
TEST(Layer, Observer) {
auto layer = std::make_unique<LineLayer>("line", "source");
StubLayerObserver observer;
- layer->baseImpl->setObserver(&observer);
+ layer->setObserver(&observer);
// Notifies observer on filter change.
bool filterChanged = false;
diff --git a/test/tile/geojson_tile.test.cpp b/test/tile/geojson_tile.test.cpp
index a0383f06c9..8669c02dfd 100644
--- a/test/tile/geojson_tile.test.cpp
+++ b/test/tile/geojson_tile.test.cpp
@@ -55,7 +55,7 @@ TEST(GeoJSONTile, Issue7648) {
observer.tileChanged = [&] (const Tile&) {
// Once present, the bucket should never "disappear", which would cause
// flickering.
- ASSERT_NE(nullptr, tile.getBucket(*test.style.getRenderLayer("circle")));
+ ASSERT_NE(nullptr, tile.getBucket(*test.style.getLayer("circle")->baseImpl));
};
tile.setObserver(&observer);
diff --git a/test/tile/vector_tile.test.cpp b/test/tile/vector_tile.test.cpp
index 37bfe8512d..a966f3b706 100644
--- a/test/tile/vector_tile.test.cpp
+++ b/test/tile/vector_tile.test.cpp
@@ -89,7 +89,7 @@ TEST(VectorTile, Issue7615) {
0
});
- EXPECT_EQ(symbolBucket.get(), tile.getBucket(*symbolLayer.baseImpl->createRenderLayer()));
+ EXPECT_EQ(symbolBucket.get(), tile.getBucket(*symbolLayer.baseImpl));
}
TEST(VectorTile, Issue8542) {