4

たとえば、C++で次のように定義されたキー処理インターフェイスがあるとします。

class KeyBoardHandler 
{ 
public:
    virtual onKeyPressed(const KeyEventArgs& e);
    virtual onKeyReleased(const KeyEventArgs& e);
}

ここで、これをLuaに拡張して、LuaがKeyboardHandlerを利用してスクリプトに登録できるようにします。

これがこれまでのプロトタイプです。

class ScriptKeyboardHandler : public KeyboardHandler
{
public:
    ... previous methods omitted
    static void createFromScript(lua_State* L);
    bool createCppData();

private:
    ScriptKeyBoardHandler(lua_State* L);

    int mSelf;
    int mKeyPressFunc;
    int mKeyReleaseFunc;
    lua_State* mpLuaState;
}

今、私は実装が次のようになることを知っています:

ScriptKeyboardHandler::ScriptKeyboardHandler(lua_State* L) :
    mpState(L)
{ }

ScriptKeyboardHandler::onKeyPressed(...) { 
     // check if mKeyPressFunc is a function
     // call it, passing in mself, and the event args as params
} 

// On Key Release omitted because being similar to the key pressed

ScriptKeyboardHandler::createFromScript(lua_State* L)
{
    auto scriptKeyboardHandler = new ScriptKeyboardHandler(L);
    if (scriptKeyboardHandler->createCppData())
    {
        // set the light user data and return a reference to ourself (mSelf)
    }
}

ScriptKeyboardHandler::createCppData() 
{
    // get the constructor data (second param) and find the keyPressed and keyReleased function, store those for later usage
    // any other data within the constructor data will apply to object
}

-- Syntax of the lua code
MyScriptHandler = { }
MyScriptHandler.__index = MyScriptHandler

MyScriptHandler.onKeyPress = function(self, args)
end

handler = createScriptHandler(handler, MyScriptHandler)
registerKeyHandler(handler)

テーブル内で引数として渡された関数を見つける方法がわかりません。

私はこれを正しくやっていますか?toluaは仮想クラスを簡単にサポートしておらず、とにかくスクリプトから派生できるものではないので、私がそうだといいのですが、それはお尻の痛みでした。

他の関数については心配していません。Cコードからこれらの変数(キーを押す関数など)を見つけるにはどうすればよいですか。

4

1 に答える 1

2

これは、私の実装がonKeyPressedどのように見えるかを大まかに示しています。

void ScriptKeyboardHandler::onKeyPressed()
{
   //Get the table corresponding to this object from the C registry
   lua_pushlightuserdata(mpLuaState, this);
   lua_gettable(mpLuaState,LUA_REGISTRYINDEX);

   //Now get the function to call from the object
   lua_pushstring(mpLuaState,"onKeyPress");
   lua_gettable(mpLuaState,-2);

   //Now call the function 
   lua_pushvalue(mpLuaState, -2 ); // Duplicate the self table as first argument
   //TODO: Add the other arguments
   lua_pcall(mpLuaState, 1, 0, 0 ); // TODO: You'll need some error checking here and change the 1 to represent the number of args.

   lua_pop(mpLuaState,1); //Clean up the stack

}

ただし、コンストラクターを更新して、ハンドラーを表す lua オブジェクトをレジストリーに格納する必要もあります。

于 2012-08-19T03:36:59.263 に答える