线程局部变量

我正在开发一个多人游戏的服务器,在这个游戏中我想为每个玩家提供一个独立的 Lua 线程,填充一些唯一的全局变量,例如玩家的名字和 id。基本上,我想能够在实际编写的脚本中不需要任何其他代码的情况下,从主机应用程序中设置线程本地变量,这样我就可以在调用函数时将其用于整个游戏会话的持续时间。这是否可以使用 Lua 实现?

// 以下的示例代码展示了如何实现该功能

var L = Lua.LuaLNewState();
Lua.LuaRegister(L, "print", WriteLine);
dostring(L, "print('hello, world')", null);

var x = Lua.LuaNewThread(L);
Lua.LuaPushLiteral(x, "charId");
Lua.LuaPushNumber(x, 123);
Lua.LuaRawSet(x, Lua.LUA_GLOBALSINDEX);
dostring(x, "print('x1 '..charId)", null); // 调用使用 charId 的函数

var y = Lua.LuaNewThread(L);
Lua.LuaPushLiteral(y, "charId");
Lua.LuaPushNumber(y, 456);
Lua.LuaRawSet(y, Lua.LUA_GLOBALSINDEX);
dostring(y, "print('y1 '..charId)", null); // 调用使用 charId 的函数

dostring(x, "print('x2 '..charId)", null); // 我想这里依然输出 123

更新:我的应用程序是多线程的,多个玩家可以同时运行脚本。我理解的 Lua 函数环境的设置方式是修改全局环境,这在我的情况下无法工作。

点赞
用户5240636
用户5240636

你是否正在使用现有的游戏引擎?如果是的话,那么使用现有的库可能是值得的。例如,如果使用LÖVE2D,你可以使用像这样的这样的

您可以使用setfenv_ENV(取决于Lua版本)创建单独的环境,并在其中选择性地使用协程

2015-08-29 14:16:44
用户1171898
用户1171898

我找到了另一种实现这个的方法,这种方法对我来说感觉不太“hacky”。Lua有一个叫做LUAI_EXTRASPACE的常量,它用于在Lua状态之前添加指定数量的字节。我现在使用一个普通的C Lua库来编译自己,我将该常量更改为4,以在实际的Lua状态结构前面腾出空间,以保存引用应用程序中需要的对象,在函数中需要时可以查询。

存储

var NL = Lua.lua_newthread(L);
unsafe
{
    var ptr = (int*)NL.ToPointer();
    ptr -= 8;
    *ptr = index;
}
return NL;

检索

var index = 0;
unsafe
{
    var ptr = (int*)L.ToPointer();
    ptr -= 4;
    index = *ptr;
}
var obj = objects[index];

虽然这不能让我自由地推送变量,但我可以轻松编写使用存储的整数的函数,从数组中获取对象,并将值传递给Lua。或者,如果只需要一些特定变量,也可以增加更多的空间。

由于这是每个Lua状态独立的,每个拥有自己线程的玩家都可以拥有自己的变量。

2015-08-31 00:56:40