Skip to content

Commit

Permalink
重构:提取DelegateRegistry
Browse files Browse the repository at this point in the history
  • Loading branch information
forsakenyang committed Apr 1, 2022
1 parent 17910d1 commit b059468
Show file tree
Hide file tree
Showing 11 changed files with 276 additions and 28 deletions.
41 changes: 13 additions & 28 deletions Plugins/UnLua/Source/UnLua/Private/BaseLib/LuaLib_Delegate.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,25 +49,16 @@ static int32 FScriptDelegate_Bind(lua_State *L)
return 0;
}

FCallbackDesc Callback(Object->GetClass(), CallbackFunction, Object);
FName FuncName = FDelegateHelper::GetBindedFunctionName(Callback);
if (FuncName == NAME_None)
{
lua_pushvalue(L, 3);
int32 CallbackRef = luaL_ref(L, LUA_REGISTRYINDEX);
FDelegateHelper::Bind(Delegate, Object, Callback, CallbackRef);
}
else
{
Delegate->BindUFunction(Object, FuncName);
}
const auto Registry = UnLua::FLuaEnv::FindEnvChecked(L).GetDelegateRegistry();
Registry->Bind(L, 3, Delegate, Object);

return 0;
}

/**
* Unbind the callback for the delegate
*/
static int32 FScriptDelegate_Unbind(lua_State *L)
static int32 FScriptDelegate_Unbind(lua_State* L)
{
int32 NumParams = lua_gettop(L);
if (NumParams != 1)
Expand All @@ -76,22 +67,16 @@ static int32 FScriptDelegate_Unbind(lua_State *L)
return 0;
}

FScriptDelegate *Delegate = (FScriptDelegate*)GetCppInstanceFast(L, 1);
if (Delegate)
{
FDelegateHelper::Unbind(Delegate);
}
else
FScriptDelegate* Delegate = (FScriptDelegate*)GetCppInstanceFast(L, 1);
if (Delegate == nullptr)
{
UObject *Object = nullptr;
const void *CallbackFunction = nullptr;
int32 FuncIdx = GetDelegateInfo(L, 1, Object, CallbackFunction); // get target UObject and Lua function
if (FuncIdx != INDEX_NONE)
{
FDelegateHelper::Unbind(FCallbackDesc(Object->GetClass(), CallbackFunction, Object));
}
UNLUA_LOGERROR(L, LogUnLua, Error, TEXT("%s: Invalid parameter!"), ANSI_TO_TCHAR(__FUNCTION__));
return 0;
}

const auto Registry = UnLua::FLuaEnv::FindEnvChecked(L).GetDelegateRegistry();
Registry->Unbind(Delegate);

return 0;
}

Expand All @@ -114,8 +99,8 @@ static int32 FScriptDelegate_Execute(lua_State *L)
return 0;
}

int32 NumReturnValues = FDelegateHelper::Execute(L, Delegate, NumParams - 1, 2);
return NumReturnValues;
const auto Registry = UnLua::FLuaEnv::FindEnvChecked(L).GetDelegateRegistry();
return Registry->Execute(L, Delegate, NumParams + 2, 2);
}

static const luaL_Reg FScriptDelegateLib[] =
Expand Down
105 changes: 105 additions & 0 deletions Plugins/UnLua/Source/UnLua/Private/DelegateRegistry.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
// Tencent is pleased to support the open source community by making UnLua available.
//
// Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
//
// Licensed under the MIT License (the "License");
// you may not use this file except in compliance with the License. You may obtain a copy of the License at
//
// http://opensource.org/licenses/MIT
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and limitations under the License.

#include "DelegateRegistry.h"

#include "LuaDelegateHandler.h"
#include "lauxlib.h"
#include "UEObjectReferencer.h"
#include "UnLuaBase.h"
#include "LuaEnv.h"


UnLua::FDelegateRegistry::FDelegateRegistry(lua_State* GL)
: GL(GL)
{
}

void UnLua::FDelegateRegistry::Bind(lua_State* L, int32 Index, FScriptDelegate* Delegate, UObject* Lifecycle)
{
const auto Type = lua_type(L, Index);
if (Type == LUA_TFUNCTION)
{
auto& Env = FLuaEnv::FindEnvChecked(GL);
lua_pushvalue(L, Index);
const auto Ref = luaL_ref(L, LUA_REGISTRYINDEX);
const auto Handler = NewObject<ULuaDelegateHandler>();
GObjectReferencer.AddObjectRef(Handler);
Handler->BindTo(Delegate, &Env, Ref, Lifecycle);
return;
}

if (Type == LUA_TUSERDATA)
{
const auto Func = (UFunction*)UnLua::GetUObject(L, -1);
Delegate->BindUFunction(Func->GetOuter(), Func->GetFName());
return;
}
}

