4

我对 Lua 还很陌生,我一直在努力尝试在我正在组装的游戏引擎中实现 Lua 脚本以实现逻辑。到目前为止,我在启动 Lua 并通过引擎运行时没有遇到任何问题,而且我能够从 C 调用 Lua 函数,从 Lua 调用 C 函数。

引擎现在的工作方式,每个 Object 类都包含一组变量,引擎可以快速迭代这些变量以绘制或处理物理。虽然游戏对象都需要访问和操作这些变量才能让游戏引擎本身看到任何变化,但它们可以自由创建自己的变量,Lua 在这方面非常灵活,所以我不预见任何问题。

无论如何,目前游戏引擎方面的东西都位于 C 领域,出于性能原因,我真的希望他们留在那里。所以在一个理想的世界里,当产生一个新的游戏对象时,我需要能够作为 Lua 对象的基类的一部分,赋予 Lua 对这个标准变量集的读/写访问权限,然后它的游戏逻辑可以继续狂奔。

到目前为止,我保留了两个单独的对象表——Lua 生成了一个新的游戏对象,它将自身添加到一个数字索引的全局对象表中,然后继续调用一个 C++ 函数,该函数创建一个新的 GameObject 类和向类注册 Lua 索引(一个 int)。到目前为止一切顺利,C++ 函数现在可以看到 Lua 对象并使用 dostring 在 Lua 领域轻松执行操作或调用函数。

我现在需要做的是获取 C++ 变量,它是 GameObject 类的一部分,并将它们暴露给 Lua,这就是 google 让我失望的地方。我在这里遇到了一个非常好的方法,它详细说明了使用标签的过程,但我读过这种方法已被弃用,有利于元表。

实现这一目标的理想方法是什么?学习如何使用 libBind 或其他等效方法传递类定义是否值得,或者是否有一种简单的方法可以将每个变量(一次,在生成时)注册到全局 lua 对象?从 Lua 5.1.4 开始,“当前”的最佳方法是什么?

4

1 回答 1

6

一种方法是使用

  • 指向 C++ 变量的 lightuserdata
  • 使用 lightuserdata 访问 C++ 变量的 C 函数
  • 将 lightuserdata 保留为 C 函数的上值,因此一个函数足以满足所有变量
  • 使用函数的参数数量在获取和设置变量之间进行选择

例如:

int game_state_var_accessor (lua_State *L)
{
    int *p = lua_topointer(L, lua_upvalueindex(1));
    if (lua_gettop(L) == 0)
    {   // stack empty, so get
        lua_pushinteger(L, *p);
        return 1;
    }
    else
    {   // arg provided, so set
        *p = lua_tointeger(L,1);
        return 0;
    }
}

当您创建一个新的游戏状态时,您可以使用以下方法为每个变量创建访问器:

lua_pushlightuserdata(L, (int *)p); // where p points to your variable
lua_pushcclosure(L, game_state_var_accessor, 1);

访问器现在在堆栈上,可以绑定到全局名称或 Lua 类中的方法名称。如果你的 Lua 类表在索引的堆栈上,t这将是:

lua_setfield(L, t, "name_of_accessor");
于 2010-04-21T03:08:22.677 回答