summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJohn Firebaugh <john.firebaugh@gmail.com>2016-04-26 10:36:25 -0700
committerJohn Firebaugh <john.firebaugh@gmail.com>2016-04-26 11:44:48 -0700
commit878310b8912c83445ce7b12ee2b30a4489bf34f7 (patch)
tree826e2c7087f11fbfcb5556e98ee4e501548e19bb /src
parent64fe75b01109d38977b20c83773e6236e55905a8 (diff)
downloadqtlocation-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.hpp2
-rw-r--r--src/mbgl/style/paint_property.hpp4
-rw-r--r--src/mbgl/style/property_parsing.cpp183
-rw-r--r--src/mbgl/style/property_parsing.hpp102
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