diff options
author | John Firebaugh <john.firebaugh@gmail.com> | 2016-04-26 10:36:25 -0700 |
---|---|---|
committer | John Firebaugh <john.firebaugh@gmail.com> | 2016-04-26 11:44:48 -0700 |
commit | 878310b8912c83445ce7b12ee2b30a4489bf34f7 (patch) | |
tree | 826e2c7087f11fbfcb5556e98ee4e501548e19bb /src | |
parent | 64fe75b01109d38977b20c83773e6236e55905a8 (diff) | |
download | qtlocation-mapboxgl-878310b8912c83445ce7b12ee2b30a4489bf34f7.tar.gz |
[core] Simplify property parsing
This is a followup to #4811. Now that use of Function is consistent, we can have a single separate parseProperty template function that delegates to a parseConstant template function.
Diffstat (limited to 'src')
-rw-r--r-- | src/mbgl/style/layout_property.hpp | 2 | ||||
-rw-r--r-- | src/mbgl/style/paint_property.hpp | 4 | ||||
-rw-r--r-- | src/mbgl/style/property_parsing.cpp | 183 | ||||
-rw-r--r-- | src/mbgl/style/property_parsing.hpp | 102 |
4 files changed, 115 insertions, 176 deletions
diff --git a/src/mbgl/style/layout_property.hpp b/src/mbgl/style/layout_property.hpp index 894fc44467..dd3c032152 100644 --- a/src/mbgl/style/layout_property.hpp +++ b/src/mbgl/style/layout_property.hpp @@ -17,7 +17,7 @@ public: void parse(const char * name, const JSValue& layout) { if (layout.HasMember(name)) { - parsedValue = parseProperty<Function<T>>(name, layout[name]); + parsedValue = parseProperty<T>(name, layout[name]); } } diff --git a/src/mbgl/style/paint_property.hpp b/src/mbgl/style/paint_property.hpp index 124b0a7c0a..3c2b4ba7d7 100644 --- a/src/mbgl/style/paint_property.hpp +++ b/src/mbgl/style/paint_property.hpp @@ -51,14 +51,14 @@ public: ClassID classID = isClass ? ClassDictionary::Get().lookup(paintName.substr(6)) : ClassID::Default; if (it->value.HasMember(name)) { - auto v = parseProperty<Fn>(name, it->value[name]); + auto v = parseProperty<T>(name, it->value[name]); if (v) { values.emplace(classID, *v); } } if (it->value.HasMember(transitionName.c_str())) { - auto v = parseProperty<PropertyTransition>(name, it->value[transitionName.c_str()]); + auto v = parsePropertyTransition(name, it->value[transitionName.c_str()]); if (v) { transitions.emplace(classID, *v); } diff --git a/src/mbgl/style/property_parsing.cpp b/src/mbgl/style/property_parsing.cpp index 84589ea414..7994f245e8 100644 --- a/src/mbgl/style/property_parsing.cpp +++ b/src/mbgl/style/property_parsing.cpp @@ -1,17 +1,11 @@ #include <mbgl/style/property_parsing.hpp> -#include <mbgl/style/property_transition.hpp> -#include <mbgl/style/function.hpp> - -#include <mbgl/platform/log.hpp> #include <csscolorparser/csscolorparser.hpp> -#include <vector> - namespace mbgl { template <> -optional<bool> parseProperty(const char* name, const JSValue& value) { +optional<bool> parseConstant(const char* name, const JSValue& value) { if (!value.IsBool()) { Log::Warning(Event::ParseStyle, "value of '%s' must be a boolean", name); return {}; @@ -21,7 +15,7 @@ optional<bool> parseProperty(const char* name, const JSValue& value) { } template <> -optional<float> parseProperty(const char* name, const JSValue& value) { +optional<float> parseConstant(const char* name, const JSValue& value) { if (!value.IsNumber()) { Log::Warning(Event::ParseStyle, "value of '%s' must be a number, or a number function", name); return {}; @@ -31,7 +25,7 @@ optional<float> parseProperty(const char* name, const JSValue& value) { } template <> -optional<std::string> parseProperty(const char* name, const JSValue& value) { +optional<std::string> parseConstant(const char* name, const JSValue& value) { if (!value.IsString()) { Log::Warning(Event::ParseStyle, "value of '%s' must be a string", name); return {}; @@ -41,7 +35,7 @@ optional<std::string> parseProperty(const char* name, const JSValue& value) { } template <> -optional<Color> parseProperty(const char* name, const JSValue& value) { +optional<Color> parseConstant(const char* name, const JSValue& value) { if (!value.IsString()) { Log::Warning(Event::ParseStyle, "value of '%s' must be a string", name); return {}; @@ -64,7 +58,7 @@ MBGL_DEFINE_ENUM_CLASS(TranslateAnchorTypeClass, TranslateAnchorType, { }); template <> -optional<TranslateAnchorType> parseProperty(const char* name, const JSValue& value) { +optional<TranslateAnchorType> parseConstant(const char* name, const JSValue& value) { if (!value.IsString()) { Log::Warning(Event::ParseStyle, "value of '%s' must be a string", name); return {}; @@ -79,7 +73,7 @@ MBGL_DEFINE_ENUM_CLASS(RotateAnchorTypeClass, RotateAnchorType, { }); template <> -optional<RotateAnchorType> parseProperty<RotateAnchorType>(const char* name, const JSValue& value) { +optional<RotateAnchorType> parseConstant<RotateAnchorType>(const char* name, const JSValue& value) { if (!value.IsString()) { Log::Warning(Event::ParseStyle, "value of '%s' must be a string", name); return {}; @@ -95,7 +89,7 @@ MBGL_DEFINE_ENUM_CLASS(LineCapTypeClass, LineCapType, { }); template <> -optional<LineCapType> parseProperty<LineCapType>(const char* name, const JSValue& value) { +optional<LineCapType> parseConstant<LineCapType>(const char* name, const JSValue& value) { if (!value.IsString()) { Log::Warning(Event::ParseStyle, "value of '%s' must be a string", name); return {}; @@ -113,7 +107,7 @@ MBGL_DEFINE_ENUM_CLASS(LineJoinTypeClass, LineJoinType, { }); template <> -optional<LineJoinType> parseProperty<LineJoinType>(const char* name, const JSValue& value) { +optional<LineJoinType> parseConstant<LineJoinType>(const char* name, const JSValue& value) { if (!value.IsString()) { Log::Warning(Event::ParseStyle, "value of '%s' must be a string", name); return {}; @@ -128,7 +122,7 @@ MBGL_DEFINE_ENUM_CLASS(SymbolPlacementTypeClass, SymbolPlacementType, { }); template <> -optional<SymbolPlacementType> parseProperty<SymbolPlacementType>(const char* name, const JSValue& value) { +optional<SymbolPlacementType> parseConstant<SymbolPlacementType>(const char* name, const JSValue& value) { if (!value.IsString()) { Log::Warning(Event::ParseStyle, "value of '%s' must be a string", name); return {}; @@ -150,7 +144,7 @@ MBGL_DEFINE_ENUM_CLASS(TextAnchorTypeClass, TextAnchorType, { }); template <> -optional<TextAnchorType> parseProperty<TextAnchorType>(const char* name, const JSValue& value) { +optional<TextAnchorType> parseConstant<TextAnchorType>(const char* name, const JSValue& value) { if (!value.IsString()) { Log::Warning(Event::ParseStyle, "value of '%s' must be a string", name); return {}; @@ -166,7 +160,7 @@ MBGL_DEFINE_ENUM_CLASS(TextJustifyTypeClass, TextJustifyType, { }); template <> -optional<TextJustifyType> parseProperty<TextJustifyType>(const char* name, const JSValue& value) { +optional<TextJustifyType> parseConstant<TextJustifyType>(const char* name, const JSValue& value) { if (!value.IsString()) { Log::Warning(Event::ParseStyle, "value of '%s' must be a string", name); return {}; @@ -182,7 +176,7 @@ MBGL_DEFINE_ENUM_CLASS(TextTransformTypeClass, TextTransformType, { }); template <> -optional<TextTransformType> parseProperty<TextTransformType>(const char* name, const JSValue& value) { +optional<TextTransformType> parseConstant<TextTransformType>(const char* name, const JSValue& value) { if (!value.IsString()) { Log::Warning(Event::ParseStyle, "value of '%s' must be a string", name); return {}; @@ -197,7 +191,7 @@ MBGL_DEFINE_ENUM_CLASS(RotationAlignmentTypeClass, RotationAlignmentType, { }); template <> -optional<RotationAlignmentType> parseProperty<RotationAlignmentType>(const char* name, const JSValue& value) { +optional<RotationAlignmentType> parseConstant<RotationAlignmentType>(const char* name, const JSValue& value) { if (!value.IsString()) { Log::Warning(Event::ParseStyle, "value of '%s' must be a string", name); return {}; @@ -207,7 +201,7 @@ optional<RotationAlignmentType> parseProperty<RotationAlignmentType>(const char* } template <> -optional<std::array<float, 2>> parseProperty(const char* name, const JSValue& value) { +optional<std::array<float, 2>> parseConstant(const char* name, const JSValue& value) { if (value.IsArray() && value.Size() == 2 && value[rapidjson::SizeType(0)].IsNumber() && value[rapidjson::SizeType(1)].IsNumber()) { @@ -222,7 +216,7 @@ optional<std::array<float, 2>> parseProperty(const char* name, const JSValue& va } template <> -optional<std::vector<float>> parseProperty(const char* name, const JSValue& value) { +optional<std::vector<float>> parseConstant(const char* name, const JSValue& value) { if (!value.IsArray()) { Log::Warning(Event::ParseStyle, "value of '%s' must be an array of numbers", name); return {}; @@ -245,7 +239,7 @@ optional<std::vector<float>> parseProperty(const char* name, const JSValue& valu } template <> -optional<std::vector<std::string>> parseProperty(const char* name, const JSValue& value) { +optional<std::vector<std::string>> parseConstant(const char* name, const JSValue& value) { if (!value.IsArray()) { Log::Warning(Event::ParseStyle, "value of '%s' must be an array of strings", name); return {}; @@ -267,8 +261,7 @@ optional<std::vector<std::string>> parseProperty(const char* name, const JSValue return result; } -template <> -optional<PropertyTransition> parseProperty(const char *, const JSValue& value) { +optional<PropertyTransition> parsePropertyTransition(const char *, const JSValue& value) { PropertyTransition transition; if (value.IsObject()) { bool parsed = false; @@ -287,146 +280,4 @@ optional<PropertyTransition> parseProperty(const char *, const JSValue& value) { return transition; } -// --- Function --- - -template <typename T> -optional<std::vector<std::pair<float, T>>> parseStops(const char* name, const JSValue& value) { - if (!value.IsArray()) { - Log::Warning(Event::ParseStyle, "stops function must specify a stops array"); - return {}; - } - - std::vector<std::pair<float, T>> stops; - - for (rapidjson::SizeType i = 0; i < value.Size(); ++i) { - const JSValue& stop = value[i]; - - if (!stop.IsArray()) { - Log::Warning(Event::ParseStyle, "function argument must be a numeric value"); - return {}; - } - - if (stop.Size() != 2) { - Log::Warning(Event::ParseStyle, "stop must have zoom level and value specification"); - return {}; - } - - const JSValue& z = stop[rapidjson::SizeType(0)]; - if (!z.IsNumber()) { - Log::Warning(Event::ParseStyle, "zoom level in stop must be a number"); - return {}; - } - - optional<T> v = parseProperty<T>(name, stop[rapidjson::SizeType(1)]); - if (!v) { - return {}; - } - - stops.emplace_back(z.GetDouble(), *v); - } - - return stops; -} - -template <typename T> -optional<Function<T>> parseFunction(const char* name, const JSValue& value) { - if (!value.IsObject()) { - auto constant = parseProperty<T>(name, value); - if (!constant) { - return {}; - } - return { Function<T>(*constant) }; - } - - if (!value.HasMember("stops")) { - Log::Warning(Event::ParseStyle, "function must specify a function type"); - return {}; - } - - float base = 1.0f; - - if (value.HasMember("base")) { - const JSValue& value_base = value["base"]; - - if (!value_base.IsNumber()) { - Log::Warning(Event::ParseStyle, "base must be numeric"); - return {}; - } - - base = value_base.GetDouble(); - } - - auto stops = parseStops<T>(name, value["stops"]); - - if (!stops) { - return {}; - } - - return { Function<T>(*stops, base) }; -} - -template <> optional<Function<std::array<float, 2>>> parseProperty(const char* name, const JSValue& value) { - return parseFunction<std::array<float, 2>>(name, value); -} - -template <> optional<Function<std::string>> parseProperty(const char* name, const JSValue& value) { - return parseFunction<std::string>(name, value); -} - -template <> optional<Function<TranslateAnchorType>> parseProperty(const char* name, const JSValue& value) { - return parseFunction<TranslateAnchorType>(name, value); -} - -template <> optional<Function<RotateAnchorType>> parseProperty(const char* name, const JSValue& value) { - return parseFunction<RotateAnchorType>(name, value); -} - -template <> optional<Function<LineCapType>> parseProperty(const char* name, const JSValue& value) { - return parseFunction<LineCapType>(name, value); -} - -template <> optional<Function<LineJoinType>> parseProperty(const char* name, const JSValue& value) { - return parseFunction<LineJoinType>(name, value); -} - -template <> optional<Function<SymbolPlacementType>> parseProperty(const char* name, const JSValue& value) { - return parseFunction<SymbolPlacementType>(name, value); -} - -template <> optional<Function<TextAnchorType>> parseProperty(const char* name, const JSValue& value) { - return parseFunction<TextAnchorType>(name, value); -} - -template <> optional<Function<TextJustifyType>> parseProperty(const char* name, const JSValue& value) { - return parseFunction<TextJustifyType>(name, value); -} - -template <> optional<Function<TextTransformType>> parseProperty(const char* name, const JSValue& value) { - return parseFunction<TextTransformType>(name, value); -} - -template <> optional<Function<RotationAlignmentType>> parseProperty(const char* name, const JSValue& value) { - return parseFunction<RotationAlignmentType>(name, value); -} - -template <> optional<Function<bool>> parseProperty(const char* name, const JSValue& value) { - return parseFunction<bool>(name, value); -} - -template<> optional<Function<float>> parseProperty(const char* name, const JSValue& value) { - return parseFunction<float>(name, value); -} - -template<> optional<Function<Color>> parseProperty(const char* name, const JSValue& value) { - return parseFunction<Color>(name, value); -} - -template<> optional<Function<std::vector<float>>> parseProperty(const char* name, const JSValue& value) { - return parseFunction<std::vector<float>>(name, value); -} - -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/style/property_parsing.hpp b/src/mbgl/style/property_parsing.hpp index 73bc5a72c7..8deb58c00b 100644 --- a/src/mbgl/style/property_parsing.hpp +++ b/src/mbgl/style/property_parsing.hpp @@ -1,21 +1,109 @@ -#ifndef MBGL_PROPERTY_PARSING -#define MBGL_PROPERTY_PARSING +#pragma once #include <mbgl/style/types.hpp> +#include <mbgl/style/function.hpp> +#include <mbgl/style/property_transition.hpp> #include <mbgl/util/rapidjson.hpp> #include <mbgl/util/optional.hpp> -#include <functional> +#include <mbgl/platform/log.hpp> + +#include <string> +#include <array> +#include <vector> namespace mbgl { template <typename T> -using optional = optional<T>; +optional<T> parseConstant(const char* name, const JSValue&); + +template <> optional<bool> parseConstant(const char*, const JSValue&); +template <> optional<float> parseConstant(const char*, const JSValue&); +template <> optional<std::string> parseConstant(const char*, const JSValue&); +template <> optional<Color> parseConstant(const char*, const JSValue&); +template <> optional<TranslateAnchorType> parseConstant(const char*, const JSValue&); +template <> optional<RotateAnchorType> parseConstant(const char*, const JSValue&); +template <> optional<LineCapType> parseConstant(const char*, const JSValue&); +template <> optional<LineJoinType> parseConstant(const char*, const JSValue&); +template <> optional<SymbolPlacementType> parseConstant(const char*, const JSValue&); +template <> optional<TextAnchorType> parseConstant(const char*, const JSValue&); +template <> optional<TextJustifyType> parseConstant(const char*, const JSValue&); +template <> optional<TextTransformType> parseConstant(const char*, const JSValue&); +template <> optional<RotationAlignmentType> parseConstant(const char*, const JSValue&); +template <> optional<std::array<float, 2>> parseConstant(const char*, const JSValue&); +template <> optional<std::vector<float>> parseConstant(const char*, const JSValue&); +template <> optional<std::vector<std::string>> parseConstant(const char*, const JSValue&); template <typename T> -optional<T> parseProperty(const char* name, const JSValue&); +optional<Function<T>> parseProperty(const char* name, const JSValue& value) { + if (!value.IsObject()) { + auto constant = parseConstant<T>(name, value); -} // namespace mbgl + if (!constant) { + return {}; + } + + return { Function<T>(*constant) }; + } + + if (!value.HasMember("stops")) { + Log::Warning(Event::ParseStyle, "function must specify a function type"); + return {}; + } + + float base = 1.0f; + + if (value.HasMember("base")) { + const JSValue& value_base = value["base"]; + + if (!value_base.IsNumber()) { + Log::Warning(Event::ParseStyle, "base must be numeric"); + return {}; + } + + base = value_base.GetDouble(); + } + + const JSValue& stopsValue = value["stops"]; + + if (!stopsValue.IsArray()) { + Log::Warning(Event::ParseStyle, "stops function must specify a stops array"); + return {}; + } -#endif + std::vector<std::pair<float, T>> stops; + + for (rapidjson::SizeType i = 0; i < stopsValue.Size(); ++i) { + const JSValue& stop = stopsValue[i]; + + if (!stop.IsArray()) { + Log::Warning(Event::ParseStyle, "function argument must be a numeric value"); + return {}; + } + + if (stop.Size() != 2) { + Log::Warning(Event::ParseStyle, "stop must have zoom level and value specification"); + return {}; + } + + const JSValue& z = stop[rapidjson::SizeType(0)]; + if (!z.IsNumber()) { + Log::Warning(Event::ParseStyle, "zoom level in stop must be a number"); + return {}; + } + + optional<T> v = parseConstant<T>(name, stop[rapidjson::SizeType(1)]); + if (!v) { + return {}; + } + + stops.emplace_back(z.GetDouble(), *v); + } + + return { Function<T>(stops, base) }; +} + +optional<PropertyTransition> parsePropertyTransition(const char * name, const JSValue&); + +} // namespace mbgl |