From d1695a0691c9f78f9cb05feae9c3feea03c19402 Mon Sep 17 00:00:00 2001 From: NickNaso Date: Wed, 29 Aug 2018 15:36:07 +0200 Subject: [PATCH 1/9] First pass on objectwrap documentation --- doc/class_property_descriptor.md | 39 +++- doc/object_wrap.md | 384 +++++++++++++++++++++++++++++++ 2 files changed, 419 insertions(+), 4 deletions(-) diff --git a/doc/class_property_descriptor.md b/doc/class_property_descriptor.md index cca90d186..2997e3e6f 100644 --- a/doc/class_property_descriptor.md +++ b/doc/class_property_descriptor.md @@ -1,5 +1,36 @@ -# Class propertry and descriptior +# Class propertry and descriptor -You are reading a draft of the next documentation and it's in continuous update so -if you don't find what you need please refer to: -[C++ wrapper classes for the ABI-stable C APIs for Node.js](https://nodejs.github.io/node-addon-api/) +Property descriptor for use with `Napi::ObjectWrap::DefineClass()`. +This is different from the standalone `Napi::PropertyDescriptor` because it is +specific to each `Napi::ObjectWrap` subclass. +This prevents using descriptors from a different class when defining a new class +(preventing the callbacks from having incorrect `this` pointers). + +## Methods + +### Contructor + +Creates new instance of `ClassPropertyDescriptor` descriptor object. + +```cpp +ClassPropertyDescriptor(napi_property_descriptor desc) : _desc(desc) {} +``` + +- `[in] desc`: The `napi_property_descriptor` + +Returns new instance of `Napi::ClassPropertyDescriptor` that is used as property descriptor +inside the `Napi::ObjectWrap` class. + +### Operator + +```cpp +operator napi_property_descriptor&() { return _desc; } +``` + +Returns the original N-API `napi_property_descriptor` wrapped inside the `ClassPropertyDescriptor` + +```cpp +operator const napi_property_descriptor&() const { return _desc; } +``` + +Returns the original N-API `napi_property_descriptor` wrapped inside the `ClassPropertyDescriptor` \ No newline at end of file diff --git a/doc/object_wrap.md b/doc/object_wrap.md index 9f4422e61..e92141d32 100644 --- a/doc/object_wrap.md +++ b/doc/object_wrap.md @@ -11,3 +11,387 @@ will be your responsibility write custom code to bridge each of your C++ class m You are reading a draft of the next documentation and it's in continuous update so if you don't find what you need please refer to: [C++ wrapper classes for the ABI-stable C APIs for Node.js](https://nodejs.github.io/node-addon-api/) +# Object Wrap + +The `ObjectWrap` class is used to expose C++ code to JavaScript. Every C++ +class instance will be "wrapped" by a JavaScript object that is managed by the +`ObjectWrap` class. To create a wrapper it's necessary to extend the `ObjectWrap` +class that contains all the plumbing to connect JavaScript code with a C++ object. +Classes extending `ObjectWrap` can be instantiated from JavaScript using the +**new** operator, and their methods can be directly invoked from JavaScript. +The **wrap** word refers to a way of grouping methods and state of the class +because it will be necessary write custom code to bridge each of your C++ class +methods. + +## Example + +```cpp +#include + +class Example : public Napi::ObjectWrap { + public: + static Napi::Object Init(Napi::Env env, Napi::Object exports); + Example(const Napi::CallbackInfo &info); + + private: + static Napi::FunctionReference constructor; + double _value; + Napi::Value GetValue(const Napi::CallbackInfo &info); + Napi::Value SetValue(const Napi::CallbackInfo &info); +}; + +Napi::Object Example::Init(Napi::Env env, Napi::Object exports) { + Napi::HandleScope scope(env); + // This method is used to hook the accessor and method callbacks + Napi::Function func = DefineClass(env, "Example", { + InstanceMethod("GetValue", &Example::GetValue), + InstanceMethod("SetValue", &Example::SetValue) + }); + + constructor = Napi::Persistent(func); + constructor.SuppressDestruct(); + exports.Set("Example", func); + return exports; +} +Example::Example(const Napi::CallbackInfo &info) : Napi::ObjectWrap(info) { + Napi::Env env = info.Env(); + // ... + Napi::Number value = info[0].As(); + this->_value = value.DoubleValue(); +} +Napi::FunctionReference Example::constructor; + +Napi::Value Example::GetValue(const Napi::CallbackInfo &info){ + Napi::Env env = info.Env(); + return Napi::Number::New(env, this->_value); +} +Napi::Value Example::SetValue(const Napi::CallbackInfo &info){ + Napi::Env env = info.Env(); + // ... + Napi::Number value = info[0].As(); + this->_value = value.DoubleValue(); + return this->GetValue(info); +} + +// Initialize native add-on +Napi::Object Init (Napi::Env env, Napi::Object exports) { + Example::Init(env, exports); + return exports; +} + +// Regisgter and initialize native add-on +NODE_API_MODULE(NODE_GYP_MODULE_NAME, Init) +``` + +The above code can be used from JavaScript as follows: + +```js +'use strict' + +const { Example } = require('bindings')('addon') + +const example = new Example(11) +console.log(example.GetValue()) +// It prints 11 +example.SetValue(19) +console.log(example.GetValue()); +// It prints 19 +``` + +At initialization time, the `Napi::ObjectWrap::DefineClass()` method must be used +to hook up the accessor and method callbacks. It takes a list of property +descriptors, which can be constructed via the various static methods on the base +class. + +When JavaScript code invokes the constructor, the constructor callback will wrap +a new C++ instance in a JavaScript object. + +When JavaScript code invokes a method or a property accessor on the class the +corresponding C++ callback function will be executed. + +For wrapped object it could be difficult to distinguish between a function called +on a class prototype and a function called on instance of a class so a good practice +is to save a persistent to the class constructor. + +## Methods + +### Contructor + +Creates a new instance of a JavaScript object that wraps native instance. + +```cpp +ObjectWrap(const CallbackInfo& callbackInfo); +``` + +- `[in] callbackInfo`: The object representing the components of the JavaScript +request being made. + +### Unwrap + +Retrieves a native instance wrapped in a JavaScript object. + +```cpp +static T* Unwrap(Object wrapper); +``` + +* `[in] wrapper`: The JavaScript object that wraps the native instance. + +Returns a native instace wrapped in a JavaScript object. + +### DefineClass + +Defnines a JavaScript class with constructor, static and instance properties and +methods. + +```cpp +static Function DefineClass(Napi::Env env, + const char* utf8name, + const std::initializer_list& properties, + void* data = nullptr); +``` + +* `[in] env`: The environment in which to construct a JavaScript class. +* `[in] utf8name`: Null-terminated string that represents the name of the +JavaScript constructor function. +* `[in] properties`: Initializer list of class property descriptor describing +static and instance properties and methods of the class. See: [`Class propertry and descriptor`](class_property_descriptor.md). +* `[in] data`: User-provided data passed to the constructor callback as `data` +property of the `Napi::CallbackInfo`. + +Returns a `Napi::Function` representing the constructor function for the class. + +### DefineClass + +Defnines a JavaScript class with constructor, static and instance properties and +methods. + +```cpp +static Function DefineClass(Napi::Env env, + const char* utf8name, + const std::vector& properties, + void* data = nullptr); +``` + +* `[in] env`: The environment in which to construct a JavaScript class. +* `[in] utf8name`: Null-terminated string that represents the name of the +JavaScript constructor function. +* `[in] properties`: Vector of class property descriptor describing static and +instance properties and methods of the class. See: [`Class propertry and descriptor`](class_property_descriptor.md). +* `[in] data`: User-provided data passed to the constructor callback as `data` +property of the `Napi::CallbackInfo`. + +Returns a `Napi::Function` representing the constructor function for the class. + +### StaticMethod + +Creates property descriptor that represents a static method of a JavaScript class. + +```cpp +static PropertyDescriptor StaticMethod(const char* utf8name, + StaticVoidMethodCallback method, + napi_property_attributes attributes = napi_default, + void* data = nullptr); +``` + +- `[in] utf8name`: Null-terminated string that represents the name of a static +method for the class. +- `[in] method`: The native function that represents a static method of a +JavaScript class. +- `[in] attributes`: The attributes associated with a particular property. +- `[in] data`: User-provided data passed into method when it is invoked. + +Returns `Napi::PropertyDescriptor` object that represents the static method of a +JavaScript class. + +### StaticMethod + +Creates property descriptor that represents a static method of a JavaScript class. + +```cpp +static PropertyDescriptor StaticMethod(const char* utf8name, + StaticMethodCallback method, + napi_property_attributes attributes = napi_default, + void* data = nullptr); +``` + +- `[in] utf8name`: Null-terminated string that represents the name of a static +method for the class. +- `[in] method`: The native function that represents a static method of a +JavaScript class. +- `[in] attributes`: The attributes associated with a particular property. +- `[in] data`: User-provided data passed into method when it is invoked. + +Returns `Napi::PropertyDescriptor` object that represents a static method of a +JavaScript class. + +### StaticAccessor + +Creates property descriptor that represents a static accessor property of a +JavaScript class. + +```cpp +static PropertyDescriptor StaticAccessor(const char* utf8name, + StaticGetterCallback getter, + StaticSetterCallback setter, + napi_property_attributes attributes = napi_default, + void* data = nullptr); +``` + +- `[in] utf8name`: Null-terminated string that represents the name of a static +accessor property for the class. +- `[in] getter`: The native function to call when a get access to the property of +a JavaScript class is performed. +- `[in] setter`: The native function to call when a set access to the property of +a JavaScript class is performed. +- `[in] attributes`: The attributes associated with a particular property. +- `[in] data`: User-provided data passed into getter or setter when this is invoked. + +Returns `Napi::PropertyDescriptor` object that represents a static accessor +property of a JavaScript class. + +### InstanceMethod + +Creates property descriptor that represents an instance method of a JavaScript class. + +```cpp +static PropertyDescriptor InstanceMethod(const char* utf8name, + InstanceVoidMethodCallback method, + napi_property_attributes attributes = napi_default, + void* data = nullptr); +``` + +- `[in] utf8name`: Null-terminated string that represents the name of an instance +method for the class. +- `[in] method`: The native function that represents an instance method of a +JavaScript class. +- `[in] attributes`: The attributes associated with a particular property. +- `[in] data`: User-provided data passed into method when it is invoked. + +Returns `Napi::PropertyDescriptor` object that represents an instance method of a +JavaScript class. + +### InstanceMethod + +Creates property descriptor that represents an instance method of a JavaScript class. + +```cpp +static PropertyDescriptor InstanceMethod(const char* utf8name, + InstanceMethodCallback method, + napi_property_attributes attributes = napi_default, + void* data = nullptr); +``` + +- `[in] utf8name`: Null-terminated string that represents the name of an instance +method for the class. +- `[in] method`: The native function that represents an instance method of a +JavaScript class. +- `[in] attributes`: The attributes associated with a particular property. +- `[in] data`: User-provided data passed into method when it is invoked. + +Returns `Napi::PropertyDescriptor` object that represents an instance method of a +JavaScript class. + +### InstanceMethod + +Creates property descriptor that represents an instance method of a JavaScript class. + +```cpp +static PropertyDescriptor InstanceMethod(Symbol name, + InstanceVoidMethodCallback method, + napi_property_attributes attributes = napi_default, + void* data = nullptr); +``` + +- `[in] name`: The `Napi::Symbol` object whose value is used to identify the +instance method for the class. +- `[in] method`: The native function that represents an instance method of a +JavaScript class. +- `[in] attributes`: The attributes associated with a particular property. +- `[in] data`: User-provided data passed into method when it is invoked. + +Returns `Napi::PropertyDescriptor` object that represents an instance method of a +JavaScript class. + +### InstanceMethod + +Creates property descriptor that represents an instance method of a JavaScript class. + +```cpp +static PropertyDescriptor InstanceMethod(Symbol name, + InstanceMethodCallback method, + napi_property_attributes attributes = napi_default, + void* data = nullptr); +``` + +- `[in] name`: The `Napi::Symbol` object whose value is used to identify the +instance method for the class. +- `[in] method`: The native function that represents an instance method of a +JavaScript class. +- `[in] attributes`: The attributes associated with a particular property. +- `[in] data`: User-provided data passed into method when it is invoked. + +Returns `Napi::PropertyDescriptor` object that represents an instance method of a +JavaScript class. + +### InstanceAccessor + +Creates property descriptor that represents an instance accessor property of a +JavaScript class. + +```cpp +static PropertyDescriptor InstanceAccessor(const char* utf8name, + InstanceGetterCallback getter, + InstanceSetterCallback setter, + napi_property_attributes attributes = napi_default, + void* data = nullptr); +``` + +- `[in] utf8name`: Null-terminated string that represents the name of an instance +accessor property for the class. +- `[in] getter`: The native function to call when a get access to the property of +a JavaScript class is performed. +- `[in] setter`: The native function to call when a set access to the property of +a JavaScript class is performed. +- `[in] attributes`: The attributes associated with the particular property. +- `[in] data`: User-provided data passed into getter or setter when this is invoked. + +Returns `Napi::PropertyDescriptor` object that represents an instance accessor +property of a JavaScript class. + +### StaticValue + +Creates property descriptor that represents an instance accessor property of a +JavaScript class. +```cpp +static PropertyDescriptor StaticValue(const char* utf8name, + Napi::Value value, + napi_property_attributes attributes = napi_default); +``` + +- `[in] utf8name`: Null-terminated string that represents the name of an instance +accessor property for the class. +- `[in] value`: The value that's retrieved by a get access of the property if the +property is a data property. +- `[in] attributes`: User-provided data passed into getter or setter when this is invoked. + +Returns `Napi::PropertyDescriptor` object that represents an instance accessor +property of a JavaScript class + +### InstanceValue + +Creates property descriptor that represents an instance accessor property of a +JavaScript class. +```cpp +static PropertyDescriptor InstanceValue(const char* utf8name, + Napi::Value value, + napi_property_attributes attributes = napi_default); +``` + +- `[in] utf8name`: Null-terminated string that represents the name of an instance +accessor property for the class. +- `[in] value`: The value that's retrieved by a get access of the property if the +property is a data property. +- `[in] attributes`: User-provided data passed into getter or setter when this is invoked. + +Returns `Napi::PropertyDescriptor` object that represents an instance accessor +property of a JavaScript class. From 750482947beb1d31e733688f5f1321c0416dfdfe Mon Sep 17 00:00:00 2001 From: NickNaso Date: Wed, 29 Aug 2018 15:57:01 +0200 Subject: [PATCH 2/9] Removed old content --- doc/object_wrap.md | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/doc/object_wrap.md b/doc/object_wrap.md index e92141d32..c967cd10e 100644 --- a/doc/object_wrap.md +++ b/doc/object_wrap.md @@ -1,16 +1,3 @@ -## Object Wrap - -The ```ObjectWrap``` class can be used to expose C++ code to JavaScript. To do -this you need to extend the ObjectWrap class that contain all the plumbing to connect -JavaScript code to a C++ object. -Classes extending ```ObjectWrap``` can be instantiated from JavaScript using the -**new** operator, and their methods can be directly invoked from JavaScript. -The **wrap** word refers to a way to group methods and state of your class because it -will be your responsibility write custom code to bridge each of your C++ class methods. - -You are reading a draft of the next documentation and it's in continuous update so -if you don't find what you need please refer to: -[C++ wrapper classes for the ABI-stable C APIs for Node.js](https://nodejs.github.io/node-addon-api/) # Object Wrap The `ObjectWrap` class is used to expose C++ code to JavaScript. Every C++ From 7a36a96138e7e96fd86caa06caa7cc310451fc1a Mon Sep 17 00:00:00 2001 From: NickNaso Date: Thu, 30 Aug 2018 19:08:05 +0200 Subject: [PATCH 3/9] Added missing namespace --- doc/class_property_descriptor.md | 6 +++--- doc/object_wrap.md | 16 ++++++++-------- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/doc/class_property_descriptor.md b/doc/class_property_descriptor.md index 2997e3e6f..9a0ef5e21 100644 --- a/doc/class_property_descriptor.md +++ b/doc/class_property_descriptor.md @@ -10,7 +10,7 @@ This prevents using descriptors from a different class when defining a new class ### Contructor -Creates new instance of `ClassPropertyDescriptor` descriptor object. +Creates new instance of `Napi::ClassPropertyDescriptor` descriptor object. ```cpp ClassPropertyDescriptor(napi_property_descriptor desc) : _desc(desc) {} @@ -27,10 +27,10 @@ inside the `Napi::ObjectWrap` class. operator napi_property_descriptor&() { return _desc; } ``` -Returns the original N-API `napi_property_descriptor` wrapped inside the `ClassPropertyDescriptor` +Returns the original N-API `napi_property_descriptor` wrapped inside the `Napi::ClassPropertyDescriptor` ```cpp operator const napi_property_descriptor&() const { return _desc; } ``` -Returns the original N-API `napi_property_descriptor` wrapped inside the `ClassPropertyDescriptor` \ No newline at end of file +Returns the original N-API `napi_property_descriptor` wrapped inside the `Napi::ClassPropertyDescriptor` \ No newline at end of file diff --git a/doc/object_wrap.md b/doc/object_wrap.md index c967cd10e..5df1e2fab 100644 --- a/doc/object_wrap.md +++ b/doc/object_wrap.md @@ -1,14 +1,14 @@ # Object Wrap -The `ObjectWrap` class is used to expose C++ code to JavaScript. Every C++ +The `Napi::ObjectWrap` class is used to expose C++ code to JavaScript. Every C++ class instance will be "wrapped" by a JavaScript object that is managed by the -`ObjectWrap` class. To create a wrapper it's necessary to extend the `ObjectWrap` -class that contains all the plumbing to connect JavaScript code with a C++ object. -Classes extending `ObjectWrap` can be instantiated from JavaScript using the -**new** operator, and their methods can be directly invoked from JavaScript. -The **wrap** word refers to a way of grouping methods and state of the class -because it will be necessary write custom code to bridge each of your C++ class -methods. +`Napi::ObjectWrap` class. To create a wrapper it's necessary to extend the +`Napi::ObjectWrap`class that contains all the plumbing to connect JavaScript code +with a C++ object. Classes extending `Napi::ObjectWrap` can be instantiated from +JavaScript using the **new** operator, and their methods can be directly invoked +from JavaScript. The **wrap** word refers to a way of grouping methods and state +of the class because it will be necessary write custom code to bridge each of +your C++ class methods. ## Example From cdc4970e025e4c3478b0b48951786e90b7d3491f Mon Sep 17 00:00:00 2001 From: NickNaso Date: Mon, 17 Sep 2018 20:35:56 +0200 Subject: [PATCH 4/9] Added changes after first review --- doc/class_property_descriptor.md | 2 +- doc/object_wrap.md | 41 ++++++++++++++++++-------------- 2 files changed, 24 insertions(+), 19 deletions(-) diff --git a/doc/class_property_descriptor.md b/doc/class_property_descriptor.md index 9a0ef5e21..fb533124e 100644 --- a/doc/class_property_descriptor.md +++ b/doc/class_property_descriptor.md @@ -13,7 +13,7 @@ This prevents using descriptors from a different class when defining a new class Creates new instance of `Napi::ClassPropertyDescriptor` descriptor object. ```cpp -ClassPropertyDescriptor(napi_property_descriptor desc) : _desc(desc) {} +Napi::ClassPropertyDescriptor(napi_property_descriptor desc) : _desc(desc) {} ``` - `[in] desc`: The `napi_property_descriptor` diff --git a/doc/object_wrap.md b/doc/object_wrap.md index 5df1e2fab..3daf3b83b 100644 --- a/doc/object_wrap.md +++ b/doc/object_wrap.md @@ -28,14 +28,19 @@ class Example : public Napi::ObjectWrap { }; Napi::Object Example::Init(Napi::Env env, Napi::Object exports) { - Napi::HandleScope scope(env); // This method is used to hook the accessor and method callbacks Napi::Function func = DefineClass(env, "Example", { InstanceMethod("GetValue", &Example::GetValue), InstanceMethod("SetValue", &Example::SetValue) }); - + + // Create a peristent reference to the class constructor. This will allow to + // distinguish between a function called on a class prototype and a function + // called on instance of a class. constructor = Napi::Persistent(func); + // Call the SuppressDestruct() method on the static data prevent the calling + // to this destructor to reset the reference when the environment is no longer + // available. constructor.SuppressDestruct(); exports.Set("Example", func); return exports; @@ -98,7 +103,7 @@ corresponding C++ callback function will be executed. For wrapped object it could be difficult to distinguish between a function called on a class prototype and a function called on instance of a class so a good practice -is to save a persistent to the class constructor. +is to save a persistent reference to the class constructor. ## Methods @@ -107,7 +112,7 @@ is to save a persistent to the class constructor. Creates a new instance of a JavaScript object that wraps native instance. ```cpp -ObjectWrap(const CallbackInfo& callbackInfo); +Napi::ObjectWrap(const Napi::CallbackInfo& callbackInfo); ``` - `[in] callbackInfo`: The object representing the components of the JavaScript @@ -118,7 +123,7 @@ request being made. Retrieves a native instance wrapped in a JavaScript object. ```cpp -static T* Unwrap(Object wrapper); +static T* Napi::ObjectWrap::Unwrap(Napi::Object wrapper); ``` * `[in] wrapper`: The JavaScript object that wraps the native instance. @@ -127,11 +132,11 @@ Returns a native instace wrapped in a JavaScript object. ### DefineClass -Defnines a JavaScript class with constructor, static and instance properties and +Defnines is a JavaScript class with constructor, static and instance properties and methods. ```cpp -static Function DefineClass(Napi::Env env, +static Napi::Function Napi::ObjectWrap::DefineClass(Napi::Env env, const char* utf8name, const std::initializer_list& properties, void* data = nullptr); @@ -153,7 +158,7 @@ Defnines a JavaScript class with constructor, static and instance properties and methods. ```cpp -static Function DefineClass(Napi::Env env, +static Napi::Function Napi::ObjectWrap::DefineClass(Napi::Env env, const char* utf8name, const std::vector& properties, void* data = nullptr); @@ -174,7 +179,7 @@ Returns a `Napi::Function` representing the constructor function for the class. Creates property descriptor that represents a static method of a JavaScript class. ```cpp -static PropertyDescriptor StaticMethod(const char* utf8name, +static Napi::PropertyDescriptor Napi::ObjectWrap::StaticMethod(const char* utf8name, StaticVoidMethodCallback method, napi_property_attributes attributes = napi_default, void* data = nullptr); @@ -195,7 +200,7 @@ JavaScript class. Creates property descriptor that represents a static method of a JavaScript class. ```cpp -static PropertyDescriptor StaticMethod(const char* utf8name, +static Napi::PropertyDescriptor Napi::ObjectWrap::StaticMethod(const char* utf8name, StaticMethodCallback method, napi_property_attributes attributes = napi_default, void* data = nullptr); @@ -217,7 +222,7 @@ Creates property descriptor that represents a static accessor property of a JavaScript class. ```cpp -static PropertyDescriptor StaticAccessor(const char* utf8name, +static Napi::PropertyDescriptor Napi::ObjectWrap::StaticAccessor(const char* utf8name, StaticGetterCallback getter, StaticSetterCallback setter, napi_property_attributes attributes = napi_default, @@ -241,7 +246,7 @@ property of a JavaScript class. Creates property descriptor that represents an instance method of a JavaScript class. ```cpp -static PropertyDescriptor InstanceMethod(const char* utf8name, +static Napi::PropertyDescriptor Napi::ObjectWrap::InstanceMethod(const char* utf8name, InstanceVoidMethodCallback method, napi_property_attributes attributes = napi_default, void* data = nullptr); @@ -262,7 +267,7 @@ JavaScript class. Creates property descriptor that represents an instance method of a JavaScript class. ```cpp -static PropertyDescriptor InstanceMethod(const char* utf8name, +static Napi::PropertyDescriptor Napi::ObjectWrap::InstanceMethod(const char* utf8name, InstanceMethodCallback method, napi_property_attributes attributes = napi_default, void* data = nullptr); @@ -283,7 +288,7 @@ JavaScript class. Creates property descriptor that represents an instance method of a JavaScript class. ```cpp -static PropertyDescriptor InstanceMethod(Symbol name, +static Napi::PropertyDescriptor Napi::ObjectWrap::InstanceMethod(Napi::Symbol name, InstanceVoidMethodCallback method, napi_property_attributes attributes = napi_default, void* data = nullptr); @@ -304,7 +309,7 @@ JavaScript class. Creates property descriptor that represents an instance method of a JavaScript class. ```cpp -static PropertyDescriptor InstanceMethod(Symbol name, +static Napi::PropertyDescriptor Napi::ObjectWrap::InstanceMethod(Napi::Symbol name, InstanceMethodCallback method, napi_property_attributes attributes = napi_default, void* data = nullptr); @@ -326,7 +331,7 @@ Creates property descriptor that represents an instance accessor property of a JavaScript class. ```cpp -static PropertyDescriptor InstanceAccessor(const char* utf8name, +static Napi::PropertyDescriptor Napi::ObjectWrap::InstanceAccessor(const char* utf8name, InstanceGetterCallback getter, InstanceSetterCallback setter, napi_property_attributes attributes = napi_default, @@ -350,7 +355,7 @@ property of a JavaScript class. Creates property descriptor that represents an instance accessor property of a JavaScript class. ```cpp -static PropertyDescriptor StaticValue(const char* utf8name, +static Napi::PropertyDescriptor Napi::ObjectWrap::StaticValue(const char* utf8name, Napi::Value value, napi_property_attributes attributes = napi_default); ``` @@ -369,7 +374,7 @@ property of a JavaScript class Creates property descriptor that represents an instance accessor property of a JavaScript class. ```cpp -static PropertyDescriptor InstanceValue(const char* utf8name, +static Napi::PropertyDescriptor Napi::ObjectWrap::InstanceValue(const char* utf8name, Napi::Value value, napi_property_attributes attributes = napi_default); ``` From 2d85c2ca4fc9c6710d67020520c2946e3c747f4e Mon Sep 17 00:00:00 2001 From: Michael Dawson Date: Tue, 18 Sep 2018 10:00:44 -0400 Subject: [PATCH 5/9] squash: some suggested updates --- doc/object_wrap.md | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/doc/object_wrap.md b/doc/object_wrap.md index 3daf3b83b..137963901 100644 --- a/doc/object_wrap.md +++ b/doc/object_wrap.md @@ -1,9 +1,13 @@ # Object Wrap -The `Napi::ObjectWrap` class is used to expose C++ code to JavaScript. Every C++ -class instance will be "wrapped" by a JavaScript object that is managed by the -`Napi::ObjectWrap` class. To create a wrapper it's necessary to extend the -`Napi::ObjectWrap`class that contains all the plumbing to connect JavaScript code +The `Napi::ObjectWrap` class is used to bind the lifetime of C++ code to a +JavaScript object. Once bound, each time an instance of the JavaScript object +is created, an instance of the C++ class will also be created. When a method +is called on the JavaScript object which is defined as an InstanceMethod, the +corresponding C++ methond on the wrapped C++ class will be invoked. + +In order to create a wrapper it's necessary to extend the +`Napi::ObjectWrap`class which contains all the plumbing to connect JavaScript code with a C++ object. Classes extending `Napi::ObjectWrap` can be instantiated from JavaScript using the **new** operator, and their methods can be directly invoked from JavaScript. The **wrap** word refers to a way of grouping methods and state @@ -34,9 +38,9 @@ Napi::Object Example::Init(Napi::Env env, Napi::Object exports) { InstanceMethod("SetValue", &Example::SetValue) }); - // Create a peristent reference to the class constructor. This will allow to - // distinguish between a function called on a class prototype and a function - // called on instance of a class. + // Create a peristent reference to the class constructor. This will allow + // a function called on a class prototype and a function + // called on instance of a class to be identified. constructor = Napi::Persistent(func); // Call the SuppressDestruct() method on the static data prevent the calling // to this destructor to reset the reference when the environment is no longer @@ -45,18 +49,21 @@ Napi::Object Example::Init(Napi::Env env, Napi::Object exports) { exports.Set("Example", func); return exports; } + Example::Example(const Napi::CallbackInfo &info) : Napi::ObjectWrap(info) { Napi::Env env = info.Env(); // ... Napi::Number value = info[0].As(); - this->_value = value.DoubleValue(); + this->_value = value.DoubleValue(); } + Napi::FunctionReference Example::constructor; Napi::Value Example::GetValue(const Napi::CallbackInfo &info){ Napi::Env env = info.Env(); return Napi::Number::New(env, this->_value); } + Napi::Value Example::SetValue(const Napi::CallbackInfo &info){ Napi::Env env = info.Env(); // ... From 300df6aef41f27947e3b96a0413f6ba086590c52 Mon Sep 17 00:00:00 2001 From: Michael Dawson Date: Tue, 18 Sep 2018 10:24:40 -0400 Subject: [PATCH 6/9] squash: additional suggestions. --- doc/object_wrap.md | 34 ++++++++++++++++++++++------------ 1 file changed, 22 insertions(+), 12 deletions(-) diff --git a/doc/object_wrap.md b/doc/object_wrap.md index 137963901..4e3727edf 100644 --- a/doc/object_wrap.md +++ b/doc/object_wrap.md @@ -4,7 +4,7 @@ The `Napi::ObjectWrap` class is used to bind the lifetime of C++ code to a JavaScript object. Once bound, each time an instance of the JavaScript object is created, an instance of the C++ class will also be created. When a method is called on the JavaScript object which is defined as an InstanceMethod, the -corresponding C++ methond on the wrapped C++ class will be invoked. +corresponding C++ methon on the wrapped C++ class will be invoked. In order to create a wrapper it's necessary to extend the `Napi::ObjectWrap`class which contains all the plumbing to connect JavaScript code @@ -40,7 +40,7 @@ Napi::Object Example::Init(Napi::Env env, Napi::Object exports) { // Create a peristent reference to the class constructor. This will allow // a function called on a class prototype and a function - // called on instance of a class to be identified. + // called on instance of a class to be distinguished from each other. constructor = Napi::Persistent(func); // Call the SuppressDestruct() method on the static data prevent the calling // to this destructor to reset the reference when the environment is no longer @@ -102,15 +102,17 @@ to hook up the accessor and method callbacks. It takes a list of property descriptors, which can be constructed via the various static methods on the base class. -When JavaScript code invokes the constructor, the constructor callback will wrap -a new C++ instance in a JavaScript object. +When JavaScript code invokes the constructor, the constructor callback will create +a new C++ instance and "wrap" it into the newly created JavaScript object. When JavaScript code invokes a method or a property accessor on the class the corresponding C++ callback function will be executed. -For wrapped object it could be difficult to distinguish between a function called -on a class prototype and a function called on instance of a class so a good practice -is to save a persistent reference to the class constructor. +For a wrapped object it could be difficult to distinguish between a function called +on a class prototype and a function called on instance of a class. Therefore it is +good practice to save a persistent reference to the class constructor. This allows +the two cases to be distinguished from each other by checking the this object +against the class constructor. ## Methods @@ -135,11 +137,16 @@ static T* Napi::ObjectWrap::Unwrap(Napi::Object wrapper); * `[in] wrapper`: The JavaScript object that wraps the native instance. -Returns a native instace wrapped in a JavaScript object. +Returns a native instace wrapped in a JavaScript object. Given the +Napi:Object, this allows a method to get a pointer to the wrapped +C++ object and then reference fields, call methods, etc. within that class. +In many cases calling Unwrap is not required, as methods can +use the `this` field for ObjectWrap when running in a method on a +class that extends ObjectWrap. ### DefineClass -Defnines is a JavaScript class with constructor, static and instance properties and +Defnines a JavaScript class with constructor, static and instance properties and methods. ```cpp @@ -153,7 +160,8 @@ static Napi::Function Napi::ObjectWrap::DefineClass(Napi::Env env, * `[in] utf8name`: Null-terminated string that represents the name of the JavaScript constructor function. * `[in] properties`: Initializer list of class property descriptor describing -static and instance properties and methods of the class. See: [`Class propertry and descriptor`](class_property_descriptor.md). +static and instance properties and methods of the class. +See: [`Class propertry and descriptor`](class_property_descriptor.md). * `[in] data`: User-provided data passed to the constructor callback as `data` property of the `Napi::CallbackInfo`. @@ -175,7 +183,8 @@ static Napi::Function Napi::ObjectWrap::DefineClass(Napi::Env env, * `[in] utf8name`: Null-terminated string that represents the name of the JavaScript constructor function. * `[in] properties`: Vector of class property descriptor describing static and -instance properties and methods of the class. See: [`Class propertry and descriptor`](class_property_descriptor.md). +instance properties and methods of the class. +See: [`Class propertry and descriptor`](class_property_descriptor.md). * `[in] data`: User-provided data passed to the constructor callback as `data` property of the `Napi::CallbackInfo`. @@ -243,7 +252,8 @@ a JavaScript class is performed. - `[in] setter`: The native function to call when a set access to the property of a JavaScript class is performed. - `[in] attributes`: The attributes associated with a particular property. -- `[in] data`: User-provided data passed into getter or setter when this is invoked. +- `[in] data`: User-provided data passed into getter or setter when +is invoked. Returns `Napi::PropertyDescriptor` object that represents a static accessor property of a JavaScript class. From 47b8b0bddc401f75416810e61c9d2192c1f399e1 Mon Sep 17 00:00:00 2001 From: Michael Dawson Date: Tue, 18 Sep 2018 10:40:34 -0400 Subject: [PATCH 7/9] squash: additional suggestions --- doc/object_wrap.md | 35 +++++++++++++++++++++-------------- 1 file changed, 21 insertions(+), 14 deletions(-) diff --git a/doc/object_wrap.md b/doc/object_wrap.md index 4e3727edf..e16d97681 100644 --- a/doc/object_wrap.md +++ b/doc/object_wrap.md @@ -206,6 +206,7 @@ method for the class. - `[in] method`: The native function that represents a static method of a JavaScript class. - `[in] attributes`: The attributes associated with a particular property. +One or more of `napi_property_attributes`. - `[in] data`: User-provided data passed into method when it is invoked. Returns `Napi::PropertyDescriptor` object that represents the static method of a @@ -227,6 +228,7 @@ method for the class. - `[in] method`: The native function that represents a static method of a JavaScript class. - `[in] attributes`: The attributes associated with a particular property. +One or more of `napi_property_attributes`. - `[in] data`: User-provided data passed into method when it is invoked. Returns `Napi::PropertyDescriptor` object that represents a static method of a @@ -252,6 +254,7 @@ a JavaScript class is performed. - `[in] setter`: The native function to call when a set access to the property of a JavaScript class is performed. - `[in] attributes`: The attributes associated with a particular property. +One or more of `napi_property_attributes`. - `[in] data`: User-provided data passed into getter or setter when is invoked. @@ -274,6 +277,7 @@ method for the class. - `[in] method`: The native function that represents an instance method of a JavaScript class. - `[in] attributes`: The attributes associated with a particular property. +One or more of `napi_property_attributes`. - `[in] data`: User-provided data passed into method when it is invoked. Returns `Napi::PropertyDescriptor` object that represents an instance method of a @@ -295,6 +299,7 @@ method for the class. - `[in] method`: The native function that represents an instance method of a JavaScript class. - `[in] attributes`: The attributes associated with a particular property. +One or more of `napi_property_attributes`. - `[in] data`: User-provided data passed into method when it is invoked. Returns `Napi::PropertyDescriptor` object that represents an instance method of a @@ -316,6 +321,7 @@ instance method for the class. - `[in] method`: The native function that represents an instance method of a JavaScript class. - `[in] attributes`: The attributes associated with a particular property. +One or more of `napi_property_attributes`. - `[in] data`: User-provided data passed into method when it is invoked. Returns `Napi::PropertyDescriptor` object that represents an instance method of a @@ -337,6 +343,7 @@ instance method for the class. - `[in] method`: The native function that represents an instance method of a JavaScript class. - `[in] attributes`: The attributes associated with a particular property. +One or more of `napi_property_attributes`. - `[in] data`: User-provided data passed into method when it is invoked. Returns `Napi::PropertyDescriptor` object that represents an instance method of a @@ -362,6 +369,7 @@ a JavaScript class is performed. - `[in] setter`: The native function to call when a set access to the property of a JavaScript class is performed. - `[in] attributes`: The attributes associated with the particular property. +One or more of `napi_property_attributes`. - `[in] data`: User-provided data passed into getter or setter when this is invoked. Returns `Napi::PropertyDescriptor` object that represents an instance accessor @@ -369,7 +377,7 @@ property of a JavaScript class. ### StaticValue -Creates property descriptor that represents an instance accessor property of a +Creates property descriptor that represents an static value property of a JavaScript class. ```cpp static Napi::PropertyDescriptor Napi::ObjectWrap::StaticValue(const char* utf8name, @@ -377,18 +385,18 @@ static Napi::PropertyDescriptor Napi::ObjectWrap::StaticValue(const char* utf8na napi_property_attributes attributes = napi_default); ``` -- `[in] utf8name`: Null-terminated string that represents the name of an instance -accessor property for the class. -- `[in] value`: The value that's retrieved by a get access of the property if the -property is a data property. -- `[in] attributes`: User-provided data passed into getter or setter when this is invoked. +- `[in] utf8name`: Null-terminated string that represents the name of the static +property. +- `[in] value`: The value that's retrieved by a get access of the property. +- `[in] attributes`: The attributes to be associated with the property in addition +to the napi_static attribute. One or more of `napi_property_attributes`. -Returns `Napi::PropertyDescriptor` object that represents an instance accessor +Returns `Napi::PropertyDescriptor` object that represents an Static Value property of a JavaScript class ### InstanceValue -Creates property descriptor that represents an instance accessor property of a +Creates property descriptor that represents an instance value property of a JavaScript class. ```cpp static Napi::PropertyDescriptor Napi::ObjectWrap::InstanceValue(const char* utf8name, @@ -396,11 +404,10 @@ static Napi::PropertyDescriptor Napi::ObjectWrap::InstanceValue(const char* utf8 napi_property_attributes attributes = napi_default); ``` -- `[in] utf8name`: Null-terminated string that represents the name of an instance -accessor property for the class. -- `[in] value`: The value that's retrieved by a get access of the property if the -property is a data property. -- `[in] attributes`: User-provided data passed into getter or setter when this is invoked. +- `[in] utf8name`: Null-terminated string that represents the name of the property. +- `[in] value`: The value that's retrieved by a get access of the property. +- `[in] attributes`: The attributes to be associated with the property. +One or more of `napi_property_attributes`. -Returns `Napi::PropertyDescriptor` object that represents an instance accessor +Returns `Napi::PropertyDescriptor` object that represents an Instance value property of a JavaScript class. From 6ec99c09e766d2af5ee2653ec40ffda225f3aa29 Mon Sep 17 00:00:00 2001 From: Michael Dawson Date: Tue, 18 Sep 2018 10:41:57 -0400 Subject: [PATCH 8/9] squash: fix typo --- doc/object_wrap.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/object_wrap.md b/doc/object_wrap.md index e16d97681..cde1e0116 100644 --- a/doc/object_wrap.md +++ b/doc/object_wrap.md @@ -4,7 +4,7 @@ The `Napi::ObjectWrap` class is used to bind the lifetime of C++ code to a JavaScript object. Once bound, each time an instance of the JavaScript object is created, an instance of the C++ class will also be created. When a method is called on the JavaScript object which is defined as an InstanceMethod, the -corresponding C++ methon on the wrapped C++ class will be invoked. +corresponding C++ method on the wrapped C++ class will be invoked. In order to create a wrapper it's necessary to extend the `Napi::ObjectWrap`class which contains all the plumbing to connect JavaScript code From eafa7a3ed5d447027913b766ae0fa47db6d7b2f4 Mon Sep 17 00:00:00 2001 From: Michael Dawson Date: Tue, 18 Sep 2018 10:43:29 -0400 Subject: [PATCH 9/9] squash: fix typos --- doc/object_wrap.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/object_wrap.md b/doc/object_wrap.md index cde1e0116..ffbefa660 100644 --- a/doc/object_wrap.md +++ b/doc/object_wrap.md @@ -391,7 +391,7 @@ property. - `[in] attributes`: The attributes to be associated with the property in addition to the napi_static attribute. One or more of `napi_property_attributes`. -Returns `Napi::PropertyDescriptor` object that represents an Static Value +Returns `Napi::PropertyDescriptor` object that represents an static value property of a JavaScript class ### InstanceValue @@ -409,5 +409,5 @@ static Napi::PropertyDescriptor Napi::ObjectWrap::InstanceValue(const char* utf8 - `[in] attributes`: The attributes to be associated with the property. One or more of `napi_property_attributes`. -Returns `Napi::PropertyDescriptor` object that represents an Instance value +Returns `Napi::PropertyDescriptor` object that represents an instance value property of a JavaScript class.