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