CommonDelegate解决方案
实现业务时,经常需要用到全局级别的 CommonDelegate
;
定义如下 UTestCommonDelegate
,即可定义出 UTestCommonDelegate::GetDelegate()->OnTestEvent
这样的一个 Delegate
;
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
|
UCLASS() class UTestCommonDelegate : public UCommonDelegateBase { GENERATED_BODY()
public: UFUNCTION() static UTestCommonDelegate* GetDelegate() { return GetCommonDelegate<UTestCommonDelegate>(); } public: DECLARE_DELEGATE_AnyParams(FTestEvent, int32 ); FTestEvent OnTestEvent; }
|
CommonDelegateBase
首先定义 UCommonDelegateBase
作为所有 Delegate
的基类;
1 2 3 4 5 6 7
|
UCLASS(Abstract) class UCommonDelegateBase : public UObject { GENERATED_BODY() };
|
定义 GlobalCommonDelegates
用于存储全局的所有 Delegates
;
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| USTRUCT() struct FCommonDelegates { GENERATED_BODY()
public: TMap<TSubclassOf<UCommonDelegateBase>, UCommonDelegateBase*>* GetDelegateMap() { return &DelegateMap; } private: UPROPERTY() TMap<TSubclassOf<UCommonDelegateBase>, UCommonDelegateBase*> DelegateMap; };
extern FCommonDelegates GlobalCommonDelegates;
|
在 GetDelegate
中尝试寻找或创建 Delegate
,将其 AddToRoot
;
同时提供 DeleteAllCommonDelegates
在合适的时候(比如切换 World
)调用,清空所有数据;
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
| template<class T> typename TEnableIf<TIsDerivedFrom<T, UCommonDelegateBase>::Value, T*>::Type GetCommonDelegate() { auto DelegateMap = GlobalCommonDelegates.GetDelegateMap(); if (DelegateMap == nullptr) return nullptr;
if (auto Delegate = DelegateMap->FindRef(T::StaticClass()); IsValid(Delegate)) { return Cast<T>(Delegate); }
auto NewDelegate = NewObject<T>(); NewDelegate->AddToRoot(); DelegateMap->FindOrAdd(T::StaticClass()) = NewDelegate; return NewDelegate; }
void DeleteAllCommonDelegates() { auto DelegateMap = GlobalCommonDelegates.GetDelegateMap(); if (DelegateMap == nullptr) return nullptr;
for (auto DelegatePair : *DelegateMap) { if (IsValid(DelegatePair.Value)) { DelegatePair.Value->RemoveFromRoot(); } }
DelegateMap->Empty(); }
|
DeclareAnyParams
一般的 DECLARE_DELEGATE
需要写明 Params
的个数;比如 DECLARE_MULTICAST_DELEGATE_OneParam
,这里限定了 OneParam
;
实际上,可以看到在 Engine\Source\Runtime\Core\Public\Delegates\Delegate.h
中,支持添加 AnyParams
:
1 2 3 4 5 6 7 8 9 10 11 12 13
|
#define FUNC_DECLARE_DELEGATE( DelegateName, ReturnType, ... ) \ typedef TDelegate<ReturnType(__VA_ARGS__)> DelegateName;
#define FUNC_DECLARE_MULTICAST_DELEGATE( MulticastDelegateName, ReturnType, ... ) \ typedef TMulticastDelegate<ReturnType(__VA_ARGS__)> MulticastDelegateName;
#define FUNC_DECLARE_EVENT( OwningType, EventName, ReturnType, ... ) \ class EventName : public TMulticastDelegate<ReturnType(__VA_ARGS__)> \ { \ friend class OwningType; \ };
|
于是可以对非 DYNAMIC
的 DELEGATE
添加声明,
直接在 Engine\Source\Runtime\Core\Public\Delegates\DelegateCombinations.h
中补充:
1 2 3 4
| #define DECLARE_DELEGATE_AnyParams( DelegateName, ... ) FUNC_DECLARE_DELEGATE( DelegateName, void, __VA_ARGS__ ) #define DECLARE_MULTICAST_DELEGATE_AnyParams( DelegateName, ... ) FUNC_DECLARE_MULTICAST_DELEGATE( DelegateName, void, __VA_ARGS__ ) #define DECLARE_EVENT_AnyParams( OwningType, EventName, ... ) FUNC_DECLARE_EVENT( OwningType, EventName, void, __VA_ARGS__ ) #define DECLARE_DELEGATE_RetVal_AnyParams( ReturnValueType, DelegateName, ... ) FUNC_DECLARE_DELEGATE( DelegateName, ReturnValueType, __VA_ARGS__ )
|