프로그램 런타임에 Event가 발생하면 EventManager는 이를 모두 Queue에 저장해 놓았다가 특정 시점에서 모두 Dispath한다.
게임엔진은 사용자가 원하는 Event Type을 정의하고, 특정 Event Type을 처리하는 Callback을 등록하도록 인터페이스를 제공할 수 있다.
classKeydownEvent : public Event<KeydownEvent> { ... };
사용자는 Event<T>를 상속하여 새로운 Event Type을 정의할 수 있다.
Event<T> 클래스는 T에 따라서 유니크한 EventTypeID를 static 멤버로 갖는다. 이는 Event를 특정 Type에 따라서 처리해야하는 경우에 사용하고, 주로 EventManager에서 접근하므로 해당 클래스에서 접근할 수 있는 방법을 마련해 놓는다.
여기서는 EVENT_TYPE_ID를 public 으로 공개하여 인스턴스가 없어도 T::EVENT_TYPE_ID로 직접 접근할 수 있고, GetEventTypeID()를 override 하여 인스턴스를 통해서도 접근할 수 있도록 하였다.
Delegate<E, C>는 특정 Event Type(E)과 그걸 처리하는 Callback(C의 멤버함수)의 래퍼클래스이다. 만약 멤버함수가 아닌 Callback을 사용하고 싶다면, Delegate<E>와 같이 특수화를 해주면 될 것이다. Invoke(const IEvent* const e)함수에서는 인자로 받은 IEvent를 E type으로 다운캐스팅 하여 콜백함수를 호출한다.
당연한 이야기지만 콜백함수의 형태는 InputSystem::ProcessKeyDownEvent(const KeydownEvent* const e)와 같이 사용자 정의된 Event Type을 인자로하는 함수이다.
EventManager에서 모든 이벤트 관련 처리를 담당한다. Add/RemoveEventDelegate함수를 통해서 특정 Event type에 대한 Dispather를 구성하고, Delegate를 추가한다. SendEvent함수를 통해서 어디서든 Event를 발생시킬 수 있으며, 해당 이벤트는 _eventQueue에 저장되어 DispathAllEvent가 호출될때 한번에 처리된다.
IEventListener는 Event 처리 콜백을 등록/해제 하기위한 인터페이스이다. 특정 Event 를 처리하고자 하는 클래스는 IEventListener를 상속하여 Register/UnRegisterEventCallback함수를 통하여 Event 콜백을 등록/해제한다. 해당 함수가 호출되면 콜백에서 처리하고자하는 특정 Event type과 콜백 함수를 랩핑한 Delegate를 생성하고 EventManager에 등록/해제 한다.