2011-10-18 3 views
2

メニューシステムでは、メニューコンポーネントイベントのコールバックに使用されるluaチャンクを使用してxmlのメニューを定義します。現在、スクリプトのコールバックが呼び出されるたびに、lua_loadstringが呼び出されますが、これはかなり遅いです。私はそれを作るようにしようとしている、これはメニューがロードされるときに一度しか起こらない。メニューシステムのルアコールバックの実装

私の最初に考えたのは、メニューコンポーネントごとのLuaのテーブルを維持するために、テーブルに新しいコールバック関数を追加するには、次の操作を実行することでした。

//create lua code that will assign a function to our table 
std::string callback = "temp." + callbackName + " = function (" + params + ")" + luaCode + "end"; 

//push table onto stack 
lua_rawgeti(L, LUA_REGISTRYINDEX, luaTableRef_); 

//pop table from stack and set it as value of global "temp" 
lua_setglobal(L, "temp"); 

//push new function onto stack 
int error = luaL_loadstring(L, callback.c_str()); 
if (error) 
{ 
    const char* errorMsg = lua_tostring(L, -1); 
    Dbg::Printf("error loading the script '%s' : %s\n", callbackName, errorMsg); 
    lua_pop(L,1); 
    return; 
} 

//call the lua code to insert the loaded function into the global temp table 
if (lua_pcall(L, 0, 0, 0)) 
{ 
    Dbg::Printf("luascript: error running the script '%s'\n", lua_tostring(L, -1)); 
    lua_pop(L, 1); 
} 

//table now has function in it 

これは一種の汚れたようです。一時的なグローバル変数を使用せずにlua_pcallを実行することなく、関数をluaチャンクから直接テーブルに割り当てることができるより良い方法はありますか?

答えて

3

テーブルに関数を配置する場合は、関数をテーブルに配置します。あなたのルアスタックフーは強くないようです。考慮するとstudying the manuala bit more closely

とにかく、あなたが持っている最大の問題は、あなたの主張がparamsだと思います。コールバック関数は、varadicであることが期待されます。彼らはパラメータとして...を取る。彼らはこれらの値を取得したい場合、彼らはこのように地元の人々を使用する必要があります。

local param1, param2 = ...; 

しかし、あなたがそれらをパラメータのリストを指定できるようにすることを主張する場合は、次の操作を行う可能性がありますため

std::string luaChunk = 
    //The ; is here instead of a \n so that the line numbering 
    //won't be broken by the addition of this code. 
    "local " + params + " = ...; " + 
    luaCode; 

lua_checkstack(L, 3); 
lua_rawgeti(L, LUA_REGISTRYINDEX, luaTableRef_); 
if(lua_isnil(L, -1)) 
{ 
    //Create the table if it doesn't already exist. 
    lua_newtable(L); 

    //Put it in the registry. 
    lua_rawseti(L, LUA_REGISTRYINDEX, luaTableRef_); 

    //Get it back, since setting it popped it. 
    lua_rawgeti(L, LUA_REGISTRYINDEX, luaTableRef_); 
} 

//The table is on the stack. Now put the key on the stack. 
lua_pushlstring(L, callbackName.c_str(), callbackName.size()); 

//Load up our function. 
int error = luaL_loadbuffer(L, luaChunk.c_str(), luaChunk.size(), 
    callbackName.c_str()); 
if(error) 
{ 
    const char* errorMsg = lua_tostring(L, -1); 
    Dbg::Printf("error loading the script '%s' : %s\n", callbackName, errorMsg); 
    //Pop the function name and the table. 
    lua_pop(L, 2); 
    return; 
} 

//Put the function in the table. 
lua_settable(L, -3); 

//Remove the table from the stack. 
lua_pop(L, 1); 
+0

感謝それをクリアする。私は "..."を使用します – brunoma