On C++, EventEmitter, Callbacks

167 views
Skip to first unread message

Ingwie Phoenix

unread,
Aug 2, 2014, 2:29:16 PM8/2/14
to nod...@googlegroups.com
Hey everyone!

I have a library that does some heavy tasks that would block the main progress if I made it a blocking method. But I would like to go with a event-driven method, but I havent found out how these are written in C++. Here is what Id like to see in JS side:

var task = require(…).myTaskCreator(…);
task.on(…);

Especially the .on() kind of thing would be very interesting.

Further, I think I will let my library ran off in a separate process, using TinyThreads++ as my thread abstraction.

But… What things do I need in order to create/use an EventEmitter in C++? From what I can imagine is, that I have to export a function that creates the event emitter and feeds the worker-thread the information…via a struct or alike. But how do I emit events then?

Hope you can understand what I am trying to say ^^;

Kind regards, Ingwie

Dmitry Unkovsky

unread,
Aug 4, 2014, 1:02:30 PM8/4/14
to nod...@googlegroups.com
Hey Ingwie!

You don't just create EventEmitter in C++. Well, technically you
could, but that's not how things are usually done in node-js addons.

If you have your ToughClass in C++ class for heavylifting, it should
inherit from ObjectWrap, which enables your ToughClass to interact
with v8 GC and with other js parts of your application.

Then, usually in ToughClass::Initialize method, you "manually", by
calling special v8 api methods,
create some js-style JSTough class constructor function, an you set all
methods that you want to be accessible from js-land on
JSTough.prototype (like this: NODE_SET_PROTOTYPE_METHOD(t,
"someMethod", ToughClass::someMethod)), and you set your C++ module's
`export.JSWrap` to this JSTough function.

Then, what happens in runtime? In js, you do:
var JSTough = require("./path/to/tough_class").JSTough
var jsw = new JSTough()

new JSTough() is usually bound to (static) ToughClass::New, which
creates ToughClass instance (say, `tc`), and sets it's handle_ member
to `jsw` (which, remember, is a js-object initized with new JSTough()
call).

Then, in js-land, you set callbacks on `jsw`, like `jsw.on_something =
function(arg1, arg2){ ... }`, and call it's methods, like
`jsw.someMethod()` (which invokes ToughClass::someMethod). Sometime
later, you can call `on_something` callback from C++ land.

If you want to have EventEmitter over this construction, you do some
other js class, this time in js-land:

```
function Tough(){
EventEmitter.apply(this, arguments)
this._handle = new JSTough()
this._handle.on_something = function(result){
this.emit("result", result)
}.bind(this)
}
```

This is just a quick overview of what happens somewhere under the
hood, just a brief picture. The details vary in 0.10 and 0.11
versions, but the overall flow is essentially the same.

For details and real examples, please see the addons documentation for
your version of node http://nodejs.org/api/addons.html.

You may find interesting `src/tcp_wrap.{h,cc}` and `lib/net.js` an
interesting reference, or, for more simple and straightforward code,
`src/node_buffer.{h,cc}`.

HTH.

Ingwie Phoenix

unread,
Aug 4, 2014, 2:20:22 PM8/4/14
to nod...@googlegroups.com
Hey Dmitry,

thank you for your explanation, although this is not my first C++ addon. This time, I just wanted to create a more async module and wanted to hook this up to events. But obviously, as long as I am in C++-land, I cant seem to access the JS-land EventEmitter to let my object inherit from there.

But while I am at it, what else does ObjectWrap offer, other than the own Wrap() method, that lets me put a C++ instance inside?

Kind regards, Ingwie
> --
> Job board: http://jobs.nodejs.org/
> New group rules: https://gist.github.com/othiym23/9886289#file-moderation-policy-md
> Old group rules: https://github.com/joyent/node/wiki/Mailing-List-Posting-Guidelines
> ---
> You received this message because you are subscribed to the Google Groups "nodejs" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to nodejs+un...@googlegroups.com.
> To post to this group, send email to nod...@googlegroups.com.
> To view this discussion on the web visit https://groups.google.com/d/msgid/nodejs/CAM4U4uUYTDnzf5JqGQZdh%3DCF3Na6SNwrU0FMz3pDw%2B2x%2ByF7fg%40mail.gmail.com.
> For more options, visit https://groups.google.com/d/optout.

Dmitry Unkovsky

unread,
Aug 12, 2014, 3:23:26 PM8/12/14
to nod...@googlegroups.com
Hey Ingwie!

Basically, other than Wrap and Unwrap methods, it has Ref, Unref, and
WeakCallback methods. Ref and Unref
correspondingly increase and decrease v8's reference count on handle_.
And it's method WeakCallback will be called by gc at some point after
there's no more references to it's handle_ member, and every call to
Ref is matched by call to Unref.

See object_wrap.{h,cc} for the gory details.
> To view this discussion on the web visit https://groups.google.com/d/msgid/nodejs/96A75DE9-7817-4F11-8E0A-6FC7E0F48614%40googlemail.com.
> For more options, visit https://groups.google.com/d/optout.



--
DU
Reply all
Reply to author
Forward
0 new messages