我不明白什么时候应该使用 lua_pop,在这种情况下,堆栈每帧增长 5,达到 10k 然后崩溃。
在这种特殊情况下,我调用必须返回值的 lua 函数。
另外,如果表没有函数,我检查是 metatable 在 while 循环中有它。它是否有意义或有更好的方法来做到这一点?
ModifierVariant_t LuaValue(FModifierParams_t& Params, const char* InName, int TableID)
{
lua_State* L = FLua::State();
const int Top = lua_gettop(L);
FModifierParams_t* v = (FModifierParams_t*)lua_newuserdata(L, sizeof(FModifierParams_t));
luaL_getmetatable(L, MOD_PARAMS_NAME);
const int Arg = lua_setmetatable(L, -2);
memcpy(v, &Params, sizeof(FModifierParams_t));
lua_rawgeti(L, LUA_REGISTRYINDEX, TableID);
const int Table = lua_gettop(L);
int I = Table;
SCRIPT_ASSERT(lua_istable(L, Table), TEXT("On top of the stack is not a table!"));
lua_getfield(L, Table, InName);
int Func = lua_gettop(L);
while (!(lua_isfunction(L, Func)))
{
lua_getfield(L, I, "__index");
I = lua_gettop(L);
SCRIPT_ASSERT(!(lua_isnil(L, I) && lua_isnone(L, I)), TEXT("Function %hs could not be found!"), InName);
lua_getfield(L, I, InName);
Func = lua_gettop(L);
}
SCRIPT_ASSERT(lua_isfunction(L, Func), TEXT("Could not found a field %hs of meta %d, adress is %hs"), InName, TableID, lua_tostring(L, Table));
lua_pushvalue(L, Table);
lua_pushvalue(L, Arg);
#if !UE_BUILD_SHIPPING
const int ErrCode = LUA_CALL(FLua::State(), 2, 1);
if (ErrCode != LUA_OK)
{
return 0;
}
#else
LUA_CALL(FLua::State(), 1, 0);
#endif
ModifierVariant_t Result(0);
UTIL_PrintF(SysEntity, "Lua stack size (after call) id %d", FLua::StackSize());
switch (lua_type(L, -1)) {
case LUA_TNUMBER:
{
Result = ModifierVariant_t(((float)lua_tonumber(L, -1)));
}
case LUA_TSTRING:
{
Result = ModifierVariant_t(lua_tostring(L, -1));
}
case LUA_TBOOLEAN:
{
Result = ModifierVariant_t(lua_toboolean(L, -1) == 1);
}
case LUA_TNIL:
XASSERT(false, "ModifierVariant cannot be nil!");
break;
default:
XASSERT(false, "ModifierVariant cannot be a pointer!");
break;
}
return Result;
}
函数末尾的 lua_settop 不起作用 - 冻结然后崩溃。 lua_pop(L, 5) 也不起作用。