[core] Use mbgl::style::conversion in node bindings

This commit is contained in:
John Firebaugh
2016-06-19 20:05:05 -07:00
parent a18d6dda5d
commit 8a9ee26b0e
7 changed files with 117 additions and 127 deletions

View File

@@ -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"

View File

@@ -0,0 +1,73 @@
#pragma once
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-parameter"
#pragma GCC diagnostic ignored "-Wshadow"
#include <nan.h>
#pragma GCC diagnostic pop
#include <mbgl/util/optional.hpp>
namespace mbgl {
namespace style {
namespace conversion {
inline bool isArray(v8::Local<v8::Value> value) {
Nan::HandleScope scope;
return value->IsArray();
}
inline std::size_t arrayLength(v8::Local<v8::Value> value) {
Nan::HandleScope scope;
return value.As<v8::Array>()->Length();
}
inline v8::Local<v8::Value> arrayMember(v8::Local<v8::Value> value, std::size_t i) {
Nan::EscapableHandleScope scope;
return scope.Escape(Nan::Get(value.As<v8::Array>(), i).ToLocalChecked());
}
inline bool isObject(v8::Local<v8::Value> value) {
Nan::HandleScope scope;
return value->IsObject();
}
inline optional<v8::Local<v8::Value>> objectMember(v8::Local<v8::Value> value, const char * name) {
Nan::EscapableHandleScope scope;
if (!Nan::Has(value.As<v8::Array>(), Nan::New(name).ToLocalChecked()).FromJust()) {
return {};
}
Nan::MaybeLocal<v8::Value> result = Nan::Get(value.As<v8::Array>(), Nan::New(name).ToLocalChecked());
if (result.IsEmpty()) {
return {};
}
return scope.Escape(result.ToLocalChecked());
}
inline optional<bool> toBool(v8::Local<v8::Value> value) {
Nan::HandleScope scope;
if (!value->IsBoolean()) {
return {};
}
return value->BooleanValue();
}
inline optional<float> toNumber(v8::Local<v8::Value> value) {
Nan::HandleScope scope;
if (!value->IsNumber()) {
return {};
}
return value->NumberValue();
}
inline optional<std::string> toString(v8::Local<v8::Value> value) {
Nan::HandleScope scope;
if (!value->IsString()) {
return {};
}
return std::string(*Nan::Utf8String(value));
}
} // namespace conversion
} // namespace style
} // namespace mbgl

View File

@@ -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<v8::Value>& info, const PropertySetters& setters) {
auto nodeMap = Nan::ObjectWrap::Unwrap<NodeMap>(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<NodeMap>(info.Holder());
if (!nodeMap->map) return Nan::ThrowError(releasedMessage());

View File

@@ -1,5 +1,7 @@
#pragma once
#include "node_style.hpp"
#include <mbgl/map/map.hpp>
#include <mbgl/storage/file_source.hpp>
#include <mbgl/platform/default/headless_view.hpp>
@@ -10,8 +12,6 @@
#include <nan.h>
#pragma GCC diagnostic pop
#include <queue>
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<v8::Value>&, const PropertySetters&);
void startRender(RenderOptions options);
void renderFinished();

View File

@@ -1,117 +1,22 @@
#include <mbgl/style/property_value.hpp>
#pragma once
#include "node_conversion.hpp"
#include <mbgl/style/layer.hpp>
#include <mbgl/util/optional.hpp>
#include <mbgl/util/enum.hpp>
#include <mbgl/style/conversion.hpp>
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-parameter"
#pragma GCC diagnostic ignored "-Wshadow"
#include <nan.h>
#pragma GCC diagnostic pop
#include <functional>
#include <string>
#include <unordered_map>
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 { float(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 {
if (!value->IsString()) {
Nan::ThrowTypeError("string required");
return {};
}
mbgl::optional<mbgl::Color> result = mbgl::Color::parse(*Nan::Utf8String(value));
if (!result) {
Nan::ThrowTypeError("invalid color");
return {};
}
return { *result };
}
};
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::array<float, 4>> {
mbgl::optional<mbgl::style::PropertyValue<std::array<float, 4>>> 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>;
@@ -124,19 +29,19 @@ PropertySetter makePropertySetter(void (L::*setter)(mbgl::style::PropertyValue<V
return false;
}
mbgl::optional<mbgl::style::PropertyValue<V>> typedValue;
if (value->IsNull() || value->IsUndefined()) {
typedValue = mbgl::style::PropertyValue<V>();
} else {
typedValue = ValueConverter<V>()(value);
(typedLayer->*setter)(mbgl::style::PropertyValue<V>());
return true;
}
if (!typedValue) {
mbgl::style::conversion::Result<mbgl::style::PropertyValue<V>> typedValue
= mbgl::style::conversion::convertPropertyValue<V>(value);
if (typedValue.template is<mbgl::style::conversion::Error>()) {
Nan::ThrowTypeError(typedValue.template get<mbgl::style::conversion::Error>().message);
return false;
}
(typedLayer->*setter)(*typedValue);
(typedLayer->*setter)(typedValue.template get<mbgl::style::PropertyValue<V>>());
return true;
};
}

View File

@@ -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;

View File

@@ -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;