diff options
author | John Firebaugh <john.firebaugh@gmail.com> | 2016-06-10 21:17:23 -0700 |
---|---|---|
committer | John Firebaugh <john.firebaugh@gmail.com> | 2016-06-13 17:22:05 -0700 |
commit | 282e626ac112b1ca7a9bf9f9d4c0239db8fbd97a (patch) | |
tree | f83ef7974687a84341dd616b364b2aa5a9c012a8 /src/mbgl | |
parent | 36bef2157595e1455aa55c64c6c526f096dd1c8e (diff) | |
download | qtlocation-mapboxgl-282e626ac112b1ca7a9bf9f9d4c0239db8fbd97a.tar.gz |
[core] Make enum ↔ string conversion more generic-friendly
Rewrite enum.hpp in such a way that parseConstant can be defined generically for all enumerated types.
While there, properly validated enumerated property values.
Diffstat (limited to 'src/mbgl')
-rw-r--r-- | src/mbgl/platform/event.cpp | 34 | ||||
-rw-r--r-- | src/mbgl/platform/log.cpp | 3 | ||||
-rw-r--r-- | src/mbgl/style/parser.cpp | 33 | ||||
-rw-r--r-- | src/mbgl/style/property_parsing.cpp | 148 | ||||
-rw-r--r-- | src/mbgl/style/property_parsing.hpp | 28 | ||||
-rw-r--r-- | src/mbgl/style/source.cpp | 4 | ||||
-rw-r--r-- | src/mbgl/style/types.cpp | 80 |
7 files changed, 157 insertions, 173 deletions
diff --git a/src/mbgl/platform/event.cpp b/src/mbgl/platform/event.cpp new file mode 100644 index 0000000000..68d75a2941 --- /dev/null +++ b/src/mbgl/platform/event.cpp @@ -0,0 +1,34 @@ +#include <mbgl/platform/event.hpp> +#include <mbgl/util/enum.hpp> + +namespace mbgl { + +MBGL_DEFINE_ENUM(EventSeverity, { + { EventSeverity::Debug, "DEBUG" }, + { EventSeverity::Info, "INFO" }, + { EventSeverity::Warning, "WARNING" }, + { EventSeverity::Error, "ERROR" }, + { EventSeverity(-1), "UNKNOWN" }, +}); + +MBGL_DEFINE_ENUM(Event, { + { Event::General, "General" }, + { Event::Setup, "Setup" }, + { Event::Shader, "Shader" }, + { Event::ParseStyle, "ParseStyle" }, + { Event::ParseTile, "ParseTile" }, + { Event::Render, "Render" }, + { Event::Style, "Style" }, + { Event::Database, "Database" }, + { Event::HttpRequest, "HttpRequest" }, + { Event::Sprite, "Sprite" }, + { Event::Image, "Image" }, + { Event::OpenGL, "OpenGL" }, + { Event::JNI, "JNI" }, + { Event::Android, "Android" }, + { Event::Crash, "Crash" }, + { Event::Glyph, "Glyph" }, + { Event(-1), "Unknown" }, +}); + +} // namespace mbgl diff --git a/src/mbgl/platform/log.cpp b/src/mbgl/platform/log.cpp index 2118511592..4b56435df0 100644 --- a/src/mbgl/platform/log.cpp +++ b/src/mbgl/platform/log.cpp @@ -1,4 +1,5 @@ #include <mbgl/platform/log.hpp> +#include <mbgl/util/enum.hpp> #include <cstdio> #include <cstdarg> @@ -54,7 +55,7 @@ void Log::record(EventSeverity severity, Event event, int64_t code, const std::s logStream << "{" << name << "}"; #endif - logStream << "[" << event << "]"; + logStream << "[" << Enum<Event>::toString(event) << "]"; if (code >= 0) { logStream << "(" << code << ")"; diff --git a/src/mbgl/style/parser.cpp b/src/mbgl/style/parser.cpp index 8e632ac6a0..870fd6d71e 100644 --- a/src/mbgl/style/parser.cpp +++ b/src/mbgl/style/parser.cpp @@ -14,6 +14,7 @@ #include <mbgl/tile/geometry_tile_data.hpp> #include <mbgl/util/mapbox.hpp> +#include <mbgl/util/enum.hpp> #include <rapidjson/document.h> #include <rapidjson/error/en.h> @@ -161,11 +162,15 @@ void Parser::parseSources(const JSValue& value) { const JSValue& typeVal = sourceVal["type"]; if (!typeVal.IsString()) { - Log::Warning(Event::ParseStyle, "source type must have one of the enum values"); + Log::Warning(Event::ParseStyle, "source type must be a string"); continue; } - const auto type = SourceTypeClass({ typeVal.GetString(), typeVal.GetStringLength() }); + const auto type = Enum<SourceType>::toEnum({ typeVal.GetString(), typeVal.GetStringLength() }); + if (!type) { + Log::Warning(Event::ParseStyle, "source type must have one of the enum values"); + continue; + } // Sources can have URLs, either because they reference an external TileJSON file, or // because reference a GeoJSON file. They don't have to have one though when all source @@ -177,7 +182,7 @@ void Parser::parseSources(const JSValue& value) { std::unique_ptr<Tileset> tileset; std::unique_ptr<mapbox::geojsonvt::GeoJSONVT> geojsonvt; - switch (type) { + switch (*type) { case SourceType::Raster: if (sourceVal.HasMember("tileSize")) { const JSValue& tileSizeVal = sourceVal["tileSize"]; @@ -236,7 +241,7 @@ void Parser::parseSources(const JSValue& value) { } const std::string id { nameVal.GetString(), nameVal.GetStringLength() }; - std::unique_ptr<Source> source = std::make_unique<Source>(type, id, url, tileSize, std::move(tileset), std::move(geojsonvt)); + std::unique_ptr<Source> source = std::make_unique<Source>(*type, id, url, tileSize, std::move(tileset), std::move(geojsonvt)); sourcesMap.emplace(id, source.get()); sources.emplace_back(std::move(source)); @@ -481,21 +486,25 @@ void Parser::parseLayer(const std::string& id, const JSValue& value, std::unique } } -MBGL_DEFINE_ENUM_CLASS(VisibilityTypeClass, VisibilityType, { - { VisibilityType::Visible, "visible" }, - { VisibilityType::None, "none" }, -}) - void Parser::parseVisibility(Layer& layer, const JSValue& value) { Layer::Impl& impl = *layer.baseImpl; + if (!value.HasMember("visibility")) { return; - } else if (!value["visibility"].IsString()) { + } + + if (!value["visibility"].IsString()) { Log::Warning(Event::ParseStyle, "value of 'visibility' must be a string"); - impl.visibility = VisibilityType::Visible; return; } - impl.visibility = VisibilityTypeClass({ value["visibility"].GetString(), value["visibility"].GetStringLength() }); + + const auto enumValue = Enum<VisibilityType>::toEnum({ value["visibility"].GetString(), value["visibility"].GetStringLength() }); + if (!enumValue) { + Log::Warning(Event::ParseStyle, "value of 'visibility' must be a valid enumeration value"); + return; + } + + impl.visibility = *enumValue; } Value parseFeatureType(const Value& value) { diff --git a/src/mbgl/style/property_parsing.cpp b/src/mbgl/style/property_parsing.cpp index 6e5174e936..9985cc7f39 100644 --- a/src/mbgl/style/property_parsing.cpp +++ b/src/mbgl/style/property_parsing.cpp @@ -55,154 +55,6 @@ optional<Color> parseConstant(const char* name, const JSValue& value) { css_color.a}}; } -MBGL_DEFINE_ENUM_CLASS(TranslateAnchorTypeClass, TranslateAnchorType, { - { TranslateAnchorType::Map, "map" }, - { TranslateAnchorType::Viewport, "viewport" }, -}) - -template <> -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 {}; - } - - return { TranslateAnchorTypeClass({ value.GetString(), value.GetStringLength() }) }; -} - -MBGL_DEFINE_ENUM_CLASS(RotateAnchorTypeClass, RotateAnchorType, { - { RotateAnchorType::Map, "map" }, - { RotateAnchorType::Viewport, "viewport" }, -}) - -template <> -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 {}; - } - - return { RotateAnchorTypeClass({ value.GetString(), value.GetStringLength() }) }; -} - -MBGL_DEFINE_ENUM_CLASS(LineCapTypeClass, LineCapType, { - { LineCapType::Round, "round" }, - { LineCapType::Butt, "butt" }, - { LineCapType::Square, "square" }, -}) - -template <> -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 {}; - } - - return { LineCapTypeClass({ value.GetString(), value.GetStringLength() }) }; -} - -MBGL_DEFINE_ENUM_CLASS(LineJoinTypeClass, LineJoinType, { - { LineJoinType::Miter, "miter" }, - { LineJoinType::Bevel, "bevel" }, - { LineJoinType::Round, "round" }, - { LineJoinType::FakeRound, "fakeround" }, - { LineJoinType::FlipBevel, "flipbevel" }, -}) - -template <> -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 {}; - } - - return { LineJoinTypeClass({ value.GetString(), value.GetStringLength() }) }; -} - -MBGL_DEFINE_ENUM_CLASS(SymbolPlacementTypeClass, SymbolPlacementType, { - { SymbolPlacementType::Point, "point" }, - { SymbolPlacementType::Line, "line" }, -}) - -template <> -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 {}; - } - - return { SymbolPlacementTypeClass({ value.GetString(), value.GetStringLength() }) }; -} - -MBGL_DEFINE_ENUM_CLASS(TextAnchorTypeClass, TextAnchorType, { - { TextAnchorType::Center, "center" }, - { TextAnchorType::Left, "left" }, - { TextAnchorType::Right, "right" }, - { TextAnchorType::Top, "top" }, - { TextAnchorType::Bottom, "bottom" }, - { TextAnchorType::TopLeft, "top-left" }, - { TextAnchorType::TopRight, "top-right" }, - { TextAnchorType::BottomLeft, "bottom-left" }, - { TextAnchorType::BottomRight, "bottom-right" } -}) - -template <> -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 {}; - } - - return { TextAnchorTypeClass({ value.GetString(), value.GetStringLength() }) }; -} - -MBGL_DEFINE_ENUM_CLASS(TextJustifyTypeClass, TextJustifyType, { - { TextJustifyType::Center, "center" }, - { TextJustifyType::Left, "left" }, - { TextJustifyType::Right, "right" }, -}) - -template <> -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 {}; - } - - return { TextJustifyTypeClass({ value.GetString(), value.GetStringLength() }) }; -} - -MBGL_DEFINE_ENUM_CLASS(TextTransformTypeClass, TextTransformType, { - { TextTransformType::None, "none" }, - { TextTransformType::Uppercase, "uppercase" }, - { TextTransformType::Lowercase, "lowercase" }, -}) - -template <> -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 {}; - } - - return { TextTransformTypeClass({ value.GetString(), value.GetStringLength() }) }; -} - -MBGL_DEFINE_ENUM_CLASS(AlignmentTypeClass, AlignmentType, { - { AlignmentType::Map, "map" }, - { AlignmentType::Viewport, "viewport" }, -}) - -template <> -optional<AlignmentType> parseConstant<AlignmentType>(const char* name, const JSValue& value) { - if (!value.IsString()) { - Log::Warning(Event::ParseStyle, "value of '%s' must be a string", name); - return {}; - } - - return { AlignmentTypeClass({ value.GetString(), value.GetStringLength() }) }; -} - template <> optional<std::array<float, 2>> parseConstant(const char* name, const JSValue& value) { if (value.IsArray() && value.Size() == 2 && diff --git a/src/mbgl/style/property_parsing.hpp b/src/mbgl/style/property_parsing.hpp index d2d283fe17..d27a9e5031 100644 --- a/src/mbgl/style/property_parsing.hpp +++ b/src/mbgl/style/property_parsing.hpp @@ -7,6 +7,7 @@ #include <mbgl/util/rapidjson.hpp> #include <mbgl/util/optional.hpp> #include <mbgl/util/color.hpp> +#include <mbgl/util/enum.hpp> #include <mbgl/platform/log.hpp> @@ -17,27 +18,34 @@ namespace mbgl { namespace style { -template <typename T> +template <typename T, typename = std::enable_if_t<!std::is_enum<T>::value>> 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<AlignmentType> 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> parseConstant(const char* name, const JSValue& value, + typename std::enable_if_t<std::is_enum<T>::value, void*> = nullptr) { + if (!value.IsString()) { + Log::Warning(Event::ParseStyle, "value of '%s' must be a string", name); + return {}; + } + + const auto result = Enum<T>::toEnum({ value.GetString(), value.GetStringLength() }); + if (!result) { + Log::Warning(Event::ParseStyle, "value of '%s' must be a valid enumeration value", name); + } + + return result; +} + +template <typename T> PropertyValue<T> parseProperty(const char* name, const JSValue& value) { if (!value.IsObject()) { auto constant = parseConstant<T>(name, value); diff --git a/src/mbgl/style/source.cpp b/src/mbgl/style/source.cpp index 544d230a25..bffb6a8fcc 100644 --- a/src/mbgl/style/source.cpp +++ b/src/mbgl/style/source.cpp @@ -18,6 +18,7 @@ #include <mbgl/util/token.hpp> #include <mbgl/util/string.hpp> #include <mbgl/util/tile_cover.hpp> +#include <mbgl/util/enum.hpp> #include <mbgl/tile/raster_tile.hpp> #include <mbgl/tile/geojson_tile.hpp> @@ -197,8 +198,7 @@ std::unique_ptr<Tile> Source::createTile(const OverscaledTileID& overscaledTileI } else if (type == SourceType::GeoJSON) { return std::make_unique<GeoJSONTile>(overscaledTileID, id, parameters, geojsonvt.get()); } else { - Log::Warning(Event::Style, "Source type '%s' is not implemented", - SourceTypeClass(type).c_str()); + Log::Warning(Event::Style, "Source type '%s' is not implemented", Enum<SourceType>::toString(type)); return nullptr; } } diff --git a/src/mbgl/style/types.cpp b/src/mbgl/style/types.cpp new file mode 100644 index 0000000000..d292d2d5b4 --- /dev/null +++ b/src/mbgl/style/types.cpp @@ -0,0 +1,80 @@ +#include <mbgl/style/types.hpp> +#include <mbgl/util/enum.hpp> + +namespace mbgl { + +using namespace style; + +MBGL_DEFINE_ENUM(SourceType, { + { SourceType::Vector, "vector" }, + { SourceType::Raster, "raster" }, + { SourceType::GeoJSON, "geojson" }, + { SourceType::Video, "video" }, + { SourceType::Annotations, "annotations" }, +}); + +MBGL_DEFINE_ENUM(VisibilityType, { + { VisibilityType::Visible, "visible" }, + { VisibilityType::None, "none" }, +}); + +MBGL_DEFINE_ENUM(TranslateAnchorType, { + { TranslateAnchorType::Map, "map" }, + { TranslateAnchorType::Viewport, "viewport" }, +}); + +MBGL_DEFINE_ENUM(RotateAnchorType, { + { RotateAnchorType::Map, "map" }, + { RotateAnchorType::Viewport, "viewport" }, +}); + +MBGL_DEFINE_ENUM(LineCapType, { + { LineCapType::Round, "round" }, + { LineCapType::Butt, "butt" }, + { LineCapType::Square, "square" }, +}); + +MBGL_DEFINE_ENUM(LineJoinType, { + { LineJoinType::Miter, "miter" }, + { LineJoinType::Bevel, "bevel" }, + { LineJoinType::Round, "round" }, + { LineJoinType::FakeRound, "fakeround" }, + { LineJoinType::FlipBevel, "flipbevel" }, +}); + +MBGL_DEFINE_ENUM(SymbolPlacementType, { + { SymbolPlacementType::Point, "point" }, + { SymbolPlacementType::Line, "line" }, +}); + +MBGL_DEFINE_ENUM(TextAnchorType, { + { TextAnchorType::Center, "center" }, + { TextAnchorType::Left, "left" }, + { TextAnchorType::Right, "right" }, + { TextAnchorType::Top, "top" }, + { TextAnchorType::Bottom, "bottom" }, + { TextAnchorType::TopLeft, "top-left" }, + { TextAnchorType::TopRight, "top-right" }, + { TextAnchorType::BottomLeft, "bottom-left" }, + { TextAnchorType::BottomRight, "bottom-right" } +}); + +MBGL_DEFINE_ENUM(TextJustifyType, { + { TextJustifyType::Center, "center" }, + { TextJustifyType::Left, "left" }, + { TextJustifyType::Right, "right" }, +}); + +MBGL_DEFINE_ENUM(TextTransformType, { + { TextTransformType::None, "none" }, + { TextTransformType::Uppercase, "uppercase" }, + { TextTransformType::Lowercase, "lowercase" }, +}); + +MBGL_DEFINE_ENUM(AlignmentType, { + { AlignmentType::Map, "map" }, + { AlignmentType::Viewport, "viewport" }, + { AlignmentType::Undefined, "undefined" }, +}); + +} // namespace mbgl |