1

私はいくつかの非常によく似た機能を持っています:

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 日の更新

これをどのように解決したかについては、私の回答を参照してください。

4

2 に答える 2

6

ラムダの魔法へようこそ。

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

例えば。

于 2012-07-18T19:31:26.757 に答える
-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>));

ここで、最後の 2 つのステップを理解する必要があります。可変数の引数とjsConvert、目的の型を返すための適切なテンプレート化<A0>です。

于 2012-07-24T16:34:51.640 に答える