• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #include "myobject.h"
2 #include "../common.h"
3 
4 napi_ref MyObject::constructor;
5 
MyObject(double value)6 MyObject::MyObject(double value)
7     : value_(value), env_(nullptr), wrapper_(nullptr) {}
8 
~MyObject()9 MyObject::~MyObject() { napi_delete_reference(env_, wrapper_); }
10 
Destructor(napi_env env,void * nativeObject,void *)11 void MyObject::Destructor(
12   napi_env env, void* nativeObject, void* /*finalize_hint*/) {
13   MyObject* obj = static_cast<MyObject*>(nativeObject);
14   delete obj;
15 }
16 
Init(napi_env env,napi_value exports)17 void MyObject::Init(napi_env env, napi_value exports) {
18   napi_property_descriptor properties[] = {
19     { "value", nullptr, nullptr, GetValue, SetValue, 0, napi_default, 0 },
20     { "valueReadonly", nullptr, nullptr, GetValue, nullptr, 0, napi_default,
21       0 },
22     DECLARE_NAPI_PROPERTY("plusOne", PlusOne),
23     DECLARE_NAPI_PROPERTY("multiply", Multiply),
24   };
25 
26   napi_value cons;
27   NAPI_CALL_RETURN_VOID(env, napi_define_class(
28       env, "MyObject", -1, New, nullptr,
29       sizeof(properties) / sizeof(napi_property_descriptor),
30       properties, &cons));
31 
32   NAPI_CALL_RETURN_VOID(env, napi_create_reference(env, cons, 1, &constructor));
33 
34   NAPI_CALL_RETURN_VOID(env,
35       napi_set_named_property(env, exports, "MyObject", cons));
36 }
37 
New(napi_env env,napi_callback_info info)38 napi_value MyObject::New(napi_env env, napi_callback_info info) {
39   napi_value new_target;
40   NAPI_CALL(env, napi_get_new_target(env, info, &new_target));
41   bool is_constructor = (new_target != nullptr);
42 
43   size_t argc = 1;
44   napi_value args[1];
45   napi_value _this;
46   NAPI_CALL(env, napi_get_cb_info(env, info, &argc, args, &_this, nullptr));
47 
48   if (is_constructor) {
49     // Invoked as constructor: `new MyObject(...)`
50     double value = 0;
51 
52     napi_valuetype valuetype;
53     NAPI_CALL(env, napi_typeof(env, args[0], &valuetype));
54 
55     if (valuetype != napi_undefined) {
56       NAPI_CALL(env, napi_get_value_double(env, args[0], &value));
57     }
58 
59     MyObject* obj = new MyObject(value);
60 
61     obj->env_ = env;
62     NAPI_CALL(env, napi_wrap(env,
63                              _this,
64                              obj,
65                              MyObject::Destructor,
66                              nullptr,  // finalize_hint
67                              &obj->wrapper_));
68 
69     return _this;
70   }
71 
72   // Invoked as plain function `MyObject(...)`, turn into construct call.
73   argc = 1;
74   napi_value argv[1] = {args[0]};
75 
76   napi_value cons;
77   NAPI_CALL(env, napi_get_reference_value(env, constructor, &cons));
78 
79   napi_value instance;
80   NAPI_CALL(env, napi_new_instance(env, cons, argc, argv, &instance));
81 
82   return instance;
83 }
84 
GetValue(napi_env env,napi_callback_info info)85 napi_value MyObject::GetValue(napi_env env, napi_callback_info info) {
86   napi_value _this;
87   NAPI_CALL(env,
88       napi_get_cb_info(env, info, nullptr, nullptr, &_this, nullptr));
89 
90   MyObject* obj;
91   NAPI_CALL(env, napi_unwrap(env, _this, reinterpret_cast<void**>(&obj)));
92 
93   napi_value num;
94   NAPI_CALL(env, napi_create_double(env, obj->value_, &num));
95 
96   return num;
97 }
98 
SetValue(napi_env env,napi_callback_info info)99 napi_value MyObject::SetValue(napi_env env, napi_callback_info info) {
100   size_t argc = 1;
101   napi_value args[1];
102   napi_value _this;
103   NAPI_CALL(env, napi_get_cb_info(env, info, &argc, args, &_this, nullptr));
104 
105   MyObject* obj;
106   NAPI_CALL(env, napi_unwrap(env, _this, reinterpret_cast<void**>(&obj)));
107 
108   NAPI_CALL(env, napi_get_value_double(env, args[0], &obj->value_));
109 
110   return nullptr;
111 }
112 
PlusOne(napi_env env,napi_callback_info info)113 napi_value MyObject::PlusOne(napi_env env, napi_callback_info info) {
114   napi_value _this;
115   NAPI_CALL(env,
116       napi_get_cb_info(env, info, nullptr, nullptr, &_this, nullptr));
117 
118   MyObject* obj;
119   NAPI_CALL(env, napi_unwrap(env, _this, reinterpret_cast<void**>(&obj)));
120 
121   obj->value_ += 1;
122 
123   napi_value num;
124   NAPI_CALL(env, napi_create_double(env, obj->value_, &num));
125 
126   return num;
127 }
128 
Multiply(napi_env env,napi_callback_info info)129 napi_value MyObject::Multiply(napi_env env, napi_callback_info info) {
130   size_t argc = 1;
131   napi_value args[1];
132   napi_value _this;
133   NAPI_CALL(env, napi_get_cb_info(env, info, &argc, args, &_this, nullptr));
134 
135   double multiple = 1;
136   if (argc >= 1) {
137     NAPI_CALL(env, napi_get_value_double(env, args[0], &multiple));
138   }
139 
140   MyObject* obj;
141   NAPI_CALL(env, napi_unwrap(env, _this, reinterpret_cast<void**>(&obj)));
142 
143   napi_value cons;
144   NAPI_CALL(env, napi_get_reference_value(env, constructor, &cons));
145 
146   const int kArgCount = 1;
147   napi_value argv[kArgCount];
148   NAPI_CALL(env, napi_create_double(env, obj->value_ * multiple, argv));
149 
150   napi_value instance;
151   NAPI_CALL(env, napi_new_instance(env, cons, kArgCount, argv, &instance));
152 
153   return instance;
154 }
155 
156 EXTERN_C_START
Init(napi_env env,napi_value exports)157 napi_value Init(napi_env env, napi_value exports) {
158   MyObject::Init(env, exports);
159   return exports;
160 }
161 EXTERN_C_END
162