[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.
This commit is contained in:
@@ -1,7 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
#include <mbgl/util/enum.hpp>
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
namespace mbgl {
|
||||
@@ -13,14 +11,6 @@ enum class EventSeverity : uint8_t {
|
||||
Error,
|
||||
};
|
||||
|
||||
MBGL_DEFINE_ENUM_CLASS(EventSeverityClass, EventSeverity, {
|
||||
{ EventSeverity::Debug, "DEBUG" },
|
||||
{ EventSeverity::Info, "INFO" },
|
||||
{ EventSeverity::Warning, "WARNING" },
|
||||
{ EventSeverity::Error, "ERROR" },
|
||||
{ EventSeverity(-1), "UNKNOWN" },
|
||||
})
|
||||
|
||||
enum class Event : uint8_t {
|
||||
General,
|
||||
Setup,
|
||||
@@ -40,27 +30,6 @@ enum class Event : uint8_t {
|
||||
Glyph,
|
||||
};
|
||||
|
||||
MBGL_DEFINE_ENUM_CLASS(EventClass, 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" },
|
||||
})
|
||||
|
||||
|
||||
struct EventPermutation {
|
||||
const EventSeverity severity;
|
||||
const Event event;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#include <mbgl/util/enum.hpp>
|
||||
#include <cstdint>
|
||||
|
||||
namespace mbgl {
|
||||
|
||||
@@ -13,14 +13,6 @@ enum class SourceType : uint8_t {
|
||||
Annotations
|
||||
};
|
||||
|
||||
MBGL_DEFINE_ENUM_CLASS(SourceTypeClass, SourceType, {
|
||||
{ SourceType::Vector, "vector" },
|
||||
{ SourceType::Raster, "raster" },
|
||||
{ SourceType::GeoJSON, "geojson" },
|
||||
{ SourceType::Video, "video" },
|
||||
{ SourceType::Annotations, "annotations" },
|
||||
})
|
||||
|
||||
namespace style {
|
||||
|
||||
enum class VisibilityType : bool {
|
||||
|
||||
@@ -1,52 +1,36 @@
|
||||
#pragma once
|
||||
|
||||
#include <iosfwd>
|
||||
#include <mbgl/util/optional.hpp>
|
||||
|
||||
#include <algorithm>
|
||||
#include <cassert>
|
||||
#include <string>
|
||||
|
||||
namespace mbgl {
|
||||
|
||||
template <typename Type>
|
||||
struct EnumValue {
|
||||
const Type value;
|
||||
const char *name;
|
||||
};
|
||||
|
||||
template <typename EnumName, const EnumValue<EnumName> *names, const size_t length>
|
||||
struct Enum {
|
||||
using Type = EnumName;
|
||||
Type value;
|
||||
static const constexpr size_t l = length;
|
||||
private:
|
||||
static constexpr inline bool compare(const char *a, const char *b) {
|
||||
return *a == *b && (*a == '\0' || compare(a + 1, b + 1));
|
||||
}
|
||||
static constexpr inline const char *lookup_type(Type e, EnumValue<Type> const * const list, size_t r) {
|
||||
return r == 0 ? "" : list->value == e ? list->name : lookup_type(e, list + 1, r - 1);
|
||||
}
|
||||
static constexpr inline Type lookup_name(const char *n, EnumValue<Type> const * const list, size_t r) {
|
||||
return r == 0 ? Type(-1) : compare(list->name, n) ? list->value : lookup_name(n, list + 1, r - 1);
|
||||
}
|
||||
template <typename T>
|
||||
class Enum {
|
||||
public:
|
||||
inline constexpr Enum(const char *n) : value(lookup_name(n, names, length)) {}
|
||||
inline constexpr Enum(const std::string &n) : value(lookup_name(n.c_str(), names, length)) {}
|
||||
inline constexpr Enum(Type t) : value(t) {}
|
||||
using Value = std::pair<const T, const char *>;
|
||||
|
||||
inline void operator=(const char *n) { value = lookup_name(n, names, length); }
|
||||
inline void operator=(const std::string &n) { *this = n.c_str(); }
|
||||
inline void operator=(Type t) { value = t; }
|
||||
static const char * toString(T t) {
|
||||
auto it = std::find_if(begin, end, [&] (const auto& v) { return t == v.first; });
|
||||
assert(it != end); return it->second;
|
||||
}
|
||||
|
||||
inline constexpr bool valid() const { return value != Type(-1); }
|
||||
static optional<T> toEnum(const std::string& s) {
|
||||
auto it = std::find_if(begin, end, [&] (const auto& v) { return s == v.second; });
|
||||
return it == end ? optional<T>() : it->first;
|
||||
}
|
||||
|
||||
inline constexpr const char *c_str() const { return lookup_type(value, names, length); }
|
||||
inline std::string str() const { return c_str(); }
|
||||
|
||||
inline constexpr operator Type() const { return value; }
|
||||
private:
|
||||
static const Value* begin;
|
||||
static const Value* end;
|
||||
};
|
||||
|
||||
#define MBGL_DEFINE_ENUM_CLASS(name, type, strings...) \
|
||||
const constexpr ::mbgl::EnumValue<type> type##_names[] = strings; \
|
||||
using name = ::mbgl::Enum<type, type##_names, sizeof(type##_names) / sizeof(::mbgl::EnumValue<type>)>; \
|
||||
inline std::ostream& operator<<(std::ostream& os, type t) { return os << name(t).str(); }
|
||||
#define MBGL_DEFINE_ENUM(type, strings...) \
|
||||
const constexpr Enum<type>::Value type##_names[] = strings; \
|
||||
template <> const Enum<type>::Value* Enum<type>::begin = std::begin(type##_names); \
|
||||
template <> const Enum<type>::Value* Enum<type>::end = std::end(type##_names)
|
||||
|
||||
} // namespace mbgl
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
#include <mbgl/platform/log.hpp>
|
||||
#include <mbgl/util/enum.hpp>
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
@@ -7,7 +8,7 @@ namespace mbgl {
|
||||
void Log::platformRecord(EventSeverity severity, const std::string &msg) {
|
||||
NSString *message =
|
||||
[[NSString alloc] initWithBytes:msg.data() length:msg.size() encoding:NSUTF8StringEncoding];
|
||||
NSLog(@"[%s] %@", EventSeverityClass(severity).c_str(), message);
|
||||
NSLog(@"[%s] %@", Enum<EventSeverity>::toString(severity), message);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
#include <mbgl/platform/log.hpp>
|
||||
#include <mbgl/util/enum.hpp>
|
||||
|
||||
#include <iostream>
|
||||
|
||||
namespace mbgl {
|
||||
|
||||
void Log::platformRecord(EventSeverity severity, const std::string &msg) {
|
||||
std::cerr << "[" << severity << "] " << msg << std::endl;
|
||||
std::cerr << "[" << Enum<EventSeverity>::toString(severity) << "] " << msg << std::endl;
|
||||
}
|
||||
|
||||
} // namespace mbgl
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
#include "node_log.hpp"
|
||||
#include "util/async_queue.hpp"
|
||||
|
||||
#include <mbgl/util/enum.hpp>
|
||||
|
||||
namespace node_mbgl {
|
||||
|
||||
struct NodeLogObserver::LogMessage {
|
||||
@@ -23,10 +25,10 @@ NodeLogObserver::NodeLogObserver(v8::Local<v8::Object> target)
|
||||
auto msg = Nan::New<v8::Object>();
|
||||
|
||||
Nan::Set(msg, Nan::New("class").ToLocalChecked(),
|
||||
Nan::New(mbgl::EventClass(message.event).c_str()).ToLocalChecked());
|
||||
Nan::New(mbgl::Enum<mbgl::Event>::toString(message.event)).ToLocalChecked());
|
||||
|
||||
Nan::Set(msg, Nan::New("severity").ToLocalChecked(),
|
||||
Nan::New(mbgl::EventSeverityClass(message.severity).c_str()).ToLocalChecked());
|
||||
Nan::New(mbgl::Enum<mbgl::EventSeverity>::toString(message.severity)).ToLocalChecked());
|
||||
|
||||
if (message.code != -1) {
|
||||
Nan::Set(msg, Nan::New("code").ToLocalChecked(),
|
||||
|
||||
34
src/mbgl/platform/event.cpp
Normal file
34
src/mbgl/platform/event.cpp
Normal file
@@ -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
|
||||
@@ -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 << ")";
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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 &&
|
||||
|
||||
@@ -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,26 +18,33 @@
|
||||
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()) {
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
80
src/mbgl/style/types.cpp
Normal file
80
src/mbgl/style/types.cpp
Normal file
@@ -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
|
||||
@@ -1,5 +1,6 @@
|
||||
#include <mbgl/test/fixture_log_observer.hpp>
|
||||
#include <mbgl/test/util.hpp>
|
||||
#include <mbgl/util/enum.hpp>
|
||||
|
||||
namespace mbgl {
|
||||
|
||||
@@ -96,7 +97,8 @@ std::vector<FixtureLog::Message> FixtureLogObserver::unchecked() const {
|
||||
}
|
||||
|
||||
::std::ostream& operator<<(::std::ostream& os, const FixtureLog::Message& message) {
|
||||
os << "[\"" << message.severity << "\", \"" << message.event << "\"";
|
||||
os << "[\"" << Enum<EventSeverity>::toString(message.severity) << "\", \"";
|
||||
os << Enum<Event>::toString(message.event) << "\"";
|
||||
os << ", " << message.code;
|
||||
os << ", \"" << message.msg << "\"";
|
||||
return os << "]" << std::endl;
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
|
||||
#include <mbgl/style/parser.hpp>
|
||||
#include <mbgl/util/io.hpp>
|
||||
#include <mbgl/util/enum.hpp>
|
||||
|
||||
#include <rapidjson/document.h>
|
||||
|
||||
@@ -46,8 +47,8 @@ TEST_P(StyleParserTest, ParseStyle) {
|
||||
|
||||
const uint32_t count = js_entry[rapidjson::SizeType(0)].GetUint();
|
||||
const FixtureLogObserver::LogMessage message {
|
||||
EventSeverityClass(js_entry[rapidjson::SizeType(1)].GetString()),
|
||||
EventClass(js_entry[rapidjson::SizeType(2)].GetString()),
|
||||
*Enum<EventSeverity>::toEnum(js_entry[rapidjson::SizeType(1)].GetString()),
|
||||
*Enum<Event>::toEnum(js_entry[rapidjson::SizeType(2)].GetString()),
|
||||
int64_t(-1),
|
||||
js_entry[rapidjson::SizeType(3)].GetString()
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user