Let's say I have two classes that are developed in C++, but are exposed using Nan NodeJS native modules. For example, a "Sprite" and "Texture" class.
In the JavaScript, I want to be able to have a Sprite store a Texture as if it were just another property:
// Local instance of texture
var t = new Texture();
// Global instances of Sprites that won't be GC'd
global.spr = new Sprite();
global.spr2 = new Sprite();
// Same texture can be assigned to multiple sprites
spr.texture = t;
spr2.texture = t;
console.log(spr.texture);
On the C++ side of things, the "texture" property of the Sprite would be a Getter/Setter that stores or retrieves the Texture. The question is though, what would be the proper way to store an instance of Texture internally (from the provided v8::Local)? Like, what do I need to do to register it as "owned" by the Sprite and cause it not to get GC'd as it probably would be in the example above?
You can have a Persistent
handle as a member of your Sprite class that stores the Texture instance. The Sprite destructor needs to reset the the handle to avoid a leak.
class Sprite : public Nan::ObjectWrap {
public:
Nan::Persistent<v8::Object> textureHandle;
static NAN_SETTER(SetTexture) {
Sprite* sprite = Nan::ObjectWrap::Unwrap<Sprite>(info.This());
if (Nan::New(Texture::constructor)->HasInstance(value)) {
sprite->textureHandle.Reset(value);
} else {
// value wasn't a Texture instance; do something
}
}
static NAN_GETTER(GetTexture) {
Sprite* sprite = Nan::ObjectWrap::Unwrap<Sprite>(info.This());
Isolate* iso = Isolate::GetCurrent();
if (sprite->textureHandle.IsEmpty()) {
// Texture hasn't been set yet; do something
} else {
info.GetReturnValue().Set(sprite->TextureHandle.Get(iso));
}
}
~Sprite() {
textureHandle.Reset();
}
}
(Not shown: the initialization code to register the getter/setter.)