summaryrefslogtreecommitdiff
path: root/include/mbgl/style/property_expression.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'include/mbgl/style/property_expression.hpp')
-rw-r--r--include/mbgl/style/property_expression.hpp103
1 files changed, 32 insertions, 71 deletions
diff --git a/include/mbgl/style/property_expression.hpp b/include/mbgl/style/property_expression.hpp
index b198de02b2..32983e2380 100644
--- a/include/mbgl/style/property_expression.hpp
+++ b/include/mbgl/style/property_expression.hpp
@@ -1,7 +1,6 @@
#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>
@@ -11,46 +10,38 @@
namespace mbgl {
namespace style {
-template <class T>
-class PropertyExpression {
+class PropertyExpressionBase {
public:
- // Second parameter to be used only for conversions from legacy functions.
- PropertyExpression(std::unique_ptr<expression::Expression> expression_, optional<T> defaultValue_ = {})
- : expression(std::move(expression_)),
- defaultValue(std::move(defaultValue_)),
- zoomCurve(expression::findZoomCurveChecked(expression.get())) {
- }
+ explicit PropertyExpressionBase(std::unique_ptr<expression::Expression>);
- bool isZoomConstant() const { return expression::isZoomConstant(*expression); }
- bool isFeatureConstant() const { return expression::isFeatureConstant(*expression); }
+ bool isZoomConstant() const noexcept;
+ bool isFeatureConstant() const noexcept;
+ bool canEvaluateWith(const expression::EvaluationContext&) const noexcept;
+ float interpolationFactor(const Range<float>&, const float) const noexcept;
+ Range<float> getCoveringStops(const float, const float) const noexcept;
+ const expression::Expression& getExpression() const noexcept;
- T evaluate(float zoom) const {
- assert(!expression::isZoomConstant(*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();
- }
+ bool useIntegerZoom = false;
- template <class Feature>
- 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;
+protected:
+ std::shared_ptr<const expression::Expression> expression;
+ variant<std::nullptr_t, const expression::Interpolate*, const expression::Step*> zoomCurve;
+ bool isZoomConstant_;
+ bool isFeatureConstant_;
+};
+
+template <class T>
+class PropertyExpression final : public PropertyExpressionBase {
+public:
+ // Second parameter to be used only for conversions from legacy functions.
+ PropertyExpression(std::unique_ptr<expression::Expression> expression_, optional<T> defaultValue_ = nullopt)
+ : PropertyExpressionBase(std::move(expression_)),
+ defaultValue(std::move(defaultValue_)) {
}
- 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));
+ T evaluate(const expression::EvaluationContext& context, T finalDefaultValue = T()) const {
+ assert(canEvaluateWith(context));
+ const expression::EvaluationResult result = expression->evaluate(context);
if (result) {
const optional<T> typed = expression::fromExpressionValue<T>(*result);
return typed ? *typed : defaultValue ? *defaultValue : finalDefaultValue;
@@ -58,59 +49,29 @@ 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;
- }
- );
+ T evaluate(float zoom) const {
+ return evaluate(expression::EvaluationContext(zoom));
}
- Range<float> getCoveringStops(const float lower, const float upper) const {
- return zoomCurve.match(
- [](std::nullptr_t) {
- assert(false);
- return Range<float>(0.0f, 0.0f);
- },
- [&](auto z) {
- return z->getCoveringStops(lower, upper);
- }
- );
+ T evaluate(const GeometryTileFeature& feature, T finalDefaultValue) const {
+ return evaluate(expression::EvaluationContext(&feature), finalDefaultValue);
}
- // 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(float zoom, const GeometryTileFeature& feature, T finalDefaultValue) const {
+ return evaluate(expression::EvaluationContext(zoom, &feature), finalDefaultValue);
}
std::vector<optional<T>> possibleOutputs() const {
return expression::fromExpressionValues<T>(expression->possibleOutputs());
}
- const expression::Expression& getExpression() const { return *expression; }
-
- bool useIntegerZoom = false;
-
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;
- variant<std::nullptr_t, const expression::Interpolate*, const expression::Step*> zoomCurve;
};
} // namespace style