在Nan :: ObjectWrap C ++类中存储JavaScript实例的正确方法

时间:2018-12-10 15:22:22

标签: javascript c++ node.js node.js-addon node.js-nan

假设我有两个用C ++开发的类,但是使用Nan NodeJS本机模块公开。例如,一个“ Sprite”和“ Texture”类。

在JavaScript中,我希望Sprite可以将Texture存储为另一个属性:

// 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);

在C ++方面,Sprite的“ texture”属性将是用于存储或检索Texture的Getter / Setter。但问题是,在内部(从提供的v8 :: Local中)存储Texture实例的正确方法是什么?就像,我需要怎么做才能将其注册为Sprite的“所有者”,并使其不像上面的示例中那样获得GC认证?

1 个答案:

答案 0 :(得分:1)

您可以将Persistent句柄作为存储Texture实例的Sprite类的成员。 Sprite析构函数需要重置手柄以避免泄漏。

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();
  }
}

(未显示:用于注册getter / setter的初始化代码。)