emitter wip
This commit is contained in:
parent
b28b206922
commit
fa989dda66
|
@ -0,0 +1,11 @@
|
|||
.idea
|
||||
.cproject
|
||||
.project
|
||||
.lock-wscript
|
||||
build*
|
||||
.DS_Store
|
||||
Debug
|
||||
node_modules
|
||||
package-lock.json
|
||||
binary
|
||||
*.log
|
|
@ -0,0 +1,14 @@
|
|||
.idea
|
||||
.cproject
|
||||
.project
|
||||
.lock-wscript
|
||||
build*
|
||||
.DS_Store
|
||||
Debug
|
||||
node_modules
|
||||
package-lock.json
|
||||
binary
|
||||
*.log
|
||||
examples
|
||||
.gitignore
|
||||
test
|
|
@ -0,0 +1,88 @@
|
|||
{
|
||||
'variables': {
|
||||
'rm' : '<!(node -e "require(\'addon-tools-raub\').rm()")',
|
||||
'cp' : '<!(node -e "require(\'addon-tools-raub\').cp()")',
|
||||
'mkdir' : '<!(node -e "require(\'addon-tools-raub\').mkdir()")',
|
||||
},
|
||||
'targets': [
|
||||
{
|
||||
'target_name': 'addon',
|
||||
'sources': [
|
||||
'cpp/bindings.cpp',
|
||||
'cpp/example.cpp',
|
||||
],
|
||||
'include_dirs': [
|
||||
'<!@(node -e "require(\'addon-tools-raub\').include()")',
|
||||
],
|
||||
'conditions' : [
|
||||
[
|
||||
'OS=="win"',
|
||||
{
|
||||
'msvs_settings' : {
|
||||
'VCCLCompilerTool' : {
|
||||
'AdditionalOptions' : [
|
||||
'/O2','/Oy','/GL','/GF','/Gm-', '/Fm-',
|
||||
'/EHsc','/MT','/GS','/Gy','/GR-','/Gd',
|
||||
]
|
||||
},
|
||||
'VCLinkerTool' : {
|
||||
'AdditionalOptions' : ['/RELEASE','/OPT:REF','/OPT:ICF','/LTCG']
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
],
|
||||
},
|
||||
{
|
||||
'target_name' : 'make_directory',
|
||||
'type' : 'none',
|
||||
'dependencies' : ['addon'],
|
||||
'actions' : [{
|
||||
'action_name' : 'Directory created.',
|
||||
'inputs' : [],
|
||||
'outputs' : ['build'],
|
||||
'action': ['<(mkdir)', '-p', 'binary']
|
||||
}],
|
||||
},
|
||||
{
|
||||
'target_name' : 'copy_binary',
|
||||
'type' : 'none',
|
||||
'dependencies' : ['make_directory'],
|
||||
'actions' : [{
|
||||
'action_name' : 'Module copied.',
|
||||
'inputs' : [],
|
||||
'outputs' : ['binary'],
|
||||
'action' : ['<(cp)', 'build/Release/addon.node', 'binary/addon.node'],
|
||||
}],
|
||||
},
|
||||
{
|
||||
'target_name' : 'remove_extras',
|
||||
'type' : 'none',
|
||||
'dependencies' : ['copy_binary'],
|
||||
'actions' : [{
|
||||
'action_name' : 'Build intermediates removed.',
|
||||
'inputs' : [],
|
||||
'outputs' : ['cpp'],
|
||||
'conditions' : [
|
||||
[ 'OS=="linux"', { 'action' : [
|
||||
'rm',
|
||||
'<(module_root_dir)/build/Release/obj.target/addon/cpp/addon.o',
|
||||
'<(module_root_dir)/build/Release/obj.target/addon.node',
|
||||
'<(module_root_dir)/build/Release/addon.node'
|
||||
] } ],
|
||||
[ 'OS=="mac"', { 'action' : [
|
||||
'rm',
|
||||
'<(module_root_dir)/build/Release/obj.target/addon/cpp/bindings.o',
|
||||
'<(module_root_dir)/build/Release/obj.target/addon/cpp/example.o',
|
||||
'<(module_root_dir)/build/Release/addon.node'
|
||||
] } ],
|
||||
[ 'OS=="win"', { 'action' : [
|
||||
'<(rm)',
|
||||
'<(module_root_dir)/build/Release/addon.*',
|
||||
'<(module_root_dir)/build/Release/obj/addon/*.*'
|
||||
] } ],
|
||||
],
|
||||
}],
|
||||
},
|
||||
]
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
'use strict';
|
||||
|
||||
module.exports = require('./binary/example');
|
|
@ -0,0 +1,23 @@
|
|||
#include <cstdlib>
|
||||
|
||||
#include "example.hpp"
|
||||
|
||||
using namespace v8;
|
||||
using namespace node;
|
||||
using namespace std;
|
||||
|
||||
|
||||
extern "C" {
|
||||
|
||||
|
||||
void init(Handle<Object> target) {
|
||||
|
||||
Example::init(target);
|
||||
|
||||
}
|
||||
|
||||
|
||||
NODE_MODULE(NODE_GYP_MODULE_NAME, init);
|
||||
|
||||
|
||||
} // extern "C"
|
|
@ -0,0 +1,8 @@
|
|||
#ifndef _COMMON_HPP_
|
||||
#define _COMMON_HPP_
|
||||
|
||||
|
||||
#include <addon-tools.hpp>
|
||||
|
||||
|
||||
#endif /* _COMMON_HPP_ */
|
|
@ -0,0 +1,83 @@
|
|||
#include <cstdlib>
|
||||
#include <iostream>
|
||||
|
||||
#include "example.hpp"
|
||||
|
||||
using namespace v8;
|
||||
using namespace node;
|
||||
using namespace std;
|
||||
|
||||
#define THIS_EXAMPLE \
|
||||
Example *example = ObjectWrap::Unwrap<Example>(info.This());
|
||||
|
||||
#define THIS_CHECK \
|
||||
if (body->_isDestroyed) return;
|
||||
|
||||
|
||||
Nan::Persistent<v8::Function> Example::_constructor;
|
||||
|
||||
|
||||
void Example::init(Handle<Object> target) {
|
||||
|
||||
Local<FunctionTemplate> ctor = Nan::New<FunctionTemplate>(newCtor);
|
||||
|
||||
ctor->InstanceTemplate()->SetInternalFieldCount(1);
|
||||
ctor->SetClassName(JS_STR("Example"));
|
||||
|
||||
|
||||
// prototype
|
||||
Nan::SetPrototypeMethod(ctor, "destroy", destroy);
|
||||
|
||||
Local<ObjectTemplate> proto = ctor->PrototypeTemplate();
|
||||
// ACCESSOR_RW(proto, prop);
|
||||
|
||||
|
||||
EventEmitter::extend(ctor, proto);
|
||||
|
||||
|
||||
_constructor.Reset(Nan::GetFunction(ctor).ToLocalChecked());
|
||||
Nan::Set(target, JS_STR("Example"), Nan::GetFunction(ctor).ToLocalChecked());
|
||||
|
||||
}
|
||||
|
||||
|
||||
NAN_METHOD(Example::newCtor) {
|
||||
|
||||
CTOR_CHECK("Example");
|
||||
|
||||
Example *example = new Example();
|
||||
example->Wrap(info.This());
|
||||
|
||||
RET_VALUE(info.This());
|
||||
|
||||
}
|
||||
|
||||
|
||||
Example::Example() {
|
||||
|
||||
_isDestroyed = false;
|
||||
|
||||
}
|
||||
|
||||
|
||||
Body::~Body() {
|
||||
|
||||
_destroy();
|
||||
|
||||
}
|
||||
|
||||
|
||||
void Body::_destroy() { DES_CHECK;
|
||||
|
||||
_isDestroyed = true;
|
||||
|
||||
emit("destroy");
|
||||
|
||||
}
|
||||
|
||||
|
||||
NAN_METHOD(Body::destroy) { THIS_BODY; THIS_CHECK;
|
||||
|
||||
example->_destroy();
|
||||
|
||||
}
|
|
@ -0,0 +1,37 @@
|
|||
#ifndef _EXAMPLE_HPP_
|
||||
#define _EXAMPLE_HPP_
|
||||
|
||||
|
||||
#include <event-emitter.hpp>
|
||||
|
||||
#include "common.hpp"
|
||||
|
||||
|
||||
class Example : public EventEmitter {
|
||||
|
||||
public:
|
||||
|
||||
static void init(v8::Handle<v8::Object> target);
|
||||
|
||||
virtual ~Example();
|
||||
|
||||
|
||||
protected:
|
||||
|
||||
Example();
|
||||
|
||||
static NAN_METHOD(newCtor);
|
||||
|
||||
static NAN_METHOD(destroy);
|
||||
|
||||
|
||||
private:
|
||||
|
||||
static Nan::Persistent<v8::Function> _constructor;
|
||||
|
||||
bool _isDestroyed;
|
||||
|
||||
};
|
||||
|
||||
|
||||
#endif // _EXAMPLE_HPP_
|
|
@ -0,0 +1,10 @@
|
|||
'use strict';
|
||||
|
||||
const Wrapped = require('./js/wrapped');
|
||||
const Example = require('./js/example');
|
||||
|
||||
console.log('Example', Example);
|
||||
|
||||
console.log('Wrapped', Wrapped);
|
||||
|
||||
module.exports = { Wrapped, Example };
|
|
@ -0,0 +1,7 @@
|
|||
'use strict';
|
||||
|
||||
|
||||
const { Example } = require('../core');
|
||||
|
||||
|
||||
module.exports = Example;
|
|
@ -0,0 +1,12 @@
|
|||
'use strict';
|
||||
|
||||
|
||||
const { Example } = require('../core');
|
||||
|
||||
|
||||
class Wrapped extends Example {
|
||||
|
||||
}
|
||||
|
||||
|
||||
module.exports = Wrapped;
|
|
@ -0,0 +1,25 @@
|
|||
{
|
||||
"name": "example",
|
||||
"version": "0.0.1",
|
||||
"description": "EXAMPLE",
|
||||
"main": "index.js",
|
||||
"author": "Luis Blanco <raubtierxxx@gmail.com>",
|
||||
"keywords": [
|
||||
"addon"
|
||||
],
|
||||
"maintainers": [
|
||||
{
|
||||
"name": "Luis Blanco",
|
||||
"email": "raubtierxxx@gmail.com",
|
||||
"skype": "rauber666"
|
||||
}
|
||||
],
|
||||
"license": "MIT",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/raub/node-addon-tools"
|
||||
},
|
||||
"dependencies": {
|
||||
"addon-tools-raub": "../../"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
node_modules
|
||||
*.log
|
||||
build*
|
||||
.DS_Store
|
||||
*.pro.user
|
||||
*.exp
|
||||
*.pdb
|
||||
*.ilk
|
||||
package-lock.json
|
|
@ -0,0 +1,11 @@
|
|||
node_modules
|
||||
*.log
|
||||
build*
|
||||
.DS_Store
|
||||
*.pro.user
|
||||
*.exp
|
||||
*.pdb
|
||||
*.ilk
|
||||
.gitignore
|
||||
package-lock.json
|
||||
test
|
|
@ -0,0 +1,20 @@
|
|||
{
|
||||
'variables': {
|
||||
'rm' : '<!(node -e "require(\'addon-tools-raub\').rm()")',
|
||||
'rem' : '<!(node -e "require(\'.\').rem()")',
|
||||
},
|
||||
'targets': [
|
||||
{
|
||||
'target_name' : 'remove_extras',
|
||||
'type' : 'none',
|
||||
'actions' : [
|
||||
{
|
||||
'action_name' : 'Unnecessary binaries removed.',
|
||||
'inputs' : [],
|
||||
'outputs' : ['build'],
|
||||
'action' : ['<(rm)', '-rf', '<@(rem)'],
|
||||
}
|
||||
],
|
||||
}
|
||||
]
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
'use strict';
|
||||
|
||||
module.exports = require('addon-tools-raub').paths(__dirname);
|
|
@ -0,0 +1,29 @@
|
|||
{
|
||||
"name": "deps-example",
|
||||
"author": "Luis Blanco <raubtierxxx@gmail.com>",
|
||||
"description": "EXAMPLE",
|
||||
"version": "0.0.1",
|
||||
"main": "index.js",
|
||||
"keywords": [
|
||||
"deps",
|
||||
"dependency",
|
||||
"lib",
|
||||
"library",
|
||||
"binary"
|
||||
],
|
||||
"maintainers": [
|
||||
{
|
||||
"name": "Luis Blanco",
|
||||
"email": "raubtierxxx@gmail.com",
|
||||
"skype": "rauber666"
|
||||
}
|
||||
],
|
||||
"license": "MIT",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/raub/node-addon-tools"
|
||||
},
|
||||
"dependencies": {
|
||||
"addon-tools-raub": "../../"
|
||||
}
|
||||
}
|
|
@ -5,41 +5,47 @@
|
|||
#include <addon-tools.hpp>
|
||||
|
||||
#include <map>
|
||||
#include <vector>
|
||||
#include <deque>
|
||||
|
||||
|
||||
#define THIS_VIEW \
|
||||
#define THIS_EMITTER \
|
||||
EventEmitter *emitter = ObjectWrap::Unwrap<EventEmitter>(info.This());
|
||||
|
||||
|
||||
class EventEmitter : public Nan::ObjectWrap {
|
||||
|
||||
typedef Nan::CopyablePersistentTraits<v8::Function>::CopyablePersistent FN_TYPE;
|
||||
typedef std::vector<FN_TYPE> VEC_TYPE;
|
||||
typedef std::deque<FN_TYPE> VEC_TYPE;
|
||||
typedef std::map<std::string, VEC_TYPE> MAP_TYPE;
|
||||
typedef std::map<FN_TYPE, FN_TYPE> FNMAP_TYPE;
|
||||
typedef VEC_TYPE::iterator IT_TYPE;
|
||||
typedef MAP_TYPE::iterator MAP_IT_TYPE;
|
||||
|
||||
public:
|
||||
|
||||
Emitter () {}
|
||||
~Emitter () {}
|
||||
EventEmitter () {
|
||||
_maxListeners = _defaultMaxListeners;
|
||||
}
|
||||
~EventEmitter () {}
|
||||
|
||||
|
||||
init(v8::Local<v8::FunctionTemplate> &ctor, v8::Local<v8::ObjectTemplate> &proto) {
|
||||
static void extend(v8::Local<v8::FunctionTemplate> &ctor, v8::Local<v8::ObjectTemplate> &proto) {
|
||||
|
||||
v8::Local<v8::Function> ctorFunc = Nan::GetFunction(ctor).ToLocalChecked();
|
||||
v8::Local<v8::Object> ctorObj = ctorFunc;
|
||||
|
||||
|
||||
// -------- static
|
||||
|
||||
Nan::SetMethod(ctorFunc, "listenerCount", jsStaticListenerCount);
|
||||
ACCESSOR_RW(ctorFunc, defaultMaxListeners);
|
||||
ACCESSOR_RW(ctorObj, defaultMaxListeners);
|
||||
|
||||
|
||||
// -------- dynamic
|
||||
|
||||
Nan::SetPrototypeMethod(ctor, "listenerCount", jsListenerCount);
|
||||
Nan::SetPrototypeMethod(ctor, "addListener", jsAddListener);
|
||||
Nan::SetPrototypeMethod(ctor, "emit", jsEmit);
|
||||
Nan::SetPrototypeMethod(ctor, "eventNames", jsEventNames);
|
||||
Nan::SetPrototypeMethod(ctor, "getMaxListeners", jsGetMaxListeners);
|
||||
Nan::SetPrototypeMethod(ctor, "listeners", jsListeners);
|
||||
|
@ -57,9 +63,9 @@ public:
|
|||
}
|
||||
|
||||
|
||||
void emit(const std::string &name, int argc, Local<Value> argv[]) {
|
||||
void emit(const std::string &name, int argc = 0, v8::Local<v8::Value> *argv = NULL) {
|
||||
|
||||
const VEC_TYPE &list = _listeners[name];
|
||||
VEC_TYPE &list = _listeners[name];
|
||||
|
||||
if (list.empty()) {
|
||||
return;
|
||||
|
@ -78,59 +84,83 @@ public:
|
|||
}
|
||||
|
||||
|
||||
// Deprecated method
|
||||
static NAN_METHOD(jsStaticListenerCount) {
|
||||
|
||||
|
||||
|
||||
NAN_METHOD(jsStaticListenerCount) {
|
||||
|
||||
Emitter *emitter = ObjectWrap::Unwrap<Emitter>(info[0]);
|
||||
EventEmitter *emitter = ObjectWrap::Unwrap<EventEmitter>(info[0]);
|
||||
REQ_UTF8_ARG(1, name);
|
||||
|
||||
const VEC_TYPE &list = emitter->_listeners[*name];
|
||||
|
||||
Local<Array> jsListeners = Nan::New<Array>(list.size());
|
||||
|
||||
if (list.empty()) {
|
||||
RET_VALUE(jsListeners);
|
||||
return;
|
||||
}
|
||||
|
||||
for (IT_TYPE it = list.begin(), int i = 0; it != list.end(); ++it) {
|
||||
|
||||
jsListeners->Set(JS_INT(j), Nan::New(*it));
|
||||
}
|
||||
|
||||
RET_VALUE(jsListeners);
|
||||
RET_VALUE(JS_INT(list.size()));
|
||||
|
||||
}
|
||||
|
||||
|
||||
static NAN_SETTER(defaultMaxListenersSetter) { THIS_EMITTER; SETTER_INT32_ARG;
|
||||
|
||||
NAN_METHOD(jsStaticListenerCount) {
|
||||
EventEmitter::_defaultMaxListeners = v;
|
||||
|
||||
Emitter *emitter = ObjectWrap::Unwrap<Emitter>(info[0]);
|
||||
REQ_UTF8_ARG(1, name);
|
||||
}
|
||||
|
||||
const VEC_TYPE &list = emitter->_listeners[*name];
|
||||
static NAN_GETTER(defaultMaxListenersGetter) { THIS_EMITTER;
|
||||
|
||||
Local<Array> jsListeners = Nan::New<Array>(list.size());
|
||||
|
||||
if (list.empty()) {
|
||||
RET_VALUE(jsListeners);
|
||||
return;
|
||||
}
|
||||
|
||||
for (IT_TYPE it = list.begin(), int i = 0; it != list.end(); ++it) {
|
||||
|
||||
jsListeners->Set(JS_INT(j), Nan::New(*it));
|
||||
}
|
||||
|
||||
RET_VALUE(jsListeners);
|
||||
RET_VALUE(JS_INT(EventEmitter::_defaultMaxListeners));
|
||||
|
||||
}
|
||||
|
||||
|
||||
NAN_METHOD(jsListenerCount) { THIS_EMITTER;
|
||||
static NAN_METHOD(jsAddListener) { THIS_EMITTER;
|
||||
|
||||
REQ_UTF8_ARG(0, name);
|
||||
REQ_FUN_ARG(1, cb);
|
||||
|
||||
Nan::Persistent<v8::Function> persistentCb;
|
||||
persistentCb.Reset(cb);
|
||||
|
||||
emitter->_listeners[std::string(*name)].push_back(persistentCb);
|
||||
|
||||
}
|
||||
|
||||
|
||||
static NAN_METHOD(jsEmit) { THIS_EMITTER;
|
||||
|
||||
REQ_UTF8_ARG(0, name);
|
||||
|
||||
emitter->emit(*name, info.Length() - 1, &info[1]);
|
||||
|
||||
}
|
||||
|
||||
|
||||
static NAN_METHOD(jsEventNames) { THIS_EMITTER;
|
||||
|
||||
v8::Local<v8::Array> jsNames = Nan::New<v8::Array>(emitter->_listeners.size());
|
||||
|
||||
if (emitter->_listeners.empty()) {
|
||||
RET_VALUE(jsNames);
|
||||
return;
|
||||
}
|
||||
|
||||
int i = 0;
|
||||
for (MAP_IT_TYPE it = emitter->_listeners.begin(); it != emitter->_listeners.end(); ++it, i++) {
|
||||
|
||||
jsNames->Set(JS_INT(i), JS_STR(it->first));
|
||||
|
||||
}
|
||||
|
||||
RET_VALUE(jsNames);
|
||||
|
||||
}
|
||||
|
||||
|
||||
static NAN_METHOD(jsGetMaxListeners) { THIS_EMITTER;
|
||||
|
||||
RET_VALUE(JS_INT(emitter->_maxListeners));
|
||||
|
||||
}
|
||||
|
||||
|
||||
static NAN_METHOD(jsListenerCount) { THIS_EMITTER;
|
||||
|
||||
REQ_UTF8_ARG(0, name);
|
||||
|
||||
|
@ -141,7 +171,53 @@ public:
|
|||
}
|
||||
|
||||
|
||||
NAN_METHOD(jsAddListener) { THIS_EMITTER;
|
||||
static NAN_METHOD(jsListeners) { THIS_EMITTER;
|
||||
|
||||
REQ_UTF8_ARG(0, name);
|
||||
|
||||
VEC_TYPE &list = emitter->_listeners[*name];
|
||||
|
||||
v8::Local<v8::Array> jsListeners = Nan::New<v8::Array>(list.size());
|
||||
|
||||
if (list.empty()) {
|
||||
RET_VALUE(jsListeners);
|
||||
return;
|
||||
}
|
||||
|
||||
int i = 0;
|
||||
for (IT_TYPE it = list.begin(); it != list.end(); ++it, i++) {
|
||||
|
||||
jsListeners->Set(JS_INT(i), Nan::New(*it));
|
||||
|
||||
}
|
||||
|
||||
RET_VALUE(jsListeners);
|
||||
|
||||
}
|
||||
|
||||
|
||||
static inline void _addListener(
|
||||
const Nan::FunctionCallbackInfo<v8::Value> &info,
|
||||
const std::string &name,
|
||||
Nan::Persistent<v8::Function> &cb,
|
||||
bool isFront
|
||||
) { THIS_EMITTER;
|
||||
|
||||
if (isFront) {
|
||||
emitter->_listeners[name].push_front(cb);
|
||||
emitter->_raw[name].push_front(cb);
|
||||
} else {
|
||||
emitter->_listeners[name].push_back(cb);
|
||||
emitter->_raw[name].push_back(cb);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
static inline void _wrapListener(
|
||||
const Nan::FunctionCallbackInfo<v8::Value> &info,
|
||||
bool isFront = false
|
||||
) {
|
||||
|
||||
REQ_UTF8_ARG(0, name);
|
||||
REQ_FUN_ARG(1, cb);
|
||||
|
@ -149,28 +225,211 @@ public:
|
|||
Nan::Persistent<v8::Function> persistentCb;
|
||||
persistentCb.Reset(cb);
|
||||
|
||||
emitter->_listeners[std::string(*name)].push_back(persistentCb);
|
||||
_addListener(info, *name, persistentCb, isFront);
|
||||
|
||||
}
|
||||
|
||||
|
||||
NAN_METHOD(jsOn) { THIS_EMITTER;
|
||||
static inline void _addOnceListener(
|
||||
const Nan::FunctionCallbackInfo<v8::Value> &info,
|
||||
const std::string &name,
|
||||
Nan::Persistent<v8::Function> &raw,
|
||||
Nan::Persistent<v8::Function> &cb,
|
||||
bool isFront
|
||||
) { THIS_EMITTER;
|
||||
|
||||
if (isFront) {
|
||||
emitter->_listeners[name].push_front(cb);
|
||||
emitter->_raw[name].push_front(raw);
|
||||
} else {
|
||||
emitter->_listeners[name].push_back(cb);
|
||||
emitter->_raw[name].push_back(raw);
|
||||
}
|
||||
emitter->_wrapped[raw] = cb;
|
||||
|
||||
}
|
||||
|
||||
|
||||
static inline void _wrapOnceListener(
|
||||
const Nan::FunctionCallbackInfo<v8::Value> &info,
|
||||
bool isFront = false
|
||||
) {
|
||||
|
||||
REQ_UTF8_ARG(0, name);
|
||||
REQ_FUN_ARG(1, cb);
|
||||
REQ_FUN_ARG(1, raw);
|
||||
|
||||
Nan::Persistent<v8::Function> persistentCb;
|
||||
persistentCb.Reset(cb);
|
||||
v8::Local<v8::String> code = JS_STR(
|
||||
"((emitter, cb) => (...args) => {\n\
|
||||
cb(...args);\n\
|
||||
emitter.removeListener(cb);\n\
|
||||
})"
|
||||
);
|
||||
|
||||
emitter->_listeners[std::string(*name)].push_back(persistentCb);
|
||||
v8::Local<v8::Function> decor = v8::Local<v8::Function>::Cast(v8::Script::Compile(code)->Run());
|
||||
Nan::Callback decorCb(decor);
|
||||
v8::Local<v8::Value> argv[] = { info.This(), raw };
|
||||
v8::Local<v8::Function> wrap = v8::Local<v8::Function>::Cast(decorCb.Call(2, argv));
|
||||
|
||||
Nan::Persistent<v8::Function> persistentWrap;
|
||||
persistentWrap.Reset(wrap);
|
||||
|
||||
Nan::Persistent<v8::Function> persistentRaw;
|
||||
persistentRaw.Reset(raw);
|
||||
|
||||
_addOnceListener(info, *name, persistentRaw, persistentWrap, isFront);
|
||||
|
||||
}
|
||||
|
||||
|
||||
static NAN_METHOD(jsOn) { _wrapListener(info); }
|
||||
|
||||
static NAN_METHOD(jsOnce) { _wrapOnceListener(info); }
|
||||
|
||||
static NAN_METHOD(jsPrependListener) { _wrapListener(info, true); }
|
||||
|
||||
static NAN_METHOD(jsPrependOnceListener) { _wrapOnceListener(info, true); }
|
||||
|
||||
|
||||
static NAN_METHOD(jsRemoveAllListeners) { THIS_EMITTER;
|
||||
|
||||
if (info->Length > 0 && info[0]->IsString()) {
|
||||
|
||||
_listeners->clear();
|
||||
_raw->clear();
|
||||
_wrapped->clear();
|
||||
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
REQ_UTF8_ARG(0, n);
|
||||
|
||||
std::string name = std::string(*n);
|
||||
VEC_TYPE &list = emitter->_raw[name];
|
||||
|
||||
if (list.empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (IT_TYPE it = list.begin(); it != list.end(); ++it) {
|
||||
|
||||
emitter->_wrapped.erase(*it)
|
||||
|
||||
}
|
||||
|
||||
emitter->_listeners[*name].clear();
|
||||
emitter->_raw[*name].clear();
|
||||
|
||||
}
|
||||
|
||||
|
||||
static NAN_METHOD(jsRemoveListener) { THIS_EMITTER;
|
||||
|
||||
REQ_UTF8_ARG(0, n);
|
||||
REQ_FUN_ARG(1, raw);
|
||||
|
||||
Nan::Persistent<v8::Function> persistentCb;
|
||||
persistentCb.Reset(raw);
|
||||
|
||||
std::string name = std::string(*n);
|
||||
|
||||
|
||||
VEC_TYPE &rawList = emitter->_raw[name];
|
||||
|
||||
if (rawList.empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (IT_TYPE it = rawList.begin(); it != rawList.end(); ++it) {
|
||||
|
||||
if (*it === persistentCb) {
|
||||
rawList.erase(it);
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
VEC_TYPE &wrapList = emitter->_listeners[name];
|
||||
|
||||
if (emitter->_wrapped.count(persistentCb) == 0) {
|
||||
|
||||
for (IT_TYPE it = wrapList.begin(); it != wrapList.end(); ++it) {
|
||||
|
||||
if (*it === persistentCb) {
|
||||
wrapList.erase(it);
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
|
||||
const FN_TYPE &wrapped = _wrapped[persistentCb];
|
||||
|
||||
for (IT_TYPE it = wrapList.begin(); it != wrapList.end(); ++it) {
|
||||
|
||||
if (*it === wrapped) {
|
||||
wrapList.erase(it);
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
emitter->_wrapped.erase(persistentCb);
|
||||
|
||||
}
|
||||
|
||||
|
||||
static NAN_METHOD(jsSetMaxListeners) { THIS_EMITTER;
|
||||
|
||||
REQ_INT32_ARG(0, value);
|
||||
|
||||
emitter->_maxListeners = value;
|
||||
|
||||
}
|
||||
|
||||
|
||||
static NAN_METHOD(jsRawListeners) { THIS_EMITTER;
|
||||
|
||||
REQ_UTF8_ARG(0, name);
|
||||
|
||||
VEC_TYPE &list = emitter->_raw[*name];
|
||||
|
||||
Local<Array> jsListeners = Nan::New<Array>(list.size());
|
||||
|
||||
if (list.empty()) {
|
||||
RET_VALUE(jsListeners);
|
||||
return;
|
||||
}
|
||||
|
||||
int i = 0;
|
||||
for (IT_TYPE it = list.begin(); it != list.end(); ++it, i++) {
|
||||
|
||||
jsListeners->Set(JS_INT(i), Nan::New(*it));
|
||||
|
||||
}
|
||||
|
||||
RET_VALUE(jsListeners);
|
||||
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
|
||||
static int _defaultMaxListeners;
|
||||
|
||||
|
||||
private:
|
||||
|
||||
int _maxListeners;
|
||||
|
||||
MAP_TYPE _listeners;
|
||||
MAP_TYPE _raw;
|
||||
FNMAP_TYPE _wrapped;
|
||||
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in New Issue