diff options
author | John Firebaugh <john.firebaugh@gmail.com> | 2018-07-13 18:14:12 -0700 |
---|---|---|
committer | John Firebaugh <john.firebaugh@gmail.com> | 2018-07-20 11:56:30 -0700 |
commit | c8edbb0500cbf4baf1d5fdb0e63679539e166585 (patch) | |
tree | 750f3b72b9e3b1c91ddbc0541cfc64d7d80ffe71 /include/mbgl | |
parent | 6d7072162b764c2432c010cd463a5a2c0093d606 (diff) | |
download | qtlocation-mapboxgl-c8edbb0500cbf4baf1d5fdb0e63679539e166585.tar.gz |
[core] Replace {Source,Camera,Composite}Function with PropertyExpression
Diffstat (limited to 'include/mbgl')
-rw-r--r-- | include/mbgl/style/color_ramp_property_value.hpp | 2 | ||||
-rw-r--r-- | include/mbgl/style/conversion/color_ramp_property_value.hpp | 2 | ||||
-rw-r--r-- | include/mbgl/style/conversion/data_driven_property_value.hpp | 64 | ||||
-rw-r--r-- | include/mbgl/style/conversion/function.hpp | 66 | ||||
-rw-r--r-- | include/mbgl/style/conversion/property_value.hpp | 49 | ||||
-rw-r--r-- | include/mbgl/style/data_driven_property_value.hpp | 40 | ||||
-rw-r--r-- | include/mbgl/style/expression/find_zoom_curve.hpp | 2 | ||||
-rw-r--r-- | include/mbgl/style/function/camera_function.hpp | 70 | ||||
-rw-r--r-- | include/mbgl/style/function/source_function.hpp | 52 | ||||
-rw-r--r-- | include/mbgl/style/property_expression.hpp (renamed from include/mbgl/style/function/composite_function.hpp) | 87 | ||||
-rw-r--r-- | include/mbgl/style/property_value.hpp | 23 |
11 files changed, 164 insertions, 293 deletions
diff --git a/include/mbgl/style/color_ramp_property_value.hpp b/include/mbgl/style/color_ramp_property_value.hpp index 3e93285d5a..bc5639c899 100644 --- a/include/mbgl/style/color_ramp_property_value.hpp +++ b/include/mbgl/style/color_ramp_property_value.hpp @@ -2,7 +2,7 @@ #include <mbgl/util/variant.hpp> #include <mbgl/style/undefined.hpp> -#include <mbgl/style/function/camera_function.hpp> +#include <mbgl/style/expression/expression.hpp> namespace mbgl { namespace style { diff --git a/include/mbgl/style/conversion/color_ramp_property_value.hpp b/include/mbgl/style/conversion/color_ramp_property_value.hpp index cf5d5e55d9..9394daa050 100644 --- a/include/mbgl/style/conversion/color_ramp_property_value.hpp +++ b/include/mbgl/style/conversion/color_ramp_property_value.hpp @@ -3,11 +3,9 @@ #include <mbgl/style/color_ramp_property_value.hpp> #include <mbgl/style/conversion.hpp> #include <mbgl/style/conversion/constant.hpp> -#include <mbgl/style/conversion/function.hpp> #include <mbgl/style/expression/value.hpp> #include <mbgl/style/expression/is_constant.hpp> #include <mbgl/style/expression/is_expression.hpp> -#include <mbgl/style/expression/find_zoom_curve.hpp> #include <mbgl/style/expression/parsing_context.hpp> namespace mbgl { diff --git a/include/mbgl/style/conversion/data_driven_property_value.hpp b/include/mbgl/style/conversion/data_driven_property_value.hpp index 07ed201c99..363134bd3e 100644 --- a/include/mbgl/style/conversion/data_driven_property_value.hpp +++ b/include/mbgl/style/conversion/data_driven_property_value.hpp @@ -6,74 +6,54 @@ #include <mbgl/style/conversion/function.hpp> #include <mbgl/style/expression/is_expression.hpp> #include <mbgl/style/expression/is_constant.hpp> -#include <mbgl/style/expression/find_zoom_curve.hpp> #include <mbgl/style/expression/literal.hpp> #include <mbgl/style/expression/value.hpp> #include <mbgl/style/expression/parsing_context.hpp> -#include <unordered_set> - - namespace mbgl { namespace style { namespace conversion { template <class T> struct Converter<DataDrivenPropertyValue<T>> { - optional<DataDrivenPropertyValue<T>> operator()(const Convertible& value, Error& error) const { using namespace mbgl::style::expression; - + if (isUndefined(value)) { return DataDrivenPropertyValue<T>(); - } else if (isExpression(value)) { + } + + optional<PropertyExpression<T>> expression; + + if (isExpression(value)) { ParsingContext ctx(valueTypeToExpressionType<T>()); - ParseResult expression = ctx.parseLayerPropertyExpression(value); - if (!expression) { + ParseResult parsed = ctx.parseLayerPropertyExpression(value); + if (!parsed) { error = { ctx.getCombinedErrors() }; return {}; } - - bool featureConstant = isFeatureConstant(**expression); - bool zoomConstant = isZoomConstant(**expression); - - if (featureConstant && !zoomConstant) { - return DataDrivenPropertyValue<T>(CameraFunction<T>(std::move(*expression))); - } else if (!featureConstant && zoomConstant) { - return DataDrivenPropertyValue<T>(SourceFunction<T>(std::move(*expression))); - } else if (!featureConstant && !zoomConstant) { - return DataDrivenPropertyValue<T>(CompositeFunction<T>(std::move(*expression))); - } else { - auto literal = dynamic_cast<Literal*>(expression->get()); - assert(literal); - optional<T> constant = fromExpressionValue<T>(literal->getValue()); - if (!constant) { - return {}; - } - return DataDrivenPropertyValue<T>(*constant); - } - } else if (!isObject(value)) { + expression = PropertyExpression<T>(std::move(*parsed)); + } else if (isObject(value)) { + expression = convertFunctionToExpression<T>(value, error); + } else { optional<T> constant = convert<T>(value, error); if (!constant) { return {}; } return DataDrivenPropertyValue<T>(*constant); - } else if (!objectMember(value, "property")) { - optional<CameraFunction<T>> function = convert<CameraFunction<T>>(value, error); - if (!function) { - return {}; - } - return DataDrivenPropertyValue<T>(*function); + } + + if (!expression) { + return {}; + } else if (!(*expression).isFeatureConstant() || !(*expression).isZoomConstant()) { + return { std::move(*expression) }; } else { - optional<CompositeFunction<T>> composite = convert<CompositeFunction<T>>(value, error); - if (composite) { - return DataDrivenPropertyValue<T>(*composite); - } - optional<SourceFunction<T>> source = convert<SourceFunction<T>>(value, error); - if (!source) { + optional<T> constant = fromExpressionValue<T>( + dynamic_cast<const Literal&>((*expression).getExpression()).getValue()); + if (!constant) { return {}; } - return DataDrivenPropertyValue<T>(*source); + return DataDrivenPropertyValue<T>(*constant); } } }; diff --git a/include/mbgl/style/conversion/function.hpp b/include/mbgl/style/conversion/function.hpp index 5ddede324b..6bc75d7141 100644 --- a/include/mbgl/style/conversion/function.hpp +++ b/include/mbgl/style/conversion/function.hpp @@ -1,8 +1,6 @@ #pragma once -#include <mbgl/style/function/camera_function.hpp> -#include <mbgl/style/function/source_function.hpp> -#include <mbgl/style/function/composite_function.hpp> +#include <mbgl/style/property_expression.hpp> #include <mbgl/style/conversion.hpp> #include <mbgl/style/conversion/constant.hpp> #include <mbgl/style/expression/expression.hpp> @@ -12,66 +10,28 @@ namespace mbgl { namespace style { namespace conversion { -template <class T> -optional<optional<T>> convertDefaultValue(const Convertible& value, Error& error) { - auto defaultValueValue = objectMember(value, "default"); - if (!defaultValueValue) { - return optional<T>(); - } +optional<std::unique_ptr<expression::Expression>> convertFunctionToExpression(expression::type::Type, const Convertible&, Error&); - auto defaultValue = convert<T>(*defaultValueValue, error); - if (!defaultValue) { - error = { R"(wrong type for "default": )" + error.message }; +template <class T> +optional<PropertyExpression<T>> convertFunctionToExpression(const Convertible& value, Error& error) { + auto expression = convertFunctionToExpression(expression::valueTypeToExpressionType<T>(), value, error); + if (!expression) { return {}; } - return { *defaultValue }; -} - -optional<std::unique_ptr<expression::Expression>> convertCameraFunctionToExpression(expression::type::Type, const Convertible&, Error&); -optional<std::unique_ptr<expression::Expression>> convertSourceFunctionToExpression(expression::type::Type, const Convertible&, Error&); -optional<std::unique_ptr<expression::Expression>> convertCompositeFunctionToExpression(expression::type::Type, const Convertible&, Error&); + optional<T> defaultValue; -template <class T> -struct Converter<CameraFunction<T>> { - optional<CameraFunction<T>> operator()(const Convertible& value, Error& error) const { - auto expression = convertCameraFunctionToExpression(expression::valueTypeToExpressionType<T>(), value, error); - if (!expression) { - return {}; - } - return CameraFunction<T>(std::move(*expression), false); - } -}; - -template <class T> -struct Converter<SourceFunction<T>> { - optional<SourceFunction<T>> operator()(const Convertible& value, Error& error) const { - auto expression = convertSourceFunctionToExpression(expression::valueTypeToExpressionType<T>(), value, error); - if (!expression) { - return {}; - } - auto defaultValue = convertDefaultValue<T>(value, error); + auto defaultValueValue = objectMember(value, "default"); + if (defaultValueValue) { + defaultValue = convert<T>(*defaultValueValue, error); if (!defaultValue) { + error = { R"(wrong type for "default": )" + error.message }; return {}; } - return SourceFunction<T>(std::move(*expression), *defaultValue); } -}; -template <class T> -struct Converter<CompositeFunction<T>> { - optional<CompositeFunction<T>> operator()(const Convertible& value, Error& error) const { - auto expression = convertCompositeFunctionToExpression(expression::valueTypeToExpressionType<T>(), value, error); - if (!expression) { - return {}; - } - auto defaultValue = convertDefaultValue<T>(value, error); - if (!defaultValue) { - return {}; - } - return CompositeFunction<T>(std::move(*expression), *defaultValue); - } -}; + return PropertyExpression<T>(std::move(*expression), defaultValue); +} } // namespace conversion } // namespace style diff --git a/include/mbgl/style/conversion/property_value.hpp b/include/mbgl/style/conversion/property_value.hpp index e52c63d023..2256cfffb4 100644 --- a/include/mbgl/style/conversion/property_value.hpp +++ b/include/mbgl/style/conversion/property_value.hpp @@ -7,7 +7,6 @@ #include <mbgl/style/expression/value.hpp> #include <mbgl/style/expression/is_constant.hpp> #include <mbgl/style/expression/is_expression.hpp> -#include <mbgl/style/expression/find_zoom_curve.hpp> #include <mbgl/style/expression/parsing_context.hpp> #include <mbgl/style/expression/literal.hpp> @@ -22,34 +21,20 @@ struct Converter<PropertyValue<T>> { if (isUndefined(value)) { return PropertyValue<T>(); - } else if (isExpression(value)) { + } + + optional<PropertyExpression<T>> expression; + + if (isExpression(value)) { ParsingContext ctx(valueTypeToExpressionType<T>()); - ParseResult expression = ctx.parseLayerPropertyExpression(value); - if (!expression) { + ParseResult parsed = ctx.parseLayerPropertyExpression(value); + if (!parsed) { error = { ctx.getCombinedErrors() }; return {}; } - - if (!isFeatureConstant(**expression)) { - error = { "property expressions not supported" }; - return {}; - } else if (!isZoomConstant(**expression)) { - return { CameraFunction<T>(std::move(*expression)) }; - } else { - auto literal = dynamic_cast<Literal*>(expression->get()); - assert(literal); - optional<T> constant = fromExpressionValue<T>(literal->getValue()); - if (!constant) { - return {}; - } - return PropertyValue<T>(*constant); - } + expression = PropertyExpression<T>(std::move(*parsed)); } else if (isObject(value)) { - optional<CameraFunction<T>> function = convert<CameraFunction<T>>(value, error); - if (!function) { - return {}; - } - return { *function }; + expression = convertFunctionToExpression<T>(value, error); } else { optional<T> constant = convert<T>(value, error); if (!constant) { @@ -57,6 +42,22 @@ struct Converter<PropertyValue<T>> { } return { *constant }; } + + if (!expression) { + return {}; + } else if (!(*expression).isFeatureConstant()) { + error = { "data expressions not supported" }; + return {}; + } else if (!(*expression).isZoomConstant()) { + return { std::move(*expression) }; + } else { + optional<T> constant = fromExpressionValue<T>( + dynamic_cast<const Literal&>((*expression).getExpression()).getValue()); + if (!constant) { + return {}; + } + return PropertyValue<T>(*constant); + } } }; diff --git a/include/mbgl/style/data_driven_property_value.hpp b/include/mbgl/style/data_driven_property_value.hpp index 0a1fce29c7..a95eaa4ea8 100644 --- a/include/mbgl/style/data_driven_property_value.hpp +++ b/include/mbgl/style/data_driven_property_value.hpp @@ -2,9 +2,7 @@ #include <mbgl/util/variant.hpp> #include <mbgl/style/undefined.hpp> -#include <mbgl/style/function/camera_function.hpp> -#include <mbgl/style/function/source_function.hpp> -#include <mbgl/style/function/composite_function.hpp> +#include <mbgl/style/property_expression.hpp> namespace mbgl { namespace style { @@ -15,9 +13,7 @@ private: using Value = variant< Undefined, T, - CameraFunction<T>, - SourceFunction<T>, - CompositeFunction<T>>; + PropertyExpression<T>>; Value value; @@ -33,32 +29,40 @@ private: public: DataDrivenPropertyValue() = default; - DataDrivenPropertyValue( T v) : value(std::move(v)) {} - DataDrivenPropertyValue( CameraFunction<T> v) : value(std::move(v)) {} - DataDrivenPropertyValue( SourceFunction<T> v) : value(std::move(v)) {} - DataDrivenPropertyValue(CompositeFunction<T> v) : value(std::move(v)) {} + DataDrivenPropertyValue( T v) : value(std::move(v)) {} + DataDrivenPropertyValue(PropertyExpression<T> v) : value(std::move(v)) {} bool isUndefined() const { return value.template is<Undefined>(); } bool isDataDriven() const { - return value.template is<SourceFunction<T>>() || value.template is<CompositeFunction<T>>(); + return value.match( + [] (const Undefined&) { return false; }, + [] (const T&) { return false; }, + [] (const PropertyExpression<T>& fn) { return !fn.isFeatureConstant(); } + ); } - + bool isZoomConstant() const { - return !value.template is<CameraFunction<T>>() && !value.template is<CompositeFunction<T>>(); + return value.match( + [] (const Undefined&) { return true; }, + [] (const T&) { return true; }, + [] (const PropertyExpression<T>& fn) { return fn.isZoomConstant(); } + ); } bool isExpression() const { return value.match( - [] (const Undefined&) { return false; }, - [] (const T&) { return false; }, - [] (const CameraFunction<T>& fn) { return fn.isExpression; }, - [] (const SourceFunction<T>& fn) { return fn.isExpression; }, - [] (const CompositeFunction<T>& fn) { return fn.isExpression; }); + [] (const Undefined&) { return false; }, + [] (const T&) { return false; }, + [] (const PropertyExpression<T>& fn) { return fn.isExpression; } + ); } + const T & asConstant() const { return value.template get< T >(); } + const PropertyExpression<T>& asExpression() const { return value.template get<PropertyExpression<T>>(); } + template <class... Ts> auto match(Ts&&... ts) const { return value.match(std::forward<Ts>(ts)...); diff --git a/include/mbgl/style/expression/find_zoom_curve.hpp b/include/mbgl/style/expression/find_zoom_curve.hpp index 1e19436dd9..6f1419a69f 100644 --- a/include/mbgl/style/expression/find_zoom_curve.hpp +++ b/include/mbgl/style/expression/find_zoom_curve.hpp @@ -13,7 +13,7 @@ namespace expression { optional<variant<const Interpolate*, const Step*, ParsingError>> findZoomCurve(const expression::Expression* e); -variant<const Interpolate*, const Step*> findZoomCurveChecked(const expression::Expression* e); +variant<std::nullptr_t, const Interpolate*, const Step*> findZoomCurveChecked(const expression::Expression* e); } // namespace expression } // namespace style diff --git a/include/mbgl/style/function/camera_function.hpp b/include/mbgl/style/function/camera_function.hpp deleted file mode 100644 index 65b7991849..0000000000 --- a/include/mbgl/style/function/camera_function.hpp +++ /dev/null @@ -1,70 +0,0 @@ -#pragma once - -#include <mbgl/style/expression/expression.hpp> -#include <mbgl/style/expression/value.hpp> -#include <mbgl/style/expression/is_constant.hpp> -#include <mbgl/style/expression/interpolate.hpp> -#include <mbgl/style/expression/step.hpp> -#include <mbgl/style/expression/find_zoom_curve.hpp> -#include <mbgl/util/range.hpp> - -namespace mbgl { -namespace style { - -template <class T> -class CameraFunction { -public: - // The second parameter should be used only for conversions from legacy functions. - CameraFunction(std::unique_ptr<expression::Expression> expression_, bool isExpression_ = true) - : isExpression(isExpression_), - expression(std::move(expression_)), - zoomCurve(expression::findZoomCurveChecked(expression.get())) { - assert(!expression::isZoomConstant(*expression)); - assert(expression::isFeatureConstant(*expression)); - } - - T evaluate(float zoom) const { - const expression::EvaluationResult result = expression->evaluate(expression::EvaluationContext(zoom, nullptr)); - if (result) { - const optional<T> typed = expression::fromExpressionValue<T>(*result); - return typed ? *typed : T(); - } - return T(); - } - - float interpolationFactor(const Range<float>& inputLevels, const float inputValue) const { - return zoomCurve.match( - [&](const expression::Interpolate* z) { - return z->interpolationFactor(Range<double> { inputLevels.min, inputLevels.max }, inputValue); - }, - [&](const expression::Step*) { return 0.0f; } - ); - } - - Range<float> getCoveringStops(const float lower, const float upper) const { - return zoomCurve.match( - [&](auto z) { return z->getCoveringStops(lower, upper); } - ); - } - - std::vector<optional<T>> possibleOutputs() const { - return expression::fromExpressionValues<T>(expression->possibleOutputs()); - } - - friend bool operator==(const CameraFunction& lhs, - const CameraFunction& rhs) { - return *lhs.expression == *rhs.expression; - } - - bool useIntegerZoom = false; - bool isExpression; - - const expression::Expression& getExpression() const { return *expression; } - -private: - std::shared_ptr<const expression::Expression> expression; - const variant<const expression::Interpolate*, const expression::Step*> zoomCurve; -}; - -} // namespace style -} // namespace mbgl diff --git a/include/mbgl/style/function/source_function.hpp b/include/mbgl/style/function/source_function.hpp deleted file mode 100644 index a83e73a5d0..0000000000 --- a/include/mbgl/style/function/source_function.hpp +++ /dev/null @@ -1,52 +0,0 @@ -#pragma once - -#include <mbgl/style/expression/expression.hpp> -#include <mbgl/style/expression/value.hpp> -#include <mbgl/style/expression/is_constant.hpp> - -namespace mbgl { -namespace style { - -template <class T> -class SourceFunction { -public: - // The second parameter should be used only for conversions from legacy functions. - SourceFunction(std::unique_ptr<expression::Expression> expression_, optional<T> defaultValue_ = {}) - : isExpression(defaultValue_), - expression(std::move(expression_)), - defaultValue(std::move(defaultValue_)) { - assert(expression::isZoomConstant(*expression)); - assert(!expression::isFeatureConstant(*expression)); - } - - template <class Feature> - T evaluate(const Feature& feature, T finalDefaultValue) const { - const expression::EvaluationResult result = expression->evaluate(expression::EvaluationContext(&feature)); - if (result) { - const optional<T> typed = expression::fromExpressionValue<T>(*result); - return typed ? *typed : defaultValue ? *defaultValue : finalDefaultValue; - } - return defaultValue ? *defaultValue : finalDefaultValue; - } - - std::vector<optional<T>> possibleOutputs() const { - return expression::fromExpressionValues<T>(expression->possibleOutputs()); - } - - friend bool operator==(const SourceFunction& lhs, - const SourceFunction& rhs) { - return *lhs.expression == *rhs.expression; - } - - bool useIntegerZoom = false; - bool isExpression; - - const expression::Expression& getExpression() const { return *expression; } - -private: - std::shared_ptr<const expression::Expression> expression; - optional<T> defaultValue; -}; - -} // namespace style -} // namespace mbgl diff --git a/include/mbgl/style/function/composite_function.hpp b/include/mbgl/style/property_expression.hpp index 3b63bd005d..16f154cdf2 100644 --- a/include/mbgl/style/function/composite_function.hpp +++ b/include/mbgl/style/property_expression.hpp @@ -12,29 +12,51 @@ namespace mbgl { namespace style { template <class T> -class CompositeFunction { +class PropertyExpression { public: - // The second parameter should be used only for conversions from legacy functions. - CompositeFunction(std::unique_ptr<expression::Expression> expression_, optional<T> defaultValue_ = {}) - : isExpression(defaultValue_), + PropertyExpression(std::unique_ptr<expression::Expression> expression_) + : isExpression(true), + expression(std::move(expression_)), + zoomCurve(expression::findZoomCurveChecked(expression.get())) { + } + + // To be used only for conversions from legacy functions. + PropertyExpression(std::unique_ptr<expression::Expression> expression_, optional<T> defaultValue_) + : isExpression(false), expression(std::move(expression_)), defaultValue(std::move(defaultValue_)), zoomCurve(expression::findZoomCurveChecked(expression.get())) { + } + + bool isZoomConstant() const { return expression::isZoomConstant(*expression); } + bool isFeatureConstant() const { return expression::isFeatureConstant(*expression); } + + T evaluate(float zoom) const { assert(!expression::isZoomConstant(*expression)); - assert(!expression::isFeatureConstant(*expression)); + assert(expression::isFeatureConstant(*expression)); + const expression::EvaluationResult result = expression->evaluate(expression::EvaluationContext(zoom, nullptr)); + if (result) { + const optional<T> typed = expression::fromExpressionValue<T>(*result); + return typed ? *typed : defaultValue ? *defaultValue : T(); + } + return defaultValue ? *defaultValue : T(); } - // Return the range obtained by evaluating the function at each of the zoom levels in zoomRange template <class Feature> - Range<T> evaluate(const Range<float>& zoomRange, const Feature& feature, T finalDefaultValue) { - return Range<T> { - evaluate(zoomRange.min, feature, finalDefaultValue), - evaluate(zoomRange.max, feature, finalDefaultValue) - }; + T evaluate(const Feature& feature, T finalDefaultValue) const { + assert(expression::isZoomConstant(*expression)); + assert(!expression::isFeatureConstant(*expression)); + const expression::EvaluationResult result = expression->evaluate(expression::EvaluationContext(&feature)); + if (result) { + const optional<T> typed = expression::fromExpressionValue<T>(*result); + return typed ? *typed : defaultValue ? *defaultValue : finalDefaultValue; + } + return defaultValue ? *defaultValue : finalDefaultValue; } template <class Feature> T evaluate(float zoom, const Feature& feature, T finalDefaultValue) const { + assert(!expression::isFeatureConstant(*expression)); const expression::EvaluationResult result = expression->evaluate(expression::EvaluationContext({zoom}, &feature)); if (result) { const optional<T> typed = expression::fromExpressionValue<T>(*result); @@ -42,40 +64,61 @@ public: } return defaultValue ? *defaultValue : finalDefaultValue; } - + float interpolationFactor(const Range<float>& inputLevels, const float inputValue) const { return zoomCurve.match( + [](std::nullptr_t) { + assert(false); + return 0.0f; + }, [&](const expression::Interpolate* z) { return z->interpolationFactor(Range<double> { inputLevels.min, inputLevels.max }, inputValue); }, - [&](const expression::Step*) { return 0.0f; } + [&](const expression::Step*) { + return 0.0f; + } ); } - + Range<float> getCoveringStops(const float lower, const float upper) const { return zoomCurve.match( - [&](auto z) { return z->getCoveringStops(lower, upper); } + [](std::nullptr_t) { + assert(false); + return Range<float>(0.0f, 0.0f); + }, + [&](auto z) { + return z->getCoveringStops(lower, upper); + } ); } - std::vector<optional<T>> possibleOutputs() const { - return expression::fromExpressionValues<T>(expression->possibleOutputs()); + // Return the range obtained by evaluating the function at each of the zoom levels in zoomRange + template <class Feature> + Range<T> evaluate(const Range<float>& zoomRange, const Feature& feature, T finalDefaultValue) { + return Range<T> { + evaluate(zoomRange.min, feature, finalDefaultValue), + evaluate(zoomRange.max, feature, finalDefaultValue) + }; } - friend bool operator==(const CompositeFunction& lhs, - const CompositeFunction& rhs) { - return *lhs.expression == *rhs.expression; + std::vector<optional<T>> possibleOutputs() const { + return expression::fromExpressionValues<T>(expression->possibleOutputs()); } const expression::Expression& getExpression() const { return *expression; } bool useIntegerZoom = false; bool isExpression; - + + friend bool operator==(const PropertyExpression& lhs, + const PropertyExpression& rhs) { + return *lhs.expression == *rhs.expression; + } + private: std::shared_ptr<const expression::Expression> expression; optional<T> defaultValue; - const variant<const expression::Interpolate*, const expression::Step*> zoomCurve; + variant<std::nullptr_t, const expression::Interpolate*, const expression::Step*> zoomCurve; }; } // namespace style diff --git a/include/mbgl/style/property_value.hpp b/include/mbgl/style/property_value.hpp index 02d3a31148..1b0f3d2ab0 100644 --- a/include/mbgl/style/property_value.hpp +++ b/include/mbgl/style/property_value.hpp @@ -2,7 +2,7 @@ #include <mbgl/util/variant.hpp> #include <mbgl/style/undefined.hpp> -#include <mbgl/style/function/camera_function.hpp> +#include <mbgl/style/property_expression.hpp> namespace mbgl { namespace style { @@ -10,7 +10,7 @@ namespace style { template <class T> class PropertyValue { private: - using Value = variant<Undefined, T, CameraFunction<T>>; + using Value = variant<Undefined, T, PropertyExpression<T>>; Value value; friend bool operator==(const PropertyValue& lhs, const PropertyValue& rhs) { @@ -22,17 +22,24 @@ private: } public: - PropertyValue() : value() {} - PropertyValue( T constant) : value(constant) {} - PropertyValue(CameraFunction<T> function) : value(function) {} + PropertyValue() + : value() {} + + PropertyValue(T constant) + : value(constant) {} + + PropertyValue(PropertyExpression<T> expression) + : value(expression) { + assert(expression.isFeatureConstant()); + } bool isUndefined() const { return value.which() == 0; } bool isConstant() const { return value.which() == 1; } - bool isCameraFunction() const { return value.which() == 2; } + bool isExpression() const { return value.which() == 2; } bool isDataDriven() const { return false; } - const T & asConstant() const { return value.template get< T >(); } - const CameraFunction<T>& asCameraFunction() const { return value.template get<CameraFunction<T>>(); } + const T & asConstant() const { return value.template get< T >(); } + const PropertyExpression<T>& asExpression() const { return value.template get<PropertyExpression<T>>(); } template <typename Evaluator> auto evaluate(const Evaluator& evaluator, TimePoint = {}) const { |