diff options
author | John Firebaugh <john.firebaugh@gmail.com> | 2016-06-22 16:28:21 -0700 |
---|---|---|
committer | John Firebaugh <john.firebaugh@gmail.com> | 2016-06-24 09:39:51 -0700 |
commit | 16c435b1517b15a5ea8654987979ef58800b838b (patch) | |
tree | 8f81c4e202e1337d0966a06f27842d45a113fded /platform/node | |
parent | c4e4cc5081965d03132eea754c27ece3c95961cb (diff) | |
download | qtlocation-mapboxgl-16c435b1517b15a5ea8654987979ef58800b838b.tar.gz |
[core, node] Implement bindings for addLayer
Diffstat (limited to 'platform/node')
-rw-r--r-- | platform/node/src/node_conversion.hpp | 25 | ||||
-rw-r--r-- | platform/node/src/node_map.cpp | 119 | ||||
-rw-r--r-- | platform/node/src/node_map.hpp | 5 | ||||
-rw-r--r-- | platform/node/src/node_style.hpp | 67 | ||||
-rw-r--r-- | platform/node/src/node_style_properties.hpp | 149 | ||||
-rw-r--r-- | platform/node/src/node_style_properties.hpp.ejs | 53 |
6 files changed, 117 insertions, 301 deletions
diff --git a/platform/node/src/node_conversion.hpp b/platform/node/src/node_conversion.hpp index 03c13b5846..2418a7a6e4 100644 --- a/platform/node/src/node_conversion.hpp +++ b/platform/node/src/node_conversion.hpp @@ -8,11 +8,17 @@ #include <mbgl/util/optional.hpp> #include <mbgl/util/feature.hpp> +#include <mbgl/style/conversion.hpp> namespace mbgl { namespace style { namespace conversion { +inline bool isUndefined(v8::Local<v8::Value> value) { + Nan::HandleScope scope; + return value->IsUndefined() || value->IsNull(); +} + inline bool isArray(v8::Local<v8::Value> value) { Nan::HandleScope scope; return value->IsArray(); @@ -35,16 +41,31 @@ inline bool isObject(v8::Local<v8::Value> value) { 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()) { + if (!Nan::Has(value->ToObject(), Nan::New(name).ToLocalChecked()).FromJust()) { return {}; } - Nan::MaybeLocal<v8::Value> result = Nan::Get(value.As<v8::Array>(), Nan::New(name).ToLocalChecked()); + Nan::MaybeLocal<v8::Value> result = Nan::Get(value->ToObject(), Nan::New(name).ToLocalChecked()); if (result.IsEmpty()) { return {}; } return scope.Escape(result.ToLocalChecked()); } +template <class Fn> +optional<Error> eachMember(v8::Local<v8::Value> value, Fn&& fn) { + Nan::HandleScope scope; + v8::Local<v8::Array> names = value->ToObject()->GetOwnPropertyNames(); + for (uint32_t i = 0; i < names->Length(); ++i) { + v8::Local<v8::Value> k = Nan::Get(names, i).ToLocalChecked(); + v8::Local<v8::Value> v = Nan::Get(value->ToObject(), k).ToLocalChecked(); + optional<Error> result = fn(*Nan::Utf8String(k), v); + if (result) { + return result; + } + } + return {}; +} + inline optional<bool> toBool(v8::Local<v8::Value> value) { Nan::HandleScope scope; if (!value->IsBoolean()) { diff --git a/platform/node/src/node_map.cpp b/platform/node/src/node_map.cpp index e6ee84ee53..c73d3850f2 100644 --- a/platform/node/src/node_map.cpp +++ b/platform/node/src/node_map.cpp @@ -1,12 +1,12 @@ #include "node_map.hpp" #include "node_request.hpp" #include "node_feature.hpp" -#include "node_style_properties.hpp" +#include "node_conversion.hpp" #include <mbgl/platform/default/headless_display.hpp> #include <mbgl/util/exception.hpp> -#include <mbgl/style/layer.hpp> -#include <mbgl/style/layers/fill_layer.hpp> +#include <mbgl/style/conversion/layer.hpp> +#include <mbgl/style/conversion/filter.hpp> #include <unistd.h> @@ -56,6 +56,7 @@ NAN_MODULE_INIT(NodeMap::Init) { Nan::SetPrototypeMethod(tpl, "release", Release); Nan::SetPrototypeMethod(tpl, "addClass", AddClass); + Nan::SetPrototypeMethod(tpl, "addLayer", AddLayer); Nan::SetPrototypeMethod(tpl, "setLayoutProperty", SetLayoutProperty); Nan::SetPrototypeMethod(tpl, "setPaintProperty", SetPaintProperty); Nan::SetPrototypeMethod(tpl, "setFilter", SetFilter); @@ -483,7 +484,30 @@ NAN_METHOD(NodeMap::AddClass) { info.GetReturnValue().SetUndefined(); } -void NodeMap::setProperty(const Nan::FunctionCallbackInfo<v8::Value>& info, const PropertySetters& setters) { +NAN_METHOD(NodeMap::AddLayer) { + using namespace mbgl::style; + using namespace mbgl::style::conversion; + + auto nodeMap = Nan::ObjectWrap::Unwrap<NodeMap>(info.Holder()); + if (!nodeMap->map) return Nan::ThrowError(releasedMessage()); + + if (info.Length() != 1) { + return Nan::ThrowTypeError("One argument required"); + } + + Result<std::unique_ptr<Layer>> layer = convert<std::unique_ptr<Layer>>(info[0]); + if (!layer) { + Nan::ThrowTypeError(layer.error().message); + return; + } + + nodeMap->map->addLayer(std::move(*layer)); +} + +NAN_METHOD(NodeMap::SetLayoutProperty) { + using namespace mbgl::style; + using namespace mbgl::style::conversion; + auto nodeMap = Nan::ObjectWrap::Unwrap<NodeMap>(info.Holder()); if (!nodeMap->map) return Nan::ThrowError(releasedMessage()); @@ -504,30 +528,57 @@ void NodeMap::setProperty(const Nan::FunctionCallbackInfo<v8::Value>& info, cons return Nan::ThrowTypeError("Second argument must be a string"); } - auto it = setters.find(*Nan::Utf8String(info[1])); - if (it == setters.end()) { - return Nan::ThrowTypeError("property not found"); - } - - if (!it->second(*layer, info[2])) { - return; + mbgl::optional<Error> error = setLayoutProperty(*layer, *Nan::Utf8String(info[1]), info[2]); + if (error) { + return Nan::ThrowTypeError(error->message); } nodeMap->map->update(mbgl::Update::RecalculateStyle); 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); + using namespace mbgl::style; + using namespace mbgl::style::conversion; + + auto nodeMap = Nan::ObjectWrap::Unwrap<NodeMap>(info.Holder()); + if (!nodeMap->map) return Nan::ThrowError(releasedMessage()); + + if (info.Length() < 3) { + return Nan::ThrowTypeError("Three arguments required"); + } + + if (!info[0]->IsString()) { + return Nan::ThrowTypeError("First argument must be a string"); + } + + mbgl::style::Layer* layer = nodeMap->map->getLayer(*Nan::Utf8String(info[0])); + if (!layer) { + return Nan::ThrowTypeError("layer not found"); + } + + if (!info[1]->IsString()) { + return Nan::ThrowTypeError("Second argument must be a string"); + } + + mbgl::optional<std::string> klass; + if (info.Length() == 4 && info[3]->IsString()) { + klass = std::string(*Nan::Utf8String(info[3])); + } + + mbgl::optional<Error> error = setPaintProperty(*layer, *Nan::Utf8String(info[1]), info[2], klass); + if (error) { + return Nan::ThrowTypeError(error->message); + } + + nodeMap->map->update(mbgl::Update::RecalculateStyle); + info.GetReturnValue().SetUndefined(); } NAN_METHOD(NodeMap::SetFilter) { + using namespace mbgl::style; + using namespace mbgl::style::conversion; + auto nodeMap = Nan::ObjectWrap::Unwrap<NodeMap>(info.Holder()); if (!nodeMap->map) return Nan::ThrowError(releasedMessage()); @@ -544,23 +595,39 @@ NAN_METHOD(NodeMap::SetFilter) { return Nan::ThrowTypeError("layer not found"); } - mbgl::style::Filter filter; + Filter filter; if (!info[1]->IsNull() && !info[1]->IsUndefined()) { - mbgl::style::conversion::Result<mbgl::style::Filter> converted - = mbgl::style::conversion::convertFilter(info[1]); - if (converted.is<mbgl::style::conversion::Error>()) { - Nan::ThrowTypeError(converted.get<mbgl::style::conversion::Error>().message); + Result<Filter> converted = convert<Filter>(info[1]); + if (!converted) { + Nan::ThrowTypeError(converted.error().message); return; } - filter = std::move(converted.get<mbgl::style::Filter>()); + filter = std::move(*converted); } - if (!setFilter(*layer, filter)) { + if (layer->is<FillLayer>()) { + layer->as<FillLayer>()->setFilter(filter); + info.GetReturnValue().SetUndefined(); + return; + } + if (layer->is<LineLayer>()) { + layer->as<LineLayer>()->setFilter(filter); + info.GetReturnValue().SetUndefined(); + return; + } + if (layer->is<SymbolLayer>()) { + layer->as<SymbolLayer>()->setFilter(filter); + info.GetReturnValue().SetUndefined(); + return; + } + if (layer->is<CircleLayer>()) { + layer->as<CircleLayer>()->setFilter(filter); + info.GetReturnValue().SetUndefined(); return; } - info.GetReturnValue().SetUndefined(); + Nan::ThrowTypeError("layer doesn't support filters"); } NAN_METHOD(NodeMap::DumpDebugLogs) { diff --git a/platform/node/src/node_map.hpp b/platform/node/src/node_map.hpp index 58773e33da..8e4b073134 100644 --- a/platform/node/src/node_map.hpp +++ b/platform/node/src/node_map.hpp @@ -1,7 +1,5 @@ #pragma once -#include "node_style.hpp" - #include <mbgl/map/map.hpp> #include <mbgl/storage/file_source.hpp> #include <mbgl/platform/default/headless_view.hpp> @@ -28,14 +26,13 @@ public: static NAN_METHOD(Render); static NAN_METHOD(Release); static NAN_METHOD(AddClass); + static NAN_METHOD(AddLayer); static NAN_METHOD(SetLayoutProperty); static NAN_METHOD(SetPaintProperty); static NAN_METHOD(SetFilter); static NAN_METHOD(DumpDebugLogs); static NAN_METHOD(QueryRenderedFeatures); - static void setProperty(const Nan::FunctionCallbackInfo<v8::Value>&, const PropertySetters&); - void startRender(RenderOptions options); void renderFinished(); diff --git a/platform/node/src/node_style.hpp b/platform/node/src/node_style.hpp deleted file mode 100644 index 9befd00d10..0000000000 --- a/platform/node/src/node_style.hpp +++ /dev/null @@ -1,67 +0,0 @@ -#pragma once - -#include "node_conversion.hpp" - -#include <mbgl/style/layer.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 { - -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; - } - - if (value->IsNull() || value->IsUndefined()) { - (typedLayer->*setter)(mbgl::style::PropertyValue<V>()); - return true; - } - - 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.template get<mbgl::style::PropertyValue<V>>()); - return true; - }; -} - -inline bool setVisibility(mbgl::style::Layer& layer, const v8::Local<v8::Value>& value) { - if (value->IsNull() || value->IsUndefined()) { - layer.setVisibility(mbgl::style::VisibilityType::Visible); - return true; - } - - if (!value->IsString()) { - Nan::ThrowTypeError("visibility value must be \"visible\" or \"none\""); - return false; - } - - layer.setVisibility(std::string(*Nan::Utf8String(value)) == "none" - ? mbgl::style::VisibilityType::None - : mbgl::style::VisibilityType::Visible); - - return true; -} - -} diff --git a/platform/node/src/node_style_properties.hpp b/platform/node/src/node_style_properties.hpp deleted file mode 100644 index 0e3100207a..0000000000 --- a/platform/node/src/node_style_properties.hpp +++ /dev/null @@ -1,149 +0,0 @@ -#include "node_style.hpp" - -#include <mbgl/style/layers/fill_layer.hpp> -#include <mbgl/style/layers/line_layer.hpp> -#include <mbgl/style/layers/symbol_layer.hpp> -#include <mbgl/style/layers/circle_layer.hpp> -#include <mbgl/style/layers/raster_layer.hpp> -#include <mbgl/style/layers/background_layer.hpp> - -namespace node_mbgl { - -inline PropertySetters makeLayoutPropertySetters() { - using namespace mbgl::style; - PropertySetters result; - - result["visibility"] = &setVisibility; - - - result["line-cap"] = makePropertySetter(&LineLayer::setLineCap); - result["line-join"] = makePropertySetter(&LineLayer::setLineJoin); - result["line-miter-limit"] = makePropertySetter(&LineLayer::setLineMiterLimit); - result["line-round-limit"] = makePropertySetter(&LineLayer::setLineRoundLimit); - - result["symbol-placement"] = makePropertySetter(&SymbolLayer::setSymbolPlacement); - result["symbol-spacing"] = makePropertySetter(&SymbolLayer::setSymbolSpacing); - result["symbol-avoid-edges"] = makePropertySetter(&SymbolLayer::setSymbolAvoidEdges); - result["icon-allow-overlap"] = makePropertySetter(&SymbolLayer::setIconAllowOverlap); - result["icon-ignore-placement"] = makePropertySetter(&SymbolLayer::setIconIgnorePlacement); - result["icon-optional"] = makePropertySetter(&SymbolLayer::setIconOptional); - result["icon-rotation-alignment"] = makePropertySetter(&SymbolLayer::setIconRotationAlignment); - result["icon-size"] = makePropertySetter(&SymbolLayer::setIconSize); - result["icon-text-fit"] = makePropertySetter(&SymbolLayer::setIconTextFit); - result["icon-text-fit-padding"] = makePropertySetter(&SymbolLayer::setIconTextFitPadding); - result["icon-image"] = makePropertySetter(&SymbolLayer::setIconImage); - result["icon-rotate"] = makePropertySetter(&SymbolLayer::setIconRotate); - result["icon-padding"] = makePropertySetter(&SymbolLayer::setIconPadding); - result["icon-keep-upright"] = makePropertySetter(&SymbolLayer::setIconKeepUpright); - result["icon-offset"] = makePropertySetter(&SymbolLayer::setIconOffset); - result["text-pitch-alignment"] = makePropertySetter(&SymbolLayer::setTextPitchAlignment); - result["text-rotation-alignment"] = makePropertySetter(&SymbolLayer::setTextRotationAlignment); - result["text-field"] = makePropertySetter(&SymbolLayer::setTextField); - result["text-font"] = makePropertySetter(&SymbolLayer::setTextFont); - result["text-size"] = makePropertySetter(&SymbolLayer::setTextSize); - result["text-max-width"] = makePropertySetter(&SymbolLayer::setTextMaxWidth); - result["text-line-height"] = makePropertySetter(&SymbolLayer::setTextLineHeight); - result["text-letter-spacing"] = makePropertySetter(&SymbolLayer::setTextLetterSpacing); - result["text-justify"] = makePropertySetter(&SymbolLayer::setTextJustify); - result["text-anchor"] = makePropertySetter(&SymbolLayer::setTextAnchor); - result["text-max-angle"] = makePropertySetter(&SymbolLayer::setTextMaxAngle); - result["text-rotate"] = makePropertySetter(&SymbolLayer::setTextRotate); - result["text-padding"] = makePropertySetter(&SymbolLayer::setTextPadding); - result["text-keep-upright"] = makePropertySetter(&SymbolLayer::setTextKeepUpright); - result["text-transform"] = makePropertySetter(&SymbolLayer::setTextTransform); - result["text-offset"] = makePropertySetter(&SymbolLayer::setTextOffset); - result["text-allow-overlap"] = makePropertySetter(&SymbolLayer::setTextAllowOverlap); - result["text-ignore-placement"] = makePropertySetter(&SymbolLayer::setTextIgnorePlacement); - result["text-optional"] = makePropertySetter(&SymbolLayer::setTextOptional); - - - - - return result; -} - -inline PropertySetters makePaintPropertySetters() { - using namespace mbgl::style; - PropertySetters result; - - result["fill-antialias"] = makePropertySetter(&FillLayer::setFillAntialias); - result["fill-opacity"] = makePropertySetter(&FillLayer::setFillOpacity); - result["fill-color"] = makePropertySetter(&FillLayer::setFillColor); - result["fill-outline-color"] = makePropertySetter(&FillLayer::setFillOutlineColor); - result["fill-translate"] = makePropertySetter(&FillLayer::setFillTranslate); - result["fill-translate-anchor"] = makePropertySetter(&FillLayer::setFillTranslateAnchor); - result["fill-pattern"] = makePropertySetter(&FillLayer::setFillPattern); - - result["line-opacity"] = makePropertySetter(&LineLayer::setLineOpacity); - result["line-color"] = makePropertySetter(&LineLayer::setLineColor); - result["line-translate"] = makePropertySetter(&LineLayer::setLineTranslate); - result["line-translate-anchor"] = makePropertySetter(&LineLayer::setLineTranslateAnchor); - result["line-width"] = makePropertySetter(&LineLayer::setLineWidth); - result["line-gap-width"] = makePropertySetter(&LineLayer::setLineGapWidth); - result["line-offset"] = makePropertySetter(&LineLayer::setLineOffset); - result["line-blur"] = makePropertySetter(&LineLayer::setLineBlur); - result["line-dasharray"] = makePropertySetter(&LineLayer::setLineDasharray); - result["line-pattern"] = makePropertySetter(&LineLayer::setLinePattern); - - result["icon-opacity"] = makePropertySetter(&SymbolLayer::setIconOpacity); - result["icon-color"] = makePropertySetter(&SymbolLayer::setIconColor); - result["icon-halo-color"] = makePropertySetter(&SymbolLayer::setIconHaloColor); - result["icon-halo-width"] = makePropertySetter(&SymbolLayer::setIconHaloWidth); - result["icon-halo-blur"] = makePropertySetter(&SymbolLayer::setIconHaloBlur); - result["icon-translate"] = makePropertySetter(&SymbolLayer::setIconTranslate); - result["icon-translate-anchor"] = makePropertySetter(&SymbolLayer::setIconTranslateAnchor); - result["text-opacity"] = makePropertySetter(&SymbolLayer::setTextOpacity); - result["text-color"] = makePropertySetter(&SymbolLayer::setTextColor); - result["text-halo-color"] = makePropertySetter(&SymbolLayer::setTextHaloColor); - result["text-halo-width"] = makePropertySetter(&SymbolLayer::setTextHaloWidth); - result["text-halo-blur"] = makePropertySetter(&SymbolLayer::setTextHaloBlur); - result["text-translate"] = makePropertySetter(&SymbolLayer::setTextTranslate); - result["text-translate-anchor"] = makePropertySetter(&SymbolLayer::setTextTranslateAnchor); - - result["circle-radius"] = makePropertySetter(&CircleLayer::setCircleRadius); - result["circle-color"] = makePropertySetter(&CircleLayer::setCircleColor); - result["circle-blur"] = makePropertySetter(&CircleLayer::setCircleBlur); - result["circle-opacity"] = makePropertySetter(&CircleLayer::setCircleOpacity); - result["circle-translate"] = makePropertySetter(&CircleLayer::setCircleTranslate); - result["circle-translate-anchor"] = makePropertySetter(&CircleLayer::setCircleTranslateAnchor); - - result["raster-opacity"] = makePropertySetter(&RasterLayer::setRasterOpacity); - result["raster-hue-rotate"] = makePropertySetter(&RasterLayer::setRasterHueRotate); - result["raster-brightness-min"] = makePropertySetter(&RasterLayer::setRasterBrightnessMin); - result["raster-brightness-max"] = makePropertySetter(&RasterLayer::setRasterBrightnessMax); - result["raster-saturation"] = makePropertySetter(&RasterLayer::setRasterSaturation); - result["raster-contrast"] = makePropertySetter(&RasterLayer::setRasterContrast); - result["raster-fade-duration"] = makePropertySetter(&RasterLayer::setRasterFadeDuration); - - result["background-color"] = makePropertySetter(&BackgroundLayer::setBackgroundColor); - result["background-pattern"] = makePropertySetter(&BackgroundLayer::setBackgroundPattern); - result["background-opacity"] = makePropertySetter(&BackgroundLayer::setBackgroundOpacity); - - return result; -} - -inline bool setFilter(mbgl::style::Layer& layer, const mbgl::style::Filter& filter) { - using namespace mbgl::style; - - if (layer.is<FillLayer>()) { - layer.as<FillLayer>()->setFilter(filter); - return true; - } - if (layer.is<LineLayer>()) { - layer.as<LineLayer>()->setFilter(filter); - return true; - } - if (layer.is<SymbolLayer>()) { - layer.as<SymbolLayer>()->setFilter(filter); - return true; - } - if (layer.is<CircleLayer>()) { - layer.as<CircleLayer>()->setFilter(filter); - return true; - } - - Nan::ThrowTypeError("layer doesn't support filters"); - return false; -} - -} diff --git a/platform/node/src/node_style_properties.hpp.ejs b/platform/node/src/node_style_properties.hpp.ejs deleted file mode 100644 index bfd3f74ca5..0000000000 --- a/platform/node/src/node_style_properties.hpp.ejs +++ /dev/null @@ -1,53 +0,0 @@ -#include "node_style.hpp" - -<% for (const layer of locals.layers) { -%> -#include <mbgl/style/layers/<%- layer.type %>_layer.hpp> -<% } -%> - -namespace node_mbgl { - -inline PropertySetters makeLayoutPropertySetters() { - using namespace mbgl::style; - PropertySetters result; - - result["visibility"] = &setVisibility; - -<% for (const layer of locals.layers) { -%> -<% for (const property of layer.layoutProperties) { -%> - result["<%- property.name %>"] = makePropertySetter(&<%- camelize(layer.type) %>Layer::set<%- camelize(property.name) %>); -<% } -%> - -<% } -%> - return result; -} - -inline PropertySetters makePaintPropertySetters() { - using namespace mbgl::style; - PropertySetters result; - -<% for (const layer of locals.layers) { -%> -<% for (const property of layer.paintProperties) { -%> - result["<%- property.name %>"] = makePropertySetter(&<%- camelize(layer.type) %>Layer::set<%- camelize(property.name) %>); -<% } -%> - -<% } -%> - return result; -} - -inline bool setFilter(mbgl::style::Layer& layer, const mbgl::style::Filter& filter) { - using namespace mbgl::style; - -<% for (const layer of locals.layers) { -%> -<% if (layer.type !== 'raster' && layer.type !== 'background' && layer.type !== 'custom') { -%> - if (layer.is<<%- camelize(layer.type) %>Layer>()) { - layer.as<<%- camelize(layer.type) %>Layer>()->setFilter(filter); - return true; - } -<% } -%> -<% } -%> - - Nan::ThrowTypeError("layer doesn't support filters"); - return false; -} - -} |