UniRX 배우기 7) MessageBroker 전역 옵저버 이벤트시스템

 

 

UniRX에는 전역적으로 이벤트를 구독하고 호출할 수 있는 옵저버 시스템을 제공한다.

 

싱글턴으로 처리하는 호출방식에 비해서 직접적인 코드 참조가 없어지니 디커플링은 당연하며,

만약 UI 정보 업데이트를 전부 이벤트 방식으로 처리한다면 UI 오브젝트를 끄더라도 프로그램이 문제없이 작동된다.

 

1대 1 방식인 직접 호출에 비해서 다대일, 일대다, 다대다 방식을 전부 지원하다 보니 코드도 훨씬 유연해질 수 있다.

 

 

이벤트 구독하기

MessageBroker.Default.Receive<T> 를 사용하여 구독하며, 호출은 MessageBroker.Default.Publish를 사용한다.

using UnityEngine;
using UniRx;

public class Script : MonoBehaviour
{
    public void Start()
    {
        // UniRX라서 .Distinct()같은 오퍼레이터 입력가능
        MessageBroker.Default.Receive<TempEventA>() 
                             .Subscribe(OnEvent)
                             .AddTo(this); // 스크립객체 소멸시 구독이 종료됨.
    }

    // 함수형태는 기존과 같음.
    public void OnEvent(TempEventA e)
    {
        Debug.Log(e.val);
    }

    // 호출 예시
    public void TestCall()
    {
        // 예시는 클래스 내부에서 호출했지만, 전역함수라 다른 클래스에서도 호출가능하다.
        MessageBroker.Default.Publish(new TempEventA());
    }
}

public struct TempEventA
{
    public int val;
}

 

구독의 종료

  • 만약 오브젝트의 삭제와 구독시점이 같지 않다면 구독시 리턴되는 IDisposable을 캐싱한 다음 원하는 시점에 Dispose()를 호출하면 됨.
private IDisposable temp;

public void Subscribe()
{
    temp = MessageBroker.Default.Receive<TempEventA>() 
                                        .Subscribe(OnEvent);
}

public void EndTempA()
{
    temp.Dispose();
}

 

나는 다른 방식으로 구현된 이벤트 시스템을 사용하고 있는데,

단순히 전역으로 Dictionary에 이벤트를 담아두고 호출할 뿐이라 약간의 제약사항들이 생긴다.

UniRX에서 제공해주는 이벤트 시스템을 사용하면 메시지 필터링이 가능해지니 더욱 확장된 설계가 가능할 것이다.

 

 

댓글

Designed by JB FACTORY