#ifndef MessageRelay_h__ #define MessageRelay_h__ #include #include #include #include #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 class EventRelay : public BaseEventRelay { public: typedef std::function 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 bool EventRelay::Receive(const Event &event) { if (m_Callback != nullptr) { return m_Callback(static_cast(event)); } else { return false; } } class EventBroker { template friend class EventRelay; public: template void Publish(const EventType &event); void Subscribe(BaseEventRelay &relay); void Unsubscribe(BaseEventRelay &relay); private: std::unordered_multimap m_Subscribers; }; template 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__