Skip to content

Instantly share code, notes, and snippets.

@ZornTaov
Created January 11, 2022 20:11
Show Gist options
  • Save ZornTaov/86ded32bf497f7691ab077c46f956aa2 to your computer and use it in GitHub Desktop.
Save ZornTaov/86ded32bf497f7691ab077c46f956aa2 to your computer and use it in GitHub Desktop.
Delegate wrapper examples, might not be the best.
#include "DelegateTest.h"
void UDelegateTest::RegisterDelegate(FOnDelegate& Del)
{
if (!OnDelegate.IsBound())
{
OnDelegate = Del;
return;
}
UE_LOG(LogTemp, Warning, TEXT("OnComplete already Bound, ignoring as I can only have one binding."));
}
void UDelegateTest::RegisterMulti(FOnMulti::FDelegate& Del)
{
// uncomment if you want to ensure uniqueness
//if (!OnMulti.IsBoundToObject(Del.GetUObject()))
{
OnMulti.Add(Del);
}
}
void UDelegateTest::UnregisterDelegate()
{
if (OnDelegate.IsBound())
{
OnDelegate.Unbind();
}
}
bool UDelegateTest::UnregisterMulti(FOnMulti::FDelegate& Del)
{
if (OnMulti.IsBoundToObject(Del.GetUObject()))
{
return OnMulti.Remove(Del.GetHandle());
}
UE_LOG(LogTemp, Warning, TEXT("OnMulti doesn't have that binding."));
return false;
}
void UDelegateTest::ExecuteDelegates()
{
OnDelegate.ExecuteIfBound(this);
OnMulti.Broadcast(this);
}
#pragma once
#include "CoreMinimal.h"
#include "DelegateTest.generated.h"
class UDelegateTest;
DECLARE_DELEGATE_OneParam(FOnDelegate, UDelegateTest*);
DECLARE_MULTICAST_DELEGATE_OneParam(FOnMulti, UDelegateTest*);
UCLASS()
class TDTD_CPP_API UDelegateTest : public UObject
{
GENERATED_BODY()
public:
UDelegateTest() { }
int called = 0;
// Define delegates and Register/Unregister
FOnDelegate OnDelegate;
FOnMulti OnMulti;
void RegisterDelegate(FOnDelegate& Del);
void RegisterMulti(FOnMulti::FDelegate& Del);
void UnregisterDelegate();
bool UnregisterMulti(FOnMulti::FDelegate& Del);
void ExecuteDelegates();
};
#include "DelegateTester.h"
void UDelegateTester::SetupTest()
{
UDelegateTest* Test = NewObject<UDelegateTest>(this);
// Generate a regular Delegate and bind
FOnDelegate OnDelegate = FOnDelegate::CreateUObject(this, &UDelegateTester::Test);
Test->RegisterDelegate(OnDelegate);
// Generate a Multicast Delegate and bind
FOnMulti::FDelegate OnDoneMulti = FOnMulti::FDelegate::CreateUObject(this, &UDelegateTester::Test);
Test->RegisterMulti(OnDoneMulti);
// if allowed, you can register one delegate multiple times
Test->RegisterMulti(OnDoneMulti);
// if the Delegate is defined the same as the Multicast Delegate, you can use it as well
Test->RegisterMulti(OnDelegate);
// will print 4 times
Test->ExecuteDelegates();
// unregister existing binding
Test->UnregisterDelegate();
// unregister works only if it's with the same FDelegate, and will only remove one instance
Test->UnregisterMulti(OnDoneMulti);
// doesn't work to remove existing multicast delegates, as the Handle ID is different
FOnMulti::FDelegate OnDoneMulti2 = FOnMulti::FDelegate::CreateUObject(this, &UDelegateTester::Test);
if(!Test->UnregisterMulti(OnDoneMulti2))
UE_LOG(LogTemp, Warning, TEXT("OnDoneMulti2 wasn't unbound."));
// will print 2 times
Test->ExecuteDelegates();
// cleanup
Test->UnregisterMulti(OnDelegate);
Test->UnregisterMulti(OnDoneMulti);
// will not print
Test->ExecuteDelegates();
}
void UDelegateTester::Test(UDelegateTest* Test)
{
UE_LOG(LogTemp, Display, TEXT("Test called %d times."), Test->called++);
}
#pragma once
#include "CoreMinimal.h"
#include "UObject/Object.h"
#include "DelegateTest.h"
#include "DelegateTester.generated.h"
UCLASS()
class TDTD_CPP_API UDelegateTester : public UObject
{
public:
GENERATED_BODY()
void SetupTest();
void Test(UDelegateTest* Test);
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment