Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Upgrade node-addon-api Object Wrap example for multi-context support #137

Closed
wants to merge 5 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions multiple_load_object_wrap/node-addon-api/addon.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#include <napi.h>
#include "myobject.h"

Napi::Object InitAll(Napi::Env env, Napi::Object exports) {
return MyObject::Init(env, exports);
}

NODE_API_MODULE(addon, InitAll)
42 changes: 42 additions & 0 deletions multiple_load_object_wrap/node-addon-api/addon.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
const addon = require('bindings')('addon');
const {Worker, isMainThread, workerData} = require('worker_threads');
const os = require('os');

if (isMainThread) {
(async function main() {
const threads = new Promise(resolve => {
const size = os.cpus().length * 2;
let wait = size;

for (let i = 0; i < size; i++) {
const worker = new Worker(__filename, {workerData: i});

worker.on('exit', () => {
wait--;
if (wait === 0) {
resolve();
}
});
}
});

work('main');
await threads;
})();
} else {
work(workerData);
}

function work(id) {
const obj = new addon.MyObject(10);
for (let i = 0; i < 10; i++) {
console.log(id, obj.plusOne());
}

console.log(id, obj.multiply().value());
console.log(id, obj.multiply(10).value());

const newobj = obj.multiply(-1);
console.log(id, newobj.value());
console.log(id, obj === newobj);
}
14 changes: 14 additions & 0 deletions multiple_load_object_wrap/node-addon-api/binding.gyp
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"targets": [
{
"target_name": "addon",
"cflags!": [ "-fno-exceptions" ],
"cflags_cc!": [ "-fno-exceptions" ],
"sources": [ "addon.cc", "myobject.cc" ],
"include_dirs": [
"<!@(node -p \"require('node-addon-api').include\")"
],
'defines': [ 'NAPI_DISABLE_CPP_EXCEPTIONS' ],
}
]
}
69 changes: 69 additions & 0 deletions multiple_load_object_wrap/node-addon-api/myobject.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
#include "myobject.h"

class AddonData {
public:
AddonData(Napi::Function func) {
MyObjectConstructor = Napi::Persistent(func);
MyObjectConstructor.SuppressDestruct();
}

Napi::FunctionReference MyObjectConstructor;
};

Napi::Object MyObject::Init(Napi::Env env, Napi::Object exports) {
Napi::HandleScope scope(env);

Napi::Function func =
DefineClass(env,
"MyObject",
{InstanceMethod("plusOne", &MyObject::PlusOne),
InstanceMethod("value", &MyObject::GetValue),
InstanceMethod("multiply", &MyObject::Multiply)});

env.SetInstanceData(new AddonData(func));

exports.Set("MyObject", func);
return exports;
}

MyObject::MyObject(const Napi::CallbackInfo& info)
: Napi::ObjectWrap<MyObject>(info) {
Napi::Env env = info.Env();
Napi::HandleScope scope(env);

int length = info.Length();

if (length <= 0 || !info[0].IsNumber()) {
Napi::TypeError::New(env, "Number expected").ThrowAsJavaScriptException();
return;
}

Napi::Number value = info[0].As<Napi::Number>();
this->value_ = value.DoubleValue();
}

Napi::Value MyObject::GetValue(const Napi::CallbackInfo& info) {
double num = this->value_;

return Napi::Number::New(info.Env(), num);
}

Napi::Value MyObject::PlusOne(const Napi::CallbackInfo& info) {
this->value_ = this->value_ + 1;

return MyObject::GetValue(info);
}

Napi::Value MyObject::Multiply(const Napi::CallbackInfo& info) {
Napi::Number multiple;
if (info.Length() <= 0 || !info[0].IsNumber()) {
multiple = Napi::Number::New(info.Env(), 1);
} else {
multiple = info[0].As<Napi::Number>();
}

Napi::Object obj = info.Env().GetInstanceData<AddonData>()->MyObjectConstructor.New(
{Napi::Number::New(info.Env(), this->value_ * multiple.DoubleValue())});

return obj;
}
19 changes: 19 additions & 0 deletions multiple_load_object_wrap/node-addon-api/myobject.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
#ifndef MYOBJECT_H
#define MYOBJECT_H

#include <napi.h>

class MyObject : public Napi::ObjectWrap<MyObject> {
public:
static Napi::Object Init(Napi::Env env, Napi::Object exports);
MyObject(const Napi::CallbackInfo& info);

private:
Napi::Value GetValue(const Napi::CallbackInfo& info);
Napi::Value PlusOne(const Napi::CallbackInfo& info);
Napi::Value Multiply(const Napi::CallbackInfo& info);

double value_;
};

#endif
15 changes: 15 additions & 0 deletions multiple_load_object_wrap/node-addon-api/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
"name": "object_wrap",
"version": "0.0.0",
"description": "Multiple load example of ObjectWrap",
"main": "addon.js",
"private": true,
"gypfile": true,
"engines": {
"node": ">= 14.0.0"
},
Comment on lines +8 to +10
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This needs to work with all supported versions of Node.js.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@anfilat using the value for "engiens" as suggested at #139 (comment) should make the CI green, and it should actually test your code on Travis at least, even if it doesn't test it on GitHub actions.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, wait, #139 needs to land to update the .travis.yml removing the non-supported Node.js 8 first 🙂

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@gabrielschulhof I think I should close this PR. It's duplicate with #139 now

"dependencies": {
"bindings": "~1.2.1",
"node-addon-api": "^3.0.0"
}
}