c6.1Delegate|实践
大约 4 分钟
单播委托
1. 声明委托:
DECLARE_DELEGATE(FMyDelegate);//无参数
DECLARE_DELEGATE_OneParam(FMyDelegateOneParam,int32);//带参数
2. 定义委托实例:
在类中定义委托的实例:
FMyDelegate MyDelegate;//纯C++无参单播
UFUNCTION(BlueprintAssignable, Category = "MyCategory")//暴露给蓝图
FMyDelegate MyDelegate2;
FMyDelegateOneParam MyDelegateOneParam;//一个参数的单播
3. 绑定和解绑委托:
在构造函数或其他地方绑定和解绑委托:
在合适的实际绑定或者解绑委托
// 绑定委托
MyDelegate.BindUObject(this, &AMyActor::MyFunction);
//解绑
MyDelegate.Unbind();
//绑定带参数的委托
MyDelegateOneParam.BindUObject(this, &AMyActor::MyFunctionWithParam);
// 解绑委托
MyDelegateOneParam.Unbind();
4. 委托的回调函数:
定义委托回调的成员函数:
UFUNCTION()
void MyFunction()
{
//无参数单播委托被触发时执行的代码
}
UFUNCTION()
void MyFunctionWithParam()
{
// 带参数单播委托被触发时执行的代码
}
5. 触发委托:
在适当的地方触发委托:
// 触发委托
MyDelegate.ExecuteIfBound();
// 触发带参数的委托
MyDelegateWithParam.ExecuteIfBound(42);
Lambda
合理利用Lambda表达式
FInfoUpdatedDelegate DynamicDelegate;
DynamicDelegate.CreateLambda([this,&DynamicDelegate]()
{
、、、、、
//用完后解绑
DynamicDelegate.Unbind();
});
球体例子
1. 新建Actor类添加对应组件
//静态网格物体
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "EquipmentMesh", meta = (AllowPrivateAccess = "true"))
TObjectPtr<UStaticMeshComponent> StaticMesh;
// 球形触发器
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Trigger", meta = (AllowPrivateAccess = "true"))
TObjectPtr<USphereComponent> TriggerSphere;
2. 球体组件委托绑定
注
线程安全(Thread Safety)是指一个程序或者代码在多线程环境下执行时,能够保持正确的行为。当多个线程同时访问共享的数据或资源时,如果没有适当的同步机制,可能导致不确定的结果,甚至引发一些难以调试和修复的问题。线程安全的目标是确保在多线程环境中程序的行为是可预测和正确的。
竞态条件(Race Condition): 当两个或多个线程同时访问共享资源,并且至少一个线程对资源进行了写操作,就可能发生竞态条件。这可能导致不一致的结果,因为线程执行的顺序是不确定的。
互斥锁(Mutex): 互斥锁是一种用于保护共享资源的同步机制。它确保在任何时刻,只有一个线程能够访问共享资源,其他线程必须等待锁被释放。
死锁(Deadlock): 死锁是指两个或多个线程无限期地阻塞等待彼此持有的锁。这种情况会导致程序无法继续执行。
原子操作(Atomic Operation): 原子操作是不可被中断的操作,它在执行时不会被其他线程干扰。在多线程环境中,原子操作可以用来确保某些操作的完整性,而不会受到其他线程的影响。
可重入性(Reentrancy): 可重入性是指一个函数可以被多个线程同时调用,而不会导致不确定的行为。函数内部使用的资源应该是线程私有的或者受到适当的同步控制。
void AEquipmentBase::BeginPlay()
{
Super::BeginPlay();
TriggerSphere->OnComponentBeginOverlap.AddDynamic(this, &AEquipmentBase::OnBeginOverlap);
TriggerSphere->OnComponentEndOverlap.AddDynamic(this, &AEquipmentBase::OnEndOverlap);
}
3. 回调函数
UFUNCTION()
void OnBeginOverlap( UPrimitiveComponent* OverlappedComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult & SweepResult);
UFUNCTION()
void OnEndOverlap(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex);