UE 代理

省流:

// 定义类型

DECLARE_DELEGATE(FDelegateTaskA)
DECLARE_DELEGATE_OneParam(FDelegateTaskB, bool)
DECLARE_DELEGATE_RetVal(bool, FDelegateTaskC)
DECLARE_DELEGATE_RetVal_OneParam(int32, FDelegateTaskD, FString&)

// 声明实例

FDelegateTaskA DelegateTaskA;
FDelegateTaskB DelegateTaskB;
FDelegateTaskC DelegateTaskC;
FDelegateTaskD DelegateTaskD;

// 绑定

XXX.BindRaw // 普通C函数
XXX.BindSP  // 共享指针
XXX.BindUObject // UObject的函数
XXX.BindStatic // 全局静态
XXX.BindUFunction // UFunction

// 调用 

if (XXX.IsBound()) 
{ 
    XXX.Execute() 
} 

XXX.ExecuteIfBound()

// 记得解绑定
// XXX.UnBind()

// 多播
// 定义
DECLARE_MULTICAST_DELEGATE(FDelegateTaskE)
// 绑定函数变成 Add开头,可以加多个,调用变成 Broadcast 记得最后 Clear

一,原生C代理

// Fill out your copyright notice in the Description page of Project Settings.

#pragma once

#include "CoreMinimal.h"

DECLARE_DELEGATE(FDelegateTaskA)
DECLARE_DELEGATE_OneParam(FDelegateTaskB, bool)
DECLARE_DELEGATE_RetVal(bool, FDelegateTaskC)
DECLARE_DELEGATE_RetVal_OneParam(int32, FDelegateTaskD, FString&)

static void PrintF(FString InString)
{
    if (GEngine)
    {
        GEngine->AddOnScreenDebugMessage(-1, 20, FColor::Red, InString);
    }
}

class FClassA
{
public:
    FDelegateTaskA DelegateTaskA;
    FDelegateTaskB DelegateTaskB;
    FDelegateTaskC DelegateTaskC;
    FDelegateTaskD DelegateTaskD;

    void Init()
    {
        bool bIsRight = false;
        int32 Index = INDEX_NONE;
        FString InString = TEXT("Hello");

        bIsRight = DelegateTaskA.ExecuteIfBound();

        bIsRight = DelegateTaskB.ExecuteIfBound(bIsRight);

        if (DelegateTaskC.IsBound())
        {
            bIsRight = DelegateTaskC.Execute();
        }

        if (DelegateTaskD.IsBound())
        {
            Index = DelegateTaskD.Execute(InString);
        }
    }
};

class FClassB
{
public:
    explicit FClassB(FClassA* InObjA)
        : ObjA(InObjA)
    {
        if (ObjA)
        {
            ObjA->DelegateTaskA.BindRaw(this, &FClassB::ExcuteA);
            ObjA->DelegateTaskB.BindRaw(this, &FClassB::ExcuteB);
            ObjA->DelegateTaskC.BindRaw(this, &FClassB::ExcuteC);
            ObjA->DelegateTaskD.BindRaw(this, &FClassB::ExcuteD);    
        }
    }
    ~FClassB()
    {
        if (ObjA)
        {
            ObjA->DelegateTaskA.Unbind();
            ObjA->DelegateTaskB.Unbind();
            ObjA->DelegateTaskC.Unbind();
            ObjA->DelegateTaskD.Unbind();

            ObjA->Init();

            delete ObjA;
            ObjA = nullptr;
        }
    }

    void ExcuteA()
    {
        PrintF(TEXT("ExcuteA"));
    }

    void ExcuteB(bool bIsRight)
    {
        PrintF(TEXT("ExcuteB"));
    }

    bool ExcuteC()
    {
        PrintF(TEXT("ExcuteC"));
        return false;
    }

    int32 ExcuteD(FString& InString)
    {
        PrintF(TEXT("ExcuteD"));
        return 0;
    }

private:
    FClassA* ObjA;
};

调用随便找个beginplay

void AMyActor::BeginPlay()
{
    Super::BeginPlay();

    FClassA* ObjA = new FClassA();
    FClassB* ObjB = new FClassB(ObjA);

    ObjA->Init();
    delete ObjB;

    ObjA = nullptr;
    ObjB = nullptr;
}

二,共享指针代理

class FClassB : public TSharedFromThis<FClassB>
{
public:
    FClassB() = default;