void UnLua::FDelegateRegistry::Register(FScriptDelegate* Delegate, FDelegateProperty* Property)
{
FDelegateInfo Info;
Info.Property = Property;
Info.Desc = nullptr;
Delegates.Add(Delegate, Info);
}

void UnLua::FDelegateRegistry::Execute(const ULuaDelegateHandler* Handler, void* Params, int32 LuaRef)
{
if (!Handler->IsAlive())
return;

const auto SignatureDesc = GetSignatureDesc(Handler->Delegate);
if (!SignatureDesc)
{
// TODO: should not be here
check(false);
return;
}

const auto L = Handler->Env->GetMainState();
SignatureDesc->CallLua(L, LuaRef, Params, Handler->Lifecycle.Get());
}

int32 UnLua::FDelegateRegistry::Execute(lua_State* L, FScriptDelegate* Delegate, int32 NumParams, int32 FirstParamIndex)
{
auto SignatureDesc = GetSignatureDesc(Delegate);
if (!SignatureDesc)
{
// TODO: should not be here
check(false);
return 0;
}

const auto Ret = SignatureDesc->ExecuteDelegate(L, NumParams, FirstParamIndex, Delegate);
return Ret;
}

FFunctionDesc* UnLua::FDelegateRegistry::GetSignatureDesc(const FScriptDelegate* Delegate)
{
const auto Info = Delegates.Find(Delegate);
if (!Info)
return nullptr;
if (!Info->Desc)
Info->Desc = new FFunctionDesc(Info->Property->SignatureFunction, nullptr);
return Info->Desc;
}

void UnLua::FDelegateRegistry::Unbind(FScriptDelegate* Delegate)
{
FDelegateInfo Info = Delegates.FindAndRemoveChecked(Delegate);
Delegate->Unbind();
delete Info.Desc; // TODO: optimize this
}
42 changes: 42 additions & 0 deletions Plugins/UnLua/Source/UnLua/Private/LuaDelegateHandler.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
// Tencent is pleased to support the open source community by making UnLua available.
//
// Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
//
// Licensed under the MIT License (the "License");
// you may not use this file except in compliance with the License. You may obtain a copy of the License at
//
// http://opensource.org/licenses/MIT
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and limitations under the License.


#include "LuaDelegateHandler.h"
#include "LuaEnv.h"

void ULuaDelegateHandler::Dummy()
{
}

bool ULuaDelegateHandler::IsAlive() const
{
return Lifecycle.IsValid();
}

void ULuaDelegateHandler::BindTo(FScriptDelegate* InDelegate, UnLua::FLuaEnv* InEnv, int32 InLuaRef, UObject* InLifeCycle)
{
static const FName NAME_Invoke = TEXT("Dummy");

Env = InEnv;
LuaRef = InLuaRef;
Lifecycle = InLifeCycle;
Delegate = InDelegate;
Delegate->BindUFunction(this, NAME_Invoke);
}

void ULuaDelegateHandler::ProcessEvent(UFunction* Function, void* Parms)
{
Env->GetDelegateRegistry()->Execute(this, Parms, LuaRef);
}
2 changes: 2 additions & 0 deletions Plugins/UnLua/Source/UnLua/Private/LuaEnv.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,8 @@ namespace UnLua
ClassRegistry->Register("UObject");
ClassRegistry->Register("UClass");

DelegateRegistry = new FDelegateRegistry(L);

lua_pushstring(L, "ObjectMap"); // create weak table 'ObjectMap'
CreateWeakValueTable(L);
lua_rawset(L, LUA_REGISTRYINDEX);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -245,6 +245,15 @@ bool FFunctionDesc::CallLua(UObject *Context, FFrame &Stack, void *RetValueAddre
return bSuccess;
}

bool FFunctionDesc::CallLua(lua_State* L, int32 LuaRef, void* Params, UObject* Self)
{
bool bOk = PushFunction(L, Self, LuaRef);
if (!bOk)
return false;
bOk = CallLuaInternal(L, Params, nullptr, nullptr); // call Lua function...
return bOk;
}

/**
* Call the UFunction
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,8 @@ class FFunctionDesc
*/
bool CallLua(UObject *Context, FFrame &Stack, void *RetValueAddress, bool bRpcCall, bool bUnpackParams);

bool CallLua(lua_State* L, int32 LuaRef, void* Params, UObject* Self);

