diff options
author | John Firebaugh <john.firebaugh@gmail.com> | 2016-04-25 09:51:47 -0700 |
---|---|---|
committer | John Firebaugh <john.firebaugh@gmail.com> | 2016-04-25 09:51:47 -0700 |
commit | c4089b60bc630ee78c6755ebd7702943a30dd07d (patch) | |
tree | 662db1271ba46939efc6395b97fb609f828876a2 | |
parent | 42043599ffca9658d47792a85c136cb2384e35ed (diff) | |
download | qtlocation-mapboxgl-c4089b60bc630ee78c6755ebd7702943a30dd07d.tar.gz |
[core] Extract Function::evaluation to a separate class (#4811)
This allows the Function<Faded<T>> partial specialization to be eliminated, giving all property functions a consistent storage type.
-rw-r--r-- | include/mbgl/style/types.hpp | 12 | ||||
-rw-r--r-- | src/mbgl/layer/background_layer.hpp | 2 | ||||
-rw-r--r-- | src/mbgl/layer/fill_layer.hpp | 2 | ||||
-rw-r--r-- | src/mbgl/layer/line_layer.hpp | 4 | ||||
-rw-r--r-- | src/mbgl/style/function.hpp | 27 | ||||
-rw-r--r-- | src/mbgl/style/function_evaluator.cpp (renamed from src/mbgl/style/function.cpp) | 47 | ||||
-rw-r--r-- | src/mbgl/style/function_evaluator.hpp | 38 | ||||
-rw-r--r-- | src/mbgl/style/layout_property.hpp | 4 | ||||
-rw-r--r-- | src/mbgl/style/paint_property.hpp | 9 | ||||
-rw-r--r-- | src/mbgl/style/property_parsing.cpp | 46 | ||||
-rw-r--r-- | src/mbgl/util/interpolate.hpp | 1 | ||||
-rw-r--r-- | test/style/functions.cpp | 78 |
12 files changed, 122 insertions, 148 deletions
diff --git a/include/mbgl/style/types.hpp b/include/mbgl/style/types.hpp index ca56d39991..939dbc3a6d 100644 --- a/include/mbgl/style/types.hpp +++ b/include/mbgl/style/types.hpp @@ -21,18 +21,6 @@ struct FontStackHash { std::size_t operator()(const FontStack&) const; }; -template <typename T> -struct Faded { - Faded() = default; - Faded(const T& v) : to(v) {} - - T from; - float fromScale = 0; - T to; - float toScale = 0; - float t = 0; -}; - // ------------------------------------------------------------------------------------------------- enum class SourceType : uint8_t { diff --git a/src/mbgl/layer/background_layer.hpp b/src/mbgl/layer/background_layer.hpp index 786dd0732f..fb9f8b7140 100644 --- a/src/mbgl/layer/background_layer.hpp +++ b/src/mbgl/layer/background_layer.hpp @@ -10,7 +10,7 @@ class BackgroundPaintProperties { public: PaintProperty<float> backgroundOpacity { 1.0f }; PaintProperty<Color> backgroundColor { {{ 0, 0, 0, 1 }} }; - PaintProperty<std::string, Faded<std::string>> backgroundPattern { "" }; + PaintProperty<std::string, CrossFadedFunctionEvaluator> backgroundPattern { "" }; }; class BackgroundLayer : public StyleLayer { diff --git a/src/mbgl/layer/fill_layer.hpp b/src/mbgl/layer/fill_layer.hpp index 3a6f1fbf19..b0740a810f 100644 --- a/src/mbgl/layer/fill_layer.hpp +++ b/src/mbgl/layer/fill_layer.hpp @@ -14,7 +14,7 @@ public: PaintProperty<Color> fillOutlineColor { {{ 0, 0, 0, -1 }} }; PaintProperty<std::array<float, 2>> fillTranslate { {{ 0, 0 }} }; PaintProperty<TranslateAnchorType> fillTranslateAnchor { TranslateAnchorType::Map }; - PaintProperty<std::string, Faded<std::string>> fillPattern { "" }; + PaintProperty<std::string, CrossFadedFunctionEvaluator> fillPattern { "" }; }; class FillLayer : public StyleLayer { diff --git a/src/mbgl/layer/line_layer.hpp b/src/mbgl/layer/line_layer.hpp index 4000b95626..324573d6df 100644 --- a/src/mbgl/layer/line_layer.hpp +++ b/src/mbgl/layer/line_layer.hpp @@ -25,8 +25,8 @@ public: PaintProperty<float> lineGapWidth { 0 }; PaintProperty<float> lineBlur { 0 }; PaintProperty<float> lineOffset { 0 }; - PaintProperty<std::vector<float>, Faded<std::vector<float>>> lineDasharray { {} }; - PaintProperty<std::string, Faded<std::string>> linePattern { "" }; + PaintProperty<std::vector<float>, CrossFadedFunctionEvaluator> lineDasharray { {} }; + PaintProperty<std::string, CrossFadedFunctionEvaluator> linePattern { "" }; }; class LineLayer : public StyleLayer { diff --git a/src/mbgl/style/function.hpp b/src/mbgl/style/function.hpp index f28d71ebaa..c5de6b5db7 100644 --- a/src/mbgl/style/function.hpp +++ b/src/mbgl/style/function.hpp @@ -1,17 +1,11 @@ #ifndef MBGL_STYLE_FUNCTION #define MBGL_STYLE_FUNCTION -#include <mbgl/style/types.hpp> -#include <mbgl/util/chrono.hpp> -#include <mbgl/util/optional.hpp> - #include <vector> #include <utility> namespace mbgl { -class StyleCalculationParameters; - template <typename T> class Function { public: @@ -24,8 +18,6 @@ public: explicit Function(const Stops& stops_, float base_) : base(base_), stops(stops_) {} - T evaluate(const StyleCalculationParameters&) const; - float getBase() const { return base; } const std::vector<std::pair<float, T>>& getStops() const { return stops; } @@ -34,25 +26,6 @@ private: std::vector<std::pair<float, T>> stops; }; -// Partial specialization for cross-faded properties (*-pattern, line-dasharray). -template <typename T> -class Function<Faded<T>> { -public: - using Stop = std::pair<float, T>; - using Stops = std::vector<Stop>; - - explicit Function(const T& constant) - : stops({{ 0, constant }}) {} - - explicit Function(const Stops& stops_) - : stops(stops_) {} - - Faded<T> evaluate(const StyleCalculationParameters&) const; - -private: - std::vector<std::pair<float, T>> stops; -}; - } // namespace mbgl #endif diff --git a/src/mbgl/style/function.cpp b/src/mbgl/style/function_evaluator.cpp index bc3e6074fb..4c60207dac 100644 --- a/src/mbgl/style/function.cpp +++ b/src/mbgl/style/function_evaluator.cpp @@ -1,4 +1,4 @@ -#include <mbgl/style/function.hpp> +#include <mbgl/style/function_evaluator.hpp> #include <mbgl/style/style_calculation_parameters.hpp> #include <mbgl/util/interpolate.hpp> #include <mbgl/util/chrono.hpp> @@ -29,7 +29,9 @@ template <> inline TextTransformType defaultStopsValue() { return {}; }; template <> inline RotationAlignmentType defaultStopsValue() { return {}; }; template <typename T> -T Function<T>::evaluate(const StyleCalculationParameters& parameters) const { +T NormalFunctionEvaluator<T>::operator()(const Function<T>& fn, const StyleCalculationParameters& parameters) const { + float base = fn.getBase(); + const std::vector<std::pair<float, T>>& stops = fn.getStops(); float z = parameters.z; bool smaller = false; float smaller_z = 0.0f; @@ -76,23 +78,23 @@ T Function<T>::evaluate(const StyleCalculationParameters& parameters) const { } } -template class Function<bool>; -template class Function<float>; -template class Function<Color>; -template class Function<std::vector<float>>; -template class Function<std::vector<std::string>>; -template class Function<std::array<float, 2>>; - -template class Function<std::string>; -template class Function<TranslateAnchorType>; -template class Function<RotateAnchorType>; -template class Function<LineCapType>; -template class Function<LineJoinType>; -template class Function<SymbolPlacementType>; -template class Function<TextAnchorType>; -template class Function<TextJustifyType>; -template class Function<TextTransformType>; -template class Function<RotationAlignmentType>; +template class NormalFunctionEvaluator<bool>; +template class NormalFunctionEvaluator<float>; +template class NormalFunctionEvaluator<Color>; +template class NormalFunctionEvaluator<std::vector<float>>; +template class NormalFunctionEvaluator<std::vector<std::string>>; +template class NormalFunctionEvaluator<std::array<float, 2>>; + +template class NormalFunctionEvaluator<std::string>; +template class NormalFunctionEvaluator<TranslateAnchorType>; +template class NormalFunctionEvaluator<RotateAnchorType>; +template class NormalFunctionEvaluator<LineCapType>; +template class NormalFunctionEvaluator<LineJoinType>; +template class NormalFunctionEvaluator<SymbolPlacementType>; +template class NormalFunctionEvaluator<TextAnchorType>; +template class NormalFunctionEvaluator<TextJustifyType>; +template class NormalFunctionEvaluator<TextTransformType>; +template class NormalFunctionEvaluator<RotationAlignmentType>; template <typename T> inline size_t getBiggestStopLessThan(const std::vector<std::pair<float, T>>& stops, float z) { @@ -105,9 +107,10 @@ inline size_t getBiggestStopLessThan(const std::vector<std::pair<float, T>>& sto } template <typename T> -Faded<T> Function<Faded<T>>::evaluate(const StyleCalculationParameters& parameters) const { +Faded<T> CrossFadedFunctionEvaluator<T>::operator()(const Function<T>& fn, const StyleCalculationParameters& parameters) const { Faded<T> result; + const std::vector<std::pair<float, T>>& stops = fn.getStops(); float z = parameters.z; const float fraction = z - std::floor(z); std::chrono::duration<float> d = parameters.defaultFadeDuration; @@ -136,7 +139,7 @@ Faded<T> Function<Faded<T>>::evaluate(const StyleCalculationParameters& paramete return result; } -template class Function<Faded<std::string>>; -template class Function<Faded<std::vector<float>>>; +template class CrossFadedFunctionEvaluator<std::string>; +template class CrossFadedFunctionEvaluator<std::vector<float>>; } // namespace mbgl diff --git a/src/mbgl/style/function_evaluator.hpp b/src/mbgl/style/function_evaluator.hpp new file mode 100644 index 0000000000..3a73ec9090 --- /dev/null +++ b/src/mbgl/style/function_evaluator.hpp @@ -0,0 +1,38 @@ +#ifndef MBGL_STYLE_FUNCTION_EVALUATOR +#define MBGL_STYLE_FUNCTION_EVALUATOR + +#include <mbgl/style/function.hpp> + +namespace mbgl { + +class StyleCalculationParameters; + +template <typename T> +class NormalFunctionEvaluator { +public: + using ResultType = T; + T operator()(const Function<T>&, const StyleCalculationParameters&) const; +}; + +template <typename T> +struct Faded { + Faded() = default; + Faded(const T& v) : to(v) {} + + T from; + float fromScale = 0; + T to; + float toScale = 0; + float t = 0; +}; + +template <typename T> +class CrossFadedFunctionEvaluator { +public: + using ResultType = Faded<T>; + Faded<T> operator()(const Function<T>&, const StyleCalculationParameters&) const; +}; + +} // namespace mbgl + +#endif diff --git a/src/mbgl/style/layout_property.hpp b/src/mbgl/style/layout_property.hpp index a35728d874..894fc44467 100644 --- a/src/mbgl/style/layout_property.hpp +++ b/src/mbgl/style/layout_property.hpp @@ -3,6 +3,7 @@ #include <mbgl/style/property_parsing.hpp> #include <mbgl/style/function.hpp> +#include <mbgl/style/function_evaluator.hpp> #include <mbgl/util/rapidjson.hpp> #include <utility> @@ -22,7 +23,8 @@ public: void calculate(const StyleCalculationParameters& parameters) { if (parsedValue) { - value = (*parsedValue).evaluate(parameters); + NormalFunctionEvaluator<T> evaluator; + value = evaluator(*parsedValue, parameters); } } diff --git a/src/mbgl/style/paint_property.hpp b/src/mbgl/style/paint_property.hpp index e742b2c109..124b0a7c0a 100644 --- a/src/mbgl/style/paint_property.hpp +++ b/src/mbgl/style/paint_property.hpp @@ -4,6 +4,7 @@ #include <mbgl/style/class_dictionary.hpp> #include <mbgl/style/property_parsing.hpp> #include <mbgl/style/function.hpp> +#include <mbgl/style/function_evaluator.hpp> #include <mbgl/style/property_transition.hpp> #include <mbgl/style/style_cascade_parameters.hpp> #include <mbgl/style/style_calculation_parameters.hpp> @@ -16,10 +17,11 @@ namespace mbgl { -template <typename T, typename Result = T> +template <class T, template <class S> class Evaluator = NormalFunctionEvaluator> class PaintProperty { public: - using Fn = Function<Result>; + using Fn = Function<T>; + using Result = typename Evaluator<T>::ResultType; explicit PaintProperty(T fallbackValue) : value(fallbackValue) { @@ -114,7 +116,8 @@ public: } Result calculate(const StyleCalculationParameters& parameters) { - Result final = value.evaluate(parameters); + Evaluator<T> evaluator; + Result final = evaluator(value, parameters); if (!prior) { // No prior value. return final; diff --git a/src/mbgl/style/property_parsing.cpp b/src/mbgl/style/property_parsing.cpp index 6f052222e4..9932451975 100644 --- a/src/mbgl/style/property_parsing.cpp +++ b/src/mbgl/style/property_parsing.cpp @@ -363,50 +363,12 @@ template<> optional<Function<Color>> parseProperty(const char* name, const JSVal return parseFunction<Color>(name, value); } -template<> optional<Function<std::vector<std::string>>> parseProperty(const char* name, const JSValue& value) { - return parseFunction<std::vector<std::string>>(name, value); -} - -template <typename T> -optional<Function<Faded<T>>> parseFadedFunction(const JSValue& value) { - if (!value.HasMember("stops")) { - Log::Warning(Event::ParseStyle, "function must specify a function type"); - return {}; - } - - auto stops = parseStops<T>("", value["stops"]); - - if (!stops) { - return {}; - } - - return Function<Faded<T>>(*stops); +template<> optional<Function<std::vector<float>>> parseProperty(const char* name, const JSValue& value) { + return parseFunction<std::vector<float>>(name, value); } -template <> -optional<Function<Faded<std::vector<float>>>> parseProperty(const char* name, const JSValue& value) { - if (value.IsObject()) { - return parseFadedFunction<std::vector<float>>(value); - } - - auto constant = parseProperty<std::vector<float>>(name, value); - if (!constant) { - return {}; - } - return Function<Faded<std::vector<float>>>(*constant); -} - -template <> -optional<Function<Faded<std::string>>> parseProperty(const char* name, const JSValue& value) { - if (value.IsObject()) { - return parseFadedFunction<std::string>(value); - } - - auto constant = parseProperty<std::string>(name, value); - if (!constant) { - return {}; - } - return Function<Faded<std::string>>(*constant); +template<> optional<Function<std::vector<std::string>>> parseProperty(const char* name, const JSValue& value) { + return parseFunction<std::vector<std::string>>(name, value); } } // namespace mbgl diff --git a/src/mbgl/util/interpolate.hpp b/src/mbgl/util/interpolate.hpp index f456a0ecb1..c2b7afcb89 100644 --- a/src/mbgl/util/interpolate.hpp +++ b/src/mbgl/util/interpolate.hpp @@ -5,6 +5,7 @@ #include <vector> #include <mbgl/style/types.hpp> +#include <mbgl/style/function_evaluator.hpp> namespace mbgl { namespace util { diff --git a/test/style/functions.cpp b/test/style/functions.cpp index 26b952d7b4..2389459dbc 100644 --- a/test/style/functions.cpp +++ b/test/style/functions.cpp @@ -2,58 +2,62 @@ #include <mbgl/test/util.hpp> #include <mbgl/style/function.hpp> +#include <mbgl/style/function_evaluator.hpp> #include <mbgl/style/style_calculation_parameters.hpp> using namespace mbgl; TEST(Function, Constant) { - EXPECT_EQ(2.0f, mbgl::Function<float>(2).evaluate(StyleCalculationParameters(0))); - EXPECT_EQ(3.8f, mbgl::Function<float>(3.8).evaluate(StyleCalculationParameters(0))); - EXPECT_EQ(22.0f, mbgl::Function<float>(22).evaluate(StyleCalculationParameters(0))); - EXPECT_EQ(2.0f, mbgl::Function<float>(2).evaluate(StyleCalculationParameters(4))); - EXPECT_EQ(3.8f, mbgl::Function<float>(3.8).evaluate(StyleCalculationParameters(4))); - EXPECT_EQ(22.0f, mbgl::Function<float>(22).evaluate(StyleCalculationParameters(4))); - EXPECT_EQ(2.0f, mbgl::Function<float>(2).evaluate(StyleCalculationParameters(22))); - EXPECT_EQ(3.8f, mbgl::Function<float>(3.8).evaluate(StyleCalculationParameters(22))); - EXPECT_EQ(22.0f, mbgl::Function<float>(22).evaluate(StyleCalculationParameters(22))); + NormalFunctionEvaluator<float> evaluate; + EXPECT_EQ(2.0f, evaluate(Function<float>(2), StyleCalculationParameters(0))); + EXPECT_EQ(3.8f, evaluate(Function<float>(3.8), StyleCalculationParameters(0))); + EXPECT_EQ(22.0f, evaluate(Function<float>(22), StyleCalculationParameters(0))); + EXPECT_EQ(2.0f, evaluate(Function<float>(2), StyleCalculationParameters(4))); + EXPECT_EQ(3.8f, evaluate(Function<float>(3.8), StyleCalculationParameters(4))); + EXPECT_EQ(22.0f, evaluate(Function<float>(22), StyleCalculationParameters(4))); + EXPECT_EQ(2.0f, evaluate(Function<float>(2), StyleCalculationParameters(22))); + EXPECT_EQ(3.8f, evaluate(Function<float>(3.8), StyleCalculationParameters(22))); + EXPECT_EQ(22.0f, evaluate(Function<float>(22), StyleCalculationParameters(22))); } TEST(Function, Stops) { + NormalFunctionEvaluator<float> evaluate; + // Explicit constant slope in fringe regions. - mbgl::Function<float> slope_1({ { 0, 1.5 }, { 6, 1.5 }, { 8, 3 }, { 22, 3 } }, 1.75); - EXPECT_EQ(1.5, slope_1.evaluate(StyleCalculationParameters(0))); - EXPECT_EQ(1.5, slope_1.evaluate(StyleCalculationParameters(4))); - EXPECT_EQ(1.5, slope_1.evaluate(StyleCalculationParameters(6))); - ASSERT_FLOAT_EQ(2.0454545454545454, slope_1.evaluate(StyleCalculationParameters(7))); - EXPECT_EQ(3.0, slope_1.evaluate(StyleCalculationParameters(8))); - EXPECT_EQ(3.0, slope_1.evaluate(StyleCalculationParameters(9))); - EXPECT_EQ(3.0, slope_1.evaluate(StyleCalculationParameters(15))); - EXPECT_EQ(3.0, slope_1.evaluate(StyleCalculationParameters(22))); + Function<float> slope_1({ { 0, 1.5 }, { 6, 1.5 }, { 8, 3 }, { 22, 3 } }, 1.75); + EXPECT_EQ(1.5, evaluate(slope_1, StyleCalculationParameters(0))); + EXPECT_EQ(1.5, evaluate(slope_1, StyleCalculationParameters(4))); + EXPECT_EQ(1.5, evaluate(slope_1, StyleCalculationParameters(6))); + ASSERT_FLOAT_EQ(2.0454545454545454, evaluate(slope_1, StyleCalculationParameters(7))); + EXPECT_EQ(3.0, evaluate(slope_1, StyleCalculationParameters(8))); + EXPECT_EQ(3.0, evaluate(slope_1, StyleCalculationParameters(9))); + EXPECT_EQ(3.0, evaluate(slope_1, StyleCalculationParameters(15))); + EXPECT_EQ(3.0, evaluate(slope_1, StyleCalculationParameters(22))); // Test constant values in fringe regions. - mbgl::Function<float> slope_2({ { 6, 1.5 }, { 8, 3 } }, 1.75); - EXPECT_EQ(1.5, slope_2.evaluate(StyleCalculationParameters(0))); - EXPECT_EQ(1.5, slope_2.evaluate(StyleCalculationParameters(4))); - EXPECT_EQ(1.5, slope_2.evaluate(StyleCalculationParameters(6))); - ASSERT_FLOAT_EQ(2.0454545454545454, slope_2.evaluate(StyleCalculationParameters(7))); - EXPECT_EQ(3.0, slope_2.evaluate(StyleCalculationParameters(8))); - EXPECT_EQ(3.0, slope_2.evaluate(StyleCalculationParameters(9))); - EXPECT_EQ(3.0, slope_2.evaluate(StyleCalculationParameters(15))); - EXPECT_EQ(3.0, slope_2.evaluate(StyleCalculationParameters(22))); + Function<float> slope_2({ { 6, 1.5 }, { 8, 3 } }, 1.75); + EXPECT_EQ(1.5, evaluate(slope_2, StyleCalculationParameters(0))); + EXPECT_EQ(1.5, evaluate(slope_2, StyleCalculationParameters(4))); + EXPECT_EQ(1.5, evaluate(slope_2, StyleCalculationParameters(6))); + ASSERT_FLOAT_EQ(2.0454545454545454, evaluate(slope_2, StyleCalculationParameters(7))); + EXPECT_EQ(3.0, evaluate(slope_2, StyleCalculationParameters(8))); + EXPECT_EQ(3.0, evaluate(slope_2, StyleCalculationParameters(9))); + EXPECT_EQ(3.0, evaluate(slope_2, StyleCalculationParameters(15))); + EXPECT_EQ(3.0, evaluate(slope_2, StyleCalculationParameters(22))); // Test no values. - mbgl::Function<float> slope_3({}, 1.75); - EXPECT_EQ(1, slope_3.evaluate(StyleCalculationParameters(2))); - EXPECT_EQ(1, slope_3.evaluate(StyleCalculationParameters(6))); - EXPECT_EQ(1, slope_3.evaluate(StyleCalculationParameters(12))); + Function<float> slope_3({}, 1.75); + EXPECT_EQ(1, evaluate(slope_3, StyleCalculationParameters(2))); + EXPECT_EQ(1, evaluate(slope_3, StyleCalculationParameters(6))); + EXPECT_EQ(1, evaluate(slope_3, StyleCalculationParameters(12))); // Explicit constant slope in fringe regions. - mbgl::Function<float> slope_4({ { 0, 2 }, { 8, 10 } }, 1); - EXPECT_EQ(2, slope_4.evaluate(StyleCalculationParameters(0))); - EXPECT_EQ(3, slope_4.evaluate(StyleCalculationParameters(1))); - EXPECT_EQ(4, slope_4.evaluate(StyleCalculationParameters(2))); - EXPECT_EQ(4.75, slope_4.evaluate(StyleCalculationParameters(2.75))); - EXPECT_EQ(10, slope_4.evaluate(StyleCalculationParameters(8))); + Function<float> slope_4({ { 0, 2 }, { 8, 10 } }, 1); + EXPECT_EQ(2, evaluate(slope_4, StyleCalculationParameters(0))); + EXPECT_EQ(3, evaluate(slope_4, StyleCalculationParameters(1))); + EXPECT_EQ(4, evaluate(slope_4, StyleCalculationParameters(2))); + EXPECT_EQ(4.75, evaluate(slope_4, StyleCalculationParameters(2.75))); + EXPECT_EQ(10, evaluate(slope_4, StyleCalculationParameters(8))); } |