언리얼 - 델리게이트(멀티캐스트 델리게이트, 다이나믹 델리게이트, 이벤트)

안영욱·2023년 2월 21일
0

언리얼

목록 보기
4/5
post-thumbnail

언리얼의 Delegate(델리게이트), multiCastDelegate(멀티캐스트 델리게이트),DynamicDelegate(다이나믹 델리게이트)
그리고 Event(이벤트)에대해 알아보겠습니다.


1. Delegate 란

Delegate는 C++오브젝트 상의 멤버함수를 안전하게 호출할수 있는 기능이다.
Delegate로 지정한 오브젝트의 멤버함수를 동적으로 바인딩 시킬수있어 유동적으로 사용가능하다.
Delegate는 호출하고자하는 함수를 갖고있는 오브젝트의 유형을 알필요가없다.
Delegate를 사용할때 값 전달이 가능하지만 이때 heap메모리에 할당하기에 참조 전달 방식이 권장된다.
Delegate싱글 캐스트, 멀티 캐스트 둘다지원한다.

  • 싱글 캐스트는 1대1 통신과 비슷하다 한객체에 한함수만 호출시킬수있다.
  • 멀티 캐스트는 1대n 통신과 비슷하다 한 함수를 호출하면 해당 함수를 가지고있는 바인딩된 모든 객체를 호출한다.

1-1. MultiCastDelegate 란

MultiCastDelegateSingleCastDelegate의 특징을 대부분 갖지만 1대n을 관리할때 사용된다.
MultiCastDelegate반환값을 사용할수없다.(여러 객체마다 반환하는값이 다르기때문에)


1-2. DynamicDelegate 란

DynamicDelegateDelegate와 일반적으로 비슷하지만
Delegate는 빌드타임에 바인딩이 이루어지고 런타임에서는 바인딩 수정이 불가능하다.
DynamicDelegate는 런타임에서도 동적으로 바인딩 시켜줄수있다.


1-3. Event 란

EventMultiCastDelegate와 일반적으로 비슷하지만
Event선언한 클래스만Broadcast, IsBound, Clear 함수를 호출할수있다.
그렇기에 외부 클래스에서 Broadcast, IsBound, Clear 함수를 제한하며 접근권을 확보할때 사용할수있다.


2. Delegate 선언하기

Delegate 선언은 제공되는 매크로중 하나로 이루어진다, 사용되는 매크로는 Delegate와 바인딩되는 함수의 시그니처에따라 결정된다.

  • 시그니처는 함수의 반환자, 매개변수 로 구성되는 것들을 말한다. 예) void 반환타입에 int 매게변수를 가지는 함수 - void(int)

다음과 같은 타입들은 Delegate시그니처가 지원되는 타입들이다.

  • 값을 반환하는 함수
  • "페이로드"(payload, 유상) 변수 4 개 까지
  • 함수 파라미터 8 개 까지
  • 'const' 로 선언된 함수

시그니처 에따른 Delegate매크로들은 다음과 같다.

함수 시그너처선언 매크로
void Function()DECLARE_DELEGATE( DelegateName )
void Function( <Param1> )DECLARE_DELEGATE_OneParam( DelegateName, Param1Type )
void Function( <Param1>, <Param2> )DECLARE_DELEGATE_TwoParams( DelegateName, Param1Type, Param2Type )
void Function( <Param1>, <Param2>, ... )DECLARE_DELEGATE_<Num>Params( DelegateName, Param1Type, Param2Type, ... )
<RetVal> Function()DECLARE_DELEGATE_RetVal( RetValType, DelegateName )
<RetVal> Function( <Param1> )DECLARE_DELEGATE_RetVal_OneParam( RetValType, DelegateName, Param1Type )
<RetVal> Function( <Param1>, <Param2> )DECLARE_DELEGATE_RetVal_TwoParams( RetValType, DelegateName, Param1Type, Param2Type )
<RetVal> Function( <Param1>, <Param2>, ... )DECLARE_DELEGATE_RetVal_<Num>Params( RetValType, DelegateName, Param1Type, Param2Type, ... )

Delegate선언은 글로벌, 네임스페이스 안, 클래스 선언부(함수본문 제외) 영역에서 선언이가능하다.


2-1. MultiCastDelegate 선언하기

MultiCastDelegate또한 표준Delegate선언과 크게 다르지않으며
MultiCastDelegate전용 매크로를 사용한다는 차이점이 있다.

