I'm writing Agueas [1] addon for Node.js
For now I have synchronous code, C++ class looks like this:
class LibAugeas : public node::ObjectWrap {
public:
static void Init(Handle<Object> target);
protected:
augeas * m_aug;
LibAugeas();
~LibAugeas();
static Handle<Value> New(const Arguments& args);
static Handle<Value> get (const Arguments& args);
static Handle<Value> set (const Arguments& args);
static Handle<Value> setm (const Arguments& args);
// other methods
};
Usage of this class in JS:
var lib = require('...');
var aug = new lib.Augeas(...);
aug.set(...);
aug.get(...);
// etc
I'm going to impelement asynchronous code.
The bottleneck is creating augeas object (aug_init) while all or some lenses and files are being loaded and parsed. So the idea is creating augeas object asynchronously, and then pass created JS object in a callback function:
Usage might be as such:
lib.heracles(function(aug) {
if (!aug.error()) {
console.log('Hello!');
// async save:
aug.save(function(err, msg) {
console.log(msg);
});
} else {
console.log('Sad, but true :-(');
}
}
);
And finally, my problem: I do not know how to create JS object in C++ :-)
Constructor static Handle<Value> New(const Arguments& args);
returns args.This()
, but when I'm in C++ code I do not have args
and also can't wrap object.
So, how do I create JS object in C++? Please, don't break my heart saying it is not possible :-)
Ok, thanks to everyone :-) I've found the right way. Here is a static method which creates an JS object wrapping given augeas handle. Then I can pass this object to callback function from C++ code.
Local<Object> LibAugeas::New(augeas *aug)
{
LibAugeas *obj = new LibAugeas();
obj->m_aug = aug;
Handle<ObjectTemplate> tpl = ObjectTemplate::New();
tpl->SetInternalFieldCount(1); // one field for LibAugeas* pointer (via obj->Wrap())
#define _OBJ_NEW_METHOD(m) NODE_SET_METHOD(tpl, #m, m)
_OBJ_NEW_METHOD(get);
_OBJ_NEW_METHOD(set);
_OBJ_NEW_METHOD(setm);
_OBJ_NEW_METHOD(rm);
_OBJ_NEW_METHOD(mv);
_OBJ_NEW_METHOD(save);
_OBJ_NEW_METHOD(nmatch);
_OBJ_NEW_METHOD(insert);
_OBJ_NEW_METHOD(error);
Local<Object> O = tpl->NewInstance();
obj->Wrap(O);
return O;
}