我将如何在 C++ 中共享变量?与 Lua 一起上课?

发布于 2024-08-29 18:23:00 字数 903 浏览 5 评论 0原文

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

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

不管怎样,目前游戏引擎方面的事情都在 C 区,出于性能原因我真的希望它们留在那里。因此,在理想的情况下,当生成新的游戏对象时,我需要能够为 Lua 提供对这个标准变量集的读/写访问权限,作为 Lua 对象基类的一部分,然后其游戏逻辑可以继续进行狂奔。

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

我现在需要做的是获取 C++ 变量(GameObject 类的一部分)并将它们暴露给 Lua,而这正是 google 失败的地方。我遇到了一个非常好的方法这里详细介绍了使用标签的过程,但我读到该方法已被弃用,取而代之的是元表。

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

I'm fairly new to Lua, I've been working on trying to implement Lua scripting for logic in a Game Engine I'm putting together. I've had no trouble so far getting Lua up and running through the engine, and I'm able to call Lua functions from C and C functions from Lua.

The way the engine works now, each Object class contains a set of variables that the engine can quickly iterate over to draw or process for physics. While game objects all need to access and manipulate these variables in order for the Game Engine itself to see any changes, they are free to create their own variables, a Lua is exceedingly flexible about this so I don't forsee any issues.

Anyway, currently the Game Engine side of things are sitting in C land, and I really want them to stay there for performance reasons. So in an ideal world, when spawning a new game object, I'd need to be able to give Lua read/write access to this standard set of variables as part of the Lua object's base class, which its game logic could then proceed to run wild with.

So far, I'm keeping two separate tables of objects in place-- Lua spawns a new game object which adds itself to a numerically indexed global table of objects, and then proceeds to call a C++ function, which creates a new GameObject class and registers the Lua index (an int) with the class. So far so good, C++ functions can now see the Lua object and easily perform operations or call functions in Lua land using dostring.

What I need to do now is take the C++ variables, part of the GameObject class, and expose them to Lua, and this is where google is failing me. I've encountered a very nice method here which details the process using tags, but I've read that this method is deprecated in favor of metatables.

What is the ideal way to accomplish this? Is it worth the hassle of learning how to pass class definitions around using libBind or some equivalent method, or is there a simple way I can just register each variable (once, at spawn time) with the global lua object? What's the "current" best way to do this, as of Lua 5.1.4?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

寄意 2024-09-05 18:23:00

一种方法是使用

  • lightuserdata 指向 C++ 变量,
  • 一个 C 函数使用 lightuserdata 来访问 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 类表位于堆栈上的索引 t 处,则为:

lua_setfield(L, t, "name_of_accessor");

One approach is to use

  • a lightuserdata pointing to the C++ variable
  • a C function to access the C++ variable using the lightuserdata
  • keep the lightuserdata as an upvalue of the C function so one function suffices for all variables
  • use the number of arguments to the function to select between getting and setting the variable

For example:

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

When you make a new game state you can create accessors for each variable using:

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

The accessor is now on the stack and can be bound to a global name, or to the name of a method in a Lua class. If your Lua class table is on the stack at index t this would be:

lua_setfield(L, t, "name_of_accessor");
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文