2013-03-20 10 views
5

मैं Node.js में निम्नलिखित की तरह कुछ करना चाहते हैं के रूप में एक लिपटे वस्तु का उपयोग करता है ...एक समारोह Node.js में एक तर्क और v8

वर एक = नए ए() कॉलिंग; var बी = नया बी();

// onTick एक समारोह है कि एक तर्क के रूप

a.onTick = समारोह (bInst) { .... }

a.loop() बी का एक उदाहरण ले जाता है होना चाहिए;

जिसका अर्थ है कि ए में एक संपत्ति "ऑनटिक" है जो एक ऐसा फ़ंक्शन है जिसे लूप के अंदर बुलाया जाता है। ध्यान दें कि ए और बी 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); 
} 

की सेटर क्या मैं कोशिश कर रहा हूँ सेट कार्य को टिक पर सेट करने से लिया जाता है (जो क्लास बी का उदाहरण लेता है) और इसे एक ऐसे फ़ंक्शन के अंदर लपेटता है जो एक नए बीसीएलएएस को सक्रिय करता है।

फिर भी यहाँ 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) मेरा मानना ​​है कि मैं के लिए दृष्टांत समारोह की जरूरत है जब मैं बदलने की आवश्यकता एक बीसीएलएएस में लपेटाबीसीलास का एक उदाहरण।

WrappedBClass कुछ भी विशेष नहीं नहीं करता है लेकिन WrappedAClass एक वर्ग है जो एक पाश और एक onTick कार्य है इनहेरिट करती है, और onTick समारोह, जहां मैं अपने जावास्क्रिप्ट समारोह कॉल करने की आवश्यकता है, इसलिए WrappedAClass में मैं onTick overrode और एक 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 समारोह पहले एक C++ समारोह में जावास्क्रिप्ट समारोह रैप करने के लिए और फिर 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'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); 
    } 

मैं अभी भी एक बनाने के लिए कैसे यह पता लगाने की कोशिश कर रहा हूँ अज्ञात फ़ंक्शन जो बाहरी (एसीएल) से एक चर के मान पर रखता है। मुझे नहीं लगता कि क्लोजर यहां मान्य हैं, कुंजी यह है कि इस फ़ंक्शन में केवल एक तर्क है (लपेटा क्लासबी * wcb) क्योंकि इसे ऑनटिक फ़ंक्शन के रूप में सेट करने की आवश्यकता है।

उत्तर

0

आपको सी ++ में अनाम कार्य नहीं करना है। शायद आप इस तरह अपने 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); 
    } 
} 

वेतन ध्यान, दूसरा पैरामीटर प्रकार Local<Value> नहीं Local<Function> की है। सी ++, जेएस की तरह नहीं, स्थिर टाइप की गई भाषा है।शायद आप अपने 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)); 
} 
संबंधित मुद्दे