|
1 | 1 | #include "utils.hpp"
|
2 | 2 | #include "mapnik_expression.hpp"
|
3 | 3 | #include "mapnik_feature.hpp"
|
4 |
| -#include "utils.hpp" |
5 | 4 | #include "object_to_container.hpp"
|
6 | 5 |
|
7 | 6 | // mapnik
|
8 |
| -#include <mapnik/version.hpp> |
9 | 7 | #include <mapnik/attribute.hpp>
|
10 | 8 | #include <mapnik/expression_string.hpp>
|
11 | 9 | #include <mapnik/expression_evaluator.hpp>
|
12 | 10 |
|
13 |
| -// stl |
14 |
| -#include <exception> // for exception |
15 | 11 |
|
16 | 12 | Napi::FunctionReference Expression::constructor;
|
17 | 13 |
|
18 |
| -void Expression::Initialize(Napi::Object target) { |
19 |
| - |
20 |
| - Napi::HandleScope scope(env); |
21 |
| - |
22 |
| - Napi::FunctionReference lcons = Napi::Function::New(env, Expression::New); |
23 |
| - |
24 |
| - lcons->SetClassName(Napi::String::New(env, "Expression")); |
25 |
| - |
26 |
| - InstanceMethod("toString", &toString), |
27 |
| - InstanceMethod("evaluate", &evaluate), |
28 |
| - |
29 |
| - (target).Set(Napi::String::New(env, "Expression"), Napi::GetFunction(lcons)); |
30 |
| - constructor.Reset(lcons); |
| 14 | +Napi::Object Expression::Initialize(Napi::Env env, Napi::Object exports) |
| 15 | +{ |
| 16 | + Napi::Function func = DefineClass(env, "Expression", { |
| 17 | + InstanceMethod<&Expression::evaluate>("evaluate"), |
| 18 | + InstanceMethod<&Expression::toString>("toString") |
| 19 | + }); |
| 20 | + constructor = Napi::Persistent(func); |
| 21 | + constructor.SuppressDestruct(); |
| 22 | + exports.Set("Expression", func); |
| 23 | + return exports; |
31 | 24 | }
|
32 | 25 |
|
33 |
| -Expression::Expression() : Napi::ObjectWrap<Expression>(), |
34 |
| - this_() {} |
35 | 26 |
|
36 |
| -Expression::~Expression() |
| 27 | +Expression::Expression(Napi::CallbackInfo const& info) |
| 28 | + : Napi::ObjectWrap<Expression>(info) |
37 | 29 | {
|
38 |
| -} |
| 30 | + Napi::Env env = info.Env(); |
39 | 31 |
|
40 |
| -Napi::Value Expression::New(Napi::CallbackInfo const& info) |
41 |
| -{ |
42 |
| - if (!info.IsConstructCall()) |
| 32 | + if (info.Length() != 1 || !info[0].IsString()) |
43 | 33 | {
|
44 |
| - Napi::Error::New(env, "Cannot call constructor as function, you need to use 'new' keyword").ThrowAsJavaScriptException(); |
45 |
| - return env.Null(); |
| 34 | + Napi::TypeError::New(env, "invalid arguments: accepts a single argument of string type").ThrowAsJavaScriptException(); |
| 35 | + return; |
46 | 36 | }
|
47 |
| - |
48 |
| - mapnik::expression_ptr e_ptr; |
49 | 37 | try
|
50 | 38 | {
|
51 |
| - if (info.Length() == 1 && info[0].IsString()) { |
52 |
| - e_ptr = mapnik::parse_expression(TOSTR(info[0])); |
53 |
| - } else { |
54 |
| - Napi::TypeError::New(env, "invalid arguments: accepts a single argument of string type").ThrowAsJavaScriptException(); |
55 |
| - return env.Null(); |
56 |
| - } |
| 39 | + expression_ = mapnik::parse_expression(info[0].As<Napi::String>()); |
57 | 40 | }
|
58 | 41 | catch (std::exception const& ex)
|
59 | 42 | {
|
60 | 43 | Napi::Error::New(env, ex.what()).ThrowAsJavaScriptException();
|
61 |
| - return env.Null(); |
62 | 44 | }
|
63 |
| - |
64 |
| - Expression* e = new Expression(); |
65 |
| - e->Wrap(info.This()); |
66 |
| - e->this_ = e_ptr; |
67 |
| - return info.This(); |
68 | 45 | }
|
69 | 46 |
|
70 | 47 | Napi::Value Expression::toString(Napi::CallbackInfo const& info)
|
71 | 48 | {
|
72 |
| - Expression* e = info.Holder().Unwrap<Expression>(); |
73 |
| - return Napi::New(env, mapnik::to_expression_string(*e->get())); |
| 49 | + Napi::Env env = info.Env(); |
| 50 | + Napi::EscapableHandleScope scope(env); |
| 51 | + |
| 52 | + Napi::String str = Napi::String::New(env, mapnik::to_expression_string(*expression_)); |
| 53 | + return scope.Escape(str); |
74 | 54 | }
|
75 | 55 |
|
76 | 56 | Napi::Value Expression::evaluate(Napi::CallbackInfo const& info)
|
77 | 57 | {
|
78 |
| - if (info.Length() < 1) { |
| 58 | + Napi::Env env = info.Env(); |
| 59 | + Napi::EscapableHandleScope scope(env); |
| 60 | + |
| 61 | + if (info.Length() < 1) |
| 62 | + { |
79 | 63 | Napi::Error::New(env, "requires a mapnik.Feature as an argument").ThrowAsJavaScriptException();
|
80 |
| - return env.Null(); |
| 64 | + return env.Undefined(); |
81 | 65 | }
|
82 | 66 |
|
83 | 67 | if (!info[0].IsObject())
|
84 | 68 | {
|
85 | 69 | Napi::TypeError::New(env, "first argument is invalid, must be a mapnik.Feature").ThrowAsJavaScriptException();
|
86 |
| - return env.Null(); |
| 70 | + return env.Undefined(); |
87 | 71 | }
|
88 |
| - |
89 |
| - if (!Napi::New(env, Feature::constructor)->HasInstance(info[0])) { |
| 72 | + Napi::Object obj = info[0].As<Napi::Object>(); |
| 73 | + if (!obj.InstanceOf(Feature::constructor.Value())) |
| 74 | + { |
90 | 75 | Napi::TypeError::New(env, "first argument is invalid, must be a mapnik.Feature").ThrowAsJavaScriptException();
|
91 |
| - return env.Null(); |
| 76 | + return env.Undefined(); |
92 | 77 | }
|
93 | 78 |
|
94 |
| - Feature* f = info[0].As<Napi::Object>().Unwrap<Feature>(); |
| 79 | + Feature *f = Napi::ObjectWrap<Feature>::Unwrap(obj); |
95 | 80 |
|
96 |
| - Expression* e = info.Holder().Unwrap<Expression>(); |
97 | 81 | mapnik::attributes vars;
|
98 | 82 | if (info.Length() > 1)
|
99 | 83 | {
|
100 | 84 | if (!info[1].IsObject())
|
101 | 85 | {
|
102 | 86 | Napi::TypeError::New(env, "optional second argument must be an options object").ThrowAsJavaScriptException();
|
103 |
| - return env.Null(); |
| 87 | + return env.Undefined(); |
104 | 88 | }
|
105 | 89 | Napi::Object options = info[1].As<Napi::Object>();
|
106 | 90 |
|
107 |
| - if ((options).Has(Napi::String::New(env, "variables")).FromMaybe(false)) |
| 91 | + if (options.Has("variables")) |
108 | 92 | {
|
109 |
| - Napi::Value bind_opt = (options).Get(Napi::String::New(env, "variables")); |
| 93 | + Napi::Value bind_opt = options.Get("variables"); |
110 | 94 | if (!bind_opt.IsObject())
|
111 | 95 | {
|
112 | 96 | Napi::TypeError::New(env, "optional arg 'variables' must be an object").ThrowAsJavaScriptException();
|
113 |
| - return env.Null(); |
| 97 | + return env.Undefined(); |
114 | 98 | }
|
115 |
| - object_to_container(vars,bind_opt->ToObject(Napi::GetCurrentContext())); |
| 99 | + object_to_container(vars, bind_opt.As<Napi::Object>()); |
116 | 100 | }
|
117 | 101 | }
|
118 |
| - mapnik::value value_obj = mapnik::util::apply_visitor(mapnik::evaluate<mapnik::feature_impl,mapnik::value,mapnik::attributes>(*(f->get()),vars),*(e->get())); |
119 |
| - return mapnik::util::apply_visitor(node_mapnik::value_converter(),value_obj); |
| 102 | + using namespace mapnik; |
| 103 | + value val =util::apply_visitor(mapnik::evaluate<feature_impl, value, attributes>(*f->impl(), vars),*expression_); |
| 104 | + return scope.Escape(util::apply_visitor(node_mapnik::value_converter(env), val)); |
120 | 105 | }
|
0 commit comments