LuA嵌入C++中,能够具有持久的局部变量吗?如果没有,有没有脚本语言可以做到呢?

2024-09-30 02:26:21 发布

您现在位置:Python中文网/ 问答频道 /正文

我已经在LuabDin中嵌入了我的C++应用程序中的Lua。我需要在多个运行中保持变量,运行相同文件名的其他对象无法访问这些变量。在

例如:假设我有一个名为NPC的类。NPC包含一个字符串,即它们运行的脚本的名称。创建NPC时,将创建一个名为Health的变量。当一个NPC被击中时,他们失去5点生命值。在Lua中,脚本应该是这样的:

local health = 10

function onHit()
    health = health - 5
end

我遇到的问题是每个运行此脚本的NPC没有自己的运行状况实例。例如,假设我创建NPC A,并从其运行状况中减去5。然后,我创建NPC B。因为它将health重置回10,如果我告诉NPC A打印health,它会返回10,即使应该是5。在

如果每个对象都有一个不同的Lua实例,那么它就可以这样工作了,但是在这种情况下,我一次只能得到几百个实例,这不是一件好事。在

在Lua中有没有一种方法可以让变量像这样工作?如果没有,有没有一种脚本语言可以像这样高效地工作?在

作为参考,下面是我正在测试的代码:

卢阿:

^{pr2}$

C++:

class NPC
{
public:
   NPC(lua_State* inState);
   void onHit();

   const char* behavior;
   lua_State* luaState;  
};

NPC::NPC(lua_State* inState)
{
   luaState = inState;
   behavior = "testBehavior.lua";
   luaL_dofile(luaState, behavior);
}

void NPC::onHit()
{    
   luaL_loadfile(luaState, behavior); 
   luabind::call_function<int>(luaState, "onHit");
}

void print_out(int number) {
   cout << "Health : " << number << endl;
}

int main() 
{
   lua_State *myLuaState = luaL_newstate();
   luabind::open(myLuaState);

   luabind::module(myLuaState) [
      luabind::def("print_out", print_out)
   ];

   NPC test(myLuaState);
   NPC test2(myLuaState);
   test.onHit();
   test2.onHit();
   test.onHit();

   lua_close(myLuaState);
}

Tags: 实例脚本stateluahealthbehaviorvoidnpc
3条回答

For reference, here is the code I am testing:

这里有很多错误。你一直在运行Lua脚本;这就是为什么它总是被重置的原因。另一个问题是您的脚本正在创建一个全局函数,因此每次运行它时,都会得到一个新的全局函数,它使用一个newlocal变量。在

停止使用全局变量。每个NPC都是一个独立的对象。因此,它需要有对象特定的数据。在

behavior = "testBehavior.lua";
luaL_dofile(luaState, behavior);

这不会创建任何特定于对象的数据。它只是运行一个Lua脚本并完全丢弃所有返回值。除非该脚本实际全局存储特定于对象的内容,否则不会创建任何特定于对象的数据。在

Lua脚本需要做的是返回一个表,该表包含脚本需要的对象特定数据。脚本应该如下所示:

^{pr2}$ <>你的C++代码需要在NPC类中使用EM>Stury表,然后使用它。这很容易通过Luabind调用完成。您的构造函数应该如下所示:

NPC::NPC(lua_State* L)
{
    behavior = "testBehavior.lua";
    int err = luaL_loadfile(L, behavior);
    //Handle compiler errors. DON'T FORGET THIS!
    luabind::object func = luabind::from_stack(L, -1);
    lua_pop(L, 1);
    luaData = func(); //Catch exceptions for runtime errors
    lua_pop(L, 1);
}

您的类中没有lua_State* luaState,而是在类中保留一个luabind::object luaData。如果您需要lua_State,您可以随时从luabind::object获得一个。在

要调用Lua onHit函数,只需使用luabind::object接口:

void NPC::onHit()
{    
    luaData["onHit"](luaData);
}

请注意,不要重新运行Lua脚本。这就是你的问题所在。你只是在调用一个Lua脚本已经定义的函数。在

现在,您似乎希望使用局部变量而不是表内存。这很好,它将阻止C++代码直接访问^ {< CD8}}(不是没有欺骗)。{{cd6>我们必须简化代码。你可以在Lua中用这个:

local health = 10
local NPC = {}

function NPC.onHit()
  health = health - 5
end

return NPC

{NPC>不需要改变构造函数。在

void NPC::onHit()
{    
    luaData["onHit"]();
}

如果你一意孤行地使用全局变量,你可以和环境玩游戏,但这相当复杂。它将在各个脚本调用之间提供有保证的隔离。在

你可以看看卢娅的closures。它看起来像这样:

function healthPoints()
    local health = 10
    return function()
        health = health - 5
        return health
    end
end

结果是每个人大都有自己的功能。每次命中它们时,只需调用onHit函数。你应该这样使用它:

^{pr2}$

您可以添加如下参数:

function healthPoints(hp)
    local health = hp
    return function(dmg)
        health = health - dmg
        return health
    end
end

npc1.onHit = healthPoints(100)
npc1.onHit(-12)

我觉得值得一试。在

我不知道卢娅的事,所以我就不谈这个了。这个问题也标记为python。为此,我认为可以序列化所有“重要”的局部变量。在

或者,您可以查看我的技巧,在这里保存一个名为PyDON的字典:http://code.activestate.com/recipes/577508-pydon-an-alternative-to-xml/

同时检查一下这个,我认为这会更有帮助:How do I serialize a Python dictionary into a string, and then back to a dictionary?

相关问题 更多 >

    热门问题