/**
* Call this UFunction
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
#include "ReflectionRegistry.h"
#include "LuaCore.h"
#include "DelegateHelper.h"
#include "LuaEnv.h"
#include "Containers/LuaSet.h"
#include "Containers/LuaMap.h"
#include "UEObjectReferencer.h"
Expand Down Expand Up @@ -1340,6 +1341,7 @@ class FDelegatePropertyDesc : public FStructPropertyDesc
else
{
FScriptDelegate *ScriptDelegate = DelegateProperty->GetPropertyValuePtr((void*)ValuePtr);
UnLua::FLuaEnv::FindEnvChecked(L).GetDelegateRegistry()->Register(ScriptDelegate, DelegateProperty);
FDelegateHelper::PreBind(ScriptDelegate, DelegateProperty);
UnLua::PushPointer(L, ScriptDelegate, "FScriptDelegate", bFirstPropOfScriptStruct);
}
Expand Down
51 changes: 51 additions & 0 deletions Plugins/UnLua/Source/UnLua/Public/DelegateRegistry.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
// Tencent is pleased to support the open source community by making UnLua available.
//
// Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
//
// Licensed under the MIT License (the "License");
// you may not use this file except in compliance with the License. You may obtain a copy of the License at
//
// http://opensource.org/licenses/MIT
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and limitations under the License.

#pragma once

#include "lua.h"
#include "LuaDelegateHandler.h"
#include "ReflectionUtils/FunctionDesc.h"

namespace UnLua
{
class FDelegateRegistry
{
public:
explicit FDelegateRegistry(lua_State* GL);

lua_State* GL;

void Bind(lua_State* L, int32 Index, FScriptDelegate* Delegate, UObject* Lifecycle);

void Register(FScriptDelegate* ScriptDelegate, FDelegateProperty* DelegateProperty);

void Execute(const ULuaDelegateHandler* Handler, void* Params, int32 LuaRef);

int32 Execute(lua_State* L, FScriptDelegate* Delegate, int32 NumParams, int32 FirstParamIndex);

void Unbind(FScriptDelegate* Delegate);

private:
FFunctionDesc* GetSignatureDesc(const FScriptDelegate* Delegate);

struct FDelegateInfo
{
FDelegateProperty* Property;
FFunctionDesc* Desc;
};

TMap<FScriptDelegate*, FDelegateInfo> Delegates;
};
}
45 changes: 45 additions & 0 deletions Plugins/UnLua/Source/UnLua/Public/LuaDelegateHandler.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
// Tencent is pleased to support the open source community by making UnLua available.
//
// Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
//
// Licensed under the MIT License (the "License");
// you may not use this file except in compliance with the License. You may obtain a copy of the License at
//
// http://opensource.org/licenses/MIT
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and limitations under the License.

#pragma once

#include "CoreMinimal.h"
#include "UObject/Object.h"
#include "LuaDelegateHandler.generated.h"

namespace UnLua
{
class FLuaEnv;
}

UCLASS()
class UNLUA_API ULuaDelegateHandler : public UObject
{
GENERATED_BODY()

public:
UFUNCTION()
void Dummy();

bool IsAlive() const;

void BindTo(FScriptDelegate* Delegate, UnLua::FLuaEnv* InEnv, int32 InLuaRef, UObject* InLifecycle);

virtual void ProcessEvent(UFunction* Function, void* Parms) override;

TWeakObjectPtr<UObject> Lifecycle;
FScriptDelegate* Delegate;
UnLua::FLuaEnv* Env;
int32 LuaRef;
};
4 changes: 4 additions & 0 deletions Plugins/UnLua/Source/UnLua/Public/LuaEnv.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#pragma once

#include "ClassRegistry.h"
#include "DelegateRegistry.h"
#include "UnLuaManager.h"
#include "lua.h"
#include "LuaValue.h"
Expand Down Expand Up @@ -92,6 +93,8 @@ namespace UnLua

FClassRegistry* GetClassRegistry() const { return ClassRegistry; }

FDelegateRegistry* GetDelegateRegistry() const { return DelegateRegistry; }

void AddLoader(const FLuaFileLoader Loader);

void AddBuiltInLoader(const FString Name, lua_CFunction Loader);
Expand Down Expand Up @@ -129,6 +132,7 @@ namespace UnLua
FCriticalSection CandidatesLock;
UUnLuaManager* Manager;
FClassRegistry* ClassRegistry;
FDelegateRegistry* DelegateRegistry;
TMap<lua_State*, int32> ThreadToRef;
TMap<int32, lua_State*> RefToThread;
FDelegateHandle OnAsyncLoadingFlushUpdateHandle;
Expand Down
1 change: 1 addition & 0 deletions TPSProject.sln.DotSettings
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CppFormatting/INDENT_STYLE/@EntryValue">Space</s:String>
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/INDENT_STYLE/@EntryValue">Space</s:String>
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ECSharpKeepExistingMigration/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ECSharpPlaceEmbeddedOnSameLineMigration/@EntryIndexedValue">True</s:Boolean>
Expand Down

0 comments on commit b059468

Please sign in to comment.