설명선언 매크로
멀티캐스트 델리게이트를 생성합니다.DECLARE_MULTICAST_DELEGATE[_RetVal, etc.]( DelegateName )
다이내믹 멀티-캐스트 델리게이트를 생성합니다.DECLARE_DYNAMIC_MULTICAST_DELEGATE[RetVal, etc.]( DelegateName )

2-2. DynamicDelegate 선언하기

DynamicDelegate또한 표준Delegate선언과 크게 다르지않으며
DynamicDelegate전용 매크로를 사용한다는 차이점이 있다.

설명선언 매크로
다이나믹 델리게이트를 생성합니다.DECLARE_DYNAMIC_DELEGATE[_RetVal, etc.]( DelegateName )
다이나믹 멀티-캐스트 델리게이트를 생성합니다.DECLARE_DYNAMIC_MULTICAST_DELEGATE[_RetVal, etc.]( DelegateName )

2-3. Event 선언하기

Event또한 표준Delegate선언과 크게 다르지않으며
Event전용 매크로를 사용한다는 차이점이 있다.

설명선언 매크로
이벤트를 생성합니다.DECLARE_EVENT( OwningType, EventName )
파라미터가 하나인 이벤트를 생성합니다.DECLARE_EVENT_OneParam( OwningType, EventName, Param1Type )
파라미터가 둘인 이벤트를 생성합니다.DECLARE_EVENT_TwoParams( OwningType, EventName, Param1Type, Param2Type )
파라미터가 N 개인 이벤트를 생성합니다.DECLARE_EVENT_<Num>Params( OwningType, EventName, Param1Type, Param2Type, ... )
  • DECLARE_EVENT 매크로의 첫 파라미터는 이 이벤트를 "소유"(own)하게 될 클래스, 즉 Broadcast() 함수를 호출할 수 있는 클래스이다.

3. Delegate 바인딩하기

Delegate 시스템은 특수한기능도 제공한다, UObject나 공유 포인터 클래스를 바인딩 한경우 약한 레퍼런스를 유지할수있다.
이는 Delegate치하에서 오브젝트가 소멸한경우 IsBound()ExecuteIfBound()함수를 처리해준다.

설명함수
기존 델리게이트 오브젝트에 바인딩합니다.Bind()
raw C++ 포인터 글로벌 함수 델리게이트를 바인딩합니다.BindStatic()
날(raw) C++ 포인터 델리게이트에 바인딩합니다. 날 포인터는 어떠한 종류의 레퍼런스도 사용하지 않아, 만약 오브젝트가 델리게이트 치하에서 삭제된 경우 호출하기가 안전하지 않을 수도 있습니다. Execute() 호출시에는 조심하세요!BindRaw()
공유 포인터-기반 멤버 함수 델리게이트에 바인딩합니다. 공유 포인터 델리게이트는 오브젝트로의 약한 레퍼런스를 유지합니다. ExecuteIfBound() 로 호출할 수 있습니다.BindSP()
UObject 기반 멤버 함수 델리게이트를 바인딩합니다. UObject 델리게이트는 오브젝트로의 약한 레퍼런스를 유지합니다. ExecuteIfBound() 로 호출할 수 있습니다.BindUObject()
이 델리게이트 바인딩을 해제합니다.UnBind()

3-1. MultiCastDelegate 바인딩하기

MultiCastDelegate는 여러 개의 함수를 바인딩시켜 Delegate가 발동되면 모두 호출되도록 할 수 있다.
그 결과, 의미론적으로 함수 바인딩이 변수같은 식에 더가깝다.

설명함수
이 멀티캐스트 델리게이트의 실행 목록에 함수 델리게이트를 추가합니다.Add()
raw C++ 포인터 글로벌 함수 델리게이트를 추가합니다.AddStatic()
raw C++ 포인터 델리게이트를 추가합니다. raw 포인터는 어떠한 레퍼런스도 사용하지 않기에, 오브젝트가 자신의 델리게이트 하에서 삭제된 경우 호출시 안전하지 않을 수 있습니다. Execute() 호출시 주의하세요!AddRaw()
공유 포인터 기반 (빠르지만 스레드 안전성은 떨어지는) 멤버 함수 델리게이트를 추가합니다. 공유 포인터 델리게이트는 자신의 오브젝트에 대한 약 레퍼런스를 유지합니다.AddSP()
UObject 기반 멤버 함수 델리게이트를 추가합니다. UObject 델리게이트는 자신의 오브젝트에 대한 약 레퍼런스를 유지합니다.AddUObject()
이 멀티캐스트 델리게이트의 실행 목록에서 함수를 제거합니다 (퍼포먼스는 O(N) 입니다). 참고로 델리게이트 순서는 유지되지 않을 수 있습니다!Remove()
지정된 UserObject 에 바인딩된 이 멀티캐스트 델리게이트의 실행 목록에서 모든 함수를 제거합니다. 참고로 델리게이트 순서는 유지되지 않을 수 있습니다!RemoveAll()
  • RemoveAll() 은 제공된 포인터에 바인딩된 모든 등록 Delegate를 제거한다. 오브젝트 포인터에 바인딩되지 않은 raw Delegate는 이 함수로 제거되지 않는다!

