diff --git a/Plugins/UnLua/Source/UnLua/Private/LuaEnv.cpp b/Plugins/UnLua/Source/UnLua/Private/LuaEnv.cpp index 6b65dc1f..79ddc5d5 100644 --- a/Plugins/UnLua/Source/UnLua/Private/LuaEnv.cpp +++ b/Plugins/UnLua/Source/UnLua/Private/LuaEnv.cpp @@ -53,7 +53,7 @@ namespace UnLua UELib::Open(L); ObjectRegistry = MakeShared(this); - ClassRegistry = new FClassRegistry(L); + ClassRegistry = MakeShared(this); ClassRegistry->Register("UObject"); ClassRegistry->Register("UClass"); @@ -140,7 +140,6 @@ namespace UnLua Manager->RemoveFromRoot(); Manager = nullptr; - delete ClassRegistry; delete ContainerRegistry; delete EnumRegistry; diff --git a/Plugins/UnLua/Source/UnLua/Private/Registries/ClassRegistry.cpp b/Plugins/UnLua/Source/UnLua/Private/Registries/ClassRegistry.cpp index 7690ec72..306524de 100644 --- a/Plugins/UnLua/Source/UnLua/Private/Registries/ClassRegistry.cpp +++ b/Plugins/UnLua/Source/UnLua/Private/Registries/ClassRegistry.cpp @@ -23,277 +23,281 @@ extern int32 UObject_Identical(lua_State* L); extern int32 UObject_Delete(lua_State* L); -TMap UnLua::FClassRegistry::Classes; -TMap UnLua::FClassRegistry::Name2Classes; - -UnLua::FClassRegistry::FClassRegistry(lua_State* GL) - : GL(GL) +namespace UnLua { -} + TMap FClassRegistry::Classes; + TMap FClassRegistry::Name2Classes; -UnLua::FClassRegistry* UnLua::FClassRegistry::Find(const lua_State* L) -{ - const auto Env = FLuaEnv::FindEnv(L); - if (Env == nullptr) - return nullptr; - return Env->GetClassRegistry(); -} - -FClassDesc* UnLua::FClassRegistry::Find(const char* TypeName) -{ - const FName Key = TypeName; - FClassDesc** Ret = Name2Classes.Find(Key); - return Ret ? *Ret : nullptr; -} - -FClassDesc* UnLua::FClassRegistry::Find(const UStruct* Type) -{ - FClassDesc** Ret = Classes.Find(Type); - return Ret ? *Ret : nullptr; -} - -FClassDesc* UnLua::FClassRegistry::RegisterReflectedType(const char* MetatableName) -{ - FClassDesc* Ret = Find(MetatableName); - if (Ret) + FClassRegistry::FClassRegistry(FLuaEnv* Env) + : Env(Env) { - Classes.FindOrAdd(Ret->AsStruct(), Ret); - return Ret; } - const char* TypeName = MetatableName[0] == 'U' || MetatableName[0] == 'A' || MetatableName[0] == 'F' ? MetatableName + 1 : MetatableName; - const auto Type = LoadReflectedType(TypeName); - if (!Type) - return nullptr; - - const auto StructType = Cast(Type); - if (StructType) + TSharedPtr FClassRegistry::Find(const lua_State* L) { - Ret = RegisterInternal(StructType, UTF8_TO_TCHAR(MetatableName)); - return Ret; + const auto Env = FLuaEnv::FindEnv(L); + if (Env == nullptr) + return nullptr; + return Env->GetClassRegistry(); } - const auto EnumType = Cast(Type); - if (EnumType) + FClassDesc* FClassRegistry::Find(const char* TypeName) { - // TODO: - check(false); + const FName Key = TypeName; + FClassDesc** Ret = Name2Classes.Find(Key); + return Ret ? *Ret : nullptr; } - return nullptr; -} - -FClassDesc* UnLua::FClassRegistry::RegisterReflectedType(UStruct* Type) -{ - FClassDesc** Exists = Classes.Find(Type); - if (Exists) - return *Exists; - - const auto MetatableName = LowLevel::GetMetatableName(Type); - Exists = Name2Classes.Find(FName(MetatableName)); - if (Exists) + FClassDesc* FClassRegistry::Find(const UStruct* Type) { - Classes.Add(Type, *Exists); - return *Exists; + FClassDesc** Ret = Classes.Find(Type); + return Ret ? *Ret : nullptr; } - const auto Ret = RegisterInternal(Type, MetatableName); - return Ret; -} - -bool UnLua::FClassRegistry::StaticUnregister(UStruct* Type) -{ - FClassDesc* ClassDesc; - if (!Classes.RemoveAndCopyValue(Type, ClassDesc)) - return false; - ClassDesc->UnLoad(); - for (auto Pair : FLuaEnv::AllEnvs) + FClassDesc* FClassRegistry::RegisterReflectedType(const char* MetatableName) { - auto Registry = Pair.Value->GetClassRegistry(); - Registry->Unregister(ClassDesc); - } - return true; -} + FClassDesc* Ret = Find(MetatableName); + if (Ret) + { + Classes.FindOrAdd(Ret->AsStruct(), Ret); + return Ret; + } -bool UnLua::FClassRegistry::PushMetatable(lua_State* L, const char* MetatableName) -{ - int Type = luaL_getmetatable(L, MetatableName); - if (Type == LUA_TTABLE) - return true; - lua_pop(L, 1); + const char* TypeName = MetatableName[0] == 'U' || MetatableName[0] == 'A' || MetatableName[0] == 'F' ? MetatableName + 1 : MetatableName; + const auto Type = LoadReflectedType(TypeName); + if (!Type) + return nullptr; + + const auto StructType = Cast(Type); + if (StructType) + { + Ret = RegisterInternal(StructType, UTF8_TO_TCHAR(MetatableName)); + return Ret; + } - if (FindExportedNonReflectedClass(MetatableName)) - return false; + const auto EnumType = Cast(Type); + if (EnumType) + { + // TODO: + check(false); + } - FClassDesc* ClassDesc = RegisterReflectedType(MetatableName); - if (!ClassDesc) - return false; + return nullptr; + } - luaL_newmetatable(L, MetatableName); - lua_pushstring(L, "__index"); - lua_pushcfunction(L, Class_Index); - lua_rawset(L, -3); + FClassDesc* FClassRegistry::RegisterReflectedType(UStruct* Type) + { + FClassDesc** Exists = Classes.Find(Type); + if (Exists) + return *Exists; - lua_pushstring(L, "__newindex"); - lua_pushcfunction(L, Class_NewIndex); - lua_rawset(L, -3); + const auto MetatableName = LowLevel::GetMetatableName(Type); + Exists = Name2Classes.Find(FName(MetatableName)); + if (Exists) + { + Classes.Add(Type, *Exists); + return *Exists; + } - uint64 TypeHash = (uint64)ClassDesc->AsStruct(); - lua_pushstring(L, "TypeHash"); - lua_pushnumber(L, TypeHash); - lua_rawset(L, -3); + const auto Ret = RegisterInternal(Type, MetatableName); + return Ret; + } - UScriptStruct* ScriptStruct = ClassDesc->AsScriptStruct(); - if (ScriptStruct) + bool FClassRegistry::StaticUnregister(UStruct* Type) { - lua_pushlightuserdata(L, ClassDesc); + FClassDesc* ClassDesc; + if (!Classes.RemoveAndCopyValue(Type, ClassDesc)) + return false; + ClassDesc->UnLoad(); + for (auto Pair : FLuaEnv::AllEnvs) + { + auto Registry = Pair.Value->GetClassRegistry(); + Registry->Unregister(ClassDesc); + } + return true; + } - lua_pushstring(L, "Copy"); - lua_pushvalue(L, -2); - lua_pushcclosure(L, ScriptStruct_Copy, 1); - lua_rawset(L, -4); + bool FClassRegistry::PushMetatable(lua_State* L, const char* MetatableName) + { + int Type = luaL_getmetatable(L, MetatableName); + if (Type == LUA_TTABLE) + return true; + lua_pop(L, 1); - lua_pushstring(L, "CopyFrom"); - lua_pushvalue(L, -2); - lua_pushcclosure(L, ScriptStruct_CopyFrom, 1); - lua_rawset(L, -4); + if (FindExportedNonReflectedClass(MetatableName)) + return false; - lua_pushstring(L, "__eq"); - lua_pushvalue(L, -2); - lua_pushcclosure(L, ScriptStruct_Compare, 1); - lua_rawset(L, -4); + FClassDesc* ClassDesc = RegisterReflectedType(MetatableName); + if (!ClassDesc) + return false; - lua_pushstring(L, "__gc"); - lua_pushvalue(L, -2); - lua_pushcclosure(L, ScriptStruct_Delete, 1); - lua_rawset(L, -4); + luaL_newmetatable(L, MetatableName); + lua_pushstring(L, "__index"); + lua_pushcfunction(L, Class_Index); + lua_rawset(L, -3); - lua_pushstring(L, "__call"); - lua_pushvalue(L, -2); - lua_pushcclosure(L, ScriptStruct_New, 1); // closure - lua_rawset(L, -4); + lua_pushstring(L, "__newindex"); + lua_pushcfunction(L, Class_NewIndex); + lua_rawset(L, -3); - lua_pop(L, 1); - } - else - { - UClass* Class = ClassDesc->AsClass(); - if (Class != UObject::StaticClass() && Class != UClass::StaticClass()) + uint64 TypeHash = (uint64)ClassDesc->AsStruct(); + lua_pushstring(L, "TypeHash"); + lua_pushnumber(L, TypeHash); + lua_rawset(L, -3); + + UScriptStruct* ScriptStruct = ClassDesc->AsScriptStruct(); + if (ScriptStruct) { - lua_pushstring(L, "ClassDesc"); lua_pushlightuserdata(L, ClassDesc); - lua_rawset(L, -3); - lua_pushstring(L, "StaticClass"); - lua_pushlightuserdata(L, ClassDesc); - lua_pushcclosure(L, Class_StaticClass, 1); - lua_rawset(L, -3); + lua_pushstring(L, "Copy"); + lua_pushvalue(L, -2); + lua_pushcclosure(L, ScriptStruct_Copy, 1); + lua_rawset(L, -4); - lua_pushstring(L, "Cast"); - lua_pushcfunction(L, Class_Cast); - lua_rawset(L, -3); + lua_pushstring(L, "CopyFrom"); + lua_pushvalue(L, -2); + lua_pushcclosure(L, ScriptStruct_CopyFrom, 1); + lua_rawset(L, -4); lua_pushstring(L, "__eq"); - lua_pushcfunction(L, UObject_Identical); - lua_rawset(L, -3); + lua_pushvalue(L, -2); + lua_pushcclosure(L, ScriptStruct_Compare, 1); + lua_rawset(L, -4); lua_pushstring(L, "__gc"); - lua_pushcfunction(L, UObject_Delete); - lua_rawset(L, -3); + lua_pushvalue(L, -2); + lua_pushcclosure(L, ScriptStruct_Delete, 1); + lua_rawset(L, -4); + + lua_pushstring(L, "__call"); + lua_pushvalue(L, -2); + lua_pushcclosure(L, ScriptStruct_New, 1); // closure + lua_rawset(L, -4); + + lua_pop(L, 1); + } + else + { + UClass* Class = ClassDesc->AsClass(); + if (Class != UObject::StaticClass() && Class != UClass::StaticClass()) + { + lua_pushstring(L, "ClassDesc"); + lua_pushlightuserdata(L, ClassDesc); + lua_rawset(L, -3); + + lua_pushstring(L, "StaticClass"); + lua_pushlightuserdata(L, ClassDesc); + lua_pushcclosure(L, Class_StaticClass, 1); + lua_rawset(L, -3); + + lua_pushstring(L, "Cast"); + lua_pushcfunction(L, Class_Cast); + lua_rawset(L, -3); + + lua_pushstring(L, "__eq"); + lua_pushcfunction(L, UObject_Identical); + lua_rawset(L, -3); + + lua_pushstring(L, "__gc"); + lua_pushcfunction(L, UObject_Delete); + lua_rawset(L, -3); + } } - } - lua_pushvalue(L, -1); // set metatable to self - lua_setmetatable(L, -2); + lua_pushvalue(L, -1); // set metatable to self + lua_setmetatable(L, -2); - TArray ClassDescChain; - ClassDesc->GetInheritanceChain(ClassDescChain); + TArray ClassDescChain; + ClassDesc->GetInheritanceChain(ClassDescChain); - TArray ExportedClasses; - for (int32 i = ClassDescChain.Num() - 1; i > -1; --i) - { - auto ExportedClass = FindExportedReflectedClass(*ClassDescChain[i]->GetName()); - if (ExportedClass) - ExportedClass->Register(L); - } + TArray ExportedClasses; + for (int32 i = ClassDescChain.Num() - 1; i > -1; --i) + { + auto ExportedClass = FindExportedReflectedClass(*ClassDescChain[i]->GetName()); + if (ExportedClass) + ExportedClass->Register(L); + } - UELib::SetTableForClass(L, MetatableName); + UELib::SetTableForClass(L, MetatableName); - return true; -} + return true; + } -bool UnLua::FClassRegistry::TrySetMetatable(lua_State* L, const char* MetatableName) -{ - if (!PushMetatable(L, MetatableName)) - return false; + bool FClassRegistry::TrySetMetatable(lua_State* L, const char* MetatableName) + { + if (!PushMetatable(L, MetatableName)) + return false; - lua_setmetatable(L, -2); - return true; -} + lua_setmetatable(L, -2); + return true; + } -FClassDesc* UnLua::FClassRegistry::Register(const char* MetatableName) -{ - if (!PushMetatable(GL, MetatableName)) - return nullptr; + FClassDesc* FClassRegistry::Register(const char* MetatableName) + { + const auto L = Env->GetMainState(); + if (!PushMetatable(L, MetatableName)) + return nullptr; - // TODO: refactor - lua_pop(GL, 1); - FName Key = FName(UTF8_TO_TCHAR(MetatableName)); - return Name2Classes.FindChecked(Key); -} + // TODO: refactor + lua_pop(L, 1); + FName Key = FName(UTF8_TO_TCHAR(MetatableName)); + return Name2Classes.FindChecked(Key); + } -FClassDesc* UnLua::FClassRegistry::Register(const UStruct* Class) -{ - const auto MetatableName = LowLevel::GetMetatableName(Class); - return Register(TCHAR_TO_UTF8(*MetatableName)); -} + FClassDesc* FClassRegistry::Register(const UStruct* Class) + { + const auto MetatableName = LowLevel::GetMetatableName(Class); + return Register(TCHAR_TO_UTF8(*MetatableName)); + } -void UnLua::FClassRegistry::Cleanup() -{ - for (const auto Pair : Name2Classes) - delete Pair.Value; - Name2Classes.Empty(); - Classes.Empty(); -} + void FClassRegistry::Cleanup() + { + for (const auto Pair : Name2Classes) + delete Pair.Value; + Name2Classes.Empty(); + Classes.Empty(); + } -UField* UnLua::FClassRegistry::LoadReflectedType(const char* InName) -{ - FString Name = UTF8_TO_TCHAR(InName); - - // find candidates in memory - UField* Ret = FindObject(ANY_PACKAGE, *Name); - if (!Ret) - Ret = FindObject(ANY_PACKAGE, *Name); - if (!Ret) - Ret = FindObject(ANY_PACKAGE, *Name); - - // load candidates if not found - if (!Ret) - Ret = LoadObject(nullptr, *Name); - if (!Ret) - Ret = LoadObject(nullptr, *Name); - if (!Ret) - Ret = LoadObject(nullptr, *Name); - - return Ret; -} + UField* FClassRegistry::LoadReflectedType(const char* InName) + { + FString Name = UTF8_TO_TCHAR(InName); + + // find candidates in memory + UField* Ret = FindObject(ANY_PACKAGE, *Name); + if (!Ret) + Ret = FindObject(ANY_PACKAGE, *Name); + if (!Ret) + Ret = FindObject(ANY_PACKAGE, *Name); + + // load candidates if not found + if (!Ret) + Ret = LoadObject(nullptr, *Name); + if (!Ret) + Ret = LoadObject(nullptr, *Name); + if (!Ret) + Ret = LoadObject(nullptr, *Name); -FClassDesc* UnLua::FClassRegistry::RegisterInternal(UStruct* Type, const FString& Name) -{ - check(Type); - check(!Classes.Contains(Type)); + return Ret; + } + + FClassDesc* FClassRegistry::RegisterInternal(UStruct* Type, const FString& Name) + { + check(Type); + check(!Classes.Contains(Type)); - FClassDesc* ClassDesc = new FClassDesc(Type, Name); - Classes.Add(Type, ClassDesc); - Name2Classes.Add(FName(*Name), ClassDesc); + FClassDesc* ClassDesc = new FClassDesc(Type, Name); + Classes.Add(Type, ClassDesc); + Name2Classes.Add(FName(*Name), ClassDesc); - return ClassDesc; -} + return ClassDesc; + } -void UnLua::FClassRegistry::Unregister(const FClassDesc* ClassDesc) -{ - const auto L = GL; - const auto MetatableName = ClassDesc->GetName(); - lua_pushnil(L); - lua_setfield(L, LUA_REGISTRYINDEX, TCHAR_TO_UTF8(*MetatableName)); + void FClassRegistry::Unregister(const FClassDesc* ClassDesc) + { + const auto L = Env->GetMainState(); + const auto MetatableName = ClassDesc->GetName(); + lua_pushnil(L); + lua_setfield(L, LUA_REGISTRYINDEX, TCHAR_TO_UTF8(*MetatableName)); + } } diff --git a/Plugins/UnLua/Source/UnLua/Private/Registries/ClassRegistry.h b/Plugins/UnLua/Source/UnLua/Private/Registries/ClassRegistry.h index 28e2a3bf..f0276742 100644 --- a/Plugins/UnLua/Source/UnLua/Private/Registries/ClassRegistry.h +++ b/Plugins/UnLua/Source/UnLua/Private/Registries/ClassRegistry.h @@ -19,12 +19,14 @@ namespace UnLua { + class FLuaEnv; + class FClassRegistry { public: - explicit FClassRegistry(lua_State* GL); + explicit FClassRegistry(FLuaEnv* Env); - static FClassRegistry* Find(const lua_State* L); + static TSharedPtr Find(const lua_State* L); static FClassDesc* Find(const char* TypeName); @@ -39,7 +41,7 @@ namespace UnLua static UField* LoadReflectedType(const char* InName); static void Cleanup(); - + bool PushMetatable(lua_State* L, const char* MetatableName); bool TrySetMetatable(lua_State* L, const char* MetatableName); @@ -56,6 +58,6 @@ namespace UnLua static TMap Classes; static TMap Name2Classes; - lua_State* GL; + FLuaEnv* Env; }; } diff --git a/Plugins/UnLua/Source/UnLua/Public/LuaEnv.h b/Plugins/UnLua/Source/UnLua/Public/LuaEnv.h index e3b7cb14..d44f5344 100644 --- a/Plugins/UnLua/Source/UnLua/Public/LuaEnv.h +++ b/Plugins/UnLua/Source/UnLua/Public/LuaEnv.h @@ -98,7 +98,7 @@ namespace UnLua UUnLuaManager* GetManager() const { return Manager; } - FClassRegistry* GetClassRegistry() const { return ClassRegistry; } + TSharedPtr GetClassRegistry() const { return ClassRegistry; } TSharedPtr GetObjectRegistry() const { return ObjectRegistry; } @@ -148,7 +148,7 @@ namespace UnLua FObjectReferencer AutoObjectReference; FObjectReferencer ManualObjectReference; UUnLuaManager* Manager; - FClassRegistry* ClassRegistry; + TSharedPtr ClassRegistry; TSharedPtr ObjectRegistry; TSharedPtr DelegateRegistry; TSharedPtr FunctionRegistry; diff --git a/TPSProject.sln.DotSettings b/TPSProject.sln.DotSettings index 84a7fb57..95e82737 100644 --- a/TPSProject.sln.DotSettings +++ b/TPSProject.sln.DotSettings @@ -10,6 +10,7 @@ True True True + True True True True