2013-03-20 51 views
5

我願做這樣的事情在node.js的以下功能...調用使用一個包裝的對象,如Node.js的參數和V8

VAR一個=新的A(); var b = new B();

// onTick應該是一個函數,它接受B的實例作爲參數

a.onTick =函數(bInst){ .... }

a.loop();

這意味着A有一個屬性「onTick」,它是一個在循環內被調用的函數。 需要注意的是A和B定義爲C++包裹的功能,這裏有定義

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

我相信這是你如何設置屬性

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

的getter和setter什麼我想do是通過設置onTick(它接受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)我相信我需要的實例化功能,當我需要轉換一個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); 
    } 
    } 
} 

所以唯一的辦法我想我可以進入循環和使用JavaScript函數作爲onTick功能是首套JavaScript函數到C++函數,然後通過調用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)的值。我不認爲閉包在這裏是有效的,關鍵是這個函數只有一個參數(WrappedClassB * wcb),因爲它需要設置爲OnTick函數。

回答

0

您不必在C++中創建匿名函數。也許你可以像這樣定義你的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>Local<Function>類型。 C++,不像js,是靜態類型語言。也許你可以定義你的SetOnTick安裝員舔這個:

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)); 
} 
相關問題