From 64bea7ebc77fd0a1cbcbc2c0382dd2b6127208c6 Mon Sep 17 00:00:00 2001 From: liuxiaoyi Date: Mon, 1 Feb 2021 21:53:21 +0800 Subject: [PATCH] =?UTF-8?q?=E9=80=9A=E8=BF=87=E5=87=8F=E5=B0=91=E5=AF=B9UC?= =?UTF-8?q?lass=E7=9A=84Property=E5=92=8CFunction=E7=9A=84=E6=9F=A5?= =?UTF-8?q?=E8=AF=A2=E6=AC=A1=E6=95=B0=E6=8F=90=E5=8D=87instanceIndex?= =?UTF-8?q?=E3=80=81newInstanceIndex=E3=80=81classIndex=E4=B8=89=E4=B8=AA?= =?UTF-8?q?=E6=96=B9=E6=B3=95=E7=9A=84=E6=80=A7=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Source/slua_unreal/Private/LuaObject.cpp | 100 ++++++++++++------ .../Source/slua_unreal/Private/LuaState.cpp | 8 ++ .../Source/slua_unreal/Public/LuaObject.h | 5 +- .../Source/slua_unreal/Public/LuaState.h | 8 ++ 4 files changed, 85 insertions(+), 36 deletions(-) diff --git a/Plugins/slua_unreal/Source/slua_unreal/Private/LuaObject.cpp b/Plugins/slua_unreal/Source/slua_unreal/Private/LuaObject.cpp index 7711c45b..6cf17608 100644 --- a/Plugins/slua_unreal/Source/slua_unreal/Private/LuaObject.cpp +++ b/Plugins/slua_unreal/Source/slua_unreal/Private/LuaObject.cpp @@ -494,11 +494,16 @@ namespace NS_SLUA { } // get blueprint member - func = cls->FindFunctionByName(UTF8_TO_TCHAR(name)); - if (func) { - LuaObject::cacheFunction(L, cls, name, func); - return LuaObject::push(L, func, cls); - } + if (!func && !LuaObject::isFunctionSearched(L, cls, name)) + { + func = cls->FindFunctionByName(UTF8_TO_TCHAR(name)); + LuaObject::setFunctionSearched(L, cls, name); + if (func) + { + LuaObject::cacheFunction(L, cls, name, func); + return LuaObject::push(L, func, cls); + } + } return searchExtensionMethod(L,cls,name,true); } @@ -743,25 +748,47 @@ namespace NS_SLUA { state->classMap.cacheFunc(cls,fname,func); } + void LuaObject::setFunctionSearched(lua_State* L, UClass* cls, const char* fname) + { + auto state = LuaState::get(L); + auto& item = state->classMap.funcSearchedMap.FindOrAdd(cls); + item.Add(UTF8_TO_TCHAR(fname), true); + } + + bool LuaObject::isFunctionSearched(lua_State* L, UClass* cls, const char* fname) + { + auto state = LuaState::get(L); + auto item = state->classMap.funcSearchedMap.Find(cls); + if (!item) return false; + auto finded = item->Find(UTF8_TO_TCHAR(fname)); + return finded ? *finded : false; + } + UProperty* LuaObject::findCacheProperty(lua_State* L, UClass* cls, const char* pname) { auto state = LuaState::get(L); return state->classMap.findProp(cls, pname); } - void LuaObject::cacheProperty(lua_State* L, UClass* cls, const char* pname, UProperty* property) + void LuaObject::cacheAllProperties(lua_State* L, UClass* cls) { - auto state = LuaState::get(L); - state->classMap.cacheProp(cls, pname, property); + auto state = LuaState::get(L); + if (!state->classMap.propCachedMap.FindOrAdd(cls)) + { + auto PropertyLink = cls->PropertyLink; + for (FProperty* Property = PropertyLink; Property != NULL; Property = Property->PropertyLinkNext) { + state->classMap.cacheProp(cls, TCHAR_TO_UTF8(*(Property->GetName())), Property); + } + state->classMap.propCachedMap[cls] = true; + } } - // cache class property's - void cachePropertys(lua_State* L, UClass* cls) { - auto PropertyLink = cls->PropertyLink; - for (UProperty* Property = PropertyLink; Property != NULL; Property = Property->PropertyLinkNext) { - LuaObject::cacheProperty(L, cls, TCHAR_TO_UTF8(*(Property->GetName())), Property); - } - } + bool LuaObject::arePropertiesCached(lua_State* L, UClass* cls) + { + auto state = LuaState::get(L); + auto finded = state->classMap.propCachedMap.Find(cls); + return finded ? *finded : false; + } int instanceIndex(lua_State* L) { UObject* obj = LuaObject::checkValue(L, 1); @@ -769,6 +796,13 @@ namespace NS_SLUA { UClass* cls = obj->GetClass(); UProperty* up = LuaObject::findCacheProperty(L, cls, name); + + if (!up && !LuaObject::arePropertiesCached(L, cls)) + { + LuaObject::cacheAllProperties(L, cls); + up = LuaObject::findCacheProperty(L, cls, name); + } + if (up) { return LuaObject::push(L, up, obj, nullptr); @@ -781,23 +815,19 @@ namespace NS_SLUA { } // get blueprint member - FName wname(UTF8_TO_TCHAR(name)); - func = cls->FindFunctionByName(wname); - if(!func) { - cachePropertys(L, cls); - - up = LuaObject::findCacheProperty(L, cls, name); - if (up) { - return LuaObject::push(L, up, obj, nullptr); + if (!func && !LuaObject::isFunctionSearched(L, cls, name)) + { + func = cls->FindFunctionByName(UTF8_TO_TCHAR(name)); + LuaObject::setFunctionSearched(L, cls, name); + + if (func) + { + LuaObject::cacheFunction(L, cls, name, func); + return LuaObject::push(L,func); } - - // search extension method - return searchExtensionMethod(L, obj, name); - } - else { - LuaObject::cacheFunction(L, cls, name, func); - return LuaObject::push(L,func); } + // search extension method + return searchExtensionMethod(L, obj, name); } int newinstanceIndex(lua_State* L) { @@ -805,11 +835,11 @@ namespace NS_SLUA { const char* name = LuaObject::checkValue(L, 2); UClass* cls = obj->GetClass(); UProperty* up = LuaObject::findCacheProperty(L, cls, name); - if (!up) - { - cachePropertys(L, cls); - up = LuaObject::findCacheProperty(L, cls, name); - } + if (!up && !LuaObject::arePropertiesCached(L, cls)) + { + LuaObject::cacheAllProperties(L, cls); + up = LuaObject::findCacheProperty(L, cls, name); + } if (!up) luaL_error(L, "Property %s not found", name); if(up->GetPropertyFlags() & CPF_BlueprintReadOnly) luaL_error(L,"Property %s is readonly",name); diff --git a/Plugins/slua_unreal/Source/slua_unreal/Private/LuaState.cpp b/Plugins/slua_unreal/Source/slua_unreal/Private/LuaState.cpp index f86ff73d..74fe4f67 100644 --- a/Plugins/slua_unreal/Source/slua_unreal/Private/LuaState.cpp +++ b/Plugins/slua_unreal/Source/slua_unreal/Private/LuaState.cpp @@ -443,6 +443,14 @@ namespace NS_SLUA { it.RemoveCurrent(); for (ClassCache::CachePropMap::TIterator it(classMap.cachePropMap); it; ++it) + if (!it.Key().IsValid()) + it.RemoveCurrent(); + + for (ClassCache::PropCachedMap::TIterator it(classMap.propCachedMap); it; ++it) + if (!it.Key().IsValid()) + it.RemoveCurrent(); + + for (ClassCache::FuncSearchedMap::TIterator it(classMap.funcSearchedMap); it; ++it) if (!it.Key().IsValid()) it.RemoveCurrent(); diff --git a/Plugins/slua_unreal/Source/slua_unreal/Public/LuaObject.h b/Plugins/slua_unreal/Source/slua_unreal/Public/LuaObject.h index fbd51022..afac3728 100644 --- a/Plugins/slua_unreal/Source/slua_unreal/Public/LuaObject.h +++ b/Plugins/slua_unreal/Source/slua_unreal/Public/LuaObject.h @@ -771,9 +771,12 @@ namespace NS_SLUA { static UFunction* findCacheFunction(lua_State* L,UClass* cls,const char* fname); static void cacheFunction(lua_State* L, UClass* cls,const char* fame,UFunction* func); + static void setFunctionSearched(lua_State* L, UClass* cls, const char* fname); + static bool isFunctionSearched(lua_State* L, UClass* cls, const char* fname); static UProperty* findCacheProperty(lua_State* L, UClass* cls, const char* pname); - static void cacheProperty(lua_State* L, UClass* cls, const char* pname, UProperty* property); + static void cacheAllProperties(lua_State* L, UClass* cls); + static bool arePropertiesCached(lua_State* L, UClass* cls); static bool getObjCache(lua_State* L, void* obj, const char* tn, bool check = true); static void cacheObj(lua_State* L, void* obj); diff --git a/Plugins/slua_unreal/Source/slua_unreal/Public/LuaState.h b/Plugins/slua_unreal/Source/slua_unreal/Public/LuaState.h index 4fddb398..05a083a1 100644 --- a/Plugins/slua_unreal/Source/slua_unreal/Public/LuaState.h +++ b/Plugins/slua_unreal/Source/slua_unreal/Public/LuaState.h @@ -265,6 +265,10 @@ namespace NS_SLUA { typedef TMap> CachePropItem; typedef TMap, CachePropItem> CachePropMap; + + typedef TMap, bool> PropCachedMap; + typedef TMap FuncCachedItem; + typedef TMap, FuncCachedItem> FuncSearchedMap; UFunction* findFunc(UClass* uclass, const char* fname); UProperty* findProp(UClass* uclass, const char* pname); @@ -273,10 +277,14 @@ namespace NS_SLUA { void clear() { cacheFuncMap.Empty(); cachePropMap.Empty(); + propCachedMap.Empty(); + funcSearchedMap.Empty(); } CacheFuncMap cacheFuncMap; CachePropMap cachePropMap; + PropCachedMap propCachedMap; + FuncSearchedMap funcSearchedMap; } classMap; FDeadLoopCheck* deadLoopCheck;