#pragma once
#include "IUnityInterface.h"
#ifndef EVENTQUEUE_SUPPORTS_EVENT_CLEANUP
#define EVENTQUEUE_SUPPORTS_EVENT_CLEANUP 1
#endif
#define REGISTER_EVENT_ID(HASHH, HASHL , TYPE) \
namespace UnityEventQueue \
{ \
template<> \
inline const EventId GetEventId< TYPE > () \
{ \
return EventId(HASHH,HASHL) ; \
} \
}
#if EVENTQUEUE_SUPPORTS_EVENT_CLEANUP
#define REGISTER_EVENT_ID_WITH_CLEANUP(HASHH, HASHL, TYPE) \
namespace UnityEventQueue \
{ \
typedef StaticFunctionEventHandler< TYPE > DestructorMethod_##HASHH##HASHL; \
\
template<> \
inline void GenericDestructorMethodForType< TYPE > ( const TYPE & eventPayload ) \
{ const_cast<TYPE&>(eventPayload).Destroy(); } \
\
template<> \
inline EventHandler * GetEventDestructor< TYPE >() \
{ \
static DestructorMethod_##HASHH##HASHL g_Destructor(&GenericDestructorMethodForType< TYPE >); \
return &g_Destructor; \
} \
} \
REGISTER_EVENT_ID(HASHH,HASHL,TYPE)
#endif
namespace UnityEventQueue
{
struct EventId
{
public:
EventId(unsigned long long high, unsigned long long low)
: mGUIDHigh(high)
, mGUIDLow(low)
{}
EventId(const EventId & other)
{
mGUIDHigh = other.mGUIDHigh;
mGUIDLow = other.mGUIDLow;
}
EventId & operator=(const EventId & other)
{
mGUIDHigh = other.mGUIDHigh;
mGUIDLow = other.mGUIDLow;
return *this;
}
bool Equals(const EventId & other) const { return mGUIDHigh == other.mGUIDHigh && mGUIDLow == other.mGUIDLow; }
bool LessThan(const EventId & other) const { return mGUIDHigh < other.mGUIDHigh || (mGUIDHigh == other.mGUIDHigh && mGUIDLow < other.mGUIDLow); }
unsigned long long mGUIDHigh;
unsigned long long mGUIDLow;
};
inline bool operator==(const EventId & left, const EventId & right) { return left.Equals(right); }
inline bool operator!=(const EventId & left, const EventId & right) { return !left.Equals(right); }
inline bool operator<(const EventId & left, const EventId & right) { return left.LessThan(right); }
inline bool operator>(const EventId & left, const EventId & right) { return right.LessThan(left); }
inline bool operator>=(const EventId & left, const EventId & right) { return !operator<(left, right); }
inline bool operator<=(const EventId & left, const EventId & right) { return !operator>(left, right); }
template<typename T> const EventId GetEventId();
class EventQueue;
class EventHandler;
#if EVENTQUEUE_SUPPORTS_EVENT_CLEANUP
template<typename T> EventHandler * GetEventDestructor() { return (EventHandler*)NULL; }
template<typename T> void GenericDestructorMethodForType(const T & ) {}
#endif
class EventHandler
{
public:
EventHandler() : m_Next(0) {}
virtual ~EventHandler() {}
virtual void HandleEvent(EventId & id, void * data) = 0;
virtual EventId HandlerEventId() = 0;
#if EVENTQUEUE_SUPPORTS_EVENT_CLEANUP
virtual EventHandler * GetMyEventDestructor() = 0;
#endif
EventHandler * GetNext() { return m_Next; }
private:
friend class EventHandlerList;
EventHandler * m_Next;
};
template<typename EVENTTYPE, typename OBJECTTYPE>
class ClassBasedEventHandler : public EventHandler
{
public:
ClassBasedEventHandler(OBJECTTYPE * handler = NULL) : m_Handler(handler) {}
virtual void HandleEvent(EventId & id, void * data)
{ (void)id; m_Handler->HandleEvent(*static_cast<EVENTTYPE*>(data)); }
virtual EventId HandlerEventId()
{ return GetEventId<EVENTTYPE>(); }
#if EVENTQUEUE_SUPPORTS_EVENT_CLEANUP
virtual EventHandler * GetMyEventDestructor()
{ return GetEventDestructor<EVENTTYPE>(); }
#endif
ClassBasedEventHandler<EVENTTYPE, OBJECTTYPE> *
SetObject(OBJECTTYPE * handler)
{ m_Handler = handler; return this; }
#if EVENTQUEUE_SUPPORTS_EVENT_CLEANUP
OBJECTTYPE * GetHandler()
{ return m_Handler; }
#endif
protected:
OBJECTTYPE * m_Handler;
};
template<typename EVENTTYPE>
class StaticFunctionEventHandler : public EventHandler
{
public:
typedef void (*HandlerFunction)(const EVENTTYPE & payload);
StaticFunctionEventHandler(HandlerFunction handlerCallback) : m_Handler(handlerCallback) {}
virtual void HandleEvent(EventId & id, void * data)
{ (void)id; m_Handler(*static_cast<EVENTTYPE*>(data)); }
virtual EventId HandlerEventId()
{ return GetEventId<EVENTTYPE>(); }
#if EVENTQUEUE_SUPPORTS_EVENT_CLEANUP
virtual EventHandler * GetMyEventDestructor()
{ return GetEventDestructor<EVENTTYPE>(); }
#endif
protected:
HandlerFunction m_Handler;
};
struct AddEventHandler
{
AddEventHandler(EventHandler * handler) : m_Handler(handler) {}
EventHandler * m_Handler;
};
struct RemoveEventHandler
{
RemoveEventHandler(EventHandler * handler) : m_Handler(handler) {}
EventHandler * m_Handler;
};
UNITY_DECLARE_INTERFACE(IUnityEventQueue)
{
public:
#define kMaxEventQueueEventSize 8196+sizeof(EventId)
virtual ~IUnityEventQueue() {
}
template<typename T>
void SendEvent(T & payload)
{
Assert(sizeof(T) <= (kMaxEventQueueEventSize - sizeof(EventId)));
SendEventImpl(UnityEventQueue::GetEventId<T>(), (unsigned char*)(&payload), sizeof(T));
}
#if EVENTQUEUE_SUPPORTS_EVENT_CLEANUP
template<typename T>
void RegisterCleanup(T & payload)
{
EventHandler * eh = UnityEventQueue::GetEventDestructor<T>();
if (eh != NULL)
SetCleanupImpl(eh);
}
#endif
virtual void AddHandler(EventHandler * handler) = 0;
virtual void RemoveHandler(EventHandler * handler) = 0;
protected:
virtual void SendEventImpl(EventId id, unsigned char * data, int size) = 0;
#if EVENTQUEUE_SUPPORTS_EVENT_CLEANUP
virtual void SetCleanupImpl(EventHandler * handler) = 0;
#endif
};
}
REGISTER_EVENT_ID(0x19D736400584B24BULL, 0x98B9EFBE26D3F3C9ULL, AddEventHandler)
REGISTER_EVENT_ID(0x8D4A317C4F577F4AULL, 0x851D6E457566A905ULL, RemoveEventHandler)
UNITY_REGISTER_INTERFACE_GUID_IN_NAMESPACE(0x9959C347F5AE374DULL, 0x9BADE6FC8EF49E7FULL, IUnityEventQueue, UnityEventQueue)