97 lines
1.8 KiB
C++
97 lines
1.8 KiB
C++
#ifndef MessageRelay_h__
|
|
#define MessageRelay_h__
|
|
|
|
#include <typeinfo>
|
|
#include <functional>
|
|
#include <unordered_map>
|
|
#include <list>
|
|
|
|
#define EVENT_SUBSCRIBE_MEMBER(relay, handler) \
|
|
relay = decltype(relay)(std::bind(handler, this, std::placeholders::_1)); \
|
|
EventBroker->Subscribe(relay);
|
|
|
|
struct Event
|
|
{
|
|
protected:
|
|
Event() { }
|
|
};
|
|
|
|
class EventBroker;
|
|
|
|
class BaseEventRelay
|
|
{
|
|
friend class EventBroker;
|
|
|
|
protected:
|
|
BaseEventRelay(std::string typeName)
|
|
: m_TypeName(typeName), m_Broker(nullptr) { }
|
|
~BaseEventRelay();
|
|
|
|
public:
|
|
virtual bool Receive(const Event &event) = 0;
|
|
|
|
protected:
|
|
std::string m_TypeName;
|
|
EventBroker* m_Broker;
|
|
};
|
|
|
|
template <typename EventType>
|
|
class EventRelay : public BaseEventRelay
|
|
{
|
|
public:
|
|
typedef std::function<bool(const EventType&)> CallbackType;
|
|
|
|
EventRelay()
|
|
: m_Callback(nullptr)
|
|
, BaseEventRelay(typeid(EventType).name()) { }
|
|
EventRelay(CallbackType callback)
|
|
: m_Callback(callback)
|
|
, BaseEventRelay(typeid(EventType).name()) { }
|
|
|
|
protected:
|
|
bool Receive(const Event &event) override;
|
|
|
|
private:
|
|
CallbackType m_Callback;
|
|
};
|
|
|
|
template <typename EventType>
|
|
bool EventRelay<EventType>::Receive(const Event &event)
|
|
{
|
|
if (m_Callback != nullptr)
|
|
{
|
|
return m_Callback(static_cast<const EventType&>(event));
|
|
}
|
|
else
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
|
|
class EventBroker
|
|
{
|
|
template <typename EventType> friend class EventRelay;
|
|
|
|
public:
|
|
template <typename EventType>
|
|
void Publish(const EventType &event);
|
|
void Subscribe(BaseEventRelay &relay);
|
|
void Unsubscribe(BaseEventRelay &relay);
|
|
|
|
private:
|
|
std::unordered_multimap<std::string, BaseEventRelay*> m_Subscribers;
|
|
};
|
|
|
|
|
|
template <typename EventType>
|
|
void EventBroker::Publish(const EventType &event)
|
|
{
|
|
auto itpair = m_Subscribers.equal_range(typeid(EventType).name());
|
|
for (auto it = itpair.first; it != itpair.second; ++it)
|
|
{
|
|
it->second->Receive(event);
|
|
}
|
|
}
|
|
|
|
#endif // MessageRelay_h__
|