blob: b81d14c700f1d42de88f2ff2b09651a3b010c25a (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
|
#include <mbgl/style/property_value.hpp>
#include <mbgl/style/layer.hpp>
#include <mbgl/util/optional.hpp>
#include <mbgl/util/enum.hpp>
namespace node_mbgl {
template <class V, class Enable = void>
struct ValueConverter {};
template <>
struct ValueConverter<bool> {
mbgl::optional<mbgl::style::PropertyValue<bool>> operator()(const v8::Local<v8::Value>& value) const {
if (!value->IsBoolean()) {
Nan::ThrowTypeError("boolean required");
return {};
}
return { value->BooleanValue() };
}
};
template <>
struct ValueConverter<float> {
mbgl::optional<mbgl::style::PropertyValue<float>> operator()(const v8::Local<v8::Value>& value) const {
if (!value->IsNumber()) {
Nan::ThrowTypeError("number required");
return {};
}
return { value->NumberValue() };
}
};
template <>
struct ValueConverter<std::string> {
mbgl::optional<mbgl::style::PropertyValue<std::string>> operator()(const v8::Local<v8::Value>& value) const {
if (!value->IsString()) {
Nan::ThrowTypeError("string required");
return {};
}
return { std::string(*Nan::Utf8String(value)) };
}
};
template <typename T>
struct ValueConverter<T, std::enable_if_t<std::is_enum<T>::value>> {
mbgl::optional<mbgl::style::PropertyValue<T>> operator()(const v8::Local<v8::Value>& value) const {
if (!value->IsString()) {
Nan::ThrowTypeError("string required");
return {};
}
mbgl::optional<T> result = mbgl::Enum<T>::toEnum(*Nan::Utf8String(value));
if (!result) {
Nan::ThrowTypeError("invalid enumeration value");
return {};
}
return { *result };
}
};
template <>
struct ValueConverter<mbgl::Color> {
mbgl::optional<mbgl::style::PropertyValue<mbgl::Color>> operator()(const v8::Local<v8::Value>& value) const {
(void)value;
return {};
}
};
template <>
struct ValueConverter<std::array<float, 2>> {
mbgl::optional<mbgl::style::PropertyValue<std::array<float, 2>>> operator()(const v8::Local<v8::Value>& value) const {
(void)value;
return {};
}
};
template <>
struct ValueConverter<std::vector<float>> {
mbgl::optional<mbgl::style::PropertyValue<std::vector<float>>> operator()(const v8::Local<v8::Value>& value) const {
(void)value;
return {};
}
};
template <>
struct ValueConverter<std::vector<std::string>> {
mbgl::optional<mbgl::style::PropertyValue<std::vector<std::string>>> operator()(const v8::Local<v8::Value>& value) const {
(void)value;
return {};
}
};
using PropertySetter = std::function<bool (mbgl::style::Layer&, const v8::Local<v8::Value>&)>;
using PropertySetters = std::unordered_map<std::string, PropertySetter>;
template <class L, class V>
PropertySetter makePropertySetter(void (L::*setter)(mbgl::style::PropertyValue<V>)) {
return [setter] (mbgl::style::Layer& layer, const v8::Local<v8::Value>& value) {
L* typedLayer = layer.as<L>();
if (!typedLayer) {
Nan::ThrowTypeError("layer doesn't support this property");
return false;
}
mbgl::optional<mbgl::style::PropertyValue<V>> typedValue;
if (value->IsNull() || value->IsUndefined()) {
typedValue = mbgl::style::PropertyValue<V>();
} else {
typedValue = ValueConverter<V>()(value);
}
if (!typedValue) {
return false;
}
(typedLayer->*setter)(*typedValue);
return true;
};
}
}
|