PLCnext API Documentation 25.0.2.69
event.hxx
1
2//
3// Copyright Phoenix Contact GmbH & Co. KG
4//
6#pragma once
7
8#ifndef ARP_USE_ARP_SYSTEM_CORE
9
10#include "Arp/Base/Core/event.hxx"
11
12#else
13
14#include "Arp/System/Core/Arp.h"
15#include "Arp/System/Core/delegate.hxx"
16#include "Arp/System/Core/slim_delegate.hxx"
17#include "Arp/System/Core/Exception.hpp"
18#include <forward_list>
19
20namespace Arp
21{
22
24// class event is implemented completely implicite inline to avoid
25// code bloat in commonly used Core classe and therefore reduce compile time
26
38template<class ...TEventArgs>
39class event
40{
41public: // typedefs/usings
43 using delegate_type = delegate<void(TEventArgs...)>;
45 using slim_delegate_type = slim_delegate<void(TEventArgs...)>;
46
47public:
49 event(void) = default;
52 event(const event& arg) = default;
55 event(event&& arg)noexcept = default;
57 ~event(void) = default;
61 event& operator=(const event& arg) = default;
65 event& operator=(event&& arg)noexcept = default;
66
67public: // add/remove operators
71 event& operator+=(slim_delegate_type&& rhs)
72 {
73 if (!rhs)
74 {
75 throw Exception("As argument passed delegate is not valid.");
76 }
77 // else
78 this->slimEventHandlers.push_front(std::move(rhs));
79 return *this;
80 }
81
82
86 event& operator+=(const slim_delegate_type& rhs)
87 {
88 if (!rhs)
89 {
90 throw Exception("As argument passed delegate is not valid.");
91 }
92 // else
93 this->slimEventHandlers.push_front(rhs);
94 return *this;
95 }
96
100 event& operator-=(const slim_delegate_type& rhs)
101 {
102 this->slimEventHandlers.remove(rhs);
103 return *this;
104 }
105
109 event& operator+=(delegate_type&& rhs)
110 {
111 if (!rhs)
112 {
113 throw Exception("As argument passed delegate is not valid.");
114 }
115 if(rhs.is_lambda())
116 {
117 throw Exception("Lambda delegates are not supported by events.");
118 }
119 // else
120 this->eventHandlers.push_front(std::move(rhs));
121 return *this;
122 }
123
127 event& operator+=(const delegate_type& rhs)
128 {
129 if (!rhs)
130 {
131 throw Exception("As argument passed delegate is not valid.");
132 }
133 if (rhs.is_lambda())
134 {
135 throw Exception("Lambda delegates are not supported by events.");
136 }
137 // else
138 this->eventHandlers.push_front(rhs);
139 return *this;
140 }
141
145 event& operator-=(const delegate_type& rhs)
146 {
147 this->eventHandlers.remove(rhs);
148 return *this;
149 }
150
151public: // invokation operator, functor
155 void operator()(TEventArgs... args) const
156 {
157 for (const slim_delegate_type& slimEventHandler : this->slimEventHandlers)
158 {
159 // invoke eventHandler/delegate
160 slimEventHandler(args...);
161 }
162 for(const delegate_type& eventHandler : this->eventHandlers)
163 {
164 // invoke eventHandler/delegate
165 eventHandler(args...);
166 }
167 }
168
169public: // property operations
172 bool is_empty(void)const
173 {
174 return this->slimEventHandlers.empty() && this->eventHandlers.empty();
175 }
176
177private:
178 std::forward_list<slim_delegate_type> slimEventHandlers;
179 std::forward_list<delegate_type> eventHandlers;
180};
181
183// spcialized class event<void> is implemented completely implicite inline because
184// template class specializations cannot be implemented using explicite
185// inlining (out of class definition)
186
198template<>
199class event<void>
200{
201public: // typedefs/usings
203 using delegate_type = delegate<void()>;
205 using slim_delegate_type = slim_delegate<void()>;
206
207public:
209 event(void) = default;
212 event(const event& arg) = default;
215 event(event&& arg) = default;
217 ~event(void) = default;
221 event& operator=(const event& arg) = default;
225 event& operator=(event&& arg) = default;
226
227public: // add/remove operators
231 event& operator+=(slim_delegate_type&& rhs)
232 {
233 if (!rhs)
234 {
235 throw Exception("As argument passed delegate is not valid.");
236 }
237 // else
238 this->slimEventHandlers.push_front(std::move(rhs));
239 return *this;
240 }
241
245 event& operator+=(const slim_delegate_type& rhs)
246 {
247 if (!rhs)
248 {
249 throw Exception("As argument passed delegate is not valid.");
250 }
251 // else
252 this->slimEventHandlers.push_front(rhs);
253 return *this;
254 }
255
259 event& operator-=(const slim_delegate_type& rhs)
260 {
261 this->slimEventHandlers.remove(rhs);
262 return *this;
263 }
264
268 event& operator+=(delegate_type&& rhs)
269 {
270 if (!rhs)
271 {
272 throw Exception("As argument passed delegate is not valid.");
273 }
274 if (rhs.is_lambda())
275 {
276 throw Exception("Lambda delegates are not supported by events.");
277 }
278 // else
279 this->eventHandlers.push_front(std::move(rhs));
280 return *this;
281 }
282
286 event& operator+=(const delegate_type& rhs)
287 {
288 if (!rhs)
289 {
290 throw Exception("As argument passed delegate is not valid.");
291 }
292 if (rhs.is_lambda())
293 {
294 throw Exception("Lambda delegates are not supported by events.");
295 }
296 // else
297 this->eventHandlers.push_front(rhs);
298 return *this;
299 }
300
304 event& operator-=(const delegate_type& rhs)
305 {
306 this->eventHandlers.remove(rhs);
307 return *this;
308 }
309
310public: // invokation operator, functor
313 void operator()(void) const
314 {
315 for (const slim_delegate_type& slimEventHandler : this->slimEventHandlers)
316 {
317 // invoke eventHandler/delegate
318 slimEventHandler();
319 }
320 for (const delegate_type& eventHandler : this->eventHandlers)
321 {
322 // invoke eventHandler/delegate
323 eventHandler();
324 }
325 }
326
327public: // property operations
330 bool is_empty(void)const
331 {
332 return this->slimEventHandlers.empty() && this->eventHandlers.empty();
333 }
334
335private:
336 std::forward_list<slim_delegate_type> slimEventHandlers;
337 std::forward_list<delegate_type> eventHandlers;
338};
339
340} // end of namespace Arp
341
342#endif // ndef ARP_USE_ARP_SYSTEM_CORE
event & operator+=(delegate_type &&rhs)
Adds a delegate to this event.
Definition: event.ipp:22
void operator()(Args... args) const
Fires this event instance.
Definition: event.ipp:80
bool is_empty(void) const
Checks if this event has any delegates to be invoked.
Definition: event.ipp:93
event & operator-=(const delegate_type &rhs)
Removes a delegate from this event.
Definition: event.ipp:62
event(void)
Constructs a event instance.
Root namespace for the PLCnext API