PLCnext API Documentation  22.9.0.33
event.hxx
1 //
3 // Copyright PHOENIX CONTACT Electronics GmbH
4 //
6 #pragma once
7 #include "Arp/System/Core/Arp.h"
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 
13 namespace 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 
31 template<class ...TEventArgs>
32 class event
33 {
34 public: // typedefs/usings
36  using delegate_type = delegate<void(TEventArgs...)>;
38  using slim_delegate_type = slim_delegate<void(TEventArgs...)>;
39 
40 public:
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 
60 public: // 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 
102  event& operator+=(delegate_type&& rhs)
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 
144 public: // 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 
162 public: // property operations
165  bool is_empty(void)const
166  {
167  return this->slimEventHandlers.empty() && this->eventHandlers.empty();
168  }
169 
170 private:
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 
191 template<>
192 class event<void>
193 {
194 public: // typedefs/usings
196  using delegate_type = delegate<void()>;
199 
200 public:
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 
220 public: // 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 
238  event& operator+=(const slim_delegate_type& rhs)
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 
252  event& operator-=(const slim_delegate_type& rhs)
253  {
254  this->slimEventHandlers.remove(rhs);
255  return *this;
256  }
257 
261  event& operator+=(delegate_type&& rhs)
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 
303 public: // 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 
320 public: // property operations
323  bool is_empty(void)const
324  {
325  return this->slimEventHandlers.empty() && this->eventHandlers.empty();
326  }
327 
328 private:
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=(const event &arg)=default
The default assignment operator.
event & operator+=(const delegate_type &rhs)
Adds a delegate to this event.
Definition: event.hxx:279
event(void)=default
Constructs a event instance.
event & operator-=(const slim_delegate_type &rhs)
Removes a slim_delegate from this event.
Definition: event.hxx:252
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(const event &arg)=default
Constructs a event instance.
event & operator-=(const delegate_type &rhs)
Removes a delegate from this event.
Definition: event.hxx:297
~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+=(delegate_type &&rhs)
Adds a delegate to this event.
Definition: event.hxx:261
Use this class to register and invoke several delegates (function pointer in OOP design).
Definition: event.hxx:33
void operator()(TEventArgs... args) const
Fires this event instance.
Definition: event.hxx:148
event & operator-=(const slim_delegate_type &rhs)
Removes a slim_delegate from this event.
Definition: event.hxx:93
event & operator+=(const delegate_type &rhs)
Adds a delegate to this event.
Definition: event.hxx:120
~event(void)=default
Destructs this instance..
event & operator-=(const delegate_type &rhs)
Removes a delegate from this event.
Definition: event.hxx:138
delegate< void(TEventArgs...)> delegate_type
The delegate type of this event.
Definition: event.hxx:36
event & operator+=(delegate_type &&rhs)
Adds a delegate to this event.
Definition: event.hxx:102
event & operator=(event &&arg) noexcept=default
The move assignment operator.
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+=(slim_delegate_type &&rhs)
Adds a slim_delegate to this event.
Definition: event.hxx:64
event & operator=(const event &arg)=default
The default assignment operator.
event & operator+=(const slim_delegate_type &rhs)
Adds a slim_delegate to this event.
Definition: event.hxx:79
event(event &&arg) noexcept=default
Constructs a event instance.
Definition: slim_delegate.hxx:12
Root namespace for the PLCnext API