我有一个 C++ 回调/仿函数系统的脚本,它可以使用字符串和/或变体调用任何“注册的”C++ 函数。
//REMOVED ERROR CHECKS AND ERRONEOUS STUFF FOR THIS POST
int LuaGameObject::LuaCallFunction( lua_State *luaState )
{
if ( lua_isuserdata( luaState, 1 ) == 1 )
{
int nArgs = lua_gettop( luaState );
//Get GameObject
OGameObject* pGameObject = static_cast<OGameObject*>(lua_touserdata( luaState, 1 ));
if ( pGameObject )
{
//Get FunctionName
const char* functionNameString = lua_tostring( luaState, 2 );
//Get Args
std::vector<OVariant> args;
for ( int i = 3; i <= nArgs; ++i )
{
OVariant variant;
variant.SetFromLua( luaState, i );
args.push_back( variant );
}
//Call it!
CallGameObjectFunction( luaState, pGameObject, functionNameString, args );
return 1;
}
}
return 0;
}
OVariant LuaGameObject::ExecuteLua()
{
lua_State *lState = luaL_newstate();
luaL_openlibs( lState );
lua_register( lState, "Call", LuaCallFunction );
luaL_loadstring( lState, m_pScript );
//now run it
lua_pcall( lState, 0, 1, 0 );
//process return values
OVariant result;
result.SetFromLua( lState, -1 );
lua_close( lState );
return result;
}
在lua中我可以做这样的事情......
local king = Call("EmpireManager","GetKing")
Call("MapCamera","ZoomToActor",king)
但是,我觉得我可以使用 __index 元方法来简化 lua...
local king = EmpireManager:GetKing()
MapCamera:ZoomToActor(king)
我希望通过使用 __index 元方法的以下实现来实现简化的 lua
这是我注册 __index 元函数的方法...(主要是从在线示例中复制的)
void LuaGameObject::Register( lua_State * l )
{
luaL_Reg sRegs[] =
{
{ "__index", &LuaGameObject::LuaCallFunction },
{ NULL, NULL }
};
luaL_newmetatable( l, "luaL_EmpireManager" );
// Register the C functions into the metatable we just created.
luaL_setfuncs( l, sRegs, 0 );
lua_pushvalue( l, -1 );
// Set the "__index" field of the metatable to point to itself
// This pops the stack
lua_setfield( l, -1, "__index" );
// Now we use setglobal to officially expose the luaL_EmpireManager metatable
// to Lua. And we use the name "EmpireManager".
lua_setglobal( l, "EmpireManager" );
}
不幸的是,我似乎无法正确设置回调。Lua 正确调用了我的 LuaGameObject::LuaCallFunction,但堆栈不包含我想要的内容。在 LuaGameObject::LuaCallFunction 中,我可以在堆栈上找到函数名称和 EmpireManager 对象。但是,我在堆栈上找不到参数。设置它的正确方法是什么?还是不可能?