@@ -22,49 +22,57 @@ your C++ class methods.
2222class 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
3434Napi::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
82100NODE_API_MODULE(NODE_GYP_MODULE_NAME, Init)
83101```
0 commit comments