summaryrefslogtreecommitdiff
path: root/platform/node/src/node_style.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'platform/node/src/node_style.hpp')
-rw-r--r--platform/node/src/node_style.hpp126
1 files changed, 126 insertions, 0 deletions
diff --git a/platform/node/src/node_style.hpp b/platform/node/src/node_style.hpp
new file mode 100644
index 0000000000..b81d14c700
--- /dev/null
+++ b/platform/node/src/node_style.hpp
@@ -0,0 +1,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;
+ };
+}
+
+}