| 251 | } |
| 252 | |
| 253 | bool UUnLuaManager::BindClass(UClass* Class, const FString& InModuleName, FString& Error) |
| 254 | { |
| 255 | check(Class); |
| 256 | |
| 257 | if (Class->HasAnyFlags(RF_NeedPostLoad | RF_NeedPostLoadSubobjects)) |
| 258 | return false; |
| 259 | |
| 260 | if (Classes.Contains(Class)) |
| 261 | return true; |
| 262 | |
| 263 | const auto L = Env->GetMainState(); |
| 264 | const auto Top = lua_gettop(L); |
| 265 | const auto Type = UnLua::LowLevel::GetLoadedModule(L, TCHAR_TO_UTF8(*InModuleName)); |
| 266 | if (Type != LUA_TTABLE) |
| 267 | { |
| 268 | Error = FString::Printf(TEXT("table needed got %s"), UTF8_TO_TCHAR(lua_typename(L, Type))); |
| 269 | lua_settop(L, Top); |
| 270 | return false; |
| 271 | } |
| 272 | |
| 273 | if (!Class->IsChildOf<UBlueprintFunctionLibrary>()) |
| 274 | { |
| 275 | // 一个LuaModule可能会被绑定到一个UClass和它的子类,复制一个出来作为它们的实例的元表 |
| 276 | lua_newtable(L); |
| 277 | lua_pushnil(L); |
| 278 | while (lua_next(L, -3) != 0) |
| 279 | { |
| 280 | lua_pushvalue(L, -2); |
| 281 | lua_insert(L, -2); |
| 282 | lua_settable(L, -4); |
| 283 | } |
| 284 | } |
| 285 | |
| 286 | lua_pushvalue(L, -1); |
| 287 | const auto Ref = luaL_ref(L, LUA_REGISTRYINDEX); |
| 288 | lua_settop(L, Top); |
| 289 | |
| 290 | auto& BindInfo = Classes.Add(Class); |
| 291 | BindInfo.Class = Class; |
| 292 | BindInfo.ModuleName = InModuleName; |
| 293 | BindInfo.TableRef = Ref; |
| 294 | |
| 295 | UnLua::LowLevel::GetFunctionNames(Env->GetMainState(), Ref, BindInfo.LuaFunctions); |
| 296 | ULuaFunction::GetOverridableFunctions(Class, BindInfo.UEFunctions); |
| 297 | |
| 298 | // 用LuaTable里所有的函数来替换Class上对应的UFunction |
| 299 | for (const auto& LuaFuncName : BindInfo.LuaFunctions) |
| 300 | { |
| 301 | UFunction** Func = BindInfo.UEFunctions.Find(LuaFuncName); |
| 302 | if (Func) |
| 303 | { |
| 304 | UFunction* Function = *Func; |
| 305 | ULuaFunction::Override(Function, Class, LuaFuncName); |
| 306 | } |
| 307 | } |
| 308 | |
| 309 | if (BindInfo.LuaFunctions.Num() == 0 || BindInfo.UEFunctions.Num() == 0) |
| 310 | return true; |
nothing calls this directly
no test coverage detected