diff --git a/README.md b/README.md index 7e06615..b66cc18 100644 --- a/README.md +++ b/README.md @@ -7,6 +7,7 @@ This is a part of [Node3D](https://github.com/node-3d) project. Helpers for Node.js addons and dependency packages: +* `consoleLog()` C++ implementation. * `EventEmitter` C++ implementation. * C++ macros and shortcuts. * Crossplatform commands for GYP: `cp`, `rm`, `mkdir`. @@ -36,6 +37,8 @@ Useful links: [V8 Ref](https://v8docs.nodesource.com/node-0.8/d2/dc3/namespacev8 [Class EventEmitter](#class-eventemitter) +[Function consoleLog](#function-consolelog) + --- @@ -668,7 +671,7 @@ For Windows the `/y` flag was embedded. --- -## class EventEmitter +## Class EventEmitter A C++ implementation of [Events API](https://nodejs.org/api/events.html). @@ -750,3 +753,23 @@ void Example::init(Handle target) { ``` + +--- + + +## Function consoleLog + +In C++ addons, the use of **iostream** is discouraged because **Node.js** has its own +perspective on **stdout** behavior. +At first it may look as if `cout << "msg" << endl;` works nice, but it doesn't. +After a while, it just ceases on a midword, and you end up thinking something has +broken really hard in your addon. + +To overcome this, we can use some V8 `eval` magic to make a real `console.log` +call from C++ land. And this is where `consoleLog` comes into play. + +* `inline void consoleLog(int argc, V8_VAR_VAL *argv)` - a generic logger, +receives any set of arguments. + +* `inline void consoleLog(const std::string &message)` - an alias to log a single +string. diff --git a/include/addon-tools.hpp b/include/addon-tools.hpp index b13320f..0d602aa 100644 --- a/include/addon-tools.hpp +++ b/include/addon-tools.hpp @@ -287,4 +287,24 @@ inline void *getImageData(v8::Local arg) { } +inline void consoleLog(int argc, V8_VAR_VAL *argv) { + + V8_VAR_STR code = JS_STR("((...args) => console.log(...args))"); + + V8_VAR_FUNC log = V8_VAR_FUNC::Cast(v8::Script::Compile(code)->Run()); + Nan::Callback logCb(log); + Nan::AsyncResource async("consoleLog()"); + logCb.Call(argc, argv, &async); + +} + + +inline void consoleLog(const std::string &message) { + + V8_VAR_VAL arg = JS_STR(message); + consoleLog(1, &arg); + +} + + #endif // _ADDON_TOOLS_HPP_ diff --git a/include/event-emitter.hpp b/include/event-emitter.hpp index 3263944..d0f186b 100644 --- a/include/event-emitter.hpp +++ b/include/event-emitter.hpp @@ -7,7 +7,6 @@ #include #include #include -#include // -> std::cout << "..." << std::endl; #define THIS_EVENT_EMITTER \ @@ -308,6 +307,33 @@ private: } + static inline void _reportListeners( + const std::string &name, + int numListeners, + int maxListeners + ) { + + std::string msg = "EventEmitter Warning: too many listeners ("; + msg += std::to_string(numListeners); + msg += " > "; + msg += std::to_string(maxListeners); + msg += ") on '"; + msg += name; + msg += "' event, possible memory leak.\n"; + + // Some JS magic to retrieve the call stack + V8_VAR_STR code = JS_STR( + "(new Error()).stack.split('\\n').slice(2).join('\\n')" + ); + V8_VAR_STR stack = V8_VAR_STR::Cast( + v8::Script::Compile(code)->Run() + ); + Nan::Utf8String stackStr(stack); + msg += *stackStr; + + consoleLog(msg); + + } static inline void _addListener( const Nan::FunctionCallbackInfo &info, @@ -331,19 +357,7 @@ private: if (eventEmitter->_maxListeners > 0 && count > eventEmitter->_maxListeners) { - std::cout << "EventEmitter Warning: too many listeners ("; - std::cout << count << " > " << eventEmitter->_maxListeners << ") on '"; - std::cout << name << "' event, possible memory leak." << std::endl; - - // Some JS magic to retrieve the call stack - V8_VAR_STR code = JS_STR( - "(new Error()).stack.split('\\n').slice(1).join('\\n')" - ); - V8_VAR_STR stack = V8_VAR_STR::Cast( - v8::Script::Compile(code)->Run() - ); - Nan::Utf8String stackStr(stack); - std::cout << *stackStr << std::endl; + _reportListeners(name, count, eventEmitter->_maxListeners); } @@ -393,19 +407,7 @@ private: if (eventEmitter->_maxListeners > 0 && count > eventEmitter->_maxListeners) { - std::cout << "EventEmitter Warning: too many listeners ("; - std::cout << count << " > " << eventEmitter->_maxListeners << ") on '"; - std::cout << name << "' event, possible memory leak." << std::endl; - - // Some JS magic to retrieve the call stack - V8_VAR_STR code = JS_STR( - "(new Error()).stack.split('\\n').slice(1).join('\\n')" - ); - V8_VAR_STR stack = V8_VAR_STR::Cast( - v8::Script::Compile(code)->Run() - ); - Nan::Utf8String stackStr(stack); - std::cout << *stackStr << std::endl; + _reportListeners(name, count, eventEmitter->_maxListeners); }