Line data Source code
1 : // Copyright 2024 Accenture.
2 :
3 : /**
4 : * \ingroup async
5 : */
6 : #pragma once
7 :
8 : #include "async/Types.h"
9 :
10 : #include <etl/array.h>
11 : #include <etl/delegate.h>
12 :
13 : #include <platform/config.h>
14 :
15 : namespace async
16 : {
17 : /**
18 : * A template class that allows a handler function to be registered or deregistered, and then
19 : * executed based on the provided eventMask. Each event corresponds to a bit in the eventMask. The
20 : * handler function is executed when the specified bit in the eventMask is set.
21 : *
22 : * \tparam EventCount Number of events to be handled.
23 : * \tparam Lock RAII lock to support concurrent execution.
24 : */
25 : template<size_t EventCount, typename Lock>
26 : class EventDispatcher
27 : {
28 : public:
29 : static size_t const EVENT_COUNT = EventCount;
30 : using LockType = Lock;
31 : using HandlerFunctionType = ::etl::delegate<void()>;
32 :
33 : void setEventHandler(size_t event, HandlerFunctionType handlerFunction);
34 : void removeEventHandler(size_t event);
35 :
36 : void handleEvents(EventMaskType eventMask) const;
37 :
38 : private:
39 : using HandlerFunctionsArrayType = ::etl::array<HandlerFunctionType, EventCount>;
40 :
41 : template<size_t Event, bool IsValid = (Event < EventCount)>
42 : struct EventDispatcherImpl
43 : {
44 : static EventMaskType const EVENT_MASK = static_cast<EventMaskType>(1U << Event);
45 :
46 : static void
47 : handleEvents(HandlerFunctionsArrayType const& handlerFunctions, EventMaskType eventMask);
48 : };
49 :
50 : template<size_t Event>
51 : struct EventDispatcherImpl<Event, false>
52 : {
53 : static void
54 : handleEvents(HandlerFunctionsArrayType const& handlerFunctions, EventMaskType eventMask);
55 : };
56 :
57 : HandlerFunctionsArrayType _handlerFunctions;
58 : };
59 :
60 : /**
61 : * Inline implementations.
62 : */
63 : template<size_t EventCount, typename Lock>
64 365 : inline void EventDispatcher<EventCount, Lock>::setEventHandler(
65 : size_t const event, HandlerFunctionType const handlerFunction)
66 : {
67 365 : ESR_UNUSED const Lock lock;
68 365 : _handlerFunctions[event] = handlerFunction;
69 365 : }
70 :
71 : template<size_t EventCount, typename Lock>
72 1 : inline void EventDispatcher<EventCount, Lock>::removeEventHandler(size_t const event)
73 : {
74 1 : ESR_UNUSED const Lock lock;
75 1 : _handlerFunctions[event] = HandlerFunctionType();
76 1 : }
77 :
78 : template<size_t EventCount, typename Lock>
79 30 : inline void EventDispatcher<EventCount, Lock>::handleEvents(EventMaskType const eventMask) const
80 : {
81 30 : EventDispatcherImpl<0U>::handleEvents(_handlerFunctions, eventMask);
82 30 : }
83 :
84 : template<size_t EventCount, typename Lock>
85 : template<size_t Event, bool IsValid>
86 64 : inline void EventDispatcher<EventCount, Lock>::EventDispatcherImpl<Event, IsValid>::handleEvents(
87 : HandlerFunctionsArrayType const& handlerFunctions, EventMaskType const eventMask)
88 : {
89 64 : if ((eventMask & EVENT_MASK) != 0U && handlerFunctions[Event].is_valid())
90 : {
91 21 : handlerFunctions[Event]();
92 : }
93 64 : EventDispatcherImpl<Event + 1U>::handleEvents(handlerFunctions, eventMask);
94 64 : }
95 :
96 : template<size_t EventCount, typename Lock>
97 : template<size_t Event>
98 30 : inline void EventDispatcher<EventCount, Lock>::EventDispatcherImpl<Event, false>::handleEvents(
99 : HandlerFunctionsArrayType const& /*handlerFunctions*/, EventMaskType const /*eventMask*/)
100 30 : {}
101 :
102 : } // namespace async
|