diff options
Diffstat (limited to 'src/mbgl/style')
24 files changed, 398 insertions, 357 deletions
diff --git a/src/mbgl/style/conversion/stringify.hpp b/src/mbgl/style/conversion/stringify.hpp index 4afbf198e5..6ae6fede42 100644 --- a/src/mbgl/style/conversion/stringify.hpp +++ b/src/mbgl/style/conversion/stringify.hpp @@ -2,7 +2,7 @@ #include <mbgl/style/filter.hpp> #include <mbgl/style/property_value.hpp> -#include <mbgl/style/layout_property.hpp> +#include <mbgl/style/data_driven_property_value.hpp> #include <mbgl/util/enum.hpp> #include <mbgl/util/color.hpp> #include <mbgl/util/feature.hpp> @@ -446,13 +446,6 @@ void stringify(Writer& writer, const DataDrivenPropertyValue<T>& value) { } } -template <class Writer, class... Ps> -void stringify(Writer& writer, const LayoutProperties<Ps...>& ps) { - writer.StartObject(); - util::ignore({ (stringify<Ps>(writer, ps.unevaluated.template get<Ps>()), 0)... }); - writer.EndObject(); -} - } // namespace conversion } // namespace style } // namespace mbgl diff --git a/src/mbgl/style/layers/background_layer.cpp b/src/mbgl/style/layers/background_layer.cpp index 2aa15a779c..1c5b6c3a66 100644 --- a/src/mbgl/style/layers/background_layer.cpp +++ b/src/mbgl/style/layers/background_layer.cpp @@ -2,7 +2,6 @@ #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 { diff --git a/src/mbgl/style/layers/background_layer_properties.hpp b/src/mbgl/style/layers/background_layer_properties.hpp index fae6c26a4b..f9a67b214d 100644 --- a/src/mbgl/style/layers/background_layer_properties.hpp +++ b/src/mbgl/style/layers/background_layer_properties.hpp @@ -5,6 +5,7 @@ #include <mbgl/style/types.hpp> #include <mbgl/style/layout_property.hpp> #include <mbgl/style/paint_property.hpp> +#include <mbgl/style/properties.hpp> #include <mbgl/programs/attributes.hpp> namespace mbgl { @@ -22,7 +23,7 @@ struct BackgroundOpacity : PaintProperty<float> { static float defaultValue() { return 1; } }; -class BackgroundPaintProperties : public PaintProperties< +class BackgroundPaintProperties : public Properties< BackgroundColor, BackgroundPattern, BackgroundOpacity diff --git a/src/mbgl/style/layers/circle_layer.cpp b/src/mbgl/style/layers/circle_layer.cpp index ea812748d0..e874f00ff7 100644 --- a/src/mbgl/style/layers/circle_layer.cpp +++ b/src/mbgl/style/layers/circle_layer.cpp @@ -2,7 +2,6 @@ #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 { diff --git a/src/mbgl/style/layers/circle_layer_properties.hpp b/src/mbgl/style/layers/circle_layer_properties.hpp index 1cb4f5a635..734dab109c 100644 --- a/src/mbgl/style/layers/circle_layer_properties.hpp +++ b/src/mbgl/style/layers/circle_layer_properties.hpp @@ -5,6 +5,7 @@ #include <mbgl/style/types.hpp> #include <mbgl/style/layout_property.hpp> #include <mbgl/style/paint_property.hpp> +#include <mbgl/style/properties.hpp> #include <mbgl/programs/attributes.hpp> namespace mbgl { @@ -50,7 +51,7 @@ struct CircleStrokeOpacity : DataDrivenPaintProperty<float, attributes::a_stroke static float defaultValue() { return 1; } }; -class CirclePaintProperties : public PaintProperties< +class CirclePaintProperties : public Properties< CircleRadius, CircleColor, CircleBlur, diff --git a/src/mbgl/style/layers/fill_extrusion_layer.cpp b/src/mbgl/style/layers/fill_extrusion_layer.cpp index 9a2ec36e15..cff0c59df2 100644 --- a/src/mbgl/style/layers/fill_extrusion_layer.cpp +++ b/src/mbgl/style/layers/fill_extrusion_layer.cpp @@ -2,7 +2,6 @@ #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 { diff --git a/src/mbgl/style/layers/fill_extrusion_layer_properties.hpp b/src/mbgl/style/layers/fill_extrusion_layer_properties.hpp index c1dd3b079d..1819f98ae6 100644 --- a/src/mbgl/style/layers/fill_extrusion_layer_properties.hpp +++ b/src/mbgl/style/layers/fill_extrusion_layer_properties.hpp @@ -5,6 +5,7 @@ #include <mbgl/style/types.hpp> #include <mbgl/style/layout_property.hpp> #include <mbgl/style/paint_property.hpp> +#include <mbgl/style/properties.hpp> #include <mbgl/programs/attributes.hpp> namespace mbgl { @@ -38,7 +39,7 @@ struct FillExtrusionBase : DataDrivenPaintProperty<float, attributes::a_base> { static float defaultValue() { return 0; } }; -class FillExtrusionPaintProperties : public PaintProperties< +class FillExtrusionPaintProperties : public Properties< FillExtrusionOpacity, FillExtrusionColor, FillExtrusionTranslate, diff --git a/src/mbgl/style/layers/fill_layer.cpp b/src/mbgl/style/layers/fill_layer.cpp index 0031972842..d38b027740 100644 --- a/src/mbgl/style/layers/fill_layer.cpp +++ b/src/mbgl/style/layers/fill_layer.cpp @@ -2,7 +2,6 @@ #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 { diff --git a/src/mbgl/style/layers/fill_layer_properties.hpp b/src/mbgl/style/layers/fill_layer_properties.hpp index f44a18d0e0..67c2ae1fa4 100644 --- a/src/mbgl/style/layers/fill_layer_properties.hpp +++ b/src/mbgl/style/layers/fill_layer_properties.hpp @@ -5,6 +5,7 @@ #include <mbgl/style/types.hpp> #include <mbgl/style/layout_property.hpp> #include <mbgl/style/paint_property.hpp> +#include <mbgl/style/properties.hpp> #include <mbgl/programs/attributes.hpp> namespace mbgl { @@ -38,7 +39,7 @@ struct FillPattern : CrossFadedPaintProperty<std::string> { static std::string defaultValue() { return ""; } }; -class FillPaintProperties : public PaintProperties< +class FillPaintProperties : public Properties< FillAntialias, FillOpacity, FillColor, diff --git a/src/mbgl/style/layers/layer.cpp.ejs b/src/mbgl/style/layers/layer.cpp.ejs index b07f7db307..738165e668 100644 --- a/src/mbgl/style/layers/layer.cpp.ejs +++ b/src/mbgl/style/layers/layer.cpp.ejs @@ -7,7 +7,6 @@ #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 { @@ -46,7 +45,7 @@ std::unique_ptr<Layer> <%- camelize(type) %>Layer::cloneRef(const std::string& i <% if (layoutProperties.length) { -%> void <%- camelize(type) %>Layer::Impl::stringifyLayout(rapidjson::Writer<rapidjson::StringBuffer>& writer) const { - conversion::stringify(writer, layout); + layout.stringify(writer); } <% } else { -%> void <%- camelize(type) %>Layer::Impl::stringifyLayout(rapidjson::Writer<rapidjson::StringBuffer>&) const { @@ -119,14 +118,14 @@ void <%- camelize(type) %>Layer::setMaxZoom(float maxZoom) { } <%- propertyValueType(property) %> <%- camelize(type) %>Layer::get<%- camelize(property.name) %>() const { - return impl().layout.unevaluated.get<<%- camelize(property.name) %>>(); + return impl().layout.get<<%- camelize(property.name) %>>(); } void <%- camelize(type) %>Layer::set<%- camelize(property.name) %>(<%- propertyValueType(property) %> value) { if (value == get<%- camelize(property.name) %>()) return; auto impl_ = mutableImpl(); - impl_->layout.unevaluated.get<<%- camelize(property.name) %>>() = value; + impl_->layout.get<<%- camelize(property.name) %>>() = value; baseImpl = std::move(impl_); observer->onLayerLayoutPropertyChanged(*this, "<%- property.name %>"); } diff --git a/src/mbgl/style/layers/layer_properties.hpp.ejs b/src/mbgl/style/layers/layer_properties.hpp.ejs index 2a736ca388..a271a27e8d 100644 --- a/src/mbgl/style/layers/layer_properties.hpp.ejs +++ b/src/mbgl/style/layers/layer_properties.hpp.ejs @@ -10,6 +10,7 @@ #include <mbgl/style/types.hpp> #include <mbgl/style/layout_property.hpp> #include <mbgl/style/paint_property.hpp> +#include <mbgl/style/properties.hpp> #include <mbgl/programs/attributes.hpp> namespace mbgl { @@ -29,7 +30,7 @@ struct <%- camelize(property.name) %> : <%- paintPropertyType(property, type) %> <% } -%> <% if (layoutProperties.length) { -%> -class <%- camelize(type) %>LayoutProperties : public LayoutProperties< +class <%- camelize(type) %>LayoutProperties : public Properties< <% for (const property of layoutProperties.slice(0, -1)) { -%> <%- camelize(property.name) %>, <% } -%> @@ -37,7 +38,7 @@ class <%- camelize(type) %>LayoutProperties : public LayoutProperties< > {}; <% } -%> -class <%- camelize(type) %>PaintProperties : public PaintProperties< +class <%- camelize(type) %>PaintProperties : public Properties< <% for (const property of paintProperties.slice(0, -1)) { -%> <%- camelize(property.name) %>, <% } -%> diff --git a/src/mbgl/style/layers/line_layer.cpp b/src/mbgl/style/layers/line_layer.cpp index 359078f913..c8684ec6f5 100644 --- a/src/mbgl/style/layers/line_layer.cpp +++ b/src/mbgl/style/layers/line_layer.cpp @@ -2,7 +2,6 @@ #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 { @@ -34,7 +33,7 @@ std::unique_ptr<Layer> LineLayer::cloneRef(const std::string& id_) const { } void LineLayer::Impl::stringifyLayout(rapidjson::Writer<rapidjson::StringBuffer>& writer) const { - conversion::stringify(writer, layout); + layout.stringify(writer); } // Source @@ -98,14 +97,14 @@ PropertyValue<LineCapType> LineLayer::getDefaultLineCap() { } PropertyValue<LineCapType> LineLayer::getLineCap() const { - return impl().layout.unevaluated.get<LineCap>(); + return impl().layout.get<LineCap>(); } void LineLayer::setLineCap(PropertyValue<LineCapType> value) { if (value == getLineCap()) return; auto impl_ = mutableImpl(); - impl_->layout.unevaluated.get<LineCap>() = value; + impl_->layout.get<LineCap>() = value; baseImpl = std::move(impl_); observer->onLayerLayoutPropertyChanged(*this, "line-cap"); } @@ -114,14 +113,14 @@ PropertyValue<LineJoinType> LineLayer::getDefaultLineJoin() { } PropertyValue<LineJoinType> LineLayer::getLineJoin() const { - return impl().layout.unevaluated.get<LineJoin>(); + return impl().layout.get<LineJoin>(); } void LineLayer::setLineJoin(PropertyValue<LineJoinType> value) { if (value == getLineJoin()) return; auto impl_ = mutableImpl(); - impl_->layout.unevaluated.get<LineJoin>() = value; + impl_->layout.get<LineJoin>() = value; baseImpl = std::move(impl_); observer->onLayerLayoutPropertyChanged(*this, "line-join"); } @@ -130,14 +129,14 @@ PropertyValue<float> LineLayer::getDefaultLineMiterLimit() { } PropertyValue<float> LineLayer::getLineMiterLimit() const { - return impl().layout.unevaluated.get<LineMiterLimit>(); + return impl().layout.get<LineMiterLimit>(); } void LineLayer::setLineMiterLimit(PropertyValue<float> value) { if (value == getLineMiterLimit()) return; auto impl_ = mutableImpl(); - impl_->layout.unevaluated.get<LineMiterLimit>() = value; + impl_->layout.get<LineMiterLimit>() = value; baseImpl = std::move(impl_); observer->onLayerLayoutPropertyChanged(*this, "line-miter-limit"); } @@ -146,14 +145,14 @@ PropertyValue<float> LineLayer::getDefaultLineRoundLimit() { } PropertyValue<float> LineLayer::getLineRoundLimit() const { - return impl().layout.unevaluated.get<LineRoundLimit>(); + return impl().layout.get<LineRoundLimit>(); } void LineLayer::setLineRoundLimit(PropertyValue<float> value) { if (value == getLineRoundLimit()) return; auto impl_ = mutableImpl(); - impl_->layout.unevaluated.get<LineRoundLimit>() = value; + impl_->layout.get<LineRoundLimit>() = value; baseImpl = std::move(impl_); observer->onLayerLayoutPropertyChanged(*this, "line-round-limit"); } diff --git a/src/mbgl/style/layers/line_layer_impl.hpp b/src/mbgl/style/layers/line_layer_impl.hpp index 8328378a1f..2eab19a612 100644 --- a/src/mbgl/style/layers/line_layer_impl.hpp +++ b/src/mbgl/style/layers/line_layer_impl.hpp @@ -13,7 +13,7 @@ public: void stringifyLayout(rapidjson::Writer<rapidjson::StringBuffer>&) const override; - LineLayoutProperties layout; + LineLayoutProperties::Unevaluated layout; LinePaintProperties::Cascading paint; }; diff --git a/src/mbgl/style/layers/line_layer_properties.hpp b/src/mbgl/style/layers/line_layer_properties.hpp index 724026e3a6..62acad295b 100644 --- a/src/mbgl/style/layers/line_layer_properties.hpp +++ b/src/mbgl/style/layers/line_layer_properties.hpp @@ -5,6 +5,7 @@ #include <mbgl/style/types.hpp> #include <mbgl/style/layout_property.hpp> #include <mbgl/style/paint_property.hpp> +#include <mbgl/style/properties.hpp> #include <mbgl/programs/attributes.hpp> namespace mbgl { @@ -70,14 +71,14 @@ struct LinePattern : CrossFadedPaintProperty<std::string> { static std::string defaultValue() { return ""; } }; -class LineLayoutProperties : public LayoutProperties< +class LineLayoutProperties : public Properties< LineCap, LineJoin, LineMiterLimit, LineRoundLimit > {}; -class LinePaintProperties : public PaintProperties< +class LinePaintProperties : public Properties< LineOpacity, LineColor, LineTranslate, diff --git a/src/mbgl/style/layers/raster_layer.cpp b/src/mbgl/style/layers/raster_layer.cpp index fb31d97657..a17e34dd8a 100644 --- a/src/mbgl/style/layers/raster_layer.cpp +++ b/src/mbgl/style/layers/raster_layer.cpp @@ -2,7 +2,6 @@ #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 { diff --git a/src/mbgl/style/layers/raster_layer_properties.hpp b/src/mbgl/style/layers/raster_layer_properties.hpp index 219fe34d8c..732f5b2aff 100644 --- a/src/mbgl/style/layers/raster_layer_properties.hpp +++ b/src/mbgl/style/layers/raster_layer_properties.hpp @@ -5,6 +5,7 @@ #include <mbgl/style/types.hpp> #include <mbgl/style/layout_property.hpp> #include <mbgl/style/paint_property.hpp> +#include <mbgl/style/properties.hpp> #include <mbgl/programs/attributes.hpp> namespace mbgl { @@ -38,7 +39,7 @@ struct RasterFadeDuration : PaintProperty<float> { static float defaultValue() { return 300; } }; -class RasterPaintProperties : public PaintProperties< +class RasterPaintProperties : public Properties< RasterOpacity, RasterHueRotate, RasterBrightnessMin, diff --git a/src/mbgl/style/layers/symbol_layer.cpp b/src/mbgl/style/layers/symbol_layer.cpp index 75de1bb36b..4a3ad2ffcc 100644 --- a/src/mbgl/style/layers/symbol_layer.cpp +++ b/src/mbgl/style/layers/symbol_layer.cpp @@ -2,7 +2,6 @@ #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 { @@ -34,7 +33,7 @@ std::unique_ptr<Layer> SymbolLayer::cloneRef(const std::string& id_) const { } void SymbolLayer::Impl::stringifyLayout(rapidjson::Writer<rapidjson::StringBuffer>& writer) const { - conversion::stringify(writer, layout); + layout.stringify(writer); } // Source @@ -98,14 +97,14 @@ PropertyValue<SymbolPlacementType> SymbolLayer::getDefaultSymbolPlacement() { } PropertyValue<SymbolPlacementType> SymbolLayer::getSymbolPlacement() const { - return impl().layout.unevaluated.get<SymbolPlacement>(); + return impl().layout.get<SymbolPlacement>(); } void SymbolLayer::setSymbolPlacement(PropertyValue<SymbolPlacementType> value) { if (value == getSymbolPlacement()) return; auto impl_ = mutableImpl(); - impl_->layout.unevaluated.get<SymbolPlacement>() = value; + impl_->layout.get<SymbolPlacement>() = value; baseImpl = std::move(impl_); observer->onLayerLayoutPropertyChanged(*this, "symbol-placement"); } @@ -114,14 +113,14 @@ PropertyValue<float> SymbolLayer::getDefaultSymbolSpacing() { } PropertyValue<float> SymbolLayer::getSymbolSpacing() const { - return impl().layout.unevaluated.get<SymbolSpacing>(); + return impl().layout.get<SymbolSpacing>(); } void SymbolLayer::setSymbolSpacing(PropertyValue<float> value) { if (value == getSymbolSpacing()) return; auto impl_ = mutableImpl(); - impl_->layout.unevaluated.get<SymbolSpacing>() = value; + impl_->layout.get<SymbolSpacing>() = value; baseImpl = std::move(impl_); observer->onLayerLayoutPropertyChanged(*this, "symbol-spacing"); } @@ -130,14 +129,14 @@ PropertyValue<bool> SymbolLayer::getDefaultSymbolAvoidEdges() { } PropertyValue<bool> SymbolLayer::getSymbolAvoidEdges() const { - return impl().layout.unevaluated.get<SymbolAvoidEdges>(); + return impl().layout.get<SymbolAvoidEdges>(); } void SymbolLayer::setSymbolAvoidEdges(PropertyValue<bool> value) { if (value == getSymbolAvoidEdges()) return; auto impl_ = mutableImpl(); - impl_->layout.unevaluated.get<SymbolAvoidEdges>() = value; + impl_->layout.get<SymbolAvoidEdges>() = value; baseImpl = std::move(impl_); observer->onLayerLayoutPropertyChanged(*this, "symbol-avoid-edges"); } @@ -146,14 +145,14 @@ PropertyValue<bool> SymbolLayer::getDefaultIconAllowOverlap() { } PropertyValue<bool> SymbolLayer::getIconAllowOverlap() const { - return impl().layout.unevaluated.get<IconAllowOverlap>(); + return impl().layout.get<IconAllowOverlap>(); } void SymbolLayer::setIconAllowOverlap(PropertyValue<bool> value) { if (value == getIconAllowOverlap()) return; auto impl_ = mutableImpl(); - impl_->layout.unevaluated.get<IconAllowOverlap>() = value; + impl_->layout.get<IconAllowOverlap>() = value; baseImpl = std::move(impl_); observer->onLayerLayoutPropertyChanged(*this, "icon-allow-overlap"); } @@ -162,14 +161,14 @@ PropertyValue<bool> SymbolLayer::getDefaultIconIgnorePlacement() { } PropertyValue<bool> SymbolLayer::getIconIgnorePlacement() const { - return impl().layout.unevaluated.get<IconIgnorePlacement>(); + return impl().layout.get<IconIgnorePlacement>(); } void SymbolLayer::setIconIgnorePlacement(PropertyValue<bool> value) { if (value == getIconIgnorePlacement()) return; auto impl_ = mutableImpl(); - impl_->layout.unevaluated.get<IconIgnorePlacement>() = value; + impl_->layout.get<IconIgnorePlacement>() = value; baseImpl = std::move(impl_); observer->onLayerLayoutPropertyChanged(*this, "icon-ignore-placement"); } @@ -178,14 +177,14 @@ PropertyValue<bool> SymbolLayer::getDefaultIconOptional() { } PropertyValue<bool> SymbolLayer::getIconOptional() const { - return impl().layout.unevaluated.get<IconOptional>(); + return impl().layout.get<IconOptional>(); } void SymbolLayer::setIconOptional(PropertyValue<bool> value) { if (value == getIconOptional()) return; auto impl_ = mutableImpl(); - impl_->layout.unevaluated.get<IconOptional>() = value; + impl_->layout.get<IconOptional>() = value; baseImpl = std::move(impl_); observer->onLayerLayoutPropertyChanged(*this, "icon-optional"); } @@ -194,14 +193,14 @@ PropertyValue<AlignmentType> SymbolLayer::getDefaultIconRotationAlignment() { } PropertyValue<AlignmentType> SymbolLayer::getIconRotationAlignment() const { - return impl().layout.unevaluated.get<IconRotationAlignment>(); + return impl().layout.get<IconRotationAlignment>(); } void SymbolLayer::setIconRotationAlignment(PropertyValue<AlignmentType> value) { if (value == getIconRotationAlignment()) return; auto impl_ = mutableImpl(); - impl_->layout.unevaluated.get<IconRotationAlignment>() = value; + impl_->layout.get<IconRotationAlignment>() = value; baseImpl = std::move(impl_); observer->onLayerLayoutPropertyChanged(*this, "icon-rotation-alignment"); } @@ -210,14 +209,14 @@ DataDrivenPropertyValue<float> SymbolLayer::getDefaultIconSize() { } DataDrivenPropertyValue<float> SymbolLayer::getIconSize() const { - return impl().layout.unevaluated.get<IconSize>(); + return impl().layout.get<IconSize>(); } void SymbolLayer::setIconSize(DataDrivenPropertyValue<float> value) { if (value == getIconSize()) return; auto impl_ = mutableImpl(); - impl_->layout.unevaluated.get<IconSize>() = value; + impl_->layout.get<IconSize>() = value; baseImpl = std::move(impl_); observer->onLayerLayoutPropertyChanged(*this, "icon-size"); } @@ -226,14 +225,14 @@ PropertyValue<IconTextFitType> SymbolLayer::getDefaultIconTextFit() { } PropertyValue<IconTextFitType> SymbolLayer::getIconTextFit() const { - return impl().layout.unevaluated.get<IconTextFit>(); + return impl().layout.get<IconTextFit>(); } void SymbolLayer::setIconTextFit(PropertyValue<IconTextFitType> value) { if (value == getIconTextFit()) return; auto impl_ = mutableImpl(); - impl_->layout.unevaluated.get<IconTextFit>() = value; + impl_->layout.get<IconTextFit>() = value; baseImpl = std::move(impl_); observer->onLayerLayoutPropertyChanged(*this, "icon-text-fit"); } @@ -242,14 +241,14 @@ PropertyValue<std::array<float, 4>> SymbolLayer::getDefaultIconTextFitPadding() } PropertyValue<std::array<float, 4>> SymbolLayer::getIconTextFitPadding() const { - return impl().layout.unevaluated.get<IconTextFitPadding>(); + return impl().layout.get<IconTextFitPadding>(); } void SymbolLayer::setIconTextFitPadding(PropertyValue<std::array<float, 4>> value) { if (value == getIconTextFitPadding()) return; auto impl_ = mutableImpl(); - impl_->layout.unevaluated.get<IconTextFitPadding>() = value; + impl_->layout.get<IconTextFitPadding>() = value; baseImpl = std::move(impl_); observer->onLayerLayoutPropertyChanged(*this, "icon-text-fit-padding"); } @@ -258,14 +257,14 @@ DataDrivenPropertyValue<std::string> SymbolLayer::getDefaultIconImage() { } DataDrivenPropertyValue<std::string> SymbolLayer::getIconImage() const { - return impl().layout.unevaluated.get<IconImage>(); + return impl().layout.get<IconImage>(); } void SymbolLayer::setIconImage(DataDrivenPropertyValue<std::string> value) { if (value == getIconImage()) return; auto impl_ = mutableImpl(); - impl_->layout.unevaluated.get<IconImage>() = value; + impl_->layout.get<IconImage>() = value; baseImpl = std::move(impl_); observer->onLayerLayoutPropertyChanged(*this, "icon-image"); } @@ -274,14 +273,14 @@ DataDrivenPropertyValue<float> SymbolLayer::getDefaultIconRotate() { } DataDrivenPropertyValue<float> SymbolLayer::getIconRotate() const { - return impl().layout.unevaluated.get<IconRotate>(); + return impl().layout.get<IconRotate>(); } void SymbolLayer::setIconRotate(DataDrivenPropertyValue<float> value) { if (value == getIconRotate()) return; auto impl_ = mutableImpl(); - impl_->layout.unevaluated.get<IconRotate>() = value; + impl_->layout.get<IconRotate>() = value; baseImpl = std::move(impl_); observer->onLayerLayoutPropertyChanged(*this, "icon-rotate"); } @@ -290,14 +289,14 @@ PropertyValue<float> SymbolLayer::getDefaultIconPadding() { } PropertyValue<float> SymbolLayer::getIconPadding() const { - return impl().layout.unevaluated.get<IconPadding>(); + return impl().layout.get<IconPadding>(); } void SymbolLayer::setIconPadding(PropertyValue<float> value) { if (value == getIconPadding()) return; auto impl_ = mutableImpl(); - impl_->layout.unevaluated.get<IconPadding>() = value; + impl_->layout.get<IconPadding>() = value; baseImpl = std::move(impl_); observer->onLayerLayoutPropertyChanged(*this, "icon-padding"); } @@ -306,14 +305,14 @@ PropertyValue<bool> SymbolLayer::getDefaultIconKeepUpright() { } PropertyValue<bool> SymbolLayer::getIconKeepUpright() const { - return impl().layout.unevaluated.get<IconKeepUpright>(); + return impl().layout.get<IconKeepUpright>(); } void SymbolLayer::setIconKeepUpright(PropertyValue<bool> value) { if (value == getIconKeepUpright()) return; auto impl_ = mutableImpl(); - impl_->layout.unevaluated.get<IconKeepUpright>() = value; + impl_->layout.get<IconKeepUpright>() = value; baseImpl = std::move(impl_); observer->onLayerLayoutPropertyChanged(*this, "icon-keep-upright"); } @@ -322,14 +321,14 @@ DataDrivenPropertyValue<std::array<float, 2>> SymbolLayer::getDefaultIconOffset( } DataDrivenPropertyValue<std::array<float, 2>> SymbolLayer::getIconOffset() const { - return impl().layout.unevaluated.get<IconOffset>(); + return impl().layout.get<IconOffset>(); } void SymbolLayer::setIconOffset(DataDrivenPropertyValue<std::array<float, 2>> value) { if (value == getIconOffset()) return; auto impl_ = mutableImpl(); - impl_->layout.unevaluated.get<IconOffset>() = value; + impl_->layout.get<IconOffset>() = value; baseImpl = std::move(impl_); observer->onLayerLayoutPropertyChanged(*this, "icon-offset"); } @@ -338,14 +337,14 @@ PropertyValue<AlignmentType> SymbolLayer::getDefaultTextPitchAlignment() { } PropertyValue<AlignmentType> SymbolLayer::getTextPitchAlignment() const { - return impl().layout.unevaluated.get<TextPitchAlignment>(); + return impl().layout.get<TextPitchAlignment>(); } void SymbolLayer::setTextPitchAlignment(PropertyValue<AlignmentType> value) { if (value == getTextPitchAlignment()) return; auto impl_ = mutableImpl(); - impl_->layout.unevaluated.get<TextPitchAlignment>() = value; + impl_->layout.get<TextPitchAlignment>() = value; baseImpl = std::move(impl_); observer->onLayerLayoutPropertyChanged(*this, "text-pitch-alignment"); } @@ -354,14 +353,14 @@ PropertyValue<AlignmentType> SymbolLayer::getDefaultTextRotationAlignment() { } PropertyValue<AlignmentType> SymbolLayer::getTextRotationAlignment() const { - return impl().layout.unevaluated.get<TextRotationAlignment>(); + return impl().layout.get<TextRotationAlignment>(); } void SymbolLayer::setTextRotationAlignment(PropertyValue<AlignmentType> value) { if (value == getTextRotationAlignment()) return; auto impl_ = mutableImpl(); - impl_->layout.unevaluated.get<TextRotationAlignment>() = value; + impl_->layout.get<TextRotationAlignment>() = value; baseImpl = std::move(impl_); observer->onLayerLayoutPropertyChanged(*this, "text-rotation-alignment"); } @@ -370,14 +369,14 @@ DataDrivenPropertyValue<std::string> SymbolLayer::getDefaultTextField() { } DataDrivenPropertyValue<std::string> SymbolLayer::getTextField() const { - return impl().layout.unevaluated.get<TextField>(); + return impl().layout.get<TextField>(); } void SymbolLayer::setTextField(DataDrivenPropertyValue<std::string> value) { if (value == getTextField()) return; auto impl_ = mutableImpl(); - impl_->layout.unevaluated.get<TextField>() = value; + impl_->layout.get<TextField>() = value; baseImpl = std::move(impl_); observer->onLayerLayoutPropertyChanged(*this, "text-field"); } @@ -386,14 +385,14 @@ PropertyValue<std::vector<std::string>> SymbolLayer::getDefaultTextFont() { } PropertyValue<std::vector<std::string>> SymbolLayer::getTextFont() const { - return impl().layout.unevaluated.get<TextFont>(); + return impl().layout.get<TextFont>(); } void SymbolLayer::setTextFont(PropertyValue<std::vector<std::string>> value) { if (value == getTextFont()) return; auto impl_ = mutableImpl(); - impl_->layout.unevaluated.get<TextFont>() = value; + impl_->layout.get<TextFont>() = value; baseImpl = std::move(impl_); observer->onLayerLayoutPropertyChanged(*this, "text-font"); } @@ -402,14 +401,14 @@ DataDrivenPropertyValue<float> SymbolLayer::getDefaultTextSize() { } DataDrivenPropertyValue<float> SymbolLayer::getTextSize() const { - return impl().layout.unevaluated.get<TextSize>(); + return impl().layout.get<TextSize>(); } void SymbolLayer::setTextSize(DataDrivenPropertyValue<float> value) { if (value == getTextSize()) return; auto impl_ = mutableImpl(); - impl_->layout.unevaluated.get<TextSize>() = value; + impl_->layout.get<TextSize>() = value; baseImpl = std::move(impl_); observer->onLayerLayoutPropertyChanged(*this, "text-size"); } @@ -418,14 +417,14 @@ PropertyValue<float> SymbolLayer::getDefaultTextMaxWidth() { } PropertyValue<float> SymbolLayer::getTextMaxWidth() const { - return impl().layout.unevaluated.get<TextMaxWidth>(); + return impl().layout.get<TextMaxWidth>(); } void SymbolLayer::setTextMaxWidth(PropertyValue<float> value) { if (value == getTextMaxWidth()) return; auto impl_ = mutableImpl(); - impl_->layout.unevaluated.get<TextMaxWidth>() = value; + impl_->layout.get<TextMaxWidth>() = value; baseImpl = std::move(impl_); observer->onLayerLayoutPropertyChanged(*this, "text-max-width"); } @@ -434,14 +433,14 @@ PropertyValue<float> SymbolLayer::getDefaultTextLineHeight() { } PropertyValue<float> SymbolLayer::getTextLineHeight() const { - return impl().layout.unevaluated.get<TextLineHeight>(); + return impl().layout.get<TextLineHeight>(); } void SymbolLayer::setTextLineHeight(PropertyValue<float> value) { if (value == getTextLineHeight()) return; auto impl_ = mutableImpl(); - impl_->layout.unevaluated.get<TextLineHeight>() = value; + impl_->layout.get<TextLineHeight>() = value; baseImpl = std::move(impl_); observer->onLayerLayoutPropertyChanged(*this, "text-line-height"); } @@ -450,14 +449,14 @@ PropertyValue<float> SymbolLayer::getDefaultTextLetterSpacing() { } PropertyValue<float> SymbolLayer::getTextLetterSpacing() const { - return impl().layout.unevaluated.get<TextLetterSpacing>(); + return impl().layout.get<TextLetterSpacing>(); } void SymbolLayer::setTextLetterSpacing(PropertyValue<float> value) { if (value == getTextLetterSpacing()) return; auto impl_ = mutableImpl(); - impl_->layout.unevaluated.get<TextLetterSpacing>() = value; + impl_->layout.get<TextLetterSpacing>() = value; baseImpl = std::move(impl_); observer->onLayerLayoutPropertyChanged(*this, "text-letter-spacing"); } @@ -466,14 +465,14 @@ PropertyValue<TextJustifyType> SymbolLayer::getDefaultTextJustify() { } PropertyValue<TextJustifyType> SymbolLayer::getTextJustify() const { - return impl().layout.unevaluated.get<TextJustify>(); + return impl().layout.get<TextJustify>(); } void SymbolLayer::setTextJustify(PropertyValue<TextJustifyType> value) { if (value == getTextJustify()) return; auto impl_ = mutableImpl(); - impl_->layout.unevaluated.get<TextJustify>() = value; + impl_->layout.get<TextJustify>() = value; baseImpl = std::move(impl_); observer->onLayerLayoutPropertyChanged(*this, "text-justify"); } @@ -482,14 +481,14 @@ PropertyValue<TextAnchorType> SymbolLayer::getDefaultTextAnchor() { } PropertyValue<TextAnchorType> SymbolLayer::getTextAnchor() const { - return impl().layout.unevaluated.get<TextAnchor>(); + return impl().layout.get<TextAnchor>(); } void SymbolLayer::setTextAnchor(PropertyValue<TextAnchorType> value) { if (value == getTextAnchor()) return; auto impl_ = mutableImpl(); - impl_->layout.unevaluated.get<TextAnchor>() = value; + impl_->layout.get<TextAnchor>() = value; baseImpl = std::move(impl_); observer->onLayerLayoutPropertyChanged(*this, "text-anchor"); } @@ -498,14 +497,14 @@ PropertyValue<float> SymbolLayer::getDefaultTextMaxAngle() { } PropertyValue<float> SymbolLayer::getTextMaxAngle() const { - return impl().layout.unevaluated.get<TextMaxAngle>(); + return impl().layout.get<TextMaxAngle>(); } void SymbolLayer::setTextMaxAngle(PropertyValue<float> value) { if (value == getTextMaxAngle()) return; auto impl_ = mutableImpl(); - impl_->layout.unevaluated.get<TextMaxAngle>() = value; + impl_->layout.get<TextMaxAngle>() = value; baseImpl = std::move(impl_); observer->onLayerLayoutPropertyChanged(*this, "text-max-angle"); } @@ -514,14 +513,14 @@ DataDrivenPropertyValue<float> SymbolLayer::getDefaultTextRotate() { } DataDrivenPropertyValue<float> SymbolLayer::getTextRotate() const { - return impl().layout.unevaluated.get<TextRotate>(); + return impl().layout.get<TextRotate>(); } void SymbolLayer::setTextRotate(DataDrivenPropertyValue<float> value) { if (value == getTextRotate()) return; auto impl_ = mutableImpl(); - impl_->layout.unevaluated.get<TextRotate>() = value; + impl_->layout.get<TextRotate>() = value; baseImpl = std::move(impl_); observer->onLayerLayoutPropertyChanged(*this, "text-rotate"); } @@ -530,14 +529,14 @@ PropertyValue<float> SymbolLayer::getDefaultTextPadding() { } PropertyValue<float> SymbolLayer::getTextPadding() const { - return impl().layout.unevaluated.get<TextPadding>(); + return impl().layout.get<TextPadding>(); } void SymbolLayer::setTextPadding(PropertyValue<float> value) { if (value == getTextPadding()) return; auto impl_ = mutableImpl(); - impl_->layout.unevaluated.get<TextPadding>() = value; + impl_->layout.get<TextPadding>() = value; baseImpl = std::move(impl_); observer->onLayerLayoutPropertyChanged(*this, "text-padding"); } @@ -546,14 +545,14 @@ PropertyValue<bool> SymbolLayer::getDefaultTextKeepUpright() { } PropertyValue<bool> SymbolLayer::getTextKeepUpright() const { - return impl().layout.unevaluated.get<TextKeepUpright>(); + return impl().layout.get<TextKeepUpright>(); } void SymbolLayer::setTextKeepUpright(PropertyValue<bool> value) { if (value == getTextKeepUpright()) return; auto impl_ = mutableImpl(); - impl_->layout.unevaluated.get<TextKeepUpright>() = value; + impl_->layout.get<TextKeepUpright>() = value; baseImpl = std::move(impl_); observer->onLayerLayoutPropertyChanged(*this, "text-keep-upright"); } @@ -562,14 +561,14 @@ DataDrivenPropertyValue<TextTransformType> SymbolLayer::getDefaultTextTransform( } DataDrivenPropertyValue<TextTransformType> SymbolLayer::getTextTransform() const { - return impl().layout.unevaluated.get<TextTransform>(); + return impl().layout.get<TextTransform>(); } void SymbolLayer::setTextTransform(DataDrivenPropertyValue<TextTransformType> value) { if (value == getTextTransform()) return; auto impl_ = mutableImpl(); - impl_->layout.unevaluated.get<TextTransform>() = value; + impl_->layout.get<TextTransform>() = value; baseImpl = std::move(impl_); observer->onLayerLayoutPropertyChanged(*this, "text-transform"); } @@ -578,14 +577,14 @@ DataDrivenPropertyValue<std::array<float, 2>> SymbolLayer::getDefaultTextOffset( } DataDrivenPropertyValue<std::array<float, 2>> SymbolLayer::getTextOffset() const { - return impl().layout.unevaluated.get<TextOffset>(); + return impl().layout.get<TextOffset>(); } void SymbolLayer::setTextOffset(DataDrivenPropertyValue<std::array<float, 2>> value) { if (value == getTextOffset()) return; auto impl_ = mutableImpl(); - impl_->layout.unevaluated.get<TextOffset>() = value; + impl_->layout.get<TextOffset>() = value; baseImpl = std::move(impl_); observer->onLayerLayoutPropertyChanged(*this, "text-offset"); } @@ -594,14 +593,14 @@ PropertyValue<bool> SymbolLayer::getDefaultTextAllowOverlap() { } PropertyValue<bool> SymbolLayer::getTextAllowOverlap() const { - return impl().layout.unevaluated.get<TextAllowOverlap>(); + return impl().layout.get<TextAllowOverlap>(); } void SymbolLayer::setTextAllowOverlap(PropertyValue<bool> value) { if (value == getTextAllowOverlap()) return; auto impl_ = mutableImpl(); - impl_->layout.unevaluated.get<TextAllowOverlap>() = value; + impl_->layout.get<TextAllowOverlap>() = value; baseImpl = std::move(impl_); observer->onLayerLayoutPropertyChanged(*this, "text-allow-overlap"); } @@ -610,14 +609,14 @@ PropertyValue<bool> SymbolLayer::getDefaultTextIgnorePlacement() { } PropertyValue<bool> SymbolLayer::getTextIgnorePlacement() const { - return impl().layout.unevaluated.get<TextIgnorePlacement>(); + return impl().layout.get<TextIgnorePlacement>(); } void SymbolLayer::setTextIgnorePlacement(PropertyValue<bool> value) { if (value == getTextIgnorePlacement()) return; auto impl_ = mutableImpl(); - impl_->layout.unevaluated.get<TextIgnorePlacement>() = value; + impl_->layout.get<TextIgnorePlacement>() = value; baseImpl = std::move(impl_); observer->onLayerLayoutPropertyChanged(*this, "text-ignore-placement"); } @@ -626,14 +625,14 @@ PropertyValue<bool> SymbolLayer::getDefaultTextOptional() { } PropertyValue<bool> SymbolLayer::getTextOptional() const { - return impl().layout.unevaluated.get<TextOptional>(); + return impl().layout.get<TextOptional>(); } void SymbolLayer::setTextOptional(PropertyValue<bool> value) { if (value == getTextOptional()) return; auto impl_ = mutableImpl(); - impl_->layout.unevaluated.get<TextOptional>() = value; + impl_->layout.get<TextOptional>() = value; baseImpl = std::move(impl_); observer->onLayerLayoutPropertyChanged(*this, "text-optional"); } diff --git a/src/mbgl/style/layers/symbol_layer_impl.hpp b/src/mbgl/style/layers/symbol_layer_impl.hpp index d961dbb0b9..28760e1f74 100644 --- a/src/mbgl/style/layers/symbol_layer_impl.hpp +++ b/src/mbgl/style/layers/symbol_layer_impl.hpp @@ -13,7 +13,7 @@ public: void stringifyLayout(rapidjson::Writer<rapidjson::StringBuffer>&) const override; - SymbolLayoutProperties layout; + SymbolLayoutProperties::Unevaluated layout; SymbolPaintProperties::Cascading paint; }; diff --git a/src/mbgl/style/layers/symbol_layer_properties.hpp b/src/mbgl/style/layers/symbol_layer_properties.hpp index 42f593890b..d484d699d7 100644 --- a/src/mbgl/style/layers/symbol_layer_properties.hpp +++ b/src/mbgl/style/layers/symbol_layer_properties.hpp @@ -5,6 +5,7 @@ #include <mbgl/style/types.hpp> #include <mbgl/style/layout_property.hpp> #include <mbgl/style/paint_property.hpp> +#include <mbgl/style/properties.hpp> #include <mbgl/programs/attributes.hpp> namespace mbgl { @@ -236,7 +237,7 @@ struct TextTranslateAnchor : PaintProperty<TranslateAnchorType> { static TranslateAnchorType defaultValue() { return TranslateAnchorType::Map; } }; -class SymbolLayoutProperties : public LayoutProperties< +class SymbolLayoutProperties : public Properties< SymbolPlacement, SymbolSpacing, SymbolAvoidEdges, @@ -273,7 +274,7 @@ class SymbolLayoutProperties : public LayoutProperties< TextOptional > {}; -class SymbolPaintProperties : public PaintProperties< +class SymbolPaintProperties : public Properties< IconOpacity, IconColor, IconHaloColor, diff --git a/src/mbgl/style/layout_property.hpp b/src/mbgl/style/layout_property.hpp index 3b9d6114c0..82a19e6a80 100644 --- a/src/mbgl/style/layout_property.hpp +++ b/src/mbgl/style/layout_property.hpp @@ -4,117 +4,30 @@ #include <mbgl/style/data_driven_property_value.hpp> #include <mbgl/renderer/property_evaluator.hpp> #include <mbgl/renderer/data_driven_property_evaluator.hpp> -#include <mbgl/util/indexed_tuple.hpp> namespace mbgl { - -class PropertyEvaluationParameters; - namespace style { template <class T> class LayoutProperty { public: + using CascadingType = std::nullptr_t; using UnevaluatedType = PropertyValue<T>; using EvaluatorType = PropertyEvaluator<T>; using PossiblyEvaluatedType = T; using Type = T; + static constexpr bool IsDataDriven = false; }; template <class T> class DataDrivenLayoutProperty { public: + using CascadingType = std::nullptr_t; using UnevaluatedType = DataDrivenPropertyValue<T>; using EvaluatorType = DataDrivenPropertyEvaluator<T>; using PossiblyEvaluatedType = PossiblyEvaluatedPropertyValue<T>; using Type = T; -}; - -template <class... Ps> -class LayoutProperties { -public: - using Properties = TypeList<Ps...>; - - template <class TypeList> - using Tuple = IndexedTuple<Properties, TypeList>; - - /* - For layout properties we implement a two step evaluation process: if you have a zoom level, - you can evaluate a set of unevaluated property values, producing a set of possibly evaluated - values, where undefined, constant, or camera function values have been fully evaluated, and - source or composite function values have not. - - Once you also have a particular feature, you can evaluate that set of possibly evaluated values - fully, producing a set of fully evaluated values. - - This is in theory maximally efficient in terms of avoiding repeated evaluation of camera - functions, though it's more of a historical accident than a purposeful optimization. - */ - - using UnevaluatedTypes = TypeList<typename Ps::UnevaluatedType...>; - using PossiblyEvaluatedTypes = TypeList<typename Ps::PossiblyEvaluatedType...>; - using EvaluatedTypes = TypeList<typename Ps::Type...>; - - class Evaluated : public Tuple<EvaluatedTypes> { - public: - using Tuple<EvaluatedTypes>::Tuple; - }; - - class PossiblyEvaluated : public Tuple<PossiblyEvaluatedTypes> { - public: - using Tuple<PossiblyEvaluatedTypes>::Tuple; - - template <class T> - static T evaluate(float, const GeometryTileFeature&, const T& t, const T&) { - return t; - } - - template <class T> - static T evaluate(float z, const GeometryTileFeature& feature, - const PossiblyEvaluatedPropertyValue<T>& v, const T& defaultValue) { - return v.match( - [&] (const T& t) { - return t; - }, - [&] (const SourceFunction<T>& t) { - return t.evaluate(feature, defaultValue); - }, - [&] (const CompositeFunction<T>& t) { - return t.evaluate(z, feature, defaultValue); - }); - } - - template <class P> - auto evaluate(float z, const GeometryTileFeature& feature) const { - return evaluate(z, feature, this->template get<P>(), P::defaultValue()); - } - - Evaluated evaluate(float z, const GeometryTileFeature& feature) const { - return Evaluated { - evaluate<Ps>(z, feature)... - }; - } - }; - - class Unevaluated : public Tuple<UnevaluatedTypes> { - public: - using Tuple<UnevaluatedTypes>::Tuple; - }; - - template <class P> - auto evaluate(const PropertyEvaluationParameters& parameters) const { - using Evaluator = typename P::EvaluatorType; - return unevaluated.template get<P>() - .evaluate(Evaluator(parameters, P::defaultValue())); - } - - PossiblyEvaluated evaluate(const PropertyEvaluationParameters& parameters) const { - return PossiblyEvaluated { - evaluate<Ps>(parameters)... - }; - } - - Unevaluated unevaluated; + static constexpr bool IsDataDriven = true; }; } // namespace style diff --git a/src/mbgl/style/light_impl.hpp b/src/mbgl/style/light_impl.hpp index 4179c2b276..7cf160f439 100644 --- a/src/mbgl/style/light_impl.hpp +++ b/src/mbgl/style/light_impl.hpp @@ -2,9 +2,10 @@ #include <mbgl/style/light.hpp> #include <mbgl/style/property_value.hpp> -#include <mbgl/style/transition_options.hpp> #include <mbgl/style/types.hpp> #include <mbgl/style/position.hpp> +#include <mbgl/style/properties.hpp> +#include <mbgl/renderer/property_evaluator.hpp> #include <mbgl/util/color.hpp> #include <mbgl/util/indexed_tuple.hpp> @@ -14,11 +15,12 @@ namespace style { template <class T> class LightProperty { public: + using CascadingType = Transitionable<PropertyValue<T>>; + using UnevaluatedType = Transitioning<PropertyValue<T>>; + using EvaluatorType = PropertyEvaluator<T>; + using PossiblyEvaluatedType = T; using Type = T; - using ValueType = PropertyValue<T>; - - PropertyValue<T> value; - TransitionOptions transition; + static constexpr bool IsDataDriven = false; }; struct LightAnchor : LightProperty<LightAnchorType> { @@ -46,11 +48,11 @@ struct LightIntensity : LightProperty<float> { } }; -using LightProperties = TypeList<LightAnchor, LightPosition, LightColor, LightIntensity>; +using LightProperties = Properties<LightAnchor, LightPosition, LightColor, LightIntensity>; class Light::Impl { public: - IndexedTuple<LightProperties, LightProperties> properties; + LightProperties::Cascading properties; }; } // namespace style diff --git a/src/mbgl/style/paint_property.hpp b/src/mbgl/style/paint_property.hpp index f1752e69d9..b0dc5641fb 100644 --- a/src/mbgl/style/paint_property.hpp +++ b/src/mbgl/style/paint_property.hpp @@ -1,186 +1,51 @@ #pragma once -#include <mbgl/style/class_dictionary.hpp> +#include <mbgl/style/properties.hpp> #include <mbgl/style/property_value.hpp> #include <mbgl/style/data_driven_property_value.hpp> -#include <mbgl/style/transition_options.hpp> #include <mbgl/renderer/property_evaluator.hpp> #include <mbgl/renderer/cross_faded_property_evaluator.hpp> #include <mbgl/renderer/data_driven_property_evaluator.hpp> -#include <mbgl/renderer/property_evaluation_parameters.hpp> -#include <mbgl/renderer/cascade_parameters.hpp> -#include <mbgl/renderer/transitioning_property.hpp> -#include <mbgl/renderer/paint_property_binder.hpp> -#include <mbgl/util/constants.hpp> -#include <mbgl/util/interpolate.hpp> -#include <mbgl/util/indexed_tuple.hpp> -#include <mbgl/util/ignore.hpp> #include <utility> namespace mbgl { - -class GeometryTileFeature; - namespace style { -template <class Value> -class CascadingPaintProperty { -public: - bool isUndefined() const { - return values.find(ClassID::Default) == values.end(); - } - - const Value& get(const optional<std::string>& klass) const { - static const Value staticValue{}; - const auto it = values.find(klass ? ClassDictionary::Get().lookup(*klass) : ClassID::Default); - return it == values.end() ? staticValue : it->second; - } - - void set(const Value& value_, const optional<std::string>& klass) { - values[klass ? ClassDictionary::Get().lookup(*klass) : ClassID::Default] = value_; - } - - const TransitionOptions& getTransition(const optional<std::string>& klass) const { - static const TransitionOptions staticValue{}; - const auto it = transitions.find(klass ? ClassDictionary::Get().lookup(*klass) : ClassID::Default); - return it == transitions.end() ? staticValue : it->second; - } - - void setTransition(const TransitionOptions& transition, const optional<std::string>& klass) { - transitions[klass ? ClassDictionary::Get().lookup(*klass) : ClassID::Default] = transition; - } - - template <class TransitioningProperty> - TransitioningProperty cascade(const CascadeParameters& params, TransitioningProperty prior) const { - TransitionOptions transition; - Value value; - - for (const auto classID : params.classes) { - if (values.find(classID) != values.end()) { - value = values.at(classID); - break; - } - } - - for (const auto classID : params.classes) { - if (transitions.find(classID) != transitions.end()) { - transition = transitions.at(classID).reverseMerge(transition); - break; - } - } - - return TransitioningProperty(std::move(value), - std::move(prior), - transition.reverseMerge(params.transition), - params.now); - } - -private: - std::map<ClassID, Value> values; - std::map<ClassID, TransitionOptions> transitions; -}; - template <class T> class PaintProperty { public: - using ValueType = PropertyValue<T>; - using CascadingType = CascadingPaintProperty<ValueType>; - using UnevaluatedType = TransitioningProperty<ValueType>; + using CascadingType = Cascading<PropertyValue<T>>; + using UnevaluatedType = Transitioning<PropertyValue<T>>; using EvaluatorType = PropertyEvaluator<T>; - using EvaluatedType = T; + using PossiblyEvaluatedType = T; + using Type = T; static constexpr bool IsDataDriven = false; }; template <class T, class A> class DataDrivenPaintProperty { public: - using ValueType = DataDrivenPropertyValue<T>; - using CascadingType = CascadingPaintProperty<ValueType>; - using UnevaluatedType = TransitioningProperty<ValueType>; + using CascadingType = Cascading<DataDrivenPropertyValue<T>>; + using UnevaluatedType = Transitioning<DataDrivenPropertyValue<T>>; using EvaluatorType = DataDrivenPropertyEvaluator<T>; - using EvaluatedType = PossiblyEvaluatedPropertyValue<T>; + using PossiblyEvaluatedType = PossiblyEvaluatedPropertyValue<T>; + using Type = T; static constexpr bool IsDataDriven = true; - using Type = T; using Attribute = A; }; template <class T> class CrossFadedPaintProperty { public: - using ValueType = PropertyValue<T>; - using CascadingType = CascadingPaintProperty<ValueType>; - using UnevaluatedType = TransitioningProperty<ValueType>; + using CascadingType = Cascading<PropertyValue<T>>; + using UnevaluatedType = Transitioning<PropertyValue<T>>; using EvaluatorType = CrossFadedPropertyEvaluator<T>; - using EvaluatedType = Faded<T>; + using PossiblyEvaluatedType = Faded<T>; + using Type = T; static constexpr bool IsDataDriven = false; }; -template <class P> -struct IsDataDriven : std::integral_constant<bool, P::IsDataDriven> {}; - -template <class... Ps> -class PaintProperties { -public: - using Properties = TypeList<Ps...>; - using DataDrivenProperties = FilteredTypeList<Properties, IsDataDriven>; - using Binders = PaintPropertyBinders<DataDrivenProperties>; - - using EvaluatedTypes = TypeList<typename Ps::EvaluatedType...>; - using UnevaluatedTypes = TypeList<typename Ps::UnevaluatedType...>; - using CascadingTypes = TypeList<typename Ps::CascadingType...>; - - template <class TypeList> - using Tuple = IndexedTuple<Properties, TypeList>; - - class Evaluated : public Tuple<EvaluatedTypes> { - public: - using Tuple<EvaluatedTypes>::Tuple; - }; - - class Unevaluated : public Tuple<UnevaluatedTypes> { - public: - using Tuple<UnevaluatedTypes>::Tuple; - - bool hasTransition() const { - bool result = false; - util::ignore({ result |= this->template get<Ps>().hasTransition()... }); - return result; - } - - template <class P> - auto evaluate(const PropertyEvaluationParameters& parameters) { - using Evaluator = typename P::EvaluatorType; - - return this->template get<P>().evaluate( - Evaluator(parameters, P::defaultValue()), - parameters.now - ); - } - - Evaluated evaluate(const PropertyEvaluationParameters& parameters) { - return Evaluated { - evaluate<Ps>(parameters)... - }; - } - - }; - - class Cascading : public Tuple<CascadingTypes> { - public: - using Tuple<CascadingTypes>::Tuple; - - Unevaluated cascade(const CascadeParameters& parameters, Unevaluated&& prior) const { - return Unevaluated { - this->template get<Ps>().cascade( - parameters, - std::move(prior.template get<Ps>()) - )... - }; - } - }; -}; - } // namespace style } // namespace mbgl diff --git a/src/mbgl/style/properties.hpp b/src/mbgl/style/properties.hpp new file mode 100644 index 0000000000..c808554c93 --- /dev/null +++ b/src/mbgl/style/properties.hpp @@ -0,0 +1,268 @@ +#pragma once + +#include <mbgl/style/transition_options.hpp> +#include <mbgl/style/conversion/stringify.hpp> +#include <mbgl/renderer/cascade_parameters.hpp> +#include <mbgl/renderer/paint_property_binder.hpp> +#include <mbgl/renderer/property_evaluation_parameters.hpp> +#include <mbgl/renderer/cascade_parameters.hpp> +#include <mbgl/util/indexed_tuple.hpp> +#include <mbgl/util/ignore.hpp> + +namespace mbgl { + +class GeometryTileFeature; + +namespace style { + +template <class Value> +class Transitioning { +public: + Transitioning() = default; + + Transitioning(Value value_, + Transitioning<Value> prior_, + TransitionOptions transition, + TimePoint now) + : begin(now + transition.delay.value_or(Duration::zero())), + end(begin + transition.duration.value_or(Duration::zero())), + value(std::move(value_)) { + if (transition.isDefined()) { + prior = { std::move(prior_) }; + } + } + + template <class Evaluator> + auto evaluate(const Evaluator& evaluator, TimePoint now) const { + auto finalValue = value.evaluate(evaluator); + if (!prior) { + // No prior value. + return finalValue; + } else if (now >= end) { + // Transition from prior value is now complete. + prior = {}; + return finalValue; + } else if (value.isDataDriven()) { + // Transitions to data-driven properties are not supported. + // We snap immediately to the data-driven value so that, when we perform layout, + // we see the data-driven function and can use it to populate vertex buffers. + prior = {}; + return finalValue; + } else if (now < begin) { + // Transition hasn't started yet. + return prior->get().evaluate(evaluator, now); + } else { + // Interpolate between recursively-calculated prior value and final. + float t = std::chrono::duration<float>(now - begin) / (end - begin); + return util::interpolate(prior->get().evaluate(evaluator, now), finalValue, + util::DEFAULT_TRANSITION_EASE.solve(t, 0.001)); + } + } + + bool hasTransition() const { + return bool(prior); + } + + bool isUndefined() const { + return value.isUndefined(); + } + + const Value& getValue() const { + return value; + } + +private: + mutable optional<mapbox::util::recursive_wrapper<Transitioning<Value>>> prior; + TimePoint begin; + TimePoint end; + Value value; +}; + +template <class Value> +class Transitionable { +public: + Value value; + TransitionOptions transition; + + Transitioning<Value> cascade(const CascadeParameters& params, Transitioning<Value> prior) const { + return Transitioning<Value>(value, + std::move(prior), + transition.reverseMerge(params.transition), + params.now); + } +}; +template <class Value> +class Cascading { +public: + bool isUndefined() const { + return values.find(ClassID::Default) == values.end(); + } + + const Value& get(const optional<std::string>& klass) const { + static const Value staticValue{}; + const auto it = values.find(klass ? ClassDictionary::Get().lookup(*klass) : ClassID::Default); + return it == values.end() ? staticValue : it->second; + } + + void set(const Value& value_, const optional<std::string>& klass) { + values[klass ? ClassDictionary::Get().lookup(*klass) : ClassID::Default] = value_; + } + + const TransitionOptions& getTransition(const optional<std::string>& klass) const { + static const TransitionOptions staticValue{}; + const auto it = transitions.find(klass ? ClassDictionary::Get().lookup(*klass) : ClassID::Default); + return it == transitions.end() ? staticValue : it->second; + } + + void setTransition(const TransitionOptions& transition, const optional<std::string>& klass) { + transitions[klass ? ClassDictionary::Get().lookup(*klass) : ClassID::Default] = transition; + } + + Transitioning<Value> cascade(const CascadeParameters& params, Transitioning<Value> prior) const { + TransitionOptions transition; + Value value; + + for (const auto classID : params.classes) { + if (values.find(classID) != values.end()) { + value = values.at(classID); + break; + } + } + + for (const auto classID : params.classes) { + if (transitions.find(classID) != transitions.end()) { + transition = transitions.at(classID).reverseMerge(transition); + break; + } + } + + return Transitioning<Value>(std::move(value), + std::move(prior), + transition.reverseMerge(params.transition), + params.now); + } + +private: + std::map<ClassID, Value> values; + std::map<ClassID, TransitionOptions> transitions; +}; + + +template <class P> +struct IsDataDriven : std::integral_constant<bool, P::IsDataDriven> {}; + +template <class... Ps> +class Properties { +public: + /* + For style properties we implement a two step evaluation process: if you have a zoom level, + you can evaluate a set of unevaluated property values, producing a set of possibly evaluated + values, where undefined, constant, or camera function values have been fully evaluated, and + source or composite function values have not. + + Once you also have a particular feature, you can evaluate that set of possibly evaluated values + fully, producing a set of fully evaluated values. + + This is in theory maximally efficient in terms of avoiding repeated evaluation of camera + functions, though it's more of a historical accident than a purposeful optimization. + */ + + using PropertyTypes = TypeList<Ps...>; + using CascadingTypes = TypeList<typename Ps::CascadingType...>; + using UnevaluatedTypes = TypeList<typename Ps::UnevaluatedType...>; + using PossiblyEvaluatedTypes = TypeList<typename Ps::PossiblyEvaluatedType...>; + using EvaluatedTypes = TypeList<typename Ps::Type...>; + + using DataDrivenProperties = FilteredTypeList<PropertyTypes, IsDataDriven>; + using Binders = PaintPropertyBinders<DataDrivenProperties>; + + template <class TypeList> + using Tuple = IndexedTuple<PropertyTypes, TypeList>; + + class Evaluated : public Tuple<EvaluatedTypes> { + public: + using Tuple<EvaluatedTypes>::Tuple; + }; + + class PossiblyEvaluated : public Tuple<PossiblyEvaluatedTypes> { + public: + using Tuple<PossiblyEvaluatedTypes>::Tuple; + + template <class T> + static T evaluate(float, const GeometryTileFeature&, const T& t, const T&) { + return t; + } + + template <class T> + static T evaluate(float z, const GeometryTileFeature& feature, + const PossiblyEvaluatedPropertyValue<T>& v, const T& defaultValue) { + return v.match( + [&] (const T& t) { + return t; + }, + [&] (const SourceFunction<T>& t) { + return t.evaluate(feature, defaultValue); + }, + [&] (const CompositeFunction<T>& t) { + return t.evaluate(z, feature, defaultValue); + }); + } + + template <class P> + auto evaluate(float z, const GeometryTileFeature& feature) const { + return evaluate(z, feature, this->template get<P>(), P::defaultValue()); + } + + Evaluated evaluate(float z, const GeometryTileFeature& feature) const { + return Evaluated { + evaluate<Ps>(z, feature)... + }; + } + }; + + class Unevaluated : public Tuple<UnevaluatedTypes> { + public: + using Tuple<UnevaluatedTypes>::Tuple; + + bool hasTransition() const { + bool result = false; + util::ignore({ result |= this->template get<Ps>().hasTransition()... }); + return result; + } + + template <class P> + auto evaluate(const PropertyEvaluationParameters& parameters) const { + using Evaluator = typename P::EvaluatorType; + return this->template get<P>() + .evaluate(Evaluator(parameters, P::defaultValue()), parameters.now); + } + + PossiblyEvaluated evaluate(const PropertyEvaluationParameters& parameters) const { + return PossiblyEvaluated { + evaluate<Ps>(parameters)... + }; + } + + template <class Writer> + void stringify(Writer& writer) const { + writer.StartObject(); + util::ignore({ (conversion::stringify<Ps>(writer, this->template get<Ps>()), 0)... }); + writer.EndObject(); + } + }; + + class Cascading : public Tuple<CascadingTypes> { + public: + using Tuple<CascadingTypes>::Tuple; + + Unevaluated cascade(const CascadeParameters& parameters, Unevaluated&& prior) const { + return Unevaluated { + this->template get<Ps>() + .cascade(parameters, std::move(prior.template get<Ps>()))... + }; + } + }; +}; + +} // namespace style +} // namespace mbgl diff --git a/src/mbgl/style/style.cpp b/src/mbgl/style/style.cpp index 256949af3b..7a76d289cf 100644 --- a/src/mbgl/style/style.cpp +++ b/src/mbgl/style/style.cpp @@ -584,7 +584,7 @@ RenderData Style::getRenderData(MapDebugOptions debugOptions, float angle) const result.order.emplace_back(*layer); continue; } - const BackgroundPaintProperties::Evaluated& paint = background->evaluated; + const BackgroundPaintProperties::PossiblyEvaluated& paint = background->evaluated; 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>(); |