c++ - 为菜单系统实现 lua 回调

标签 c++ lua

在我们的菜单系统中,我们在 xml 中定义菜单,并使用用于菜单组件事件回调的 lua block 。目前,每次调用脚本回调时,我们都会调用 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 block 将函数分配给表,而不必使用临时全局变量并运行 lua_pcall?

最佳答案

如果要将函数放入表中,则将函数放入表中。看来你的Lua-stack-fu不强;考虑studying the manual a bit more closely .

无论如何,我想说你遇到的最大问题是你对params的坚持。回调函数应该是可变的;他们将 ... 作为参数。如果他们想获取这些值,他们应该使用这样的局部变量:

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

关于c++ - 为菜单系统实现 lua 回调,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7812801/

相关文章:

c - 在 C 应用程序中隐藏 Lua 源代码

lua - 清理数据表单场景

lua - 如何将表名分配给变量?

c++ - 如果我打开文件后有人覆盖该文件会怎样?

c++ - 令人困惑的声明和初始化程序

c++ - 像 int (x) 这样的声明的目的是什么?或 int (x) = 10;

lua - 如何在基于 nvim lua 的配置中排除文件或目录?

c++ - block 级使用LRU方法

c++ - 使用 stringstream,我如何解析这些字符串?

lua - 在两个表中调用函数给出相同的输出