9 #ifndef FAIR_MQ_EVENTMANAGER_H
10 #define FAIR_MQ_EVENTMANAGER_H
16 #include <unordered_map>
20 #include <boost/any.hpp>
21 #include <boost/functional/hash.hpp>
22 #include <boost/signals2.hpp>
57 template<
typename E,
typename ...Args>
58 using Signal = boost::signals2::signal<void(
typename E::KeyType, Args...)>;
60 template<
typename E,
typename ...Args>
61 auto Subscribe(
const std::string& subscriber, std::function<
void(
typename E::KeyType, Args...)> callback) ->
void
63 const std::type_index event_type_index{
typeid(E)};
64 const std::type_index callback_type_index{
typeid(std::function<void(
typename E::KeyType, Args...)>)};
65 const auto signalsKey = std::make_pair(event_type_index, callback_type_index);
66 const auto connectionsKey = std::make_pair(subscriber, signalsKey);
68 const auto connection = GetSignal<E, Args...>(signalsKey)->connect(callback);
71 std::lock_guard<std::mutex> lock{fMutex};
73 if (fConnections.find(connectionsKey) != fConnections.end())
75 fConnections.at(connectionsKey).disconnect();
76 fConnections.erase(connectionsKey);
78 fConnections.insert({connectionsKey, connection});
82 template<
typename E,
typename ...Args>
83 auto Unsubscribe(
const std::string& subscriber) ->
void
85 const std::type_index event_type_index{
typeid(E)};
86 const std::type_index callback_type_index{
typeid(std::function<void(
typename E::KeyType, Args...)>)};
87 const auto signalsKey = std::make_pair(event_type_index, callback_type_index);
88 const auto connectionsKey = std::make_pair(subscriber, signalsKey);
90 std::lock_guard<std::mutex> lock{fMutex};
92 fConnections.at(connectionsKey).disconnect();
93 fConnections.erase(connectionsKey);
96 template<
typename E,
typename ...Args>
97 auto Emit(
typename E::KeyType key, Args... args)
const ->
void
99 const std::type_index event_type_index{
typeid(E)};
100 const std::type_index callback_type_index{
typeid(std::function<void(
typename E::KeyType, Args...)>)};
101 const auto signalsKey = std::make_pair(event_type_index, callback_type_index);
103 (*GetSignal<E, Args...>(signalsKey))(key, std::forward<Args>(args)...);
107 using SignalsKey = std::pair<std::type_index, std::type_index>;
109 using SignalsValue = boost::any;
110 using SignalsMap = std::unordered_map<SignalsKey, SignalsValue, boost::hash<SignalsKey>>;
111 mutable SignalsMap fSignals;
113 using ConnectionsKey = std::pair<std::string, SignalsKey>;
115 using ConnectionsValue = boost::signals2::connection;
116 using ConnectionsMap = std::unordered_map<ConnectionsKey, ConnectionsValue, boost::hash<ConnectionsKey>>;
117 ConnectionsMap fConnections;
119 mutable std::mutex fMutex;
121 template<
typename E,
typename ...Args>
122 auto GetSignal(
const SignalsKey& key)
const -> std::shared_ptr<Signal<E, Args...>>
124 std::lock_guard<std::mutex> lock{fMutex};
126 if (fSignals.find(key) == fSignals.end())
130 auto signal = std::make_shared<Signal<E, Args...>>();
131 fSignals.insert(std::make_pair(key, signal));
134 return boost::any_cast<std::shared_ptr<Signal<E, Args...>>>(fSignals.at(key));