1 | #pragma once |
2 | |
3 | #include <mbgl/util/noncopyable.hpp> |
4 | #include <mbgl/util/unique_any.hpp> |
5 | #include <mbgl/util/immutable.hpp> |
6 | #include <mbgl/style/layer_type.hpp> |
7 | #include <mbgl/style/types.hpp> |
8 | |
9 | #include <cassert> |
10 | #include <memory> |
11 | #include <string> |
12 | #include <stdexcept> |
13 | |
14 | namespace mbgl { |
15 | namespace style { |
16 | |
17 | class FillLayer; |
18 | class LineLayer; |
19 | class CircleLayer; |
20 | class SymbolLayer; |
21 | class RasterLayer; |
22 | class HillshadeLayer; |
23 | class BackgroundLayer; |
24 | class CustomLayer; |
25 | class FillExtrusionLayer; |
26 | class HeatmapLayer; |
27 | class LayerObserver; |
28 | |
29 | /** |
30 | * The runtime representation of a [layer](https://www.mapbox.com/mapbox-gl-style-spec/#layers) from the Mapbox Style |
31 | * Specification. |
32 | * |
33 | * `Layer` is an abstract base class; concrete derived classes are provided for each layer type. `Layer` contains |
34 | * functionality that is common to all layer types: |
35 | * |
36 | * * Runtime type information: type predicates and casting |
37 | * * Accessors for properties common to all layer types: ID, visibility, etc. |
38 | * * Cloning and copying |
39 | * |
40 | * All other functionality lives in the derived classes. To instantiate a layer, create an instance of the desired |
41 | * type, passing the ID: |
42 | * |
43 | * auto circleLayer = std::make_unique<CircleLayer>("my-circle-layer"); |
44 | */ |
45 | class Layer : public mbgl::util::noncopyable { |
46 | public: |
47 | virtual ~Layer(); |
48 | |
49 | // Check whether this layer is of the given subtype. |
50 | template <class T> |
51 | bool is() const; |
52 | |
53 | // Dynamically cast this layer to the given subtype. |
54 | template <class T> |
55 | T* as() { |
56 | return is<T>() ? reinterpret_cast<T*>(this) : nullptr; |
57 | } |
58 | |
59 | template <class T> |
60 | const T* as() const { |
61 | return is<T>() ? reinterpret_cast<const T*>(this) : nullptr; |
62 | } |
63 | |
64 | // Convenience method for dynamic dispatch on the concrete layer type. Using |
65 | // method overloading, this allows consolidation of logic common to vector-based |
66 | // layers (Fill, FillExtrusion, Line, Circle, or Symbol). For example: |
67 | // |
68 | // struct Visitor { |
69 | // void operator()(CustomLayer&) { ... } |
70 | // void operator()(RasterLayer&) { ... } |
71 | // void operator()(BackgroundLayer&) { ... } |
72 | // template <class VectorLayer> |
73 | // void operator()(VectorLayer&) { ... } |
74 | // }; |
75 | // |
76 | template <class V> |
77 | auto accept(V&& visitor) { |
78 | switch (getType()) { |
79 | case LayerType::Fill: |
80 | return std::forward<V>(visitor)(*as<FillLayer>()); |
81 | case LayerType::Line: |
82 | return std::forward<V>(visitor)(*as<LineLayer>()); |
83 | case LayerType::Circle: |
84 | return std::forward<V>(visitor)(*as<CircleLayer>()); |
85 | case LayerType::Symbol: |
86 | return std::forward<V>(visitor)(*as<SymbolLayer>()); |
87 | case LayerType::Raster: |
88 | return std::forward<V>(visitor)(*as<RasterLayer>()); |
89 | case LayerType::Background: |
90 | return std::forward<V>(visitor)(*as<BackgroundLayer>()); |
91 | case LayerType::Hillshade: |
92 | return std::forward<V>(visitor)(*as<HillshadeLayer>()); |
93 | case LayerType::Custom: |
94 | return std::forward<V>(visitor)(*as<CustomLayer>()); |
95 | case LayerType::FillExtrusion: |
96 | return std::forward<V>(visitor)(*as<FillExtrusionLayer>()); |
97 | case LayerType::Heatmap: |
98 | return std::forward<V>(visitor)(*as<HeatmapLayer>()); |
99 | } |
100 | |
101 | |
102 | // Not reachable, but placate GCC. |
103 | assert(false); |
104 | throw new std::runtime_error("unknown layer type" ); |
105 | } |
106 | |
107 | LayerType getType() const; |
108 | std::string getID() const; |
109 | |
110 | // Visibility |
111 | VisibilityType getVisibility() const; |
112 | virtual void setVisibility(VisibilityType) = 0; |
113 | |
114 | // Zoom range |
115 | float getMinZoom() const; |
116 | float getMaxZoom() const; |
117 | virtual void setMinZoom(float) = 0; |
118 | virtual void setMaxZoom(float) = 0; |
119 | |
120 | // Private implementation |
121 | class Impl; |
122 | Immutable<Impl> baseImpl; |
123 | |
124 | Layer(Immutable<Impl>); |
125 | |
126 | // Create a layer, copying all properties except id and paint properties from this layer. |
127 | virtual std::unique_ptr<Layer> cloneRef(const std::string& id) const = 0; |
128 | |
129 | LayerObserver* observer = nullptr; |
130 | void setObserver(LayerObserver*); |
131 | |
132 | // For use in SDK bindings, which store a reference to a platform-native peer |
133 | // object here, so that separately-obtained references to this object share |
134 | // identical platform-native peers. |
135 | util::unique_any peer; |
136 | }; |
137 | |
138 | } // namespace style |
139 | } // namespace mbgl |
140 | |