FastArduino  v1.7
C++ library to build fast but small Arduino/AVR projects
events.h
Go to the documentation of this file.
1 // Copyright 2016-2021 Jean-Francois Poilpret
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
16 
21 #ifndef EVENTS_HH
22 #define EVENTS_HH
23 
24 #include <stddef.h>
25 #include "queue.h"
26 #include "linked_list.h"
27 
81 namespace events
82 {
92  namespace Type
93  {
98  const uint8_t NO_EVENT = 0;
99 
105  const uint8_t WDT_TIMER = 1;
106 
112  const uint8_t RTT_TIMER = 2;
113 
123  const uint8_t USER_EVENT = 128;
124  };
125 
143  template<typename T> class Event
144  {
145  public:
146  Event(const Event<T>&) = default;
147  Event<T>& operator=(const Event<T>&) = default;
148 
152  using TYPE = T;
153 
160  explicit Event(uint8_t type = Type::NO_EVENT, T value = T{}) INLINE : type_{type}, value_{value} {}
161 
165  uint8_t type() const INLINE
166  {
167  return type_;
168  }
169 
175  T value() const INLINE
176  {
177  return value_;
178  }
179 
180  private:
181  uint8_t type_;
182  T value_;
183  };
184 
186  template<> class Event<void>
187  {
188  public:
189  Event(const Event<void>&) = default;
190  Event<void>& operator=(const Event<void>&) = default;
191 
192  using TYPE = void;
193 
194  explicit Event(uint8_t type = Type::NO_EVENT) INLINE : type_{type} {}
195  uint8_t type() const INLINE
196  {
197  return type_;
198  }
199 
200  private:
201  uint8_t type_;
202  };
204 
206  template<typename T> struct Event_trait
207  {
208  static constexpr const bool IS_EVENT = false;
209  };
210  // Note: the following line compiled with GCC 7.4 but does not with 9.2 and 10.2
211  // template<> template<typename T> struct Event_trait<Event<T>>
212  // Replaced with this line to make GCC 9.2 happy
213  template<typename T> struct Event_trait<Event<T>>
214  {
215  static constexpr const bool IS_EVENT = true;
216  };
218 
220  template<typename EVENT> class EventHandler;
222 
239  template<typename EVENT> class Dispatcher : public containers::LinkedList<EventHandler<EVENT>>
240  {
241  static_assert(Event_trait<EVENT>::IS_EVENT, "EVENT type must be an events::Event<T>");
242 
243  public:
244  Dispatcher() = default;
245  Dispatcher(const Dispatcher<EVENT>&) = delete;
246  Dispatcher<EVENT>& operator=(const Dispatcher<EVENT>&) = delete;
247 
256  void dispatch(const EVENT& event)
257  {
258  this->traverse(HandlerCaller(event));
259  }
260 
261  private:
262  class HandlerCaller
263  {
264  public:
265  explicit HandlerCaller(const EVENT& event) INLINE : event_{event} {}
266  bool operator()(EventHandler<EVENT>& handler) INLINE
267  {
268  if (handler.type() == event_.type()) handler.on_event(event_);
269  return false;
270  }
271 
272  private:
273  const EVENT event_;
274  };
275  };
276 
285  template<typename EVENT> class EventHandler : public containers::Link<EventHandler<EVENT>>
286  {
287  static_assert(Event_trait<EVENT>::IS_EVENT, "EVENT type must be an events::Event<T>");
288 
289  public:
293  uint8_t type() const INLINE
294  {
295  return type_;
296  }
297 
298  protected:
299  EventHandler(const EventHandler<EVENT>&) = default;
300  EventHandler<EVENT>& operator=(const EventHandler<EVENT>&) = default;
301 
307  virtual void on_event(const EVENT& event) = 0;
308 
313  explicit EventHandler(uint8_t type = Type::NO_EVENT) INLINE : type_{type} {}
314 
315  private:
316  uint8_t type_;
317  friend class Dispatcher<EVENT>;
318  };
319 };
320 #endif /* EVENTS_HH */
321 
events::Event::TYPE
T TYPE
The type of additional event value, as defined in template paraneter T.
Definition: events.h:152
events::EventHandler::on_event
virtual void on_event(const EVENT &event)=0
This pure virtual method is called by Dispatcher::dispatch() when event.type() matches the type suppo...
events::Dispatcher::dispatch
void dispatch(const EVENT &event)
Dispatch the given event to the right EventHandler, based on the event type.
Definition: events.h:256
events::Type::USER_EVENT
const uint8_t USER_EVENT
The first ordinal event type that you may use for your own custom events.
Definition: events.h:123
events::EventHandler::type
uint8_t type() const INLINE
The type of event that this handler accepts and can act upon.
Definition: events.h:293
events::Event
A standard Event as managed by FastArduino event API.
Definition: events.h:144
events::Event::value
T value() const INLINE
The associated value of this event.
Definition: events.h:175
events::EventHandler
Abstract event handler, used by Dispatcher to get called back when an event of the expected type is d...
Definition: events.h:286
events
Defines all API to handle events within FastArduino programs.
Definition: events.h:82
queue.h
Utility API to handle ring-buffer queue containers.
events::Event::Event
Event(uint8_t type=Type::NO_EVENT, T value=T{}) INLINE
Create a new event with the given type and the given value.
Definition: events.h:160
events::EventHandler::EventHandler
EventHandler(uint8_t type=Type::NO_EVENT) INLINE
Create an Event Handler for given type of event.
Definition: events.h:313
events::Dispatcher
Utility to dispatch an event to a list of EventHandlers that are registered for its type.
Definition: events.h:240
events::Type::WDT_TIMER
const uint8_t WDT_TIMER
Type of events generated by watchdog::Watchdog for each watchdog timeout interrupt.
Definition: events.h:105
linked_list.h
Utility API to handle linked list containers.
containers::LinkedList< EventHandler< EVENT > >::traverse
void traverse(F func)
Traverse all items of this list and execute f functor.
Definition: linked_list.h:135
containers::LinkedList
Linked list of type T_ items.
Definition: linked_list.h:81
events::Type::NO_EVENT
const uint8_t NO_EVENT
Special event type attached to no event at all.
Definition: events.h:98
events::Type::RTT_TIMER
const uint8_t RTT_TIMER
Type of events generated by timer::RTTEventCallback whenever elapsed RTT::millis() reaches a multiple...
Definition: events.h:112
INLINE
#define INLINE
Specific GCC attribute to force the compiler to always inline code of a given function.
Definition: defines.h:57
events::Event::type
uint8_t type() const INLINE
The type of this event.
Definition: events.h:165