DotNetDupe 4.0.6
C++17/20 Implementation of the .NET Base Class Library (BCL)
Loading...
Searching...
No Matches
EventHandler.h
Go to the documentation of this file.
1
5
6#pragma once
7#include "Common.h"
8#include "System/Object.h"
9#include "System/EventArgs.h"
10#include "System/Action.h"
12#include <type_traits>
13#include <utility>
14
15namespace DotNetDupe {
16 namespace System {
17
26 template <typename TEventArgs = EventArgs>
28 private:
29 struct SubscriberEntry {
30 size_t m_nToken;
32
33 SubscriberEntry() : m_nToken(0), m_fnAction() {}
34 SubscriberEntry(size_t nToken, const Action<const void*, const TEventArgs&>& fnAction)
35 : m_nToken(nToken), m_fnAction(fnAction) {}
36
37 bool operator==(const SubscriberEntry& other) const {
38 return m_nToken == other.m_nToken;
39 }
40 };
41
43 size_t m_nNextToken;
44
45 public:
47 EventHandler() : m_lstSubscribers(), m_nNextToken(1) {}
48
51 : m_lstSubscribers(other.m_lstSubscribers), m_nNextToken(other.m_nNextToken) {}
52
54 EventHandler(EventHandler&& other) noexcept
55 : m_lstSubscribers(std::move(other.m_lstSubscribers)), m_nNextToken(other.m_nNextToken) {
56 other.m_nNextToken = 1;
57 }
58
61 if (this != &other) {
62 m_lstSubscribers = other.m_lstSubscribers;
63 m_nNextToken = other.m_nNextToken;
64 }
65 return *this;
66 }
67
69 EventHandler& operator=(EventHandler&& other) noexcept {
70 if (this != &other) {
71 m_lstSubscribers = std::move(other.m_lstSubscribers);
72 m_nNextToken = other.m_nNextToken;
73 other.m_nNextToken = 1;
74 }
75 return *this;
76 }
77
79 ~EventHandler() = default;
80
86 size_t nAssignedToken = m_nNextToken++;
87
89 m_lstSubscribers.Add(SubscriberEntry(nAssignedToken, fnHandler));
90 return nAssignedToken;
91 }
92
94 template <typename F, typename = std::enable_if_t<!std::is_same_v<std::decay_t<F>, EventHandler> && !std::is_same_v<std::decay_t<F>, Action<const void*, const TEventArgs&>> && std::is_invocable_v<std::decay_t<F>, const void*, const TEventArgs&>>>
95 size_t Add(F&& fnHandler) {
96 return Add(Action<const void*, const TEventArgs&>(std::forward<F>(fnHandler)));
97 }
98
100 template <typename TClass>
101 size_t Add(TClass* pInstance, void (TClass::*pMethod)(const void*, const TEventArgs&)) {
102 return Add([pInstance, pMethod](const void* pSender, const TEventArgs& e) {
103 if (pInstance != nullptr && pMethod != nullptr) {
104 (pInstance->*pMethod)(pSender, e);
105 }
106 });
107 }
108
111 return Add(fnHandler);
112 }
113
115 template <typename F, typename = std::enable_if_t<!std::is_same_v<std::decay_t<F>, EventHandler> && !std::is_same_v<std::decay_t<F>, Action<const void*, const TEventArgs&>> && std::is_invocable_v<std::decay_t<F>, const void*, const TEventArgs&>>>
116 size_t operator+=(F&& fnHandler) {
117 return Add(std::forward<F>(fnHandler));
118 }
119
122 int iCount = other.m_lstSubscribers.GetCount();
123 for (int i = 0; i < iCount; ++i) {
124 Add(other.m_lstSubscribers[i].m_fnAction);
125 }
126 return *this;
127 }
128
132 bool Remove(size_t nToken) {
134 for (int i = 0; i < m_lstSubscribers.GetCount(); ++i) {
135 if (m_lstSubscribers[i].m_nToken == nToken) {
136 m_lstSubscribers.RemoveAt(i);
137 return true;
138 }
139 }
140 return false;
141 }
142
144 bool operator-=(size_t nToken) {
145 return Remove(nToken);
146 }
147
149 void Clear() {
150 m_lstSubscribers.Clear();
151 }
152
156 void Invoke(const void* pSender, const TEventArgs& e) const {
158 int iCount = m_lstSubscribers.GetCount();
159 for (int i = 0; i < iCount; ++i) {
160 m_lstSubscribers[i].m_fnAction.Invoke(pSender, e);
161 }
162 }
163
165 void operator()(const void* pSender, const TEventArgs& e) const {
166 Invoke(pSender, e);
167 }
168
170 bool IsEmpty() const {
171 return m_lstSubscribers.GetCount() == 0;
172 }
173
175 size_t GetSubscriberCount() const {
176 return static_cast<size_t>(m_lstSubscribers.GetCount());
177 }
178
180 explicit operator bool() const {
181 return !IsEmpty();
182 }
183 };
184
185 template <typename TEventArgs = EventArgs>
187
188 }
189}
Encapsulates a delegate method that has parameters and returns void.
Defines common cross-platform macros, export decorators, and fundamental types.
Represents the base class for classes that contain event data.
Represents a strongly typed list of objects that can be accessed by index mirroring ....
Base object class for DotNetDupe mirroring .NET System.Object.
Encapsulates a method that has parameters and does not return a value.
Definition Action.h:46
Represents a strongly typed list of objects accessible by index.
Definition List.h:29
int GetCount() const
Gets the number of elements contained in the List.
Definition List.h:100
Represents the method that will handle an event when the event provides data.
~EventHandler()=default
Destructor.
void operator()(const void *pSender, const TEventArgs &e) const
Invocation call operator.
EventHandler & operator=(EventHandler &&other) noexcept
Move assignment operator.
void Clear()
Removes all registered subscribers.
bool IsEmpty() const
Checks whether the multicast event handler has zero registered subscribers.
EventHandler & operator+=(const EventHandler &other)
Multicast addition operator. Appends all subscribers from another EventHandler.
size_t GetSubscriberCount() const
Gets the number of currently active subscribers.
EventHandler(const EventHandler &other)
Copy constructor. Copies all subscriber callbacks.
EventHandler(EventHandler &&other) noexcept
Move constructor. Transfers subscriber callbacks.
size_t Add(const Action< const void *, const TEventArgs & > &fnHandler)
Subscribes an Action delegate handler and returns a monotonic subscription token.
void Invoke(const void *pSender, const TEventArgs &e) const
Sequentially invokes all registered subscriber callbacks in FIFO order.
size_t Add(TClass *pInstance, void(TClass::*pMethod)(const void *, const TEventArgs &))
Subscribes a member method on an instance object.
size_t Add(F &&fnHandler)
Subscribes a generic callable object (lambda or function pointer).
bool Remove(size_t nToken)
Unsubscribes a subscriber matching the specified subscription token.
size_t operator+=(const Action< const void *, const TEventArgs & > &fnHandler)
Multicast addition operator. Subscribes an Action callback.
EventHandler()
Initializes a new empty multicast EventHandler instance.
size_t operator+=(F &&fnHandler)
Multicast addition operator. Subscribes a generic callable object.
bool operator-=(size_t nToken)
Multicast subtraction operator. Unsubscribes using a subscription token.
EventHandler & operator=(const EventHandler &other)
Copy assignment operator.