libnick 2025.9.1
A cross-platform base for native Nickvision applications.
Loading...
Searching...
No Matches
event.h
Go to the documentation of this file.
1
22
23#ifndef EVENT_H
24#define EVENT_H
25
26#include <functional>
27#include <mutex>
28#include <type_traits>
29#include <vector>
30#include "eventargs.h"
31
33{
34 template<typename T>
35 concept DerivedEventArgs = std::is_base_of_v<EventArgs, T>;
36
40 enum class HandlerId : size_t {};
41
46 template <DerivedEventArgs T>
47 class Event
48 {
49 public:
53 Event() noexcept = default;
58 Event(const Event& e) noexcept
59 {
60 std::lock_guard<std::mutex> lock{ e.m_mutex };
61 m_handlers = e.m_handlers;
62 }
63
67 Event(Event&& e) noexcept
68 {
69 std::lock_guard<std::mutex> lock{ e.m_mutex };
70 m_handlers = std::move(e.m_handlers);
71 e.m_handlers.clear();
72 }
73
77 size_t count() const noexcept
78 {
79 std::lock_guard<std::mutex> lock{ m_mutex };
80 return m_handlers.size();
81 }
82
87 HandlerId subscribe(const std::function<void(const T&)>& handler) noexcept
88 {
89 std::lock_guard<std::mutex> lock{ m_mutex };
90 m_handlers.push_back(handler);
91 return HandlerId{ m_handlers.size() - 1 };
92 }
93
97 void unsubscribe(HandlerId id) noexcept
98 {
99 std::lock_guard<std::mutex> lock{ m_mutex };
100 if (static_cast<size_t>(id) < 0 || static_cast<size_t>(id) >= m_handlers.size())
101 {
102 return;
103 }
104 m_handlers.erase(m_handlers.begin() + static_cast<size_t>(id));
105 }
106
110 void invoke(const T& param) const noexcept
111 {
112 std::lock_guard<std::mutex> lock{ m_mutex };
113 for (const std::function<void(const T&)>& handler : m_handlers)
114 {
115 if(handler)
116 {
117 handler(param);
118 }
119 }
120 }
121
126 HandlerId operator+=(const std::function<void(const T&)>& handler) noexcept
127 {
128 return subscribe(handler);
129 }
130
134 void operator-=(HandlerId id) noexcept
135 {
136 unsubscribe(id);
137 }
138
142 void operator()(const T& param) noexcept
143 {
144 invoke(param);
145 }
146
151 Event& operator=(const Event& e) noexcept
152 {
153 if (this != &e)
154 {
155 std::lock_guard<std::mutex> lock{ m_mutex };
156 std::lock_guard<std::mutex> lock2{ e.m_mutex };
157 m_handlers = e.m_handlers;
158 }
159 return *this;
160 }
161
166 Event& operator=(Event&& e) noexcept
167 {
168 if (this != &e)
169 {
170 std::lock_guard<std::mutex> lock{ m_mutex };
171 std::lock_guard<std::mutex> lock2{ e.m_mutex };
172 m_handlers = std::move(e.m_handlers);
173 e.m_handlers.clear();
174 }
175 return *this;
176 }
177
181 operator bool() const noexcept
182 {
183 return count() > 0;
184 }
185
186 private:
187 mutable std::mutex m_mutex;
188 std::vector<std::function<void(const T&)>> m_handlers;
189 };
190}
191
192#endif //EVENT_H
void operator-=(HandlerId id) noexcept
Unsubscribes a handler from the event.
Definition event.h:134
Event(Event &&e) noexcept
Constructs an Event via move.
Definition event.h:67
HandlerId operator+=(const std::function< void(const T &)> &handler) noexcept
Subscribes a handler to the event.
Definition event.h:126
void invoke(const T &param) const noexcept
Invokes the event, calling all handlers.
Definition event.h:110
Event & operator=(const Event &e) noexcept
Copies an Event.
Definition event.h:151
void unsubscribe(HandlerId id) noexcept
Unsubscribes a handler from the event.
Definition event.h:97
Event & operator=(Event &&e) noexcept
Moves an Event.
Definition event.h:166
size_t count() const noexcept
Gets the number of handlers subscribed to the event.
Definition event.h:77
Event() noexcept=default
Constructs an Event.
HandlerId subscribe(const std::function< void(const T &)> &handler) noexcept
Subscribes a handler to the event.
Definition event.h:87
void operator()(const T &param) noexcept
Invokes the event, calling all handlers.
Definition event.h:142
Definition event.h:33
HandlerId
The ID of a handler for an event.
Definition event.h:40