Calling a function that uses a wrapped object as an argument in Node.js and v8

I would like to do something like the following in node.js ...

var a = new A (); var b = new B ();

// onTick must be a function that takes an instance of B as an argument

a.onTick = function (bInst) {....}

a.loop ();

means that A has the "onTick" property, which is a function called inside the loop. Note that A and B are defined as wrapped C ++ functions, here are the definitions

void AClass::Init(Handle<Object> target) {
  Local<FunctionTemplate> tpl = FunctionTemplate::New(New);
  tpl->SetClassName(String::NewSymbol("A"));
  tpl->InstanceTemplate()->SetInternalFieldCount(1);
  tpl->PrototypeTemplate()->Set(String::NewSymbol("tick"),
      FunctionTemplate::New(Tick)->GetFunction());
  tpl->PrototypeTemplate()->Set(String::NewSymbol("loop"),
  FunctionTemplate::New(Loop)->GetFunction());

  constructor = Persistent<Function>::New(tpl->GetFunction());
  constructor->InstanceTemplate()->SetAccessor(String::New("onTick"), GetOnTick, SetOnTick);
  target->Set(String::NewSymbol("A"), constructor);
}

Handle<Value> AClass::New(const v8::Arguments &args) {
  HandleScope scope;
  AClass* acls = new AClass();
  WrappedAClass* wrappedA = new WrappedAClass();
  acls->wrappedAInst_ = wrappedA;
  window->Wrap(args.This());
  return args.This();
}
Handle<Value> AClass::Loop(const Arguments &args) {
  HandleScope scope;
  AClass* acls = ObjectWrap::Unwrap<AClass>(args.This());
  acls->wrappedInst_->loop();
  return scope.Close(Undefined());
}

I believe this is how you set the getter and setter properties

Handle<Function> GetOnTick(Local<String> property, const AccessorInfo& info) {
  AClass* acls = ObjectWrap::Unwrap<AClass>(info.Holder());
  return acls->onTick_;
}

void SetOnTick(Local<String> property, Local<Function> value, const AccessorInfo& info) {
  AClass* acls = ObjectWrap::Unwrap<AClass>(info.Holder());

  acls->onTick_ = Persistent<Function>::New(value);
  //Here where I know I'm doing it wrong
  void func(WrappedClassB* wcb) { 
    const unsigned argc = 1;
    Local<Value> argv[argc] = 
      { Local<Value>::New(BClass::Instantiate(wcb)) };
    acls->onTick_->Call(Context::GetCurrent()->Global(), argc, argv);   
  }
  acls->wrappedAInst_->setTickFunc(func);
}

What I'm trying to do is take the function from the onTick installation (which takes an instance of class B) and wrap it inside the function that initializes the new BClass.

Anyway, this is the definition for BClass

Persistent<Function> BClass::constructor;
BClass::BClass() {
}
BClass::~BClass() {
}

void BClass::Init(Handle<Object> target) {
  Local<FunctionTemplate> tpl = FunctionTemplate::New(New);
  tpl->SetClassName(String::NewSymbol("B"));
  tpl->InstanceTemplate()->SetInternalFieldCount(1);
  constructor = Persistent<Function>::New(tpl->GetFunction());
  target->Set(String::NewSymbol("B"), constructor);
}

Handle<Value> BClass::New(const v8::Arguments &args) {
  HandleScope scope;
  BClass* bcls = new BClass();
  bcls->Wrap(args.This());
  WrappedBClass* wrappedB = new WrappedBClass();
  bcls->wrappedBInst_ = wrappedB;
  return args.This();
}
Handle<Value> BClass::Instantiate(const WrappedBClass &wbc) {
  HandleScope scope;
//I know the following is wrong but it shows what I am trying to do
  BClass* bcls = new BClass();
  bcls->wrappedBInst_ = wbc;
  return scope.Close(Local<v8::Value>::New(bcls));
}

AClass BClass ++ (wrappedBInst, wrappedAInst). , Instantiate, WrappedBClass BClass.

WrappedBClass , WrappedAClass , onTick, onTick - , Javascript, WrappedAClass overrode onTick ​​ setTickFunc.

class WrappedAClass : public InheritedClass{
public:
  void setTickFunc(void (*func)(WrappedBClass*)){
    tickFunc = func;
  }
protected:
  void tickFunc;
  virtual void onTick(WrappedBClass* wbc){
    if(tickFunc){
      tickFunc(wbc);
    }
  }
}

, , , javascript onTick, - javascript ++, , setTickFunc(). ?

, ++, , , , :

void SetOnTick(Local<String> property, Local<Function> value, const AccessorInfo& info) {
      AClass* acls = ObjectWrap::Unwrap<AClass>(info.Holder());

      acls->onTick_ = Persistent<Function>::New(value);
      //Here where I know I'm doing it wrong
      void func(WrappedClassB* wcb) { 
        const unsigned argc = 1;
        Local<Value> argv[argc] = 
          { Local<Value>::New(BClass::Instantiate(wcb)) };
        acls->onTick_->Call(Context::GetCurrent()->Global(), argc, argv);   
      }
      acls->wrappedAInst_->setTickFunc(func);
    }

, , (acls). , , , (WrappedClassB * wcb), OnTick.

+5
1

++. , WrappedAClass .

class WrappedAClass : public InheritedClass{
public:
  void setTickFunc(Local<Function> jsFn){
    HandleScope scope;
    jsTickFunc = Persistent<Function>::New(jsTickFunc);
  }
protected:
  Persistent<Function> jsTickFunc;
  virtual void onTick(WrappedBClass* wbc){
    HandleScope scope;
    if(jsTickFunc.IsEmpty())
        return;
    const unsigned argc = 1;
    Local<Value> argv[argc] = 
    { Local<Value>::New(BClass::Instantiate(wcb)) };
    jsTickFunc->Call(Context::GetCurrent()->Global(), argc, argv);  
  }
}

SetOnTick, Local<Value> not Local<Function>. ++, js, . , SetOnTick Setter, :

void SetOnTick(Local<String> property, Local<Value> value, const AccessorInfo& info){
  AClass* acls = ObjectWrap::Unwrap<AClass>(info.Holder());
  if (value->IsFunction())
    acls->wrappedAInst_->setTickFunc(Local<Function>::Cast(value));
}
0

All Articles