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