diff --git a/src/mbgl/style/piecewisefunction_properties.cpp b/src/mbgl/style/piecewisefunction_properties.cpp index 86d02e7b1..72ed0b8f7 100644 --- a/src/mbgl/style/piecewisefunction_properties.cpp +++ b/src/mbgl/style/piecewisefunction_properties.cpp @@ -6,7 +6,7 @@ namespace mbgl { template -uint32_t getBiggestStopLessThan(std::vector> stops, float z) { +size_t getBiggestStopLessThan(std::vector> stops, float z) { for (uint32_t i = 0; i < stops.size(); i++) { if (stops[i].first > z) { return i == 0 ? i : i - 1; @@ -23,7 +23,7 @@ T PiecewiseConstantFunction::evaluate(float z, const ZoomHistory &zh) const { float t = std::min((std::chrono::steady_clock::now() - zh.lastIntegerZoomTime) / duration, 1.0f); float fromScale = 1.0f; float toScale = 1.0f; - uint32_t from, to; + size_t from, to; if (z > zh.lastIntegerZoom) { result.t = fraction + (1.0f - fraction) * t; diff --git a/src/mbgl/style/piecewisefunction_properties.hpp b/src/mbgl/style/piecewisefunction_properties.hpp index 769020002..0440655ba 100644 --- a/src/mbgl/style/piecewisefunction_properties.hpp +++ b/src/mbgl/style/piecewisefunction_properties.hpp @@ -10,7 +10,7 @@ namespace mbgl { template struct PiecewiseConstantFunction { inline PiecewiseConstantFunction(const std::vector> &values_, std::chrono::duration duration_) : values(values_), duration(duration_) {} - inline PiecewiseConstantFunction(T &value) : values({{ 0, value }}), duration(std::chrono::milliseconds(300)) {} + inline PiecewiseConstantFunction(T &value, std::chrono::duration duration_) : values({{ 0, value }}), duration(duration_) {} inline PiecewiseConstantFunction() : values(), duration(std::chrono::milliseconds(300)) {} T evaluate(float z, const ZoomHistory &zoomHistory) const; diff --git a/src/mbgl/style/style_parser.cpp b/src/mbgl/style/style_parser.cpp index a334cecc0..89a266a18 100644 --- a/src/mbgl/style/style_parser.cpp +++ b/src/mbgl/style/style_parser.cpp @@ -268,13 +268,13 @@ Faded> StyleParser::parseFunctionArgument(JSVal value) { template <> Faded StyleParser::parseFunctionArgument(JSVal value) { JSVal rvalue = replaceConstant(value); + Faded parsed; if (rvalue.IsString()) { - Faded parsed; parsed.to = { value.GetString(), value.GetStringLength() }; return parsed; } else { Log::Warning(Event::ParseStyle, "function argument must be a string"); - return {}; + return parsed; } } @@ -308,7 +308,7 @@ std::tuple>> StyleParser::parseStops(JSVal return std::tuple>> { false, {}}; } } - return { true, stops }; + return std::tuple>>(true, stops); } template inline float defaultBaseValue() { return 1.75; } @@ -341,26 +341,13 @@ std::tuple> StyleParser::parseFunction(JSVal value) { return std::tuple> { true, StopsFunction(std::get<1>(stops), base) }; } -template inline std::chrono::duration defaultDurationValue() { return std::chrono::milliseconds(300); } - template -std::tuple> StyleParser::parsePiecewiseConstantFunction(JSVal value) { +std::tuple> StyleParser::parsePiecewiseConstantFunction(JSVal value, std::chrono::steady_clock::duration duration) { if (!value.HasMember("stops")) { Log::Warning(Event::ParseStyle, "function must specify a function type"); return std::tuple> { false, {} }; } - std::chrono::duration duration = defaultDurationValue(); - - if (value.HasMember("duration")) { - JSVal value_duration = value["duration"]; - if (value_duration.IsNumber()) { - duration = std::chrono::milliseconds(value_duration.GetUint()); - } else { - Log::Warning(Event::ParseStyle, "duration must be numeric"); - } - } - auto stops = parseStops(value["stops"]); if (!std::get<0>(stops)) { @@ -379,6 +366,15 @@ bool StyleParser::setProperty(JSVal value, const char *property_name, PropertyKe return std::get<0>(res); } +template +bool StyleParser::setProperty(JSVal value, const char *property_name, PropertyKey key, ClassProperties &klass, JSVal transition) { + auto res = parseProperty(value, property_name, transition); + if (std::get<0>(res)) { + klass.set(key, std::get<1>(res)); + } + return std::get<0>(res); +} + template void StyleParser::parseVisibility(StyleBucket &bucket, JSVal value) { if (!value.HasMember("visibility")) { @@ -400,6 +396,21 @@ bool StyleParser::parseOptionalProperty(const char *property_name, PropertyKey k } } +template +bool StyleParser::parseOptionalProperty(const char *property_name, PropertyKey key, ClassProperties &klass, JSVal value, const char *transition_name) { + if (!value.HasMember(property_name)) { + return false; + } else { + if (value.HasMember(transition_name)) { + return setProperty(replaceConstant(value[property_name]), property_name, key, klass, value[transition_name]); + } else { + JSVal val(rapidjson::kObjectType); + return setProperty(replaceConstant(value[property_name]), property_name, key, klass, val); + } + } +} + + template<> std::tuple StyleParser::parseProperty(JSVal value, const char *property_name) { if (!value.IsString()) { Log::Warning(Event::ParseStyle, "value of '%s' must be a string", property_name); @@ -554,27 +565,38 @@ template<> std::tuple> StyleParser::parseProperty(JSVal va } } -template<> std::tuple>>> StyleParser::parseProperty(JSVal value, const char *property_name) { +template<> std::tuple>>> StyleParser::parseProperty(JSVal value, const char *property_name, JSVal transition) { + std::chrono::steady_clock::duration duration = std::chrono::milliseconds(300); + if (transition.HasMember("duration")) { + duration = std::chrono::milliseconds(transition["duration"].GetUint()); + } + if (value.IsObject()) { - return parsePiecewiseConstantFunction>>(value); + return parsePiecewiseConstantFunction>>(value, duration); } else if (value.IsArray()) { Faded> parsed; std::tuple> floatarray = parseFloatArray(value); parsed.to = std::get<1>(floatarray); - return std::tuple>>> { std::get<0>(floatarray), parsed }; + return std::tuple>>> { std::get<0>(floatarray), { parsed, duration } }; } else { Log::Warning(Event::ParseStyle, "value of '%s' must be an array of numbers, or a number array function", property_name); return std::tuple>>> { false, {} }; } } -template<> std::tuple>> StyleParser::parseProperty(JSVal value, const char *property_name) { +template<> std::tuple>> StyleParser::parseProperty(JSVal value, const char *property_name, JSVal transition) { + + std::chrono::steady_clock::duration duration = std::chrono::milliseconds(300); + if (transition.HasMember("duration")) { + duration = std::chrono::milliseconds(transition["duration"].GetUint()); + } + if (value.IsObject()) { - return parsePiecewiseConstantFunction>(value); + return parsePiecewiseConstantFunction>(value, duration); } else if (value.IsString()) { Faded parsed; parsed.to = { value.GetString(), value.GetStringLength() }; - return std::tuple>> { true, parsed }; + return std::tuple>> { true, { parsed, duration } }; } else { Log::Warning(Event::ParseStyle, "value of '%s' must be string or a string function", property_name); return std::tuple>> { false, {} }; @@ -724,7 +746,7 @@ void StyleParser::parsePaint(JSVal value, ClassProperties &klass) { 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-image", Key::FillImage, klass, value); + parseOptionalProperty>>("fill-image", Key::FillImage, klass, value, "fill-image-transition"); parseOptionalProperty>("line-opacity", Key::LineOpacity, klass, value); parseOptionalProperty("line-opacity-transition", Key::LineOpacity, klass, value); @@ -739,8 +761,8 @@ void StyleParser::parsePaint(JSVal value, ClassProperties &klass) { parseOptionalProperty("line-gap-width-transition", Key::LineGapWidth, klass, value); parseOptionalProperty>("line-blur", Key::LineBlur, klass, value); parseOptionalProperty("line-blur-transition", Key::LineBlur, klass, value); - parseOptionalProperty>>>("line-dasharray", Key::LineDashArray, klass, value); - parseOptionalProperty>>("line-image", Key::LineImage, klass, value); + parseOptionalProperty>>>("line-dasharray", Key::LineDashArray, klass, value, "line-dasharray-transition"); + parseOptionalProperty>>("line-image", Key::LineImage, klass, value, "line-image-transition"); parseOptionalProperty>("icon-opacity", Key::IconOpacity, klass, value); parseOptionalProperty("icon-opacity-transition", Key::IconOpacity, klass, value); @@ -790,7 +812,7 @@ void StyleParser::parsePaint(JSVal value, ClassProperties &klass) { parseOptionalProperty>("background-opacity", Key::BackgroundOpacity, klass, value); parseOptionalProperty>("background-color", Key::BackgroundColor, klass, value); - parseOptionalProperty>>("background-image", Key::BackgroundImage, klass, value); + parseOptionalProperty>>("background-image", Key::BackgroundImage, klass, value, "background-image-transition"); } void StyleParser::parseLayout(JSVal value, util::ptr &bucket) { diff --git a/src/mbgl/style/style_parser.hpp b/src/mbgl/style/style_parser.hpp index fd26dc864..d25c70579 100644 --- a/src/mbgl/style/style_parser.hpp +++ b/src/mbgl/style/style_parser.hpp @@ -69,17 +69,23 @@ private: template bool parseOptionalProperty(const char *property_name, PropertyKey key, ClassProperties &klass, JSVal value); template + bool parseOptionalProperty(const char *property_name, PropertyKey key, ClassProperties &klass, JSVal value, const char *transition_name); + template bool parseOptionalProperty(const char *property_name, const std::vector &keys, ClassProperties &klass, JSVal value); template bool setProperty(JSVal value, const char *property_name, PropertyKey key, ClassProperties &klass); + template + bool setProperty(JSVal value, const char *property_name, PropertyKey key, ClassProperties &klass, JSVal transition); template std::tuple parseProperty(JSVal value, const char *property_name); + template + std::tuple parseProperty(JSVal value, const char *property_name, JSVal transition); template std::tuple> parseFunction(JSVal value); template - std::tuple> parsePiecewiseConstantFunction(JSVal value); + std::tuple> parsePiecewiseConstantFunction(JSVal value, std::chrono::steady_clock::duration duration); template T parseFunctionArgument(JSVal value); template