Skip to content

Commit 030a3c1

Browse files
修改:临时处理CacheScriptContainer的类型检测 #593
1 parent 7a5bfc3 commit 030a3c1

3 files changed

Lines changed: 50 additions & 4 deletions

File tree

Plugins/UnLua/Source/UnLua/Private/LuaCore.cpp

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -477,6 +477,36 @@ void* CacheScriptContainer(lua_State *L, void *Key, const FScriptContainerDesc &
477477
return Userdata; // return null if container is already cached, or the new created userdata otherwise
478478
}
479479

480+
481+
void* CacheScriptContainer(lua_State *L, void *Key, const FScriptContainerDesc &Desc, const TFunctionRef<bool (void*)>& Validator)
482+
{
483+
if (!Key)
484+
{
485+
UNLUA_LOGERROR(L, LogUnLua, Warning, TEXT("%s, Invalid key!"), ANSI_TO_TCHAR(__FUNCTION__));
486+
return nullptr;
487+
}
488+
489+
// return null if container is already cached, or create/cache/return a new ud
490+
void *Userdata = nullptr;
491+
lua_getfield(L, LUA_REGISTRYINDEX, "ScriptContainerMap");
492+
lua_pushlightuserdata(L, Key);
493+
int32 Type = lua_rawget(L, -2);
494+
if (Type == LUA_TNIL || !Validator(lua_touserdata(L, -1)))
495+
{
496+
lua_pop(L, 1);
497+
498+
Userdata = NewUserdataWithContainerTag(L, Desc.GetSize()); // create new userdata
499+
luaL_setmetatable(L, Desc.GetName()); // set metatable
500+
lua_pushlightuserdata(L, Key);
501+
lua_pushvalue(L, -2);
502+
lua_rawset(L, -4); // cache it in 'ScriptContainerMap'
503+
UnLua::FLuaEnv::FindEnv(L)->GetDanglingCheck()->CaptureContainer(L, Key);
504+
}
505+
506+
lua_remove(L, -2);
507+
return Userdata; // return null if container is already cached, or the new created userdata otherwise
508+
}
509+
480510
/**
481511
* Get a script container at the given stack index
482512
*/

Plugins/UnLua/Source/UnLua/Private/LuaCore.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ UNLUA_API void* GetCppInstanceFast(lua_State *L, int32 Index);
6565
*/
6666
void* NewScriptContainer(lua_State *L, const FScriptContainerDesc &Desc);
6767
void* CacheScriptContainer(lua_State *L, void *Key, const FScriptContainerDesc &Desc);
68+
void* CacheScriptContainer(lua_State* L, void* Key, const FScriptContainerDesc& Desc, const TFunctionRef<bool (void*)>& Validator);
6869
void* GetScriptContainer(lua_State *L, int32 Index);
6970
void RemoveCachedScriptContainer(lua_State *L, void *Key);
7071

Plugins/UnLua/Source/UnLua/Private/Registries/ContainerRegistry.cpp

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -57,25 +57,40 @@ namespace UnLua
5757

5858
void FContainerRegistry::FindOrAdd(lua_State* L, FScriptArray* ContainerPtr, TSharedPtr<ITypeInterface> ElementType)
5959
{
60-
void* Userdata = CacheScriptContainer(L, ContainerPtr, FScriptContainerDesc::Array);
60+
void* Userdata = CacheScriptContainer(L, ContainerPtr, FScriptContainerDesc::Array, [&](void* Cached)
61+
{
62+
const auto Array = (FLuaArray*)Cached;
63+
return Array->Inner == ElementType;
64+
});
65+
6166
if (Userdata)
6267
new(Userdata) FLuaArray(ContainerPtr, ElementType, FLuaArray::OwnedByOther);
6368
}
6469

6570
void FContainerRegistry::FindOrAdd(lua_State* L, FScriptSet* ContainerPtr, TSharedPtr<ITypeInterface> ElementType)
6671
{
67-
void* Userdata = CacheScriptContainer(L, ContainerPtr, FScriptContainerDesc::Set);
72+
void* Userdata = CacheScriptContainer(L, ContainerPtr, FScriptContainerDesc::Set, [&](void* Cached)
73+
{
74+
const auto Set = (FLuaSet*)Cached;
75+
return Set->ElementInterface == ElementType;
76+
});
77+
6878
if (Userdata)
6979
new(Userdata) FLuaSet(ContainerPtr, ElementType, FLuaSet::OwnedByOther);
7080
}
7181

7282
void FContainerRegistry::FindOrAdd(lua_State* L, FScriptMap* ContainerPtr, TSharedPtr<ITypeInterface> KeyType, TSharedPtr<ITypeInterface> ValueType)
7383
{
74-
void* Userdata = CacheScriptContainer(L, ContainerPtr, FScriptContainerDesc::Map);
84+
void* Userdata = CacheScriptContainer(L, ContainerPtr, FScriptContainerDesc::Map, [&](void* Cached)
85+
{
86+
const auto Map = (FLuaMap*)Cached;
87+
return Map->KeyInterface == KeyType && Map->ValueInterface == ValueType;
88+
});
89+
7590
if (Userdata)
7691
new(Userdata) FLuaMap(ContainerPtr, KeyType, ValueType, FLuaMap::OwnedByOther);
7792
}
78-
93+
7994
void FContainerRegistry::Remove(const FLuaArray* Container)
8095
{
8196
const auto L = Env->GetMainState();

0 commit comments

Comments
 (0)