Skip to content

Commit ef16dfb

Browse files
author
Gabriel Schulhof
committed
doc: update ObjectWrap example
* Remove the global static reference to the constructor * Use `Napi::Env::SetInstanceData` to store the constructor, and * Add a static method that uses `Napi::FunctionReference::New` to create a new instance of the class by retrieving the constructor using `Napi::Env::GetInstanceData` and using `Napi::FunctionReference::New` to create the new instance. Fixes: #711 PR-URL: #754 Reviewed-By: Nicola Del Gobbo <[email protected]> Reviewed-By: Anna Henningsen <[email protected]>
1 parent 48f6762 commit ef16dfb

File tree

1 file changed

+33
-15
lines changed

1 file changed

+33
-15
lines changed

doc/object_wrap.md

Lines changed: 33 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -22,49 +22,57 @@ your C++ class methods.
2222
class Example : public Napi::ObjectWrap<Example> {
2323
public:
2424
static Napi::Object Init(Napi::Env env, Napi::Object exports);
25-
Example(const Napi::CallbackInfo &info);
25+
Example(const Napi::CallbackInfo& info);
26+
static Napi::Value CreateNewItem(const Napi::CallbackInfo& info);
2627

2728
private:
28-
static Napi::FunctionReference constructor;
2929
double _value;
30-
Napi::Value GetValue(const Napi::CallbackInfo &info);
31-
Napi::Value SetValue(const Napi::CallbackInfo &info);
30+
Napi::Value GetValue(const Napi::CallbackInfo& info);
31+
Napi::Value SetValue(const Napi::CallbackInfo& info);
3232
};
3333

3434
Napi::Object Example::Init(Napi::Env env, Napi::Object exports) {
3535
// This method is used to hook the accessor and method callbacks
3636
Napi::Function func = DefineClass(env, "Example", {
3737
InstanceMethod<&Example::GetValue>("GetValue"),
38-
InstanceMethod<&Example::SetValue>("SetValue")
38+
InstanceMethod<&Example::SetValue>("SetValue"),
39+
StaticMethod<&Example::CreateNewItem>("CreateNewItem"),
3940
});
4041

42+
Napi::FunctionReference* constructor = new Napi::FunctionReference();
43+
4144
// Create a peristent reference to the class constructor. This will allow
4245
// a function called on a class prototype and a function
4346
// called on instance of a class to be distinguished from each other.
44-
constructor = Napi::Persistent(func);
45-
// Call the SuppressDestruct() method on the static data prevent the calling
46-
// to this destructor to reset the reference when the environment is no longer
47-
// available.
48-
constructor.SuppressDestruct();
47+
*constructor = Napi::Persistent(func);
4948
exports.Set("Example", func);
49+
50+
// Store the constructor as the add-on instance data. This will allow this
51+
// add-on to support multiple instances of itself running on multiple worker
52+
// threads, as well as multiple instances of itself running in different
53+
// contexts on the same thread.
54+
//
55+
// By default, the value set on the environment here will be destroyed when
56+
// the add-on is unloaded using the `delete` operator, but it is also
57+
// possible to supply a custom deleter.
58+
env.SetInstanceData<Napi::FunctionReference>(constructor);
59+
5060
return exports;
5161
}
5262

53-
Example::Example(const Napi::CallbackInfo &info) : Napi::ObjectWrap<Example>(info) {
63+
Example::Example(const Napi::CallbackInfo& info) : Napi::ObjectWrap<Example>(info) {
5464
Napi::Env env = info.Env();
5565
// ...
5666
Napi::Number value = info[0].As<Napi::Number>();
5767
this->_value = value.DoubleValue();
5868
}
5969

60-
Napi::FunctionReference Example::constructor;
61-
62-
Napi::Value Example::GetValue(const Napi::CallbackInfo &info){
70+
Napi::Value Example::GetValue(const Napi::CallbackInfo& info){
6371
Napi::Env env = info.Env();
6472
return Napi::Number::New(env, this->_value);
6573
}
6674

67-
Napi::Value Example::SetValue(const Napi::CallbackInfo &info){
75+
Napi::Value Example::SetValue(const Napi::CallbackInfo& info){
6876
Napi::Env env = info.Env();
6977
// ...
7078
Napi::Number value = info[0].As<Napi::Number>();
@@ -78,6 +86,16 @@ Napi::Object Init (Napi::Env env, Napi::Object exports) {
7886
return exports;
7987
}
8088

89+
// Create a new item using the constructor stored during Init.
90+
Napi::Value Example::CreateNewItem(const Napi::CallbackInfo& info) {
91+
// Retrieve the instance data we stored during `Init()`. We only stored the
92+
// constructor there, so we retrieve it here to create a new instance of the
93+
// JS class the constructor represents.
94+
Napi::FunctionReference* constructor =
95+
info.Env().GetInstanceData<Napi::FunctionReference>();
96+
return constructor->New({ Napi::Number::New(info.Env(), 42) });
97+
}
98+
8199
// Register and initialize native add-on
82100
NODE_API_MODULE(NODE_GYP_MODULE_NAME, Init)
83101
```

0 commit comments

Comments
 (0)