我有几个非常相似的功能:
v8::Handle<v8::Value> jsAudioPlay(const v8::Arguments &args) {
Audio *audio = static_cast<Audio*>(args.This()->GetPointerFromInternalField(0));
if (audio != NULL) audio->play(get(args[0], 0));
return args.This();
}
v8::Handle<v8::Value> jsAudioPause(const v8::Arguments &args) {
Audio *audio = static_cast<Audio*>(args.This()->GetPointerFromInternalField(0));
if (audio != NULL) audio->pause();
return args.This();
}
v8::Handle<v8::Value> jsAudioLoop(const v8::Arguments &args) {
Audio *audio = static_cast<Audio*>(args.This()->GetPointerFromInternalField(0));
if (audio != NULL) audio->loop(get(args[0], -1));
return args.This();
}
v8::Handle<v8::Value> jsAudioVolume(const v8::Arguments &args) {
Audio *audio = static_cast<Audio*>(args.This()->GetPointerFromInternalField(0));
if (audio != NULL) audio->volume(get(args[0], 1.0f));
return args.This();
}
我已经阅读了几个小时的C ++模板,我确信可以摆脱这些功能并用模板替换它们。我设想最终结果将是:
typedef Handle<Value> (*InvocationCallback)(const Arguments& args);
template <class T> InvocationCallback FunctionWrapper ...;
template <class T> FunctionWrapper FunctionReal ...;
template <class T, class arg1> FunctionWrapper FunctionReal ...;
template <class T, class arg1, class arg2> FunctionWrapper FunctionReal ...;
我意识到已经提出了类似的问题,但我找不到像上面这样的模板中的模板示例。
2012年7月21日更新
模板:
template <class T> v8::Handle<v8::Value> jsFunctionTemplate(const v8::Arguments &args) {
T *t = static_cast<T*>(args.This()->GetPointerFromInternalField(0));
if (t != NULL) t->volume(args[0]->NumberValue());
return args.This();
}
用法:
audio->PrototypeTemplate()->Set("Volume", v8::FunctionTemplate::New(&jsFunctionTemplate<Audio>));
现在,如果我只能弄明白如何将&Audio::volume
传递给模板,那么我将会开展业务。
2012年7月24日更新
请参阅我的回答,了解我是如何解决这个问题的。
答案 0 :(得分:6)
欢迎来到lambda的魔力。
template<typename F> v8::Handle<v8::Value> jsAudio(const v8::Arguments &args, F&& f) {
Audio *audio = static_cast<Audio*>(args.This()->GetPointerFromInternalField(0));
if (audio != NULL) f(audio, args);
return args.This();
}
int main() {
jsAudio(..., [&](Audio* audio, const v8::Arguments &args) {
audio->play(get(args[0], 0));
});
}
例如。
答案 1 :(得分:-1)
我的模板:
template <class T, class RT, RT(T::*f)()> v8::Handle<v8::Value> jsFunctionTemplate(const v8::Arguments &args) {
T *t = static_cast<T*>(args.This()->GetPointerFromInternalField(0));
if (t != NULL) (t->*f)();
return args.This();
}
template <class T, class RT, class A0, RT(T::*f)(A0)> v8::Handle<v8::Value> jsFunctionTemplate(const v8::Arguments &args) {
T *t = static_cast<T*>(args.This()->GetPointerFromInternalField(0));
if (t != NULL) (t->*f)(jsConvert<A0>(args[0]));
return args.This();
}
template <class T, class RT, class A0, class A1, RT(T::*f)(A0, A1)> v8::Handle<v8::Value> jsFunctionTemplate(const v8::Arguments &args) {
T *t = static_cast<T*>(args.This()->GetPointerFromInternalField(0));
if (t != NULL) (t->*f)(jsConvert<A0>(args[0]), jsConvert<A1>(args[1]));
return args.This();
}
用法:
audio->PrototypeTemplate()->Set("Play", v8::FunctionTemplate::New(&jsFunctionTemplate<Audio, Audio*, int, &Audio::play>));
audio->PrototypeTemplate()->Set("Pause", v8::FunctionTemplate::New(&jsFunctionTemplate<Audio, Audio*, &Audio::pause>));
audio->PrototypeTemplate()->Set("Loop", v8::FunctionTemplate::New(&jsFunctionTemplate<Audio, Audio*, int, &Audio::loop>));
audio->PrototypeTemplate()->Set("Volume", v8::FunctionTemplate::New(&jsFunctionTemplate<Audio, Audio*, float, &Audio::volume>));
现在我需要弄清楚最后两个步骤:可变数量的参数,并正确模板化jsConvert
以返回所需的类型<A0>
。