我如何链接到Lua中的callback函数,以便在重新加载脚本时更新callback函数?

我正在使用LuaBind在我的游戏中实现Lua脚本,而我不清楚的其中一件事情就是重新加载活动脚本。

目前,使用LuaBind C ++类luabind::object ,我直接在使用它们的类中保存对Luacallback的引用。 然后,我可以使用该对象的luabind::call_function来调用来自C ++代码的Lua代码。

我还没有testing过,但我的假设是,如果我重新加载脚本,那么所有的函数将被重新定义,但是对旧函数的引用仍将以C ++持有的luabind::object的forms存在码。 我希望能够换出新的旧的而不用手动管理这个游戏中的每个脚本钩子。

如何最好地改变这个过程的工作?

我的第一个想法是不直接保存对函数的引用,而是可以保存函数名称,并在每次调用函数时都按名称获取函数。 我正在寻找更好的想法!

在我看来,你可能会错误地实现你的脚本接口。

如果你正在重新加载脚本,这通常意味着某种程度的拆解和重建与之交谈的镜像C ++对象。 例如,如果您有一个为实体运行AI的Lua脚本,则会有一些代表该AI的C ++对象。 该对象负责与Lua脚本进行通信(这样外部代码就不会知道Lua脚本甚至涉及到了)。

该对象需要被销毁,并用新加载的脚本重建。


让Lua做任何事情,而不必在C ++端破坏/重建/管理任何东西。

如果你想要Lua负责这个,那么这意味着Lua负责这个 。 拥有权利的同时也被赋予了重大的责任。 如果你想让Lua拥有权力,那么现在Lua有责任正确使用它。

如果Lua把一些“function”交给C ++,那么Lua脚本的责任就是确保当脚本改变时这个函数能够被正确和透明地更新。 在Lua中有几种方法可以做到这一点。 一种方法是构建一个简单的存根函数,它可以search一些全局注册器对象来调用实际的函数:

 local stubForDoStuff = function(...) return Registrar.DoStuff(...) end 

您甚至可以创建一个简单的存根生成器函数(find不是注册服务商的直接成员的东西需要更复杂):

 function MakeStub(stubName) return function(...) return Registrar[stubName](...) end end 

脚本更改时,只需更新Registrar的function即可。 有更复杂的方法来做这件事,通过给C ++代码表包含__call来追踪实际的函数或者其他东西。 但这是最简单,最明显的做法。

这种复杂性通常是为什么我给Lua这个权力。 我想把我的Lua脚本专注于做他们的实际工作,而不是更新函数和其他废话。 所以我给C ++负责管理Lua创建的对象加载和销毁。

我倾向于使用Lua脚本作为实例化C ++派生类的替代方法。 所以“重新加载一个脚本”意味着销毁一个对象并用新的replace它。