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