From b28b2069221aba794a5b3582777c9fbb56e927b9 Mon Sep 17 00:00:00 2001 From: raub Date: Fri, 2 Mar 2018 20:14:47 +0300 Subject: [PATCH] event emitter initial --- include/event-emitter.hpp | 178 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 178 insertions(+) create mode 100644 include/event-emitter.hpp diff --git a/include/event-emitter.hpp b/include/event-emitter.hpp new file mode 100644 index 0000000..a4dbb39 --- /dev/null +++ b/include/event-emitter.hpp @@ -0,0 +1,178 @@ +#ifndef _EVENT_EMITTER_ +#define _EVENT_EMITTER_ + + +#include + +#include +#include + + +#define THIS_VIEW \ + EventEmitter *emitter = ObjectWrap::Unwrap(info.This()); + + +class EventEmitter : public Nan::ObjectWrap { + + typedef Nan::CopyablePersistentTraits::CopyablePersistent FN_TYPE; + typedef std::vector VEC_TYPE; + typedef std::map MAP_TYPE; + typedef VEC_TYPE::iterator IT_TYPE; + +public: + + Emitter () {} + ~Emitter () {} + + + init(v8::Local &ctor, v8::Local &proto) { + + v8::Local ctorFunc = Nan::GetFunction(ctor).ToLocalChecked(); + + + // -------- static + + Nan::SetMethod(ctorFunc, "listenerCount", jsStaticListenerCount); + ACCESSOR_RW(ctorFunc, defaultMaxListeners); + + + // -------- dynamic + + Nan::SetPrototypeMethod(ctor, "listenerCount", jsListenerCount); + Nan::SetPrototypeMethod(ctor, "addListener", jsAddListener); + Nan::SetPrototypeMethod(ctor, "eventNames", jsEventNames); + Nan::SetPrototypeMethod(ctor, "getMaxListeners", jsGetMaxListeners); + Nan::SetPrototypeMethod(ctor, "listeners", jsListeners); + Nan::SetPrototypeMethod(ctor, "on", jsOn); + Nan::SetPrototypeMethod(ctor, "once", jsOnce); + Nan::SetPrototypeMethod(ctor, "prependListener", jsPrependListener); + Nan::SetPrototypeMethod(ctor, "prependOnceListener", jsPrependOnceListener); + Nan::SetPrototypeMethod(ctor, "removeAllListeners", jsRemoveAllListeners); + Nan::SetPrototypeMethod(ctor, "removeListener", jsRemoveListener); + Nan::SetPrototypeMethod(ctor, "setMaxListeners", jsSetMaxListeners); + Nan::SetPrototypeMethod(ctor, "rawListeners", jsRawListeners); + + // ACCESSOR_RW(proto, type); + + } + + + void emit(const std::string &name, int argc, Local argv[]) { + + const VEC_TYPE &list = _listeners[name]; + + if (list.empty()) { + return; + } + + for (IT_TYPE it = list.begin(); it != list.end(); ++it) { + + Nan::Callback callback(Nan::New(*it)); + + if ( ! callback.IsEmpty() ) { + callback.Call(argc, argv); + } + + } + + } + + + + + + NAN_METHOD(jsStaticListenerCount) { + + Emitter *emitter = ObjectWrap::Unwrap(info[0]); + REQ_UTF8_ARG(1, name); + + const VEC_TYPE &list = emitter->_listeners[*name]; + + Local jsListeners = Nan::New(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); + + } + + + + NAN_METHOD(jsStaticListenerCount) { + + Emitter *emitter = ObjectWrap::Unwrap(info[0]); + REQ_UTF8_ARG(1, name); + + const VEC_TYPE &list = emitter->_listeners[*name]; + + Local jsListeners = Nan::New(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); + + } + + + NAN_METHOD(jsListenerCount) { THIS_EMITTER; + + REQ_UTF8_ARG(0, name); + + const VEC_TYPE &list = emitter->_listeners[*name]; + + RET_VALUE(JS_INT(list.size())); + + } + + + NAN_METHOD(jsAddListener) { THIS_EMITTER; + + REQ_UTF8_ARG(0, name); + REQ_FUN_ARG(1, cb); + + Nan::Persistent persistentCb; + persistentCb.Reset(cb); + + emitter->_listeners[std::string(*name)].push_back(persistentCb); + + } + + + NAN_METHOD(jsOn) { THIS_EMITTER; + + REQ_UTF8_ARG(0, name); + REQ_FUN_ARG(1, cb); + + Nan::Persistent persistentCb; + persistentCb.Reset(cb); + + emitter->_listeners[std::string(*name)].push_back(persistentCb); + + } + + + +private: + + MAP_TYPE _listeners; + +}; + + +#endif // _EVENT_EMITTER_