From 3a8aaad6a799fd4ab1feb47a47a7ffa0d05c1cc0 Mon Sep 17 00:00:00 2001 From: Ansis Brammanis Date: Thu, 5 Feb 2015 15:56:46 -0800 Subject: [PATCH] make everything a function --- src/mbgl/style/function_properties.cpp | 20 +++ src/mbgl/style/property_value.hpp | 21 ++-- src/mbgl/style/style_parser.cpp | 162 +++++++++++++------------ src/mbgl/style/style_parser.hpp | 4 +- src/mbgl/util/interpolate.hpp | 20 ++- 5 files changed, 133 insertions(+), 94 deletions(-) diff --git a/src/mbgl/style/function_properties.cpp b/src/mbgl/style/function_properties.cpp index 81b1c85c7..2ea3682b8 100644 --- a/src/mbgl/style/function_properties.cpp +++ b/src/mbgl/style/function_properties.cpp @@ -14,6 +14,16 @@ template <> inline float defaultStopsValue() { return 1.0f; } template <> inline Color defaultStopsValue() { return {{ 0, 0, 0, 1 }}; } template <> inline std::vector defaultStopsValue() { return {{ 1, 0 }}; } +template <> inline std:: string defaultStopsValue() { return {}; } +template <> inline TranslateAnchorType defaultStopsValue() { return {}; }; +template <> inline RotateAnchorType defaultStopsValue() { return {}; }; +template <> inline CapType defaultStopsValue() { return {}; }; +template <> inline JoinType defaultStopsValue() { return {}; }; +template <> inline PlacementType defaultStopsValue() { return {}; }; +template <> inline TextAnchorType defaultStopsValue() { return {}; }; +template <> inline TextJustifyType defaultStopsValue() { return {}; }; +template <> inline TextTransformType defaultStopsValue() { return {}; }; +template <> inline RotationAlignmentType defaultStopsValue() { return {}; }; template T StopsFunction::evaluate(float z) const { @@ -67,4 +77,14 @@ template float StopsFunction::evaluate(float z) const; template Color StopsFunction::evaluate(float z) const; template std::vector StopsFunction>::evaluate(float z) const; +template std::string StopsFunction::evaluate(float z) const; +template TranslateAnchorType StopsFunction::evaluate(float z) const; +template RotateAnchorType StopsFunction::evaluate(float z) const; +template CapType StopsFunction::evaluate(float z) const; +template JoinType StopsFunction::evaluate(float z) const; +template PlacementType StopsFunction::evaluate(float z) const; +template TextAnchorType StopsFunction::evaluate(float z) const; +template TextJustifyType StopsFunction::evaluate(float z) const; +template TextTransformType StopsFunction::evaluate(float z) const; +template RotationAlignmentType StopsFunction::evaluate(float z) const; } diff --git a/src/mbgl/style/property_value.hpp b/src/mbgl/style/property_value.hpp index c7fe82302..00f72ea64 100644 --- a/src/mbgl/style/property_value.hpp +++ b/src/mbgl/style/property_value.hpp @@ -11,18 +11,17 @@ namespace mbgl { typedef mapbox::util::variant< - std::string, - TranslateAnchorType, - RotateAnchorType, - bool, - CapType, - JoinType, + Function, + Function, + Function, + Function, + Function, VisibilityType, - PlacementType, - RotationAlignmentType, - TextTransformType, - TextJustifyType, - TextAnchorType, + Function, + Function, + Function, + Function, + Function, Function, Function, Function, diff --git a/src/mbgl/style/style_parser.cpp b/src/mbgl/style/style_parser.cpp index 4120ef470..15a9f64aa 100644 --- a/src/mbgl/style/style_parser.cpp +++ b/src/mbgl/style/style_parser.cpp @@ -228,53 +228,40 @@ std::tuple> parseFloatArray(JSVal value) { } template <> -bool StyleParser::parseFunctionArgument(JSVal value) { - JSVal rvalue = replaceConstant(value); - if (rvalue.IsBool()) { - return rvalue.GetBool(); - } else if (rvalue.IsNumber()) { - return rvalue.GetDouble(); - } else { - Log::Warning(Event::ParseStyle, "function argument must be a boolean or numeric value"); - return false; - } -} - -template <> -float StyleParser::parseFunctionArgument(JSVal value) { +std::tuple StyleParser::parseProperty(JSVal value, const char*) { JSVal rvalue = replaceConstant(value); if (rvalue.IsNumber()) { - return rvalue.GetDouble(); + return { true, rvalue.GetDouble() }; } else { Log::Warning(Event::ParseStyle, "function argument must be a numeric value"); - return 0.0f; + return { false, 0.0f }; } } template <> -Color StyleParser::parseFunctionArgument(JSVal value) { +std::tuple StyleParser::parseProperty(JSVal value, const char*) { JSVal rvalue = replaceConstant(value); - return parseColor(rvalue); + return { true, parseColor(rvalue) }; } template <> -Faded> StyleParser::parseFunctionArgument(JSVal value) { +std::tuple>> StyleParser::parseProperty(JSVal value, const char*) { Faded> parsed; JSVal rvalue = replaceConstant(value); parsed.to = std::get<1>(parseFloatArray(rvalue)); - return parsed; + return { true, parsed }; } template <> -Faded StyleParser::parseFunctionArgument(JSVal value) { +std::tuple> StyleParser::parseProperty(JSVal value, const char*) { JSVal rvalue = replaceConstant(value); Faded parsed; if (rvalue.IsString()) { parsed.to = { value.GetString(), value.GetStringLength() }; - return parsed; + return { true, parsed }; } else { Log::Warning(Event::ParseStyle, "function argument must be a string"); - return parsed; + return { false, parsed }; } } @@ -302,7 +289,7 @@ std::tuple>> StyleParser::parseStops(JSVal return std::tuple>> { false, {}}; } - stops.emplace_back(z.GetDouble(), parseFunctionArgument(stop[rapidjson::SizeType(1)])); + stops.emplace_back(z.GetDouble(), std::get<1>(parseProperty(replaceConstant(stop[rapidjson::SizeType(1)]), ""))); } else { Log::Warning(Event::ParseStyle, "function argument must be a numeric value"); return std::tuple>> { false, {}}; @@ -315,7 +302,12 @@ template inline float defaultBaseValue() { return 1.75; } template <> inline float defaultBaseValue() { return 1.0; } template -std::tuple> StyleParser::parseFunction(JSVal value) { +std::tuple> StyleParser::parseFunction(JSVal value, const char *) { + + if (!value.IsObject()) { + return std::tuple> { true, ConstantFunction(std::get<1>(parseProperty(value, ""))) }; + } + if (!value.HasMember("stops")) { Log::Warning(Event::ParseStyle, "function must specify a function type"); return std::tuple> { false, ConstantFunction(T()) }; @@ -528,41 +520,57 @@ template<> std::tuple StyleParser::parseProperty(JSVal return std::tuple { true, std::move(transition) }; } +template<> std::tuple> StyleParser::parseProperty(JSVal value, const char *property_name) { + return parseFunction(value, property_name); +} + +template<> std::tuple> StyleParser::parseProperty(JSVal value, const char *property_name) { + return parseFunction(value, property_name); +} + +template<> std::tuple> StyleParser::parseProperty(JSVal value, const char *property_name) { + return parseFunction(value, property_name); +} + +template<> std::tuple> StyleParser::parseProperty(JSVal value, const char *property_name) { + return parseFunction(value, property_name); +} + +template<> std::tuple> StyleParser::parseProperty(JSVal value, const char *property_name) { + return parseFunction(value, property_name); +} + +template<> std::tuple> StyleParser::parseProperty(JSVal value, const char *property_name) { + return parseFunction(value, property_name); +} + +template<> std::tuple> StyleParser::parseProperty(JSVal value, const char *property_name) { + return parseFunction(value, property_name); +} + +template<> std::tuple> StyleParser::parseProperty(JSVal value, const char *property_name) { + return parseFunction(value, property_name); +} + +template<> std::tuple> StyleParser::parseProperty(JSVal value, const char *property_name) { + return parseFunction(value, property_name); +} + +template<> std::tuple> StyleParser::parseProperty(JSVal value, const char *property_name) { + return parseFunction(value, property_name); +} + + template<> std::tuple> StyleParser::parseProperty(JSVal value, const char *property_name) { - if (value.IsObject()) { - return parseFunction(value); - } else if (value.IsNumber()) { - return std::tuple> { true, ConstantFunction(value.GetDouble()) }; - } else if (value.IsBool()) { - return std::tuple> { true, ConstantFunction(value.GetBool()) }; - } else { - Log::Warning(Event::ParseStyle, "value of '%s' must be convertible to boolean, or a boolean function", property_name); - return std::tuple> { false, ConstantFunction(false) }; - } + return parseFunction(value, property_name); } template<> std::tuple> StyleParser::parseProperty(JSVal value, const char *property_name) { - if (value.IsObject()) { - return parseFunction(value); - } else if (value.IsNumber()) { - return std::tuple> { true, ConstantFunction(value.GetDouble()) }; - } else if (value.IsBool()) { - return std::tuple> { true, ConstantFunction(value.GetBool()) }; - } else { - Log::Warning(Event::ParseStyle, "value of '%s' must be a number, or a number function", property_name); - return std::tuple> { false, ConstantFunction(0) }; - } + return parseFunction(value, property_name); } template<> std::tuple> StyleParser::parseProperty(JSVal value, const char *property_name) { - if (value.IsObject()) { - return parseFunction(value); - } else if (value.IsString()) { - return std::tuple> { true, ConstantFunction(parseColor(value)) }; - } else { - Log::Warning(Event::ParseStyle, "value of '%s' must be a color, or a color function", property_name); - return std::tuple> { false, ConstantFunction(Color {{ 0, 0, 0, 0 }}) }; - } + return parseFunction(value, property_name); } template<> std::tuple>>> StyleParser::parseProperty(JSVal value, const char *property_name, JSVal transition) { @@ -745,7 +753,7 @@ void StyleParser::parsePaint(JSVal value, ClassProperties &klass) { parseOptionalProperty("fill-outline-color-transition", Key::FillOutlineColor, klass, value); parseOptionalProperty>("fill-translate", { Key::FillTranslateX, Key::FillTranslateY }, klass, value); parseOptionalProperty("fill-translate-transition", Key::FillTranslate, klass, value); - parseOptionalProperty("fill-translate-anchor", Key::FillTranslateAnchor, klass, value); + parseOptionalProperty>("fill-translate-anchor", Key::FillTranslateAnchor, klass, value); parseOptionalProperty>>("fill-image", Key::FillImage, klass, value, "fill-image-transition"); parseOptionalProperty>("line-opacity", Key::LineOpacity, klass, value); @@ -754,7 +762,7 @@ void StyleParser::parsePaint(JSVal value, ClassProperties &klass) { parseOptionalProperty("line-color-transition", Key::LineColor, klass, value); parseOptionalProperty>("line-translate", { Key::LineTranslateX, Key::LineTranslateY }, klass, value); parseOptionalProperty("line-translate-transition", Key::LineTranslate, klass, value); - parseOptionalProperty("line-translate-anchor", Key::LineTranslateAnchor, klass, value); + parseOptionalProperty>("line-translate-anchor", Key::LineTranslateAnchor, klass, value); parseOptionalProperty>("line-width", Key::LineWidth, klass, value); parseOptionalProperty("line-width-transition", Key::LineWidth, klass, value); parseOptionalProperty>("line-gap-width", Key::LineGapWidth, klass, value); @@ -779,7 +787,7 @@ void StyleParser::parsePaint(JSVal value, ClassProperties &klass) { parseOptionalProperty("icon-halo-blur-transition", Key::IconHaloBlur, klass, value); parseOptionalProperty>("icon-translate", { Key::IconTranslateX, Key::IconTranslateY }, klass, value); parseOptionalProperty("icon-translate-transition", Key::IconTranslate, klass, value); - parseOptionalProperty("icon-translate-anchor", Key::IconTranslateAnchor, klass, value); + parseOptionalProperty>("icon-translate-anchor", Key::IconTranslateAnchor, klass, value); parseOptionalProperty>("text-opacity", Key::TextOpacity, klass, value); parseOptionalProperty("text-opacity-transition", Key::TextOpacity, klass, value); @@ -795,7 +803,7 @@ void StyleParser::parsePaint(JSVal value, ClassProperties &klass) { parseOptionalProperty("text-halo-blur-transition", Key::TextHaloBlur, klass, value); parseOptionalProperty>("text-translate", { Key::TextTranslateX, Key::TextTranslateY }, klass, value); parseOptionalProperty("text-translate-transition", Key::TextTranslate, klass, value); - parseOptionalProperty("text-translate-anchor", Key::TextTranslateAnchor, klass, value); + parseOptionalProperty>("text-translate-anchor", Key::TextTranslateAnchor, klass, value); parseOptionalProperty>("raster-opacity", Key::RasterOpacity, klass, value); parseOptionalProperty("raster-opacity-transition", Key::RasterOpacity, klass, value); @@ -820,42 +828,42 @@ void StyleParser::parseLayout(JSVal value, util::ptr &bucket) { parseVisibility(*bucket, value); - parseOptionalProperty("line-cap", Key::LineCap, bucket->layout, value); - parseOptionalProperty("line-join", Key::LineJoin, bucket->layout, value); + parseOptionalProperty>("line-cap", Key::LineCap, bucket->layout, value); + parseOptionalProperty>("line-join", Key::LineJoin, bucket->layout, value); parseOptionalProperty>("line-miter-limit", Key::LineMiterLimit, bucket->layout, value); parseOptionalProperty>("line-round-limit", Key::LineRoundLimit, bucket->layout, value); - parseOptionalProperty("symbol-placement", Key::SymbolPlacement, bucket->layout, value); + parseOptionalProperty>("symbol-placement", Key::SymbolPlacement, bucket->layout, value); parseOptionalProperty>("symbol-min-distance", Key::SymbolMinDistance, bucket->layout, value); - parseOptionalProperty("symbol-avoid-edges", Key::SymbolAvoidEdges, bucket->layout, value); - parseOptionalProperty("icon-allow-overlap", Key::IconAllowOverlap, bucket->layout, value); - parseOptionalProperty("icon-ignore-placement", Key::IconIgnorePlacement, bucket->layout, value); - parseOptionalProperty("icon-optional", Key::IconOptional, bucket->layout, value); - parseOptionalProperty("icon-rotation-alignment", Key::IconRotationAlignment, bucket->layout, value); + parseOptionalProperty>("symbol-avoid-edges", Key::SymbolAvoidEdges, bucket->layout, value); + parseOptionalProperty>("icon-allow-overlap", Key::IconAllowOverlap, bucket->layout, value); + parseOptionalProperty>("icon-ignore-placement", Key::IconIgnorePlacement, bucket->layout, value); + parseOptionalProperty>("icon-optional", Key::IconOptional, bucket->layout, value); + parseOptionalProperty>("icon-rotation-alignment", Key::IconRotationAlignment, bucket->layout, value); parseOptionalProperty>("icon-max-size", Key::IconMaxSize, bucket->layout, value); - parseOptionalProperty("icon-image", Key::IconImage, bucket->layout, value); + parseOptionalProperty>("icon-image", Key::IconImage, bucket->layout, value); parseOptionalProperty>("icon-rotate", Key::IconRotate, bucket->layout, value); parseOptionalProperty>("icon-padding", Key::IconPadding, bucket->layout, value); - parseOptionalProperty("icon-keep-upright", Key::IconKeepUpright, bucket->layout, value); + parseOptionalProperty>("icon-keep-upright", Key::IconKeepUpright, bucket->layout, value); parseOptionalProperty>("icon-offset", { Key::IconOffsetX, Key::IconOffsetY }, bucket->layout, value); - parseOptionalProperty("text-rotation-alignment", Key::TextRotationAlignment, bucket->layout, value); - parseOptionalProperty("text-field", Key::TextField, bucket->layout, value); - parseOptionalProperty("text-font", Key::TextFont, bucket->layout, value); + parseOptionalProperty>("text-rotation-alignment", Key::TextRotationAlignment, bucket->layout, value); + parseOptionalProperty>("text-field", Key::TextField, bucket->layout, value); + parseOptionalProperty>("text-font", Key::TextFont, bucket->layout, value); parseOptionalProperty>("text-max-size", Key::TextMaxSize, bucket->layout, value); parseOptionalProperty>("text-max-width", Key::TextMaxWidth, bucket->layout, value); parseOptionalProperty>("text-line-height", Key::TextLineHeight, bucket->layout, value); parseOptionalProperty>("text-letter-spacing", Key::TextLetterSpacing, bucket->layout, value); - parseOptionalProperty("text-justify", Key::TextJustify, bucket->layout, value); - parseOptionalProperty("text-anchor", Key::TextAnchor, bucket->layout, value); + parseOptionalProperty>("text-justify", Key::TextJustify, bucket->layout, value); + parseOptionalProperty>("text-anchor", Key::TextAnchor, bucket->layout, value); parseOptionalProperty>("text-max-angle", Key::TextMaxAngle, bucket->layout, value); parseOptionalProperty>("text-rotate", Key::TextRotate, bucket->layout, value); parseOptionalProperty>("text-padding", Key::TextPadding, bucket->layout, value); - parseOptionalProperty("text-keep-upright", Key::TextKeepUpright, bucket->layout, value); - parseOptionalProperty("text-transform", Key::TextTransform, bucket->layout, value); + parseOptionalProperty>("text-keep-upright", Key::TextKeepUpright, bucket->layout, value); + parseOptionalProperty>("text-transform", Key::TextTransform, bucket->layout, value); parseOptionalProperty>("text-offset", { Key::TextOffsetX, Key::TextOffsetY }, bucket->layout, value); - parseOptionalProperty("text-allow-overlap", Key::TextAllowOverlap, bucket->layout, value); - parseOptionalProperty("text-ignore-placement", Key::TextIgnorePlacement, bucket->layout, value); - parseOptionalProperty("text-optional", Key::TextOptional, bucket->layout, value); + parseOptionalProperty>("text-allow-overlap", Key::TextAllowOverlap, bucket->layout, value); + parseOptionalProperty>("text-ignore-placement", Key::TextIgnorePlacement, bucket->layout, value); + parseOptionalProperty>("text-optional", Key::TextOptional, bucket->layout, value); } diff --git a/src/mbgl/style/style_parser.hpp b/src/mbgl/style/style_parser.hpp index d25c70579..a32e6dd1d 100644 --- a/src/mbgl/style/style_parser.hpp +++ b/src/mbgl/style/style_parser.hpp @@ -83,12 +83,10 @@ private: std::tuple parseProperty(JSVal value, const char *property_name, JSVal transition); template - std::tuple> parseFunction(JSVal value); + std::tuple> parseFunction(JSVal value, const char *); template std::tuple> parsePiecewiseConstantFunction(JSVal value, std::chrono::steady_clock::duration duration); template - T parseFunctionArgument(JSVal value); - template std::tuple>> parseStops(JSVal value); FilterExpression parseFilter(JSVal); diff --git a/src/mbgl/util/interpolate.hpp b/src/mbgl/util/interpolate.hpp index 952d7b9c1..a2998233b 100644 --- a/src/mbgl/util/interpolate.hpp +++ b/src/mbgl/util/interpolate.hpp @@ -4,6 +4,8 @@ #include #include +#include + namespace mbgl { namespace util { @@ -22,9 +24,21 @@ inline std::array interpolate(const std::array& a, const std::array< }}; } -inline std::vector interpolate(const std::vector &a, const std::vector, const double) { - return a; -} +// fake interpolations that just return the first value +template<> inline bool interpolate(const bool a, const bool, const double) { return a; } +template<> inline std::vector interpolate(const std::vector a, const std::vector, const double) { return a; } +template<> inline std::string interpolate(const std::string a, const std::string, const double) { return a; } +template<> inline TranslateAnchorType interpolate(const TranslateAnchorType a, const TranslateAnchorType, const double) { return a; } +template<> inline RotateAnchorType interpolate(const RotateAnchorType a, const RotateAnchorType, const double) { return a; } +template<> inline CapType interpolate(const CapType a, const CapType, const double) { return a; } +template<> inline JoinType interpolate(const JoinType a, const JoinType, const double) { return a; } +template<> inline PlacementType interpolate(const PlacementType a, const PlacementType, const double) { return a; } +template<> inline TextAnchorType interpolate(const TextAnchorType a, const TextAnchorType, const double) { return a; } +template<> inline TextJustifyType interpolate(const TextJustifyType a, const TextJustifyType, const double) { return a; } +template<> inline TextTransformType interpolate(const TextTransformType a, const TextTransformType, const double) { return a; } +template<> inline RotationAlignmentType interpolate(const RotationAlignmentType a, const RotationAlignmentType, const double) { return a; } + + } }