    void Init()
    {
        ObjA = MakeShareable(new FClassA());
        ObjA->DelegateTaskA.BindSP(this, &FClassB::ExcuteA);
        ObjA->DelegateTaskB.BindSP(this, &FClassB::ExcuteB);
        ObjA->DelegateTaskC.BindSP(this, &FClassB::ExcuteC);
        ObjA->DelegateTaskD.BindSP(this, &FClassB::ExcuteD);
        ObjA->Init();
    }

    ~FClassB()
    {
        if (ObjA.Get())
        {
            ObjA->DelegateTaskA.Unbind();
            ObjA->DelegateTaskB.Unbind();
            ObjA->DelegateTaskC.Unbind();
            ObjA->DelegateTaskD.Unbind();
            ObjA->Init();
        }
    }

    // ...

    FORCEINLINE TSharedRef<FClassA> GetA() { return ObjA.ToSharedRef(); }
private:
    TSharedPtr<FClassA> ObjA;
};

调用

    TSharedPtr<FClassB> ObjB = MakeShareable(new FClassB());
    ObjB->Init();

三,UObject代理

在Actor里面定义代理

    FDelegateTaskA DelegateTaskA;

    void ActorPrint()
    {
        PrintF("Hello");
    }

然后绑定调用

void AMyActor::BeginPlay()
{
    Super::BeginPlay();

    DelegateTaskA.BindUObject(this, &AMyActor::ActorPrint);
    bool bSucc = DelegateTaskA.ExecuteIfBound();
}

四,全局静态代理

static void StaticPrint()
{
    PrintF("StaticPrint");
}

void AMyActor::BeginPlay()
{
    Super::BeginPlay();

    DelegateTaskA.BindStatic(StaticPrint);
    bool bSucc = DelegateTaskA.ExecuteIfBound();
}

五,UFunction代理

    UFUNCTION()
    void ActorPrint()
    {
        PrintF("Hello");
    }
void AMyActor::BeginPlay()
{
    Super::BeginPlay();

    DelegateTaskA.BindUFunction(this, TEXT("ActorPrint"));
    bool bSucc = DelegateTaskA.ExecuteIfBound();
}

六,多播

// Fill out your copyright notice in the Description page of Project Settings.

#pragma once

#include "CoreMinimal.h"

DECLARE_MULTICAST_DELEGATE(FDelegateTaskE)

static void PrintF(FString InString)
{
    if (GEngine)
    {
        GEngine->AddOnScreenDebugMessage(-1, 20, FColor::Red, InString);
    }
}

class FClassA
{
public:
    FDelegateTaskE DelegateTaskE;
};

class FClassB
{
public:
    FClassB() = default;

    void Init()
    {
        ObjA = new FClassA();
        ObjA->DelegateTaskE.AddRaw(this, &FClassB::ExcuteA);
        ObjA->DelegateTaskE.AddRaw(this, &FClassB::ExcuteB);
        ObjA->DelegateTaskE.Broadcast();
        ObjA->DelegateTaskE.Clear();
        delete ObjA;
    }

    void ExcuteA()
    {
        PrintF(TEXT("ExcuteA"));
    }

    void ExcuteB()
    {
        PrintF(TEXT("ExcuteB"));
    }

private:
    FClassA* ObjA;
};
    FClassB* B = new FClassB();
    B->Init();

多播就定义不一样,bindXXX变成addXXX
调用变成 Broadcast 清空用Clear 其他都一样

七,动态单播多播

// Fill out your copyright notice in the Description page of Project Settings.

#pragma once

#include "CoreMinimal.h"
#include "C_Function.generated.h"

DECLARE_DYNAMIC_DELEGATE_OneParam(FDelegateTaskA, const FString&, Str_C);
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FDelegateTaskB, const FString&, Str_C);

static void PrintF(FString InString)
{
    if (GEngine)
    {
        GEngine->AddOnScreenDebugMessage(-1, 20, FColor::Red, InString);
    }
}

UCLASS()
class UMyClass : public UObject
{
    GENERATED_BODY()
public:
    FDelegateTaskA DelegateTaskA;
    FDelegateTaskB DelegateTaskB;

