2011-10-18 2 views
2

메뉴 시스템에서는 메뉴 구성 요소 이벤트에 대한 콜백에 사용되는 루아 청크가있는 xml 메뉴를 정의합니다. 현재, 스크립트 콜백이 호출 될 때마다 우리는 매우 느린 lua_loadstring을 호출합니다. 메뉴를로드 할 때이 일이 한 번만 수행되도록하려면 노력하고있어.메뉴 시스템에 대한 루아 콜백 구현

//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에 대한 귀하의 주장입니다. 콜백 함수는 가변적 일 것으로 예상해야합니다. 그들은 ...을 매개 변수로 사용합니다. 그들은 그 값을 얻고 싶은 경우에, 그들은이 같은 지역 주민을 사용해야합니다

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

감사에 대한 :

local param1, param2 = ...; 

그러나 당신이 그 (것)들을 매개 변수의 목록을 지정할 수 있도록 주장하는 경우, 다음을 수행 할 수 있습니다 그걸 정리하고있어. 나는 "..."을 사용할 것이다. – brunoma