diff --git a/package.json b/package.json index e1a8229fd..71bfd9bf9 100644 --- a/package.json +++ b/package.json @@ -23,7 +23,7 @@ "express": "^4.11.1", "mapbox-gl-shaders": "mapbox/mapbox-gl-shaders#59e998295d548f208ee3ec10cdd21ff2630e2079", "mapbox-gl-style-spec": "mapbox/mapbox-gl-style-spec#194fc55b6a7dd54c1e2cf2dd9048fbb5e836716d", - "mapbox-gl-test-suite": "mapbox/mapbox-gl-test-suite#85d2319dd5ad75da1f39b8cd9e08f1e51ede58cb", + "mapbox-gl-test-suite": "mapbox/mapbox-gl-test-suite#2e95c51a6ed0efd1d8cda03f6b5391a6639900ae", "node-gyp": "^3.3.1", "request": "^2.72.0", "tape": "^4.5.1" diff --git a/platform/node/src/node_conversion.hpp b/platform/node/src/node_conversion.hpp new file mode 100644 index 000000000..51443f28e --- /dev/null +++ b/platform/node/src/node_conversion.hpp @@ -0,0 +1,73 @@ +#pragma once + +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wunused-parameter" +#pragma GCC diagnostic ignored "-Wshadow" +#include +#pragma GCC diagnostic pop + +#include + +namespace mbgl { +namespace style { +namespace conversion { + +inline bool isArray(v8::Local value) { + Nan::HandleScope scope; + return value->IsArray(); +} + +inline std::size_t arrayLength(v8::Local value) { + Nan::HandleScope scope; + return value.As()->Length(); +} + +inline v8::Local arrayMember(v8::Local value, std::size_t i) { + Nan::EscapableHandleScope scope; + return scope.Escape(Nan::Get(value.As(), i).ToLocalChecked()); +} + +inline bool isObject(v8::Local value) { + Nan::HandleScope scope; + return value->IsObject(); +} + +inline optional> objectMember(v8::Local value, const char * name) { + Nan::EscapableHandleScope scope; + if (!Nan::Has(value.As(), Nan::New(name).ToLocalChecked()).FromJust()) { + return {}; + } + Nan::MaybeLocal result = Nan::Get(value.As(), Nan::New(name).ToLocalChecked()); + if (result.IsEmpty()) { + return {}; + } + return scope.Escape(result.ToLocalChecked()); +} + +inline optional toBool(v8::Local value) { + Nan::HandleScope scope; + if (!value->IsBoolean()) { + return {}; + } + return value->BooleanValue(); +} + +inline optional toNumber(v8::Local value) { + Nan::HandleScope scope; + if (!value->IsNumber()) { + return {}; + } + return value->NumberValue(); +} + +inline optional toString(v8::Local value) { + Nan::HandleScope scope; + if (!value->IsString()) { + return {}; + } + return std::string(*Nan::Utf8String(value)); +} + +} // namespace conversion +} // namespace style +} // namespace mbgl diff --git a/platform/node/src/node_map.cpp b/platform/node/src/node_map.cpp index b4ea77000..c416082b6 100644 --- a/platform/node/src/node_map.cpp +++ b/platform/node/src/node_map.cpp @@ -56,6 +56,7 @@ NAN_MODULE_INIT(NodeMap::Init) { Nan::SetPrototypeMethod(tpl, "release", Release); Nan::SetPrototypeMethod(tpl, "addClass", AddClass); + Nan::SetPrototypeMethod(tpl, "setLayoutProperty", SetLayoutProperty); Nan::SetPrototypeMethod(tpl, "setPaintProperty", SetPaintProperty); Nan::SetPrototypeMethod(tpl, "dumpDebugLogs", DumpDebugLogs); @@ -481,7 +482,7 @@ NAN_METHOD(NodeMap::AddClass) { info.GetReturnValue().SetUndefined(); } -NAN_METHOD(NodeMap::SetPaintProperty) { +void NodeMap::setProperty(const Nan::FunctionCallbackInfo& info, const PropertySetters& setters) { auto nodeMap = Nan::ObjectWrap::Unwrap(info.Holder()); if (!nodeMap->map) return Nan::ThrowError(releasedMessage()); @@ -502,8 +503,6 @@ NAN_METHOD(NodeMap::SetPaintProperty) { return Nan::ThrowTypeError("Second argument must be a string"); } - static const PropertySetters setters = makePaintPropertySetters(); - auto it = setters.find(*Nan::Utf8String(info[1])); if (it == setters.end()) { return Nan::ThrowTypeError("property not found"); @@ -517,6 +516,16 @@ NAN_METHOD(NodeMap::SetPaintProperty) { info.GetReturnValue().SetUndefined(); } +NAN_METHOD(NodeMap::SetLayoutProperty) { + static const PropertySetters setters = makeLayoutPropertySetters(); + setProperty(info, setters); +} + +NAN_METHOD(NodeMap::SetPaintProperty) { + static const PropertySetters setters = makePaintPropertySetters(); + setProperty(info, setters); +} + NAN_METHOD(NodeMap::DumpDebugLogs) { auto nodeMap = Nan::ObjectWrap::Unwrap(info.Holder()); if (!nodeMap->map) return Nan::ThrowError(releasedMessage()); diff --git a/platform/node/src/node_map.hpp b/platform/node/src/node_map.hpp index 8dfb96eef..fb7fc77e5 100644 --- a/platform/node/src/node_map.hpp +++ b/platform/node/src/node_map.hpp @@ -1,5 +1,7 @@ #pragma once +#include "node_style.hpp" + #include #include #include @@ -10,8 +12,6 @@ #include #pragma GCC diagnostic pop -#include - namespace node_mbgl { class NodeMap : public Nan::ObjectWrap, @@ -28,10 +28,13 @@ public: static NAN_METHOD(Render); static NAN_METHOD(Release); static NAN_METHOD(AddClass); + static NAN_METHOD(SetLayoutProperty); static NAN_METHOD(SetPaintProperty); static NAN_METHOD(DumpDebugLogs); static NAN_METHOD(QueryRenderedFeatures); + static void setProperty(const Nan::FunctionCallbackInfo&, const PropertySetters&); + void startRender(RenderOptions options); void renderFinished(); diff --git a/platform/node/src/node_style.hpp b/platform/node/src/node_style.hpp index 0b6b05e13..032e0c8a4 100644 --- a/platform/node/src/node_style.hpp +++ b/platform/node/src/node_style.hpp @@ -1,117 +1,22 @@ -#include +#pragma once + +#include "node_conversion.hpp" + #include -#include -#include +#include + +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wunused-parameter" +#pragma GCC diagnostic ignored "-Wshadow" +#include +#pragma GCC diagnostic pop + +#include +#include +#include namespace node_mbgl { -template -struct ValueConverter {}; - -template <> -struct ValueConverter { - mbgl::optional> operator()(const v8::Local& value) const { - if (!value->IsBoolean()) { - Nan::ThrowTypeError("boolean required"); - return {}; - } - - return { value->BooleanValue() }; - } -}; - -template <> -struct ValueConverter { - mbgl::optional> operator()(const v8::Local& value) const { - if (!value->IsNumber()) { - Nan::ThrowTypeError("number required"); - return {}; - } - - return { float(value->NumberValue()) }; - } -}; - -template <> -struct ValueConverter { - mbgl::optional> operator()(const v8::Local& value) const { - if (!value->IsString()) { - Nan::ThrowTypeError("string required"); - return {}; - } - - return { std::string(*Nan::Utf8String(value)) }; - } -}; - -template -struct ValueConverter::value>> { - mbgl::optional> operator()(const v8::Local& value) const { - if (!value->IsString()) { - Nan::ThrowTypeError("string required"); - return {}; - } - - mbgl::optional result = mbgl::Enum::toEnum(*Nan::Utf8String(value)); - if (!result) { - Nan::ThrowTypeError("invalid enumeration value"); - return {}; - } - - return { *result }; - } -}; - -template <> -struct ValueConverter { - mbgl::optional> operator()(const v8::Local& value) const { - if (!value->IsString()) { - Nan::ThrowTypeError("string required"); - return {}; - } - - mbgl::optional result = mbgl::Color::parse(*Nan::Utf8String(value)); - if (!result) { - Nan::ThrowTypeError("invalid color"); - return {}; - } - - return { *result }; - } -}; - -template <> -struct ValueConverter> { - mbgl::optional>> operator()(const v8::Local& value) const { - (void)value; - return {}; - } -}; - -template <> -struct ValueConverter> { - mbgl::optional>> operator()(const v8::Local& value) const { - (void)value; - return {}; - } -}; - -template <> -struct ValueConverter> { - mbgl::optional>> operator()(const v8::Local& value) const { - (void)value; - return {}; - } -}; - -template <> -struct ValueConverter> { - mbgl::optional>> operator()(const v8::Local& value) const { - (void)value; - return {}; - } -}; - using PropertySetter = std::function&)>; using PropertySetters = std::unordered_map; @@ -124,19 +29,19 @@ PropertySetter makePropertySetter(void (L::*setter)(mbgl::style::PropertyValue> typedValue; - if (value->IsNull() || value->IsUndefined()) { - typedValue = mbgl::style::PropertyValue(); - } else { - typedValue = ValueConverter()(value); + (typedLayer->*setter)(mbgl::style::PropertyValue()); + return true; } - if (!typedValue) { + mbgl::style::conversion::Result> typedValue + = mbgl::style::conversion::convertPropertyValue(value); + if (typedValue.template is()) { + Nan::ThrowTypeError(typedValue.template get().message); return false; } - (typedLayer->*setter)(*typedValue); + (typedLayer->*setter)(typedValue.template get>()); return true; }; } diff --git a/platform/node/src/node_style_properties.hpp b/platform/node/src/node_style_properties.hpp index 2b0f233d7..88142f8e1 100644 --- a/platform/node/src/node_style_properties.hpp +++ b/platform/node/src/node_style_properties.hpp @@ -9,7 +9,7 @@ namespace node_mbgl { -PropertySetters makeLayoutPropertySetters() { +inline PropertySetters makeLayoutPropertySetters() { using namespace mbgl::style; PropertySetters result; @@ -60,7 +60,7 @@ PropertySetters makeLayoutPropertySetters() { return result; } -PropertySetters makePaintPropertySetters() { +inline PropertySetters makePaintPropertySetters() { using namespace mbgl::style; PropertySetters result; diff --git a/platform/node/src/node_style_properties.hpp.ejs b/platform/node/src/node_style_properties.hpp.ejs index 1b7fc49d8..1937421fa 100644 --- a/platform/node/src/node_style_properties.hpp.ejs +++ b/platform/node/src/node_style_properties.hpp.ejs @@ -6,7 +6,7 @@ namespace node_mbgl { -PropertySetters makeLayoutPropertySetters() { +inline PropertySetters makeLayoutPropertySetters() { using namespace mbgl::style; PropertySetters result; @@ -19,7 +19,7 @@ PropertySetters makeLayoutPropertySetters() { return result; } -PropertySetters makePaintPropertySetters() { +inline PropertySetters makePaintPropertySetters() { using namespace mbgl::style; PropertySetters result;