普通单播的定义
#define DECLARE_DELEGATE( DelegateName ) FUNC_DECLARE_DELEGATE( DelegateName, void )
#define FUNC_DECLARE_DELEGATE( DelegateName, ... ) \
typedef TBaseDelegate<__VA_ARGS__> DelegateName;
class TBaseDelegate<void, ParamTypes...>: public TBaseDelegate<TTypeWrapper<void>, ParamTypes...>
{
// ···
}
实际上是一个TBaseDelegate子类, 看父类TBaseDelegate<TTypeWrapper, ParamTypes…>的定义
template <typename WrappedRetValType, typename... ParamTypes>
class TBaseDelegate : public FDelegateBase
{
public:
/** 定义了返回的类型. */
typedef typename TUnwrapType<WrappedRetValType>::Type RetValType;
// 定义一个带有返回类型和参数的函数类型
typedef RetValType TFuncType(ParamTypes...);
/** 与此委托类兼容的委托实例类型的共享接口的类型定义. */
typedef IBaseDelegateInstance<TFuncType> TDelegateInstanceInterface;
FORCEINLINE TDelegateInstanceInterface* GetDelegateInstanceProtected() const
{
return (TDelegateInstanceInterface*)FDelegateBase::GetDelegateInstanceProtected();
}
}
内部定义了一个与此委托类兼容的委托实例类型IBaseDelegateInstance,而IBaseDelegateInstance继承自IBaseDelegateInstanceCommon
struct IBaseDelegateInstanceCommon<RetType(ArgTypes...)> : public IDelegateInstance
{
virtual void CreateCopy(FDelegateBase& Base) = 0;
virtual RetType Execute(ArgTypes...) const = 0;
};
IBaseDelegateInstanceCommon的模板参数RetType和ArgTyes和TBaseDelegate里面的模板参数对应。
之后要介绍的绑定C++原生函数TBaseRawMethodDelegateInstance,绑定UObject对象成员函数TBaseUObjectMethodDelegateInstance,绑定UFunction的TBaseUFunctionDelegateInstance和绑定Lambada的TBaseFunctorDelegateInstance,都继承自IBaseDelegateInstance。
然后讲一讲FDelegateBase,它是单播代理类的祖先类
class FDelegateBase
{
public:
FDelegateBase& operator=(FDelegateBase&& Other)
{
Unbind();
DelegateAllocator.MoveToEmpty(Other.DelegateAllocator);
DelegateSize = Other.DelegateSize;
Other.DelegateSize = 0;
return *this;
}
FORCEINLINE IDelegateInstance* GetDelegateInstanceProtected( ) const
{
return DelegateSize ? (IDelegateInstance*)DelegateAllocator.GetAllocation() : nullptr;
}
private:
FDelegateAllocatorType::ForElementType<FAlignedInlineDelegateType> DelegateAllocator;
int32 DelegateSize;
};
DelegateAllocator存储一个IDelegateInstance对象, 通过它来实现代理,获取代理的方式就是上面代码里的GetDelegateInstanceProtected(),这个方法会在TBaseDelegate里调用。
DelegateAllocator实际上是一个ForElementType类型, 继承自ForAnyElementType,MoveToEmpty方法,以级现在的GetAllocation方法,都是定义在ForAnyElementType中的
template<typename ElementType>
class ForElementType : public ForAnyElementType
{
public:
FORCEINLINE ElementType* GetAllocation() const
{
// 调用基类的GetAllocation()方法
return (ElementType*)ForAnyElementType::GetAllocation();
}
};
class CORE_API ForAnyElementType
{
public:
FORCEINLINE void MoveToEmpty(ForAnyElementType& Other)
{