mi piacerebbe fare qualcosa di simile al seguente in node.js ...Chiamata di una funzione che utilizza un oggetto avvolto come un argomento in Node.js e v8
var a = new A(); var b = new B();
// onTick dovrebbe essere una funzione che accetta un'istanza di B come argomento
a.onTick = funzione (Binst) { .... }
a.loop();
significa che A ha una proprietà "onTick" che è una funzione che viene chiamata all'interno del ciclo. Nota che A e B sono definiti come C++ funzioni avvolti, ecco le definizioni
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());
}
Credo che questo sia il modo di impostare il getter e setter di una proprietà
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);
}
Quello che sto cercando di do è prendere la funzione dall'impostazione onTick (che prende un'istanza di Class B) e avvolgerla in una funzione che instace un nuovo BClass.
Comunque heres la definizione per 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));
}
Sia AClass e BClass utilizzare un'altra classe C++ e salvare l'istanza come una proprietà (wrappedBInst, wrappedAInst) credo che mi serve la funzione Instantiate per quando ho bisogno di convertire un'istanza di WrappedBClass in una BClass.
WrappedBClass non fa nulla di speciale ma WrappedAClass eredita una classe che ha un loop e una funzione onTick, e la funzione onTick è dove devo chiamare la mia funzione Javascript, quindi in WrappedAClass ho eseguito overTick e aggiunto una funzione 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);
}
}
}
Quindi l'unico modo penso che posso entrare nel loop e utilizzare una funzione JavaScript come la funzione onTick è quello di avvolgere prima la funzione javascript in un C++ funzione e quindi impostare tale funzione chiamando setTickFunc() . Sto andando su questo nel modo giusto?
Sono un programmatore decente, ma solo di recente ha iniziato a lavorare con C++ in modo scusare i miei errori evidenti, il più grande è più probabile che questo:
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);
}
Sto ancora cercando di capire come creare un funzione anonima che trattiene il valore di una variabile dall'esterno (acls). Non penso che le chiusure siano valide qui, la chiave è che questa funzione ha solo un argomento (WrappedClassB * wcb) perché deve essere impostato come funzione OnTick.