3-2. DynamicDelegate 바인딩하기

설명헬퍼 ㄹ매크로
다이내믹 델리게이트에서 BindDynamic() 호출을 위한 헬퍼 매크로입니다. 함수 이름 문자열을 자동 생성합니다.BindDynamic( UserObject, FuncName )
다이내믹 멀티-캐스트 델리게이트에서 AddDynamic() 호출을 위한 헬퍼 매크로입니다. 함수 이름 문자열을 자동 생성합니다.AddDynamic( UserObject, FuncName )
다이내믹 멀티-캐스트 델리게이트에서 RemoveDynamic() 호출을 위한 헬퍼 매크로입니다. 함수 이름 문자열을 자동 생성합니다.RemoveDynamic( UserObject, FuncName )

3-3. Event 바인딩하기

Event바인딩은 MultiCastDelegate 바인딩과 같은 방식으로 이루어진다. (3-1 참고)


4. 페이로드 데이터

Delegate를 바인딩할대 페이로드 데이터를 같이 전달해줄수있다.

  • 페이로드 데이터란 바인딩된 함수를 불러낼(invoke)때 직접 전해지는 변수를 말한다.

바인딩 시간에 Delegate가 파라미터를 보관할수있어 유용하게 사용가능하다.
DynamicDelegate제외한 다른 모든 델리게이트들은 페이로드 변수기능을 자동으로 제공한다.

MyDelegate.BindRaw( &MyFunction, true, 20 ); // bool과 int32값을 전달

위 코드는 boolint32Delegate에게 전달하는 코드이고, 이파라미터는 바인딩된 Delegate가 실행될때 전달된다.


5. Delegate 실행시키기

Delegate에 바인딩된 함수는 Excute()함수를 호출하여 실행한다.
Delegate를 실행하기전 반드시 바인딩 되어있는지 확인해야한다.

  • 초기화 되지않은 상태로 접근,반환이 가능한 파라미터가 존재할수있기에 코드의 안정성을위해 바인딩 되어있는지 확인해야한다.
  • 바인딩 되지않은 Delegate를 싱행시키면 일부 인스턴스에서 메모리에 더미데이터를 남길수도있다.
  • IsBound()함수를 사용해 Delegate실행해도 안전한지 확인할수 있다.

ExecuteIfBound()로 반환값이없는 Delegate를 호출할수있다, 하지만 호출 파라미터는 초기화하지 않을수 있다.

설명함수
델리게이트에 바인딩된 함수를 호출한다.Execute()
반환값이 없는 델리게이트를 호출한다.ExecuteIfBound()
호출할 함수가 델리게이트에 존재하는지 확인한다.IsBound()

5-1. MultiCastDelegate 실행시키기

MultiCastDelegate를 통해 여러함수 Delegate를 붙인다음, MultiCastDelegateBroadcast()함수를 통해 함수들을 호출할수 있다.
MultiCastDelegateBroadcast()함수는 아무것도 바인딩되어있지 않아도 언제나 안전하다.
하지만 Delegate를 이용해 출력변수를 초기화하는건 매우 좋지않은 일이다.
Broadcast()통해 호출된 함수들의 순서는 정의되지않으며, 함수가 추가된순서대로 실행되지 않을수있다.

설명함수
모든 오브젝트로 호출을 시도한다.Broadcast()

5-2. DynamicDelegate 실행시키기

DynamicDelegate실행은 Delegate 실행과 같은 방식으로 이루어진다. (5. 참고)


5-3. Enevt 실행시키기

Enevt실행은 MultiCastDelegate실행과 같은 방식으로 이루어진다. (5-1. 참고)


출처

언리얼 공식 홈페이지


언리얼에서 제공하는 Delegate들에대해 알아보았습니다.
번역이나 바로이해가가지않는 부분은 제나름대로 해석하여 수정해보았습니다
공부를 위해 기술하는만큼 잘못된부분이있다면 댓글로 남겨주시기바랍니다!

profile
개발자좀 한번해보자

0개의 댓글