我願做這樣的事情在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函數。