PLCnext API Documentation 24.0.0.71
event.hxx
1
2//
3// Copyright PHOENIX CONTACT Electronics GmbH
4//
6#pragma once
8#include "Arp/System/Core/delegate.hxx"
9#include "Arp/System/Core/slim_delegate.hxx"
10#include "Arp/System/Core/Exception.hpp"
11#include <forward_list>
12
13namespace Arp
14{
15
17// class event is implemented completely implicite inline to avoid
18// code bloat in commonly used Core classe and therefore reduce compile time
19
31template<class ...TEventArgs>
32class event
33{
34public: // typedefs/usings
36 using delegate_type = delegate<void(TEventArgs...)>;
38 using slim_delegate_type = slim_delegate<void(TEventArgs...)>;
39
40public:
42 event(void) = default;
45 event(const event& arg) = default;
48 event(event&& arg)noexcept = default;
50 ~event(void) = default;
54 event& operator=(const event& arg) = default;
58 event& operator=(event&& arg)noexcept = default;
59
60public: // add/remove operators
65 {
66 if (!rhs)
67 {
68 throw Exception("As argument passed delegate is not valid.");
69 }
70 // else
71 this->slimEventHandlers.push_front(std::move(rhs));
72 return *this;
73 }
74
75
79 event& operator+=(const slim_delegate_type& rhs)
80 {
81 if (!rhs)
82 {
83 throw Exception("As argument passed delegate is not valid.");
84 }
85 // else
86 this->slimEventHandlers.push_front(rhs);
87 return *this;
88 }
89
93 event& operator-=(const slim_delegate_type& rhs)
94 {
95 this->slimEventHandlers.remove(rhs);
96 return *this;
97 }
98
103 {
104 if (!rhs)
105 {
106 throw Exception("As argument passed delegate is not valid.");
107 }
108 if(rhs.is_lambda())
109 {
110 throw Exception("Lambda delegates are not supported by events.");
111 }
112 // else
113 this->eventHandlers.push_front(std::move(rhs));
114 return *this;
115 }
116
120 event& operator+=(const delegate_type& rhs)
121 {
122 if (!rhs)
123 {
124 throw Exception("As argument passed delegate is not valid.");
125 }
126 if (rhs.is_lambda())
127 {
128 throw Exception("Lambda delegates are not supported by events.");
129 }
130 // else
131 this->eventHandlers.push_front(rhs);
132 return *this;
133 }
134
138 event& operator-=(const delegate_type& rhs)
139 {
140 this->eventHandlers.remove(rhs);
141 return *this;
142 }
143
144public: // invokation operator, functor
148 void operator()(TEventArgs... args) const
149 {
150 for (const slim_delegate_type& slimEventHandler : this->slimEventHandlers)
151 {
152 // invoke eventHandler/delegate
153 slimEventHandler(args...);
154 }
155 for(const delegate_type& eventHandler : this->eventHandlers)
156 {
157 // invoke eventHandler/delegate
158 eventHandler(args...);
159 }
160 }
161
162public: // property operations
165 bool is_empty(void)const
166 {
167 return this->slimEventHandlers.empty() && this->eventHandlers.empty();
168 }
169
170private:
171 std::forward_list<slim_delegate_type> slimEventHandlers;
172 std::forward_list<delegate_type> eventHandlers;
173};
174
176// spcialized class event<void> is implemented completely implicite inline because
177// template class specializations cannot be implemented using explicite
178// inlining (out of class definition)
179
191template<>
192class event<void>
193{
194public: // typedefs/usings
196 using delegate_type = delegate<void()>;
199
200public:
202 event(void) = default;
205 event(const event& arg) = default;
208 event(event&& arg) = default;
210 ~event(void) = default;
214 event& operator=(const event& arg) = default;
218 event& operator=(event&& arg) = default;
219
220public: // add/remove operators
225 {
226 if (!rhs)
227 {
228 throw Exception("As argument passed delegate is not valid.");
229 }
230 // else
231 this->slimEventHandlers.push_front(std::move(rhs));
232 return *this;
233 }
234
239 {
240 if (!rhs)
241 {
242 throw Exception("As argument passed delegate is not valid.");
243 }
244 // else
245 this->slimEventHandlers.push_front(rhs);
246 return *this;
247 }
248
253 {
254 this->slimEventHandlers.remove(rhs);
255 return *this;
256 }
257
262 {
263 if (!rhs)
264 {
265 throw Exception("As argument passed delegate is not valid.");
266 }
267 if (rhs.is_lambda())
268 {
269 throw Exception("Lambda delegates are not supported by events.");
270 }
271 // else
272 this->eventHandlers.push_front(std::move(rhs));
273 return *this;
274 }
275
279 event& operator+=(const delegate_type& rhs)
280 {
281 if (!rhs)
282 {
283 throw Exception("As argument passed delegate is not valid.");
284 }
285 if (rhs.is_lambda())
286 {
287 throw Exception("Lambda delegates are not supported by events.");
288 }
289 // else
290 this->eventHandlers.push_front(rhs);
291 return *this;
292 }
293
297 event& operator-=(const delegate_type& rhs)
298 {
299 this->eventHandlers.remove(rhs);
300 return *this;
301 }
302
303public: // invokation operator, functor
306 void operator()(void) const
307 {
308 for (const slim_delegate_type& slimEventHandler : this->slimEventHandlers)
309 {
310 // invoke eventHandler/delegate
311 slimEventHandler();
312 }
313 for (const delegate_type& eventHandler : this->eventHandlers)
314 {
315 // invoke eventHandler/delegate
316 eventHandler();
317 }
318 }
319
320public: // property operations
323 bool is_empty(void)const
324 {
325 return this->slimEventHandlers.empty() && this->eventHandlers.empty();
326 }
327
328private:
329 std::forward_list<slim_delegate_type> slimEventHandlers;
330 std::forward_list<delegate_type> eventHandlers;
331};
332
333} // end of namespace Arp
This is the base class of all Arp exception classes.
Definition: Exception.hpp:16
event & operator+=(const slim_delegate_type &rhs)
Adds a slim_delegate to this event.
Definition: event.hxx:238
event & operator+=(delegate_type &&rhs)
Adds a delegate to this event.
Definition: event.hxx:261
event(void)=default
Constructs a event instance.
event & operator=(event &&arg)=default
The move assignment operator.
event & operator+=(slim_delegate_type &&rhs)
Adds a slim_delegate to this event.
Definition: event.hxx:224
event & operator+=(const delegate_type &rhs)
Adds a delegate to this event.
Definition: event.hxx:279
event & operator=(const event &arg)=default
The default assignment operator.
event(const event &arg)=default
Constructs a event instance.
~event(void)=default
Destructs this instance..
event(event &&arg)=default
Constructs a event instance.
void operator()(void) const
Fires this event instance.
Definition: event.hxx:306
delegate< void()> delegate_type
The delegate type of this event.
Definition: event.hxx:196
bool is_empty(void) const
Checks if this event has any delegates to be invoked.
Definition: event.hxx:323
event & operator-=(const delegate_type &rhs)
Removes a delegate from this event.
Definition: event.hxx:297
event & operator-=(const slim_delegate_type &rhs)
Removes a slim_delegate from this event.
Definition: event.hxx:252
Use this class to register and invoke several delegates (function pointer in OOP design).
Definition: event.hxx:33
event & operator=(const event &arg)=default
The default assignment operator.
void operator()(TEventArgs... args) const
Fires this event instance.
Definition: event.hxx:148
event & operator=(event &&arg) noexcept=default
The move assignment operator.
~event(void)=default
Destructs this instance..
event & operator-=(const slim_delegate_type &rhs)
Removes a slim_delegate from this event.
Definition: event.hxx:93
delegate< void(TEventArgs...)> delegate_type
The delegate type of this event.
Definition: event.hxx:36
event & operator+=(const delegate_type &rhs)
Adds a delegate to this event.
Definition: event.hxx:120
event & operator+=(slim_delegate_type &&rhs)
Adds a slim_delegate to this event.
Definition: event.hxx:64
event(const event &arg)=default
Constructs a event instance.
bool is_empty(void) const
Checks if this event has any delegates to be invoked.
Definition: event.hxx:165
event(void)=default
Constructs a event instance.
event & operator+=(const slim_delegate_type &rhs)
Adds a slim_delegate to this event.
Definition: event.hxx:79
event & operator+=(delegate_type &&rhs)
Adds a delegate to this event.
Definition: event.hxx:102
event & operator-=(const delegate_type &rhs)
Removes a delegate from this event.
Definition: event.hxx:138
event(event &&arg) noexcept=default
Constructs a event instance.
Definition: slim_delegate.hxx:12
Root namespace for the PLCnext API