| 20 | } |
| 21 | |
| 22 | void FFunctionRegistry::Invoke(ULuaFunction* Function, UObject* Context, FFrame& Stack, RESULT_DECL) |
| 23 | { |
| 24 | // TODO: refactor |
| 25 | if (UNLIKELY(!Env->GetObjectRegistry()->IsBound(Context))) |
| 26 | Env->TryBind(Context); |
| 27 | |
| 28 | const auto SelfRef = Env->GetObjectRegistry()->GetBoundRef(Context); |
| 29 | check(SelfRef!=LUA_NOREF); |
| 30 | |
| 31 | const auto L = Env->GetMainState(); |
| 32 | lua_Integer FuncRef; |
| 33 | FFunctionDesc* FuncDesc; |
| 34 | |
| 35 | const auto Exists = LuaFunctions.Find(Function); |
| 36 | if (Exists) |
| 37 | { |
| 38 | FuncRef = Exists->LuaRef; |
| 39 | FuncDesc = Exists->Desc.Get(); |
| 40 | } |
| 41 | else |
| 42 | { |
| 43 | FuncRef = LUA_NOREF; |
| 44 | FuncDesc = new FFunctionDesc(Function, nullptr); |
| 45 | |
| 46 | lua_rawgeti(L, LUA_REGISTRYINDEX, SelfRef); |
| 47 | lua_getmetatable(L, -1); |
| 48 | do |
| 49 | { |
| 50 | lua_pushstring(L, FuncDesc->GetLuaFunctionName()); |
| 51 | lua_rawget(L, -2); |
| 52 | if (lua_isfunction(L, -1)) |
| 53 | { |
| 54 | lua_pushvalue(L, -3); |
| 55 | lua_remove(L, -3); |
| 56 | lua_remove(L, -3); |
| 57 | lua_pushvalue(L, -2); |
| 58 | FuncRef = luaL_ref(L, LUA_REGISTRYINDEX); |
| 59 | break; |
| 60 | } |
| 61 | lua_pop(L, 1); |
| 62 | lua_pushstring(L, "Super"); |
| 63 | lua_rawget(L, -2); |
| 64 | lua_remove(L, -2); |
| 65 | } |
| 66 | while (lua_istable(L, -1)); |
| 67 | lua_pop(L, 2); |
| 68 | |
| 69 | FFunctionInfo Info; |
| 70 | Info.LuaRef = FuncRef; |
| 71 | Info.Desc = TUniquePtr<FFunctionDesc>(FuncDesc); |
| 72 | LuaFunctions.Add(Function, MoveTemp(Info)); |
| 73 | } |
| 74 | |
| 75 | if (FuncRef == LUA_NOREF) |
| 76 | { |
| 77 | // 可能因为Lua模块加载失败导致找不到对应的function,转发给原函数 |
| 78 | const auto Overridden = Function->GetOverridden(); |
| 79 | if (Overridden && Stack.Code) |
no test coverage detected