17 #ifndef CPP_MATE_EVENT_HPP
18 #define CPP_MATE_EVENT_HPP
20 #include <CppMate/Checkers.hpp>
22 #include <unordered_set>
31 template<
typename E,
typename S>
44 using Lambda = std::function<void(
const S& sender,
const E& event)>;
50 Event(
const S& sender): _sender(sender) {}
59 inline void subscribe(
const T& instance,
void (T::* method)(
const S&,
const E&))
const {
60 addReceiver(&instance, *
reinterpret_cast<Method*
>(&method));
71 inline void subscribe(std::shared_ptr<T> instance,
void (T::* method)(
const S&,
const E&))
const {
72 checkArg(instance.get());
73 addReceiver(std::weak_ptr<void>(instance), *
reinterpret_cast<Method*
>(&method));
96 inline bool unsubscribe(
const T& instance,
void (T::* method)(
const S&,
const E&))
const {
97 return removeReceiver(&instance, *
reinterpret_cast<Method*
>(&method));
108 inline bool unsubscribe(std::shared_ptr<T> instance,
void (T::* method)(
const S&,
const E&))
const {
109 checkArg(instance.get());
110 return removeReceiver(std::weak_ptr<void>(instance), *
reinterpret_cast<Method*
>(&method));
128 inline bool hasSubscriber(
const T& instance,
void (T::* method)(
const S&,
const E&))
const {
129 return hasReceiver(&instance, *
reinterpret_cast<Method*
>(&method));
139 inline bool hasSubscriber(std::shared_ptr<T> instance,
void (T::* method)(
const S&,
const E&))
const {
140 return instance.get() && hasReceiver(std::weak_ptr<void>(instance), *
reinterpret_cast<Method*
>(&method));
149 return subscriber && hasReceiver(subscriber);
156 bool isEmpty()
const {
return _receivers.empty(); }
169 for (
auto it = std::begin(_receivers); it != std::end(_receivers);) {
170 const auto& receiver = *it;
171 receiver(_sender, event) ? ++it : it = _receivers.erase(it);
183 using Method = void(*)(
const void*,
const S&,
const E&);
185 struct ReceiverHasher {
186 size_t operator()(
const Receiver& receiver)
const {
return receiver.getHash(); }
189 template<
typename... T>
190 inline bool hasReceiver(T&&... args)
const {
191 return _receivers.find(Receiver(std::forward<T>(args)...)) != _receivers.end();
194 template<
typename... T>
195 inline void addReceiver(T&&... args)
const {
196 _receivers.emplace(std::forward<T>(args)...);
199 template<
typename... T>
200 inline bool removeReceiver(T&&... args)
const {
201 return _receivers.erase(Receiver(std::forward<T>(args)...)) > 0;
205 mutable std::unordered_set<Receiver, ReceiverHasher> _receivers;
208 template<
typename E,
typename S>
215 _method(reinterpret_cast<decltype(_method)>(method)) {}
217 Receiver(
const std::weak_ptr<void>&& instance, Method method):
220 _method(reinterpret_cast<decltype(_method)>(method)),
221 _instancePtr(std::move(instance)) {}
226 _method(reinterpret_cast<decltype(_method)>(receiver))
235 _lambda(std::move(receiver)) {}
238 return _type == other._type
239 && _method == other._method
240 && getInstance() == other.getInstance();
247 case Receiver::Type::Method:
248 return callMethod(sender, event);
249 case Receiver::Type::Function:
250 return callFunction(sender, event);
251 case Receiver::Type::Lambda:
252 return callLambda(sender, event);
258 return std::hash<decltype(_type)>{}(_type) ^ std::hash<decltype(_method)>{}(_method) ^ std::hash<decltype(_instance)>{}(getInstance());
262 enum class Type: uint8_t {
268 const void* getInstance()
const {
269 return _instance ? _instance : _instancePtr.lock().get();
272 bool callMethod(
const S& sender,
const E& event)
const {
273 const auto* instance = getInstance();
277 reinterpret_cast<Method
>(_method)(instance, sender, event);
281 bool callFunction(
const S& sender,
const E& event)
const {
282 reinterpret_cast<Function>(_method)(sender, event);
286 bool callLambda(
const S& sender,
const E& event)
const {
287 _lambda(sender, event);
292 const void* _instance;
293 std::weak_ptr<void> _instancePtr;
Definition: Event.hpp:210
bool operator==(const Receiver &other) const
Definition: Event.hpp:237
Receiver(Lambda receiver)
Definition: Event.hpp:231
size_t getHash() const
Definition: Event.hpp:257
Receiver(const std::weak_ptr< void > &&instance, Method method)
Definition: Event.hpp:217
bool operator!=(const Receiver &other) const
Definition: Event.hpp:243
Receiver(Function receiver)
Definition: Event.hpp:223
bool operator()(const S &sender, const E &event) const
Definition: Event.hpp:245
Receiver(const void *instance, Method method)
Definition: Event.hpp:212
Represents signal emitter with a specified event type.
Definition: Event.hpp:33
std::function< void(const S &sender, const E &event)> Lambda
Definition: Event.hpp:44
bool hasSubscriber(const T &instance, void(T::*method)(const S &, const E &)) const
Indicates that the receiver is already subscribed to the event.
Definition: Event.hpp:128
bool hasSubscriber(Function subscriber) const
Indicates that the receiver is already subscribed to the event.
Definition: Event.hpp:148
Event(const S &sender)
Constructor.
Definition: Event.hpp:50
bool unsubscribe(const T &instance, void(T::*method)(const S &, const E &)) const
Unsubscribes from the event.
Definition: Event.hpp:96
void subscribe(Lambda subscriber) const
Subscribes lambda expression to the event.
Definition: Event.hpp:87
void(*)(const S &, const E &) Function
Definition: Event.hpp:39
size_t getSubscribersCount() const
Returns number of recveivers.
Definition: Event.hpp:162
bool unsubscribe(std::shared_ptr< T > instance, void(T::*method)(const S &, const E &)) const
Unsubscribes from the event.
Definition: Event.hpp:108
void subscribe(std::shared_ptr< T > instance, void(T::*method)(const S &, const E &)) const
Subscribes method of instance to the event passed by constant reference. The subscription is unique.
Definition: Event.hpp:71
void subscribe(Function subscriber) const
Subscribes function to the event.
Definition: Event.hpp:81
bool isEmpty() const
Indicates that subsciprion is empty.
Definition: Event.hpp:156
void unsubscribeAll()
Clear all subscribers.
Definition: Event.hpp:178
bool unsubscribe(Function subscriber) const
Unsubscribes from the event.
Definition: Event.hpp:119
void subscribe(const T &instance, void(T::*method)(const S &, const E &)) const
Subscribes method of instance to the event passed by constant reference. The subscription is unique.
Definition: Event.hpp:59
void emit(const E &event)
Emits event.
Definition: Event.hpp:168
bool hasSubscriber(std::shared_ptr< T > instance, void(T::*method)(const S &, const E &)) const
Indicates that the receiver is already subscribed to the event.
Definition: Event.hpp:139
Definition: BinaryData.hpp:28