diff --git a/src/1-getting-started/8_multiple_object_exports/addon.cc b/src/1-getting-started/8_multiple_object_exports/addon.cc new file mode 100644 index 00000000..683e58fd --- /dev/null +++ b/src/1-getting-started/8_multiple_object_exports/addon.cc @@ -0,0 +1,11 @@ +#include "myobject-napi.h" +#include "otherobject-napi.h" + +Napi::Object init(Napi::Env env, Napi::Object exports) { + MyObjectNapi::init(env, exports); + OtherObjectNapi::init(env, exports); + + return exports; +} + +NODE_API_MODULE(NODE_GYP_MODULE_NAME, init) diff --git a/src/1-getting-started/8_multiple_object_exports/addon.js b/src/1-getting-started/8_multiple_object_exports/addon.js new file mode 100644 index 00000000..35d595cf --- /dev/null +++ b/src/1-getting-started/8_multiple_object_exports/addon.js @@ -0,0 +1,15 @@ +const addon = require('bindings')('addon') + +const obj = new addon.MyObject(5) + +obj.multiply(3) +obj.plusOne() + +console.log(obj.value()) + +const other = new addon.OtherObject("Hello, ") + +other.multiply(3) +other.append("NAPI!") + +console.log(other.value()) diff --git a/src/1-getting-started/8_multiple_object_exports/binding.gyp b/src/1-getting-started/8_multiple_object_exports/binding.gyp new file mode 100644 index 00000000..f5e83c03 --- /dev/null +++ b/src/1-getting-started/8_multiple_object_exports/binding.gyp @@ -0,0 +1,19 @@ +{ + "targets": [ + { + # myModule is the name of your native addon + "target_name": "addon", + "sources": [ + "addon.cc", + "myobject-napi.cc", + "myobject.cc", + "otherobject-napi.cc", + "otherobject.cc" + ], + "dependencies": [ + "(info) { + if ( info.Length() > 0 && info[0].IsNumber() ) + _nativeMyObject = std::make_shared(info[0].As().DoubleValue()); + else + _nativeMyObject = std::make_shared(0); +}; + +void MyObjectNapi::init(Napi::Env env, Napi::Object exports) { + Napi::Function func = DefineClass(env, "MyObjectNapi", { + InstanceMethod("multiply", &MyObjectNapi::multiply), + InstanceMethod("plusOne", &MyObjectNapi::plusOne), + InstanceMethod("value", &MyObjectNapi::value) + }); + + exports.Set("MyObject", func); +} + +Napi::Value MyObjectNapi::multiply(const Napi::CallbackInfo& info) { + if ( info.Length() < 1 || !info[0].IsNumber() ) + throw Napi::Error::New(info.Env(), "Invalid argument"); + + return Napi::Number::New(info.Env(), _nativeMyObject->multiply(info[0].As().DoubleValue())); +} + +Napi::Value MyObjectNapi::plusOne(const Napi::CallbackInfo& info) { + return Napi::Number::New(info.Env(), _nativeMyObject->plusOne()); +} + +Napi::Value MyObjectNapi::value(const Napi::CallbackInfo& info) { + if ( info.Length() == 0 ) + return Napi::Number::New(info.Env(), _nativeMyObject->value()); + + _nativeMyObject->value(info[0].As().DoubleValue()); + + return info.Env().Null(); +} diff --git a/src/1-getting-started/8_multiple_object_exports/myobject-napi.h b/src/1-getting-started/8_multiple_object_exports/myobject-napi.h new file mode 100644 index 00000000..f9c830ef --- /dev/null +++ b/src/1-getting-started/8_multiple_object_exports/myobject-napi.h @@ -0,0 +1,21 @@ +#ifndef MYOBJECT_NAPI_H +#define MYOBJECT_NAPI_H + +#include +#include + +#include "myobject.h" + +class MyObjectNapi : public Napi::ObjectWrap { + public: + MyObjectNapi(const Napi::CallbackInfo& info); + static void init(Napi::Env env, Napi::Object exports); + Napi::Value multiply(const Napi::CallbackInfo& info); + Napi::Value plusOne(const Napi::CallbackInfo& info); + Napi::Value value(const Napi::CallbackInfo& info); + + private: + std::shared_ptr _nativeMyObject; +}; + +#endif \ No newline at end of file diff --git a/src/1-getting-started/8_multiple_object_exports/myobject.cc b/src/1-getting-started/8_multiple_object_exports/myobject.cc new file mode 100644 index 00000000..838c66c6 --- /dev/null +++ b/src/1-getting-started/8_multiple_object_exports/myobject.cc @@ -0,0 +1,25 @@ +#include "myobject.h" + +MyObject::MyObject(double value) { + _value = value; +} + +double MyObject::multiply(double value) { + _value *= value; + + return _value; +} + +double MyObject::plusOne() { + _value++; + + return _value; +} + +double MyObject::value() { + return _value; +} + +void MyObject::value(double value) { + _value = value; +} diff --git a/src/1-getting-started/8_multiple_object_exports/myobject.h b/src/1-getting-started/8_multiple_object_exports/myobject.h new file mode 100644 index 00000000..7e102b6f --- /dev/null +++ b/src/1-getting-started/8_multiple_object_exports/myobject.h @@ -0,0 +1,18 @@ +#ifndef MYOBJECT_H +#define MYOBJECT_H + +#include + +class MyObject { + public: + MyObject(double value); + double multiply(double value); + double plusOne(); + double value(); + void value(double value); + + private: + double _value; +}; + +#endif \ No newline at end of file diff --git a/src/1-getting-started/8_multiple_object_exports/otherobject-napi.cc b/src/1-getting-started/8_multiple_object_exports/otherobject-napi.cc new file mode 100644 index 00000000..b4e22d64 --- /dev/null +++ b/src/1-getting-started/8_multiple_object_exports/otherobject-napi.cc @@ -0,0 +1,41 @@ +#include "otherobject-napi.h" + +OtherObjectNapi::OtherObjectNapi(const Napi::CallbackInfo& info) : Napi::ObjectWrap(info) { + if ( info.Length() > 0 && info[0].IsString() ) + _nativeOtherObject = std::make_shared(info[0].As().Utf8Value()); + else + _nativeOtherObject = std::make_shared(""); +}; + +void OtherObjectNapi::init(Napi::Env env, Napi::Object exports) { + Napi::Function func = DefineClass(env, "OtherObjectNapi", { + InstanceMethod("multiply", &OtherObjectNapi::multiply), + InstanceMethod("append", &OtherObjectNapi::append), + InstanceMethod("value", &OtherObjectNapi::value) + }); + + exports.Set("OtherObject", func); +} + +Napi::Value OtherObjectNapi::multiply(const Napi::CallbackInfo& info) { + if ( info.Length() < 1 || !info[0].IsNumber() ) + throw Napi::Error::New(info.Env(), "Invalid argument"); + + return Napi::String::New(info.Env(), _nativeOtherObject->multiply(info[0].As().Int32Value())); +} + +Napi::Value OtherObjectNapi::append(const Napi::CallbackInfo& info) { + if ( info.Length() < 1 || !info[0].IsString() ) + throw Napi::Error::New(info.Env(), "Invalid argument"); + + return Napi::String::New(info.Env(), _nativeOtherObject->append(info[0].As().Utf8Value())); +} + +Napi::Value OtherObjectNapi::value(const Napi::CallbackInfo& info) { + if ( info.Length() == 0 ) + return Napi::String::New(info.Env(), _nativeOtherObject->value()); + + _nativeOtherObject->value(info[0].As().Utf8Value()); + + return info.Env().Null(); +} diff --git a/src/1-getting-started/8_multiple_object_exports/otherobject-napi.h b/src/1-getting-started/8_multiple_object_exports/otherobject-napi.h new file mode 100644 index 00000000..1ebb8ab7 --- /dev/null +++ b/src/1-getting-started/8_multiple_object_exports/otherobject-napi.h @@ -0,0 +1,21 @@ +#ifndef OTHEROBJECT_NAPI_H +#define OTHEROBJECT_NAPI_H + +#include +#include + +#include "otherobject.h" + +class OtherObjectNapi : public Napi::ObjectWrap { + public: + OtherObjectNapi(const Napi::CallbackInfo& info); + static void init(Napi::Env env, Napi::Object exports); + Napi::Value multiply(const Napi::CallbackInfo& info); + Napi::Value append(const Napi::CallbackInfo& info); + Napi::Value value(const Napi::CallbackInfo& info); + + private: + std::shared_ptr _nativeOtherObject; +}; + +#endif \ No newline at end of file diff --git a/src/1-getting-started/8_multiple_object_exports/otherobject.cc b/src/1-getting-started/8_multiple_object_exports/otherobject.cc new file mode 100644 index 00000000..f01fa266 --- /dev/null +++ b/src/1-getting-started/8_multiple_object_exports/otherobject.cc @@ -0,0 +1,28 @@ +#include "otherobject.h" + +OtherObject::OtherObject(std::string value) { + _value = value; +} + +std::string OtherObject::multiply(int value) { + std::string original = _value; + + for ( int i = 0; i < value; i++ ) + _value += original; + + return _value; +} + +std::string OtherObject::append(std::string value) { + _value += value; + + return _value; +} + +std::string OtherObject::value() { + return _value; +} + +void OtherObject::value(std::string value) { + _value = value; +} diff --git a/src/1-getting-started/8_multiple_object_exports/otherobject.h b/src/1-getting-started/8_multiple_object_exports/otherobject.h new file mode 100644 index 00000000..262499b3 --- /dev/null +++ b/src/1-getting-started/8_multiple_object_exports/otherobject.h @@ -0,0 +1,19 @@ +#ifndef OTHEROBJECT_H +#define OTHEROBJECT_H + +#include +#include + +class OtherObject { + public: + OtherObject(std::string value); + std::string multiply(int value); + std::string append(std::string value); + std::string value(); + void value(std::string value); + + private: + std::string _value; +}; + +#endif \ No newline at end of file diff --git a/src/1-getting-started/8_multiple_object_exports/package.json b/src/1-getting-started/8_multiple_object_exports/package.json new file mode 100644 index 00000000..4bbc72d8 --- /dev/null +++ b/src/1-getting-started/8_multiple_object_exports/package.json @@ -0,0 +1,15 @@ +{ + "name": "multiple", + "version": "0.0.0", + "description": "Node.js Addons Example #8", + "main": "addon.js", + "private": true, + "gypfile": true, + "engines": { + "node": "~10 >=10.20 || >=12.17" + }, + "dependencies": { + "bindings": "~1.5.0", + "node-addon-api": "^8.1.0" + } +}