2013-03-20 11 views
5

としてラップされたオブジェクトを使用する関数...私はNode.jsの中で、次のような何かをしたいと思いますNode.jsの中で引数およびV8

するvar A =新しいA()を呼び出します。 var b = new B();

// onTick引数として

a.onTick =関数(bInst){ ....}

a.loopを()Bのインスタンスを取る関数であるべきです。

を意味します。Aにはループ内で呼び出される関数である "onTick"というプロパティがあります。ここでAとBはC++包まれた関数として定義されていることを 注意は、私がしようとしていますこれは、あなたが

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's 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); 
} 

プロパティのゲッターとセッターを設定する方法であると信じていた定義

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

ですdoTick(これはClass Bのインスタンスを取る)を設定し、新しいBClassを導入する関数の中にラップして関数を実行します。私は変換する必要があるとき私はインスタンス化機能を必要とすると信じて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の両方が別のC++クラスを使用し、プロパティ(wrappedBInst、wrappedAInst)としてインスタンスを保存するための定義をHERESとにかく

WrappedBClassのインスタンスをBClassに挿入します。

WrappedBClassは特別なことをしませんが、WrappedAClassはループとonTick関数を持つクラスを継承し、onTick関数はJavascript関数を呼び出す必要があります。WrappedAClassでは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); 
    } 
    } 
} 

だから私は、私はループに入るとonTick機能として、JavaScriptの機能を利用することができると思います唯一の方法は)最初のC++関数にJavaScript関数をラップしてからsetTickFuncを(呼び出すことによって、その機能を設定することです。私はこれについて正しいことをしていますか?

私は最大のものが、最も可能性が高いこれです、私の明白な過ちを許してまともなプログラマだけど、つい最近C++で作業を開始しました:

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's 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)からの変数の値を保持する無名関数。私はここでクロージャーが有効であるとは思わない、キーはOnTick関数として設定する必要があるので、この関数は1つの引数(WrappedClassB * wcb)しか持たないということが重要です。

答えて

0

C++で匿名関数を作成する必要はありません。たぶんこのようにWrappedAClassを定義することができます。 SetOnTick機能へ

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

注意し、2番目のパラメータはタイプLocal<Value>ないLocal<Function>です。 C++は、jsと異なり、静的型付き言語です。たぶんあなたはこれを定義することができます

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)); 
} 
関連する問題