📝 Farewell iostream
This commit is contained in:
parent
e244be7bea
commit
8dc8431017
25
README.md
25
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:
|
Helpers for Node.js addons and dependency packages:
|
||||||
|
|
||||||
|
* `consoleLog()` C++ implementation.
|
||||||
* `EventEmitter` C++ implementation.
|
* `EventEmitter` C++ implementation.
|
||||||
* C++ macros and shortcuts.
|
* C++ macros and shortcuts.
|
||||||
* Crossplatform commands for GYP: `cp`, `rm`, `mkdir`.
|
* 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)
|
[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).
|
A C++ implementation of [Events API](https://nodejs.org/api/events.html).
|
||||||
|
|
||||||
|
@ -750,3 +753,23 @@ void Example::init(Handle<Object> target) {
|
||||||
```
|
```
|
||||||
|
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
|
||||||
|
## 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.
|
||||||
|
|
|
@ -287,4 +287,24 @@ inline void *getImageData(v8::Local<v8::Value> 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_
|
#endif // _ADDON_TOOLS_HPP_
|
||||||
|
|
|
@ -7,7 +7,6 @@
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <deque>
|
#include <deque>
|
||||||
#include <iostream> // -> std::cout << "..." << std::endl;
|
|
||||||
|
|
||||||
|
|
||||||
#define THIS_EVENT_EMITTER \
|
#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(
|
static inline void _addListener(
|
||||||
const Nan::FunctionCallbackInfo<v8::Value> &info,
|
const Nan::FunctionCallbackInfo<v8::Value> &info,
|
||||||
|
@ -331,19 +357,7 @@ private:
|
||||||
|
|
||||||
if (eventEmitter->_maxListeners > 0 && count > eventEmitter->_maxListeners) {
|
if (eventEmitter->_maxListeners > 0 && count > eventEmitter->_maxListeners) {
|
||||||
|
|
||||||
std::cout << "EventEmitter Warning: too many listeners (";
|
_reportListeners(name, count, eventEmitter->_maxListeners);
|
||||||
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;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -393,19 +407,7 @@ private:
|
||||||
|
|
||||||
if (eventEmitter->_maxListeners > 0 && count > eventEmitter->_maxListeners) {
|
if (eventEmitter->_maxListeners > 0 && count > eventEmitter->_maxListeners) {
|
||||||
|
|
||||||
std::cout << "EventEmitter Warning: too many listeners (";
|
_reportListeners(name, count, eventEmitter->_maxListeners);
|
||||||
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;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue