diff --git a/README.md b/README.md index e70125c..7e06615 100644 --- a/README.md +++ b/README.md @@ -1,15 +1,18 @@ # Addon Tools +This is a part of [Node3D](https://github.com/node-3d) project. + ## Synopsis -This is a set of helpers for simplification and standardization of addons and -dependency packages. +Helpers for Node.js addons and dependency packages: -* EventEmitter C++ implementation. -* Contains helpers of following types: GYP, C++, JS, BAT (Windows). -* Platforms: win x32/x64, linux x32/x64, mac x64. -* Useful links: [V8 Ref](https://v8docs.nodesource.com/node-0.8/d2/dc3/namespacev8.html), +* `EventEmitter` C++ implementation. +* C++ macros and shortcuts. +* Crossplatform commands for GYP: `cp`, `rm`, `mkdir`. +* Regarded platforms: win x32/x64, linux x32/x64, mac x64. + +Useful links: [V8 Ref](https://v8docs.nodesource.com/node-0.8/d2/dc3/namespacev8.html), [Nan Docs](https://github.com/nodejs/nan#api), [GYP Docs](https://gyp.gsrc.io/docs/UserDocumentation.md). @@ -29,7 +32,7 @@ dependency packages. [index.js](#indexjs) -[Cross-platform commands](#cross-platform-commands) +[Crossplatform commands](#crossplatform-commands) [Class EventEmitter](#class-eventemitter) @@ -38,9 +41,10 @@ dependency packages. ## Snippets + ### binding.gyp -* Cross-platform file/folder removers/creators are present, you can put them into variables for later use. +* Crossplatform commands can be put into the variables for later use. ``` 'variables': { @@ -59,7 +63,11 @@ are accessible as shown below. ], ``` -* Intermediate files can be removed in a separate build-step with `<(rm)`. +* Intermediate build-files can be removed in a separate build-step with `<(rm)`. + +
+ +Show Snippet ``` [ 'OS=="linux"', { 'action' : [ @@ -79,6 +87,8 @@ are accessible as shown below. ] } ], ``` +
+ ### Binary dependencies @@ -101,30 +111,42 @@ module.exports = require('addon-tools-raub').paths(__dirname); * Your whole `binding.gyp`: +
+ +Show Snippet + ``` { 'variables': { - 'rm' : ' ### Compiled addon @@ -132,6 +154,10 @@ module.exports = require('addon-tools-raub').paths(__dirname); If you always copy your compiled addon to the `binary` directory, it will be easy to `require()` it without any hesitation. For copying, you can use the following snippet: +
+ +Show Snippet + ``` { 'target_name' : 'make_directory', @@ -157,6 +183,8 @@ If you always copy your compiled addon to the `binary` directory, it will be eas }, ``` +
+ Here `MY_ADDON` should be replaced by any name you like. Then require like this: @@ -315,7 +343,7 @@ so that you can replace: with ``` -#include +#include // or event-emitter.hpp ``` In gyp, the include directory should be set for your addon to know where to get it. @@ -327,10 +355,12 @@ require('addon-tools-raub').include() // implicit console.log() require('addon-tools-raub').includePath // just a string ``` -In the file, currently there are following helpers: +Currently, there are following helpers in **addon-tools.hpp**: -#### Handle scope +
+ +Handle scope * `NAN_HS` - creates a HandleScope. Also, you do not need them within `NAN_METHOD`, `NAN_SETTER`, and `NAN_GETTER`, as it is stated in @@ -345,14 +375,22 @@ void windowFocusCB(GLFWwindow *window, int focused) { NAN_HS; glfwSetWindowFocusCallback(window, windowFocusCB); ``` +
-#### Method return + +
+ +Method return * `RET_VALUE(VAL)` - set method return value * `RET_UNDEFINED` - set method return value as undefined +
-#### Shortcut types + +
+ +Shortcut types * `V8_VAR_VAL` = `v8::Local` * `V8_VAR_OBJ` = `v8::Local` @@ -366,8 +404,12 @@ glfwSetWindowFocusCallback(window, windowFocusCB); * `V8_STORE_OBJ` = `Nan::Persistent` * `V8_STORE_VAL` = `Nan::Persistent` +
-#### New JS value + +
+ +New JS value * `JS_STR(...)` - create a string value * `JS_UTF8(...)` - same as JS_STR @@ -383,8 +425,12 @@ glfwSetWindowFocusCallback(window, windowFocusCB); * `JS_FUN(val)` - get a function from persistent. * `JS_OBJ(val)` - get an object from persistent. +
-#### Method check + +
+ +Method check These checks throw JS TypeError if not passed. Here `T` is always used as a typename in error messages. `C` is @@ -395,13 +441,17 @@ starting from `0`. * `REQ_ARGS(N)` - check if at least `N` arguments passed * `IS_ARG_EMPTY(I)` - check if argument `I` is `undefined` or `null` * `CHECK_REQ_ARG(I, C, T)` - check if argument `I` is approved by `C` check. -* `CHECK_LET_ARG(I, C, T) - check if argument `I` is approved by `C` check or empty. +* `CHECK_LET_ARG(I, C, T)` - check if argument `I` is approved by `C` check or empty. * `CTOR_CHECK(T)` - check if method is called as a constructor * `SETTER_CHECK(C, T)` - check if setter `value` is approved by `C` check. * `DES_CHECK` - within dynamic method check if the instance wasn't destroyed by `_destroy()`. +
-#### Method arguments + +
+ +Method arguments Two types of argument retrieval are supported: `REQ_` and `LET_`. The difference is that `LET_` allows the argument to be empty, using some zero-default in this case. @@ -444,8 +494,12 @@ NAN_METHOD(test) { NOTE: The conversion from `Nan::Utf8String` to `std::string` (via `char *`) is possible with unary `*` operator. +
-#### Set properties + +
+ +Set properties Set-helpers for string and numeric keys. String keys are converted to JS strings automatically. @@ -453,8 +507,12 @@ automatically. * `SET_PROP(OBJ, KEY, VAL)` * `SET_I(ARR, I, VAL)` +
-#### Set object accessors + +
+ +Set object accessors Simplified accessor assignment, adds accessors of NAME for OBJ. Read accessor is assumed to have the name `NAME+'Getter'` and write accessor is `NAME+'Setter'`. @@ -473,8 +531,12 @@ NAN_GETTER(MyClass::messageGetter) { ... NAN_SETTER(MyClass::messageSetter) { ... ``` +
-#### Setter argument + +
+ +Setter argument Useful addition to NAN_SETTER macro. Works similar to method arguments. But there is always only one required argument stored in `v`. @@ -499,8 +561,12 @@ NAN_SETTER(MyClass::messageSetter) { SETTER_UTF8_ARG; ... ``` +
-#### Data retrieval + +
+ +Data retrieval * `T *getArrayData(value, num = NULL)` - extracts TypedArray data of any type from the given JS value. Does not accept Array, checked with `IsArrayBufferView()`. @@ -512,6 +578,8 @@ Returns `NULL` for empty JS values. For unacceptable values throws TypeError. content is then returned as `node::Buffer`. Returns `NULL` for empty JS values. For unacceptable values throws TypeError. +
+ --- @@ -541,7 +609,7 @@ input `dir`. --- -## Cross-platform commands +## Crossplatform commands Because of the differences between Windows and Unix command shells, often a whole lot of conditions have to be introduced in **binding.gyp** file. Now some of @@ -573,7 +641,7 @@ folder. This can possibly be bypassed by supplying `./-p` or something like this ### rm -Disregard `del` vs `rd` aspect of Windows command line. Now the same command can +Disregard `del` and `rd` on Windows command line. Now the same command can be used on all platforms to remove single and multiple files and directories. ``` @@ -627,7 +695,7 @@ subscribes `that[method]` to receive `name` events from this emitter, basically `emitter.on(name, that[method])`. * `virtual void _destroy()` - destroys the object, i.e. deactivates it and frees -resources, also emitting a `'destroy'` event. This is what also called inside +resources. This is what also called inside `~EventEmitter()`, but only the first call is effective anyway. @@ -639,7 +707,6 @@ Be sure to add the include directory in **binding.gyp**: ], ``` -Though it is the same directory for all the **addon-tools**. Then include the **event-emitter.hpp**, it also includes **addon-tools.hpp**. Inherit from `EventEmitter`, it already inherits from `Nan::ObjectWrap`: @@ -653,6 +720,9 @@ class Example : public EventEmitter { NOTE: Do not forget to call `EventEmitter::init()` once, in the module `init()`. +
+ +V8 Inheritance Now that everything is in place, consider providing **V8** with JS inheritance info: @@ -678,3 +748,5 @@ void Example::init(Handle target) { } ``` + + diff --git a/examples/deps/binding.gyp b/examples/deps/binding.gyp index 9847bcd..2170073 100644 --- a/examples/deps/binding.gyp +++ b/examples/deps/binding.gyp @@ -1,20 +1,21 @@ { 'variables': { - 'rm' : ' code = JS_STR( + V8_VAR_STR code = JS_STR( "((emitter, name, that, method) => emitter.on(name, that[method]))" ); @@ -247,7 +247,7 @@ private: static NAN_METHOD(jsEventNames) { THIS_EVENT_EMITTER; EVENT_EMITTER_THIS_CHECK; - v8::Local jsNames = Nan::New(eventEmitter->_raw.size()); + V8_VAR_ARR jsNames = Nan::New(eventEmitter->_raw.size()); if (eventEmitter->_raw.empty()) { RET_VALUE(jsNames); @@ -290,7 +290,7 @@ private: VEC_TYPE &list = eventEmitter->_listeners[*name]; - v8::Local jsListeners = Nan::New(list.size()); + V8_VAR_ARR jsListeners = Nan::New(list.size()); if (list.empty()) { RET_VALUE(jsListeners); @@ -336,10 +336,10 @@ private: std::cout << name << "' event, possible memory leak." << std::endl; // Some JS magic to retrieve the call stack - v8::Local code = JS_STR( + V8_VAR_STR code = JS_STR( "(new Error()).stack.split('\\n').slice(1).join('\\n')" ); - v8::Local stack = v8::Local::Cast( + V8_VAR_STR stack = V8_VAR_STR::Cast( v8::Script::Compile(code)->Run() ); Nan::Utf8String stackStr(stack); @@ -398,10 +398,10 @@ private: std::cout << name << "' event, possible memory leak." << std::endl; // Some JS magic to retrieve the call stack - v8::Local code = JS_STR( + V8_VAR_STR code = JS_STR( "(new Error()).stack.split('\\n').slice(1).join('\\n')" ); - v8::Local stack = v8::Local::Cast( + V8_VAR_STR stack = V8_VAR_STR::Cast( v8::Script::Compile(code)->Run() ); Nan::Utf8String stackStr(stack); @@ -420,7 +420,7 @@ private: REQ_UTF8_ARG(0, name); REQ_FUN_ARG(1, raw); - v8::Local code = JS_STR( + V8_VAR_STR code = JS_STR( "((emitter, name, cb) => (...args) => {\n\ cb(...args);\n\ emitter.removeListener(name, cb);\n\ @@ -633,7 +633,7 @@ private: VEC_TYPE &list = eventEmitter->_raw[*name]; - v8::Local jsListeners = Nan::New(list.size()); + V8_VAR_ARR jsListeners = Nan::New(list.size()); if (list.empty()) { RET_VALUE(jsListeners); diff --git a/index.js b/index.js index 8e949ed..854365c 100644 --- a/index.js +++ b/index.js @@ -63,6 +63,7 @@ const mkdirPath = isWindows ? `${rootPath}/_mkdir.bat` : 'mkdir'; const rmPath = isWindows ? `${rootPath}/_rm.bat` : 'rm'; const cpPath = isWindows ? `${rootPath}/_cp.bat` : 'cp'; + module.exports = { paths, diff --git a/package.json b/package.json index 9d7e55b..923e0d5 100644 --- a/package.json +++ b/package.json @@ -1,8 +1,8 @@ { "author": "Luis Blanco ", "name": "addon-tools-raub", - "version": "0.1.8", - "description": "A set of extra tools for Node.js addons", + "version": "0.1.9", + "description": "Helpers for Node.js addons and dependency packages", "license": "MIT", "main": "index.js", "keywords": [ @@ -25,7 +25,7 @@ ], "repository": { "type": "git", - "url": "https://github.com/node-3d/node-addon-tools.git" + "url": "https://github.com/node-3d/addon-tools-raub.git" }, "dependencies": { "nan": "2.10.0"