diff --git a/1_hello_world/node_4.x/binding.gyp b/1_hello_world/node_4.x/binding.gyp new file mode 100644 index 00000000..39b171f3 --- /dev/null +++ b/1_hello_world/node_4.x/binding.gyp @@ -0,0 +1,8 @@ +{ + "targets": [ + { + "target_name": "hello", + "sources": [ "hello.cc" ] + } + ] +} diff --git a/1_hello_world/node_4.x/hello.cc b/1_hello_world/node_4.x/hello.cc new file mode 100644 index 00000000..2a900535 --- /dev/null +++ b/1_hello_world/node_4.x/hello.cc @@ -0,0 +1,24 @@ +// hello.cc +#include + +namespace demo { + +using v8::FunctionCallbackInfo; +using v8::Isolate; +using v8::Local; +using v8::Object; +using v8::String; +using v8::Value; + +void Method(const v8::FunctionCallbackInfo& args) { + Isolate* isolate = args.GetIsolate(); + args.GetReturnValue().Set(String::NewFromUtf8(isolate, "world")); +} + +void Init(Local exports) { + NODE_SET_METHOD(exports, "hello", Method); +} + +NODE_MODULE(hello, Init) + +} // namespace demo diff --git a/1_hello_world/node_4.x/hello.js b/1_hello_world/node_4.x/hello.js new file mode 100644 index 00000000..00a05a11 --- /dev/null +++ b/1_hello_world/node_4.x/hello.js @@ -0,0 +1,3 @@ +const addon = require('bindings')('hello'); + +console.log(addon.hello()); // 'world' diff --git a/1_hello_world/node_4.x/package.json b/1_hello_world/node_4.x/package.json new file mode 100644 index 00000000..be588dd4 --- /dev/null +++ b/1_hello_world/node_4.x/package.json @@ -0,0 +1,14 @@ +{ + "name": "hello_world", + "version": "0.0.0", + "description": "Node.js Addons Example #1", + "main": "hello.js", + "private": true, + "scripts": { + "test": "node hello.js" + }, + "gypfile": true, + "dependencies": { + "bindings": "~1.2.1" + } +} diff --git a/2_function_arguments/node_4.x/addon.cc b/2_function_arguments/node_4.x/addon.cc new file mode 100644 index 00000000..56ef4b2a --- /dev/null +++ b/2_function_arguments/node_4.x/addon.cc @@ -0,0 +1,51 @@ +// addon.cc +#include + +namespace demo { + +using v8::Exception; +using v8::FunctionCallbackInfo; +using v8::Isolate; +using v8::Local; +using v8::Number; +using v8::Object; +using v8::String; +using v8::Value; + +// This is the implementation of the "add" method +// Input arguments are passed using the +// const FunctionCallbackInfo& args struct +void Add(const FunctionCallbackInfo& args) { + Isolate* isolate = args.GetIsolate(); + + // Check the number of arguments passed. + if (args.Length() < 2) { + // Throw an Error that is passed back to JavaScript + isolate->ThrowException(Exception::TypeError( + String::NewFromUtf8(isolate, "Wrong number of arguments"))); + return; + } + + // Check the argument types + if (!args[0]->IsNumber() || !args[1]->IsNumber()) { + isolate->ThrowException(Exception::TypeError( + String::NewFromUtf8(isolate, "Wrong arguments"))); + return; + } + + // Perform the operation + double value = args[0]->NumberValue() + args[1]->NumberValue(); + Local num = Number::New(isolate, value); + + // Set the return value (using the passed in + // FunctionCallbackInfo&) + args.GetReturnValue().Set(num); +} + +void Init(Local exports) { + NODE_SET_METHOD(exports, "add", Add); +} + +NODE_MODULE(addon, Init) + +} // namespace demo diff --git a/2_function_arguments/node_4.x/addon.js b/2_function_arguments/node_4.x/addon.js new file mode 100644 index 00000000..ffadfedc --- /dev/null +++ b/2_function_arguments/node_4.x/addon.js @@ -0,0 +1,3 @@ +const addon = require('bindings')('addon.node'); + +console.log('This should be eight:', addon.add(3, 5)); diff --git a/2_function_arguments/node_4.x/binding.gyp b/2_function_arguments/node_4.x/binding.gyp new file mode 100644 index 00000000..3c79ca84 --- /dev/null +++ b/2_function_arguments/node_4.x/binding.gyp @@ -0,0 +1,8 @@ +{ + "targets": [ + { + "target_name": "addon", + "sources": [ "addon.cc" ] + } + ] +} diff --git a/2_function_arguments/node_4.x/package.json b/2_function_arguments/node_4.x/package.json new file mode 100644 index 00000000..4ca65df5 --- /dev/null +++ b/2_function_arguments/node_4.x/package.json @@ -0,0 +1,15 @@ +{ + "name": "function_arguments", + "version": "0.0.0", + "description": "Node.js Addons Example #2", + "main": "addon.js", + "private": true, + "dependencies": { + "bindings": "~1.2.1", + "nan": "~1.3.0" + }, + "scripts": { + "test": "node addon.js" + }, + "gypfile": true +} diff --git a/3_callbacks/node_4.x/addon.cc b/3_callbacks/node_4.x/addon.cc new file mode 100644 index 00000000..c78299f2 --- /dev/null +++ b/3_callbacks/node_4.x/addon.cc @@ -0,0 +1,32 @@ +// addon.cc +#include + +namespace demo { + +using v8::Function; +using v8::FunctionCallbackInfo; +using v8::Isolate; +using v8::Local; +using v8::Null; +using v8::Object; +using v8::String; +using v8::Value; + +void RunCallback(const FunctionCallbackInfo& args) { + Isolate* isolate = args.GetIsolate(); + if (!args[0]->IsFunction()) { + return; + } + Local cb = Local::Cast(args[0]); + const unsigned argc = 1; + Local argv[argc] = { String::NewFromUtf8(isolate, "hello, world") }; + cb->Call(Null(isolate), argc, argv); +} + +void Init(Local exports, Local module) { + NODE_SET_METHOD(module, "exports", RunCallback); +} + +NODE_MODULE(addon, Init) + +} // namespace demo diff --git a/3_callbacks/node_4.x/addon.js b/3_callbacks/node_4.x/addon.js new file mode 100644 index 00000000..d12d2ff0 --- /dev/null +++ b/3_callbacks/node_4.x/addon.js @@ -0,0 +1,6 @@ +const addon = require('bindings')('addon'); + +addon((msg) => { + console.log(msg); // 'hello world' +}); +addon(); // nothing diff --git a/3_callbacks/node_4.x/binding.gyp b/3_callbacks/node_4.x/binding.gyp new file mode 100644 index 00000000..3c79ca84 --- /dev/null +++ b/3_callbacks/node_4.x/binding.gyp @@ -0,0 +1,8 @@ +{ + "targets": [ + { + "target_name": "addon", + "sources": [ "addon.cc" ] + } + ] +} diff --git a/3_callbacks/node_4.x/package.json b/3_callbacks/node_4.x/package.json new file mode 100644 index 00000000..4de7ece7 --- /dev/null +++ b/3_callbacks/node_4.x/package.json @@ -0,0 +1,11 @@ +{ + "name": "callbacks", + "version": "0.0.0", + "description": "Node.js Addons Example #3", + "main": "addon.js", + "private": true, + "gypfile": true, + "dependencies": { + "bindings": "~1.2.1" + } +} diff --git a/4_object_factory/node_4.x/addon.cc b/4_object_factory/node_4.x/addon.cc new file mode 100644 index 00000000..cbf959da --- /dev/null +++ b/4_object_factory/node_4.x/addon.cc @@ -0,0 +1,37 @@ +// addon.cc +#include + +namespace demo { + +using v8::Exception; +using v8::FunctionCallbackInfo; +using v8::Isolate; +using v8::Local; +using v8::Null; +using v8::Object; +using v8::String; +using v8::Value; + +void CreateObject(const FunctionCallbackInfo& args) { + Isolate* isolate = args.GetIsolate(); + + if (!args[0]->IsString()) { + isolate->ThrowException(Exception::TypeError( + String::NewFromUtf8(isolate, "Argument must be a string")) + ); + return; + } + + Local obj = Object::New(isolate); + obj->Set(String::NewFromUtf8(isolate, "msg"), args[0]->ToString()); + + args.GetReturnValue().Set(obj); +} + +void Init(Local exports, Local module) { + NODE_SET_METHOD(module, "exports", CreateObject); +} + +NODE_MODULE(addon, Init) + +} // namespace demo diff --git a/4_object_factory/node_4.x/addon.js b/4_object_factory/node_4.x/addon.js new file mode 100644 index 00000000..d9e7cc38 --- /dev/null +++ b/4_object_factory/node_4.x/addon.js @@ -0,0 +1,5 @@ +const addon = require('bindings')('addon'); + +const obj1 = addon('hello'); +const obj2 = addon('world'); +console.log(obj1.msg + ', ' + obj2.msg); // 'hello, world' diff --git a/4_object_factory/node_4.x/binding.gyp b/4_object_factory/node_4.x/binding.gyp new file mode 100644 index 00000000..3c79ca84 --- /dev/null +++ b/4_object_factory/node_4.x/binding.gyp @@ -0,0 +1,8 @@ +{ + "targets": [ + { + "target_name": "addon", + "sources": [ "addon.cc" ] + } + ] +} diff --git a/4_object_factory/node_4.x/package.json b/4_object_factory/node_4.x/package.json new file mode 100644 index 00000000..ce8cfceb --- /dev/null +++ b/4_object_factory/node_4.x/package.json @@ -0,0 +1,11 @@ +{ + "name": "object_factory", + "version": "0.0.0", + "description": "Node.js Addons Example #4", + "main": "addon.js", + "private": true, + "gypfile": true, + "dependencies": { + "bindings": "~1.2.1" + } +} diff --git a/5_function_factory/node_4.x/addon.cc b/5_function_factory/node_4.x/addon.cc new file mode 100644 index 00000000..e315f284 --- /dev/null +++ b/5_function_factory/node_4.x/addon.cc @@ -0,0 +1,37 @@ +#include + +namespace demo { + +using v8::Function; +using v8::FunctionCallbackInfo; +using v8::FunctionTemplate; +using v8::Isolate; +using v8::Local; +using v8::Object; +using v8::String; +using v8::Value; + +void MyFunction(const FunctionCallbackInfo& args) { + Isolate* isolate = args.GetIsolate(); + args.GetReturnValue().Set(String::NewFromUtf8(isolate, "hello, world")); +} + +void CreateFunction(const FunctionCallbackInfo& args) { + Isolate* isolate = args.GetIsolate(); + + Local tpl = FunctionTemplate::New(isolate, MyFunction); + Local fn = tpl->GetFunction(); + + // omit this to make it anonymous + fn->SetName(String::NewFromUtf8(isolate, "theFunction")); + + args.GetReturnValue().Set(fn); +} + +void Init(Local exports, Local module) { + NODE_SET_METHOD(module, "exports", CreateFunction); +} + +NODE_MODULE(addon, Init) + +} // namespace demo diff --git a/5_function_factory/node_4.x/addon.js b/5_function_factory/node_4.x/addon.js new file mode 100644 index 00000000..9bbdc811 --- /dev/null +++ b/5_function_factory/node_4.x/addon.js @@ -0,0 +1,4 @@ +const addon = require('bindings')('addon'); + +const fn = addon(); +console.log(fn()); // 'hello, world' diff --git a/5_function_factory/node_4.x/binding.gyp b/5_function_factory/node_4.x/binding.gyp new file mode 100644 index 00000000..3c79ca84 --- /dev/null +++ b/5_function_factory/node_4.x/binding.gyp @@ -0,0 +1,8 @@ +{ + "targets": [ + { + "target_name": "addon", + "sources": [ "addon.cc" ] + } + ] +} diff --git a/5_function_factory/node_4.x/package.json b/5_function_factory/node_4.x/package.json new file mode 100644 index 00000000..22f06fb0 --- /dev/null +++ b/5_function_factory/node_4.x/package.json @@ -0,0 +1,11 @@ +{ + "name": "function_factory", + "version": "0.0.0", + "description": "Node.js Addons Example #5", + "main": "addon.js", + "private": true, + "gypfile": true, + "dependencies": { + "bindings": "~1.2.1" + } +} diff --git a/6_object_wrap/node_4.x/addon.cc b/6_object_wrap/node_4.x/addon.cc new file mode 100644 index 00000000..79dbe924 --- /dev/null +++ b/6_object_wrap/node_4.x/addon.cc @@ -0,0 +1,15 @@ +// addon.cc +#include +#include "myobject.h" + +namespace demo { + +using v8::Local; + +void InitAll(Local exports) { + MyObject::Init(exports); +} + +NODE_MODULE(addon, InitAll) + +} // namespace demo diff --git a/6_object_wrap/node_4.x/addon.js b/6_object_wrap/node_4.x/addon.js new file mode 100644 index 00000000..c685dd58 --- /dev/null +++ b/6_object_wrap/node_4.x/addon.js @@ -0,0 +1,6 @@ +const addon = require('bindings')('addon'); + +const obj = new addon.MyObject(10); +console.log( obj.plusOne() ); // 11 +console.log( obj.plusOne() ); // 12 +console.log( obj.plusOne() ); // 13 diff --git a/6_object_wrap/node_4.x/binding.gyp b/6_object_wrap/node_4.x/binding.gyp new file mode 100644 index 00000000..b05e7abc --- /dev/null +++ b/6_object_wrap/node_4.x/binding.gyp @@ -0,0 +1,8 @@ +{ + "targets": [ + { + "target_name": "addon", + "sources": [ "addon.cc", "myobject.cc" ] + } + ] +} diff --git a/6_object_wrap/node_4.x/myobject.cc b/6_object_wrap/node_4.x/myobject.cc new file mode 100644 index 00000000..5da01109 --- /dev/null +++ b/6_object_wrap/node_4.x/myobject.cc @@ -0,0 +1,67 @@ +#include "myobject.h" + +namespace demo { + +using v8::Function; +using v8::FunctionCallbackInfo; +using v8::FunctionTemplate; +using v8::Isolate; +using v8::Local; +using v8::Number; +using v8::Object; +using v8::Persistent; +using v8::String; +using v8::Value; + +Persistent MyObject::constructor; + +MyObject::MyObject(double value) : value_(value) { +} + +MyObject::~MyObject() { +} + +void MyObject::Init(Local exports) { + Isolate* isolate = exports->GetIsolate(); + + // Prepare constructor template + Local tpl = FunctionTemplate::New(isolate, New); + tpl->SetClassName(String::NewFromUtf8(isolate, "MyObject")); + tpl->InstanceTemplate()->SetInternalFieldCount(1); + + // Prototype + NODE_SET_PROTOTYPE_METHOD(tpl, "plusOne", PlusOne); + + constructor.Reset(isolate, tpl->GetFunction()); + exports->Set(String::NewFromUtf8(isolate, "MyObject"), + tpl->GetFunction()); +} + +void MyObject::New(const FunctionCallbackInfo& args) { + Isolate* isolate = args.GetIsolate(); + + if (args.IsConstructCall()) { + // Invoked as constructor: `new MyObject(...)` + double value = args[0]->IsUndefined() ? 0 : args[0]->NumberValue(); + MyObject* obj = new MyObject(value); + obj->Wrap(args.This()); + return; + } else { + // Invoked as plain function `MyObject(...)`, turn into construct call. + const int argc = 1; + Local argv[argc] = { args[0] }; + Local cons = Local::New(isolate, constructor); + args.GetReturnValue().Set(cons->NewInstance(argc, argv)); + } +} + +void MyObject::PlusOne(const FunctionCallbackInfo& args) { + Isolate* isolate = args.GetIsolate(); + + MyObject* obj = ObjectWrap::Unwrap(args.Holder()); + obj->value_ += 1; + + args.GetReturnValue().Set(Number::New(isolate, obj->value_)); +} + +} // namespace demo diff --git a/6_object_wrap/node_4.x/myobject.h b/6_object_wrap/node_4.x/myobject.h new file mode 100644 index 00000000..26e9c3f6 --- /dev/null +++ b/6_object_wrap/node_4.x/myobject.h @@ -0,0 +1,32 @@ +#ifndef MYOBJECT_H +#define MYOBJECT_H + +#include +#include + +namespace demo { + +using v8::Function; +using v8::FunctionCallbackInfo; +using v8::Local; +using v8::Object; +using v8::Persistent; +using v8::Value; + +class MyObject : public node::ObjectWrap { + public: + static void Init(Local exports); + + private: + explicit MyObject(double value = 0); + ~MyObject(); + + static void New(const FunctionCallbackInfo& args); + static void PlusOne(const FunctionCallbackInfo& args); + static Persistent constructor; + double value_; +}; + +} // namespace demo + +#endif diff --git a/6_object_wrap/node_4.x/package.json b/6_object_wrap/node_4.x/package.json new file mode 100644 index 00000000..162c5861 --- /dev/null +++ b/6_object_wrap/node_4.x/package.json @@ -0,0 +1,11 @@ +{ + "name": "object_wrap", + "version": "0.0.0", + "description": "Node.js Addons Example #6", + "main": "addon.js", + "private": true, + "gypfile": true, + "dependencies": { + "bindings": "~1.2.1" + } +} diff --git a/7_factory_wrap/node_4.x/addon.cc b/7_factory_wrap/node_4.x/addon.cc new file mode 100644 index 00000000..719db7db --- /dev/null +++ b/7_factory_wrap/node_4.x/addon.cc @@ -0,0 +1,25 @@ +#include +#include "myobject.h" + +namespace demo { + +using v8::FunctionCallbackInfo; +using v8::Isolate; +using v8::Local; +using v8::Object; +using v8::String; +using v8::Value; + +void CreateObject(const FunctionCallbackInfo& args) { + MyObject::NewInstance(args); +} + +void InitAll(Local exports, Local module) { + MyObject::Init(exports->GetIsolate()); + + NODE_SET_METHOD(module, "exports", CreateObject); +} + +NODE_MODULE(addon, InitAll) + +} // namespace demo diff --git a/7_factory_wrap/node_4.x/addon.js b/7_factory_wrap/node_4.x/addon.js new file mode 100644 index 00000000..0547abe0 --- /dev/null +++ b/7_factory_wrap/node_4.x/addon.js @@ -0,0 +1,11 @@ +const createObject = require('bindings')('addon'); + +const obj = createObject(10); +console.log( obj.plusOne() ); // 11 +console.log( obj.plusOne() ); // 12 +console.log( obj.plusOne() ); // 13 + +const obj2 = createObject(20); +console.log( obj2.plusOne() ); // 21 +console.log( obj2.plusOne() ); // 22 +console.log( obj2.plusOne() ); // 23 diff --git a/7_factory_wrap/node_4.x/binding.gyp b/7_factory_wrap/node_4.x/binding.gyp new file mode 100644 index 00000000..b05e7abc --- /dev/null +++ b/7_factory_wrap/node_4.x/binding.gyp @@ -0,0 +1,8 @@ +{ + "targets": [ + { + "target_name": "addon", + "sources": [ "addon.cc", "myobject.cc" ] + } + ] +} diff --git a/7_factory_wrap/node_4.x/myobject.cc b/7_factory_wrap/node_4.x/myobject.cc new file mode 100644 index 00000000..f3f4e712 --- /dev/null +++ b/7_factory_wrap/node_4.x/myobject.cc @@ -0,0 +1,75 @@ +#include +#include "myobject.h" + +namespace demo { + +using v8::Function; +using v8::FunctionCallbackInfo; +using v8::FunctionTemplate; +using v8::Isolate; +using v8::Local; +using v8::Number; +using v8::Object; +using v8::Persistent; +using v8::String; +using v8::Value; + +Persistent MyObject::constructor; + +MyObject::MyObject(double value) : value_(value) { +} + +MyObject::~MyObject() { +} + +void MyObject::Init(Isolate* isolate) { + // Prepare constructor template + Local tpl = FunctionTemplate::New(isolate, New); + tpl->SetClassName(String::NewFromUtf8(isolate, "MyObject")); + tpl->InstanceTemplate()->SetInternalFieldCount(1); + + // Prototype + NODE_SET_PROTOTYPE_METHOD(tpl, "plusOne", PlusOne); + + constructor.Reset(isolate, tpl->GetFunction()); +} + +void MyObject::New(const FunctionCallbackInfo& args) { + Isolate* isolate = args.GetIsolate(); + + if (args.IsConstructCall()) { + // Invoked as constructor: `new MyObject(...)` + double value = args[0]->IsUndefined() ? 0 : args[0]->NumberValue(); + MyObject* obj = new MyObject(value); + obj->Wrap(args.This()); + return; + } else { + // Invoked as plain function `MyObject(...)`, turn into construct call. + const int argc = 1; + Local argv[argc] = { args[0] }; + Local cons = Local::New(isolate, constructor); + args.GetReturnValue().Set(cons->NewInstance(argc, argv)); + } +} + +void MyObject::NewInstance(const FunctionCallbackInfo& args) { + Isolate* isolate = args.GetIsolate(); + + const unsigned argc = 1; + Local argv[argc] = { args[0] }; + Local cons = Local::New(isolate, constructor); + Local instance = cons->NewInstance(argc, argv); + + args.GetReturnValue().Set(instance); +} + +void MyObject::PlusOne(const FunctionCallbackInfo& args) { + Isolate* isolate = args.GetIsolate(); + + MyObject* obj = ObjectWrap::Unwrap(args.Holder()); + obj->value_ += 1; + + args.GetReturnValue().Set(Number::New(isolate, obj->value_)); +} + +} // namespace demo diff --git a/7_factory_wrap/node_4.x/myobject.h b/7_factory_wrap/node_4.x/myobject.h new file mode 100644 index 00000000..b592a0c3 --- /dev/null +++ b/7_factory_wrap/node_4.x/myobject.h @@ -0,0 +1,32 @@ +#ifndef MYOBJECT_H +#define MYOBJECT_H + +#include +#include + +namespace demo { + +using v8::Function; +using v8::FunctionCallbackInfo; +using v8::Isolate; +using v8::Persistent; +using v8::Value; + +class MyObject : public node::ObjectWrap { + public: + static void Init(Isolate* isolate); + static void NewInstance(const FunctionCallbackInfo& args); + + private: + explicit MyObject(double value = 0); + ~MyObject(); + + static void New(const FunctionCallbackInfo& args); + static void PlusOne(const FunctionCallbackInfo& args); + static Persistent constructor; + double value_; +}; + +} // namespace demo + +#endif diff --git a/7_factory_wrap/node_4.x/package.json b/7_factory_wrap/node_4.x/package.json new file mode 100644 index 00000000..70fac90e --- /dev/null +++ b/7_factory_wrap/node_4.x/package.json @@ -0,0 +1,11 @@ +{ + "name": "factory_wrap", + "version": "0.0.0", + "description": "Node.js Addons Example #7", + "main": "addon.js", + "private": true, + "gypfile": true, + "dependencies": { + "bindings": "~1.2.1" + } +} diff --git a/8_passing_wrapped/node_4.x/addon.cc b/8_passing_wrapped/node_4.x/addon.cc new file mode 100644 index 00000000..4037e66f --- /dev/null +++ b/8_passing_wrapped/node_4.x/addon.cc @@ -0,0 +1,40 @@ +#include +#include +#include "myobject.h" + +namespace demo { + +using v8::FunctionCallbackInfo; +using v8::Isolate; +using v8::Local; +using v8::Number; +using v8::Object; +using v8::String; +using v8::Value; + +void CreateObject(const FunctionCallbackInfo& args) { + MyObject::NewInstance(args); +} + +void Add(const FunctionCallbackInfo& args) { + Isolate* isolate = args.GetIsolate(); + + MyObject* obj1 = node::ObjectWrap::Unwrap( + args[0]->ToObject()); + MyObject* obj2 = node::ObjectWrap::Unwrap( + args[1]->ToObject()); + + double sum = obj1->value() + obj2->value(); + args.GetReturnValue().Set(Number::New(isolate, sum)); +} + +void InitAll(Local exports) { + MyObject::Init(exports->GetIsolate()); + + NODE_SET_METHOD(exports, "createObject", CreateObject); + NODE_SET_METHOD(exports, "add", Add); +} + +NODE_MODULE(addon, InitAll) + +} // namespace demo diff --git a/8_passing_wrapped/node_4.x/addon.js b/8_passing_wrapped/node_4.x/addon.js new file mode 100644 index 00000000..42f65e67 --- /dev/null +++ b/8_passing_wrapped/node_4.x/addon.js @@ -0,0 +1,7 @@ +const addon = require('bindings')('addon'); + +const obj1 = addon.createObject(10); +const obj2 = addon.createObject(20); +const result = addon.add(obj1, obj2); + +console.log(result); // 30 diff --git a/8_passing_wrapped/node_4.x/binding.gyp b/8_passing_wrapped/node_4.x/binding.gyp new file mode 100644 index 00000000..b05e7abc --- /dev/null +++ b/8_passing_wrapped/node_4.x/binding.gyp @@ -0,0 +1,8 @@ +{ + "targets": [ + { + "target_name": "addon", + "sources": [ "addon.cc", "myobject.cc" ] + } + ] +} diff --git a/8_passing_wrapped/node_4.x/myobject.cc b/8_passing_wrapped/node_4.x/myobject.cc new file mode 100644 index 00000000..0231f0a1 --- /dev/null +++ b/8_passing_wrapped/node_4.x/myobject.cc @@ -0,0 +1,62 @@ +#include +#include "myobject.h" + +namespace demo { + +using v8::Function; +using v8::FunctionCallbackInfo; +using v8::FunctionTemplate; +using v8::Isolate; +using v8::Local; +using v8::Object; +using v8::Persistent; +using v8::String; +using v8::Value; + +Persistent MyObject::constructor; + +MyObject::MyObject(double value) : value_(value) { +} + +MyObject::~MyObject() { +} + +void MyObject::Init(Isolate* isolate) { + // Prepare constructor template + Local tpl = FunctionTemplate::New(isolate, New); + tpl->SetClassName(String::NewFromUtf8(isolate, "MyObject")); + tpl->InstanceTemplate()->SetInternalFieldCount(1); + + constructor.Reset(isolate, tpl->GetFunction()); +} + +void MyObject::New(const FunctionCallbackInfo& args) { + Isolate* isolate = args.GetIsolate(); + + if (args.IsConstructCall()) { + // Invoked as constructor: `new MyObject(...)` + double value = args[0]->IsUndefined() ? 0 : args[0]->NumberValue(); + MyObject* obj = new MyObject(value); + obj->Wrap(args.This()); + return; + } else { + // Invoked as plain function `MyObject(...)`, turn into construct call. + const int argc = 1; + Local argv[argc] = { args[0] }; + Local cons = Local::New(isolate, constructor); + args.GetReturnValue().Set(cons->NewInstance(argc, argv)); + } +} + +void MyObject::NewInstance(const FunctionCallbackInfo& args) { + Isolate* isolate = args.GetIsolate(); + + const unsigned argc = 1; + Local argv[argc] = { args[0] }; + Local cons = Local::New(isolate, constructor); + Local instance = cons->NewInstance(argc, argv); + + args.GetReturnValue().Set(instance); +} + +} // namespace demo diff --git a/8_passing_wrapped/node_4.x/myobject.h b/8_passing_wrapped/node_4.x/myobject.h new file mode 100644 index 00000000..bb6e317a --- /dev/null +++ b/8_passing_wrapped/node_4.x/myobject.h @@ -0,0 +1,32 @@ +#ifndef MYOBJECT_H +#define MYOBJECT_H + +#include +#include + +namespace demo { + +using v8::Function; +using v8::FunctionCallbackInfo; +using v8::Isolate; +using v8::Persistent; +using v8::Value; + +class MyObject : public node::ObjectWrap { + public: + static void Init(v8::Isolate* Isolate); + static void NewInstance(const v8::FunctionCallbackInfo& args); + inline double value() const { return value_; } + + private: + explicit MyObject(double value = 0); + ~MyObject(); + + static void New(const v8::FunctionCallbackInfo& args); + static v8::Persistent constructor; + double value_; +}; + +} // namespace demo + +#endif diff --git a/8_passing_wrapped/node_4.x/package.json b/8_passing_wrapped/node_4.x/package.json new file mode 100644 index 00000000..5c446be0 --- /dev/null +++ b/8_passing_wrapped/node_4.x/package.json @@ -0,0 +1,11 @@ +{ + "name": "passing_wrapped", + "version": "0.0.0", + "description": "Node.js Addons Example #8", + "main": "addon.js", + "private": true, + "gypfile": true, + "dependencies": { + "bindings": "~1.2.1" + } +}