    void Init()
    {
        DelegateTaskA.BindDynamic(this, &UMyClass::MyPrintA);
        DelegateTaskA.BindDynamic(this, &UMyClass::MyPrintB);

        const FString Hello = TEXT("Hello");
        bool bSucc = DelegateTaskA.ExecuteIfBound(Hello);  // 只打印了 B 因为是单播
        DelegateTaskA.Unbind();

        // DelegateTaskB.AddDynamic()
        // DelegateTaskB.RemoveAll()
    }

    UFUNCTION()
    void MyPrintA(const FString& InStr)
    {
        PrintF(InStr + TEXT("A"));
    }

    UFUNCTION()
    void MyPrintB(const FString& InStr)
    {
        PrintF(InStr + TEXT("B"));
    }
};
// Fill out your copyright notice in the Description page of Project Settings.

#pragma once

#include "CoreMinimal.h"
#include "C_Function.generated.h"

DECLARE_DYNAMIC_DELEGATE_OneParam(FDelegateTaskA, const FString&, Str_C);
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FDelegateTaskB, const FString&, Str_C);

static void PrintF(FString InString)
{
    if (GEngine)
    {
        GEngine->AddOnScreenDebugMessage(-1, 20, FColor::Red, InString);
    }
}

UCLASS()
class UMyClass : public UObject
{
    GENERATED_BODY()
public:
    FDelegateTaskA DelegateTaskA;
    FDelegateTaskB DelegateTaskB;

    void Init()
    {
        DelegateTaskB.AddDynamic(this, &UMyClass::MyPrintA);
        DelegateTaskB.AddDynamic(this, &UMyClass::MyPrintB);

        const FString Hello = TEXT("Hello");
        DelegateTaskB.Broadcast(Hello);  // 只打印了 B 因为是单播
        DelegateTaskB.RemoveAll(this);

        DelegateTaskB.Broadcast(Hello);
        // DelegateTaskB.AddDynamic()
        // DelegateTaskB.RemoveAll()
    }

    UFUNCTION()
    void MyPrintA(const FString& InStr)
    {
        PrintF(InStr + TEXT("A"));
    }

    UFUNCTION()
    void MyPrintB(const FString& InStr)
    {
        PrintF(InStr + TEXT("B"));
    }
};

八,多态事件代理

// Fill out your copyright notice in the Description page of Project Settings.

#pragma once

#include "CoreMinimal.h"

static void PrintF(FString InString)
{
    if (GEngine)
    {
        GEngine->AddOnScreenDebugMessage(-1, 20, FColor::Red, InString);
    }
}

class FEventTask
{
public:
    virtual ~FEventTask() = default;

    DECLARE_EVENT_OneParam(FEventTask, FEventTaskDeclare, const FString&)
    virtual FEventTaskDeclare& OnEventTaskDeclare() = 0;

    DECLARE_EVENT_OneParam(FEventTask, FEventDeclare, const FString&)
    FEventDeclare& OnEventDeclare() { return EventDeclare; }

private:
    FEventDeclare EventDeclare;
};

class FEventTaskChild : public FEventTask
{
public:
    DECLARE_DERIVED_EVENT(FEventTaskChild, FEventTask::FEventTaskDeclare, FEventTaskName);
    virtual FEventTaskName& OnEventTaskDeclare() override { return  EventTaskName; }

    void Init()
    {
        FString NewStr = "Hello";
        OnEventTaskDeclare().Broadcast(NewStr);

        NewStr = "World";
        OnEventDeclare().Broadcast(NewStr);
    }
private:
    FEventTaskName EventTaskName;
};

class FATask
{
public:
    void Init()
    {
        FEventTaskChild* Child = new FEventTaskChild();
        Child->OnEventTaskDeclare().AddRaw(this, &FATask::ExcuteA);
        Child->OnEventTaskDeclare().AddRaw(this, &FATask::ExcuteB);

        Child->OnEventDeclare().AddRaw(this, &FATask::ExcuteA);
        Child->OnEventDeclare().AddRaw(this, &FATask::ExcuteB);

        Child->Init();
    }

    void ExcuteA(const FString& InStr)
    {
        PrintF(TEXT("ExcuteA") + InStr);
    }
    void ExcuteB(const FString& InStr)
    {
        PrintF(TEXT("ExcuteB") + InStr);
    }
    void ExcuteC(const FString& InStr)
    {
        PrintF(TEXT("ExcuteC") + InStr);
    }
    void ExcuteD(const FString& InStr)
    {
        PrintF(TEXT("ExcuteD") + InStr);
    }
};
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