Logo Pico-Framework A web-first embedded framework for C++
Loading...
Searching...
No Matches
EventManager Class Reference

Manages the system-wide event queue and subscriptions. More...

#include <EventManager.h>

+ Collaboration diagram for EventManager:

Classes

struct  Subscriber
 

Public Member Functions

 EventManager (size_t queueSize=0)
 Constructor with optional queue size override.
 
void subscribe (uint32_t eventMask, FrameworkController *controller)
 Subscribe a task to specific event types.
 
void postEvent (const Event &e)
 Post a notification to the queue and notify matching subscribers.
 
void postNotification (const Notification &n, FrameworkTask *target)
 Post a notification to the queue and notify matching subscribers.
 
void enqueue (const Event &event)
 Post an event to the queue and notify matching subscribers.
 
bool hasPendingEvents (FrameworkController *controller) const
 Returns true if there are any pending events for a given controller.
 
template<typename Enum , typename... Rest>
void subscribeTo (FrameworkController *ctrl, Enum first, Rest... rest)
 

Static Public Member Functions

static EventManagergetInstance ()
 Get the global EventManager instance.
 

Private Member Functions

void withSubscribers (const std::function< void(std::vector< Subscriber > &)> &fn)
 
void withSubscribersFromISR (const std::function< void(std::vector< Subscriber > &)> &fn)
 Provides read-only access to subscribers from ISR context (no locking).
 

Private Attributes

SemaphoreHandle_t lock
 
std::vector< Subscribersubscribers_
 

Static Private Attributes

static StaticSemaphore_t lockBuffer_
 

Detailed Description

Allows tasks to:

  • Subscribe to specific event types (via bitmask)
  • Post events (from task or ISR context)
  • Receive and process events via onEvent()

Implemented as a singleton.

Definition at line 63 of file EventManager.h.

Constructor & Destructor Documentation

◆ EventManager()

EventManager::EventManager ( size_t  queueSize = 0)
explicit

Constructor with optional queue size override.

Parameters
queueSizeMaximum number of events in the internal queue.
Parameters
queueSizeMaximum number of events in the internal queue.

Definition at line 50 of file EventManager.cpp.

51{
52 lock = xSemaphoreCreateMutexStatic(&lockBuffer_);
54}
#define configASSERT(x)
SemaphoreHandle_t lock
static StaticSemaphore_t lockBuffer_

References configASSERT, lock, and lockBuffer_.

Member Function Documentation

◆ enqueue()

void EventManager::enqueue ( const Event event)

Post an event to the queue and notify matching subscribers.

Safe to call from task or ISR context.

Parameters
eventThe event to post.

Safe to call from task or ISR context.

Parameters
eventThe event to post.

Definition at line 111 of file EventManager.cpp.

112{
113 const uint8_t code = event.notification.code();
114
115 if (is_in_interrupt()) {
116 BaseType_t xHigherPriTaskWoken = pdFALSE;
117
118 withSubscribersFromISR([&](auto& subs) {
119 for (auto& sub : subs) {
120 if ((sub.eventMask & (1u << code)) &&
121 (event.target == nullptr || sub.controller == event.target))
122 {
123 QueueHandle_t q = sub.controller->getEventQueue();
124 if (q) {
125 BaseType_t result = xQueueSendToBackFromISR(q, &event, &xHigherPriTaskWoken);
126 if (result != pdPASS) {
127 debug_print("[EventManager] xQueueSendFromISR FAILED — queue full!\n");
128 }
129 }
130 }
131 }
132 });
133
134 portYIELD_FROM_ISR(xHigherPriTaskWoken);
135 } else {
136 withSubscribers([&](auto& subs) {
137 for (auto& sub : subs) {
138 if ((sub.eventMask & (1u << code)) &&
139 (event.target == nullptr || sub.controller == event.target))
140 {
141 QueueHandle_t q = sub.controller->getEventQueue();
142 if (q) {
143 if (xQueueSendToBack(q, &event, 0) != pdPASS) {
144 debug_print("[EventManager] xQueueSend FAILED — queue full!\n");
145 }
146 }
147 }
148 }
149 });
150 }
151}
void withSubscribersFromISR(const std::function< void(std::vector< Subscriber > &)> &fn)
Provides read-only access to subscribers from ISR context (no locking).
void withSubscribers(const std::function< void(std::vector< Subscriber > &)> &fn)
FrameworkTask * target
Optional specific target (for directed delivery)
Definition Event.h:32
int is_in_interrupt(void)
Definition utility.cpp:172
void debug_print(const char *msg)
Definition utility.cpp:184

References debug_print(), is_in_interrupt(), withSubscribers(), and withSubscribersFromISR().

Referenced by postEvent().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ getInstance()

static EventManager & EventManager::getInstance ( )
inlinestatic

Definition at line 69 of file EventManager.h.

70 {
71 static EventManager instance;
72 return instance;
73 }
Manages the system-wide event queue and subscriptions.

◆ hasPendingEvents()

bool EventManager::hasPendingEvents ( FrameworkController controller) const
Parameters
controllerPointer to the controller.
Returns
True if any matching events exist.

◆ postEvent()

void EventManager::postEvent ( const Event e)

Safe to call from task or ISR context.

Parameters
nThe notification to post.
targetOptional specific controller to notify (nullptr for all).

Definition at line 153 of file EventManager.cpp.

154{
155 enqueue(e);
157}
void enqueue(const Event &event)
Post an event to the queue and notify matching subscribers.
void postNotification(const Notification &n, FrameworkTask *target)
Post a notification to the queue and notify matching subscribers.
Notification notification
Notification identifier (system or user)
Definition Event.h:25

References enqueue(), Event::notification, postNotification(), and Event::target.

+ Here is the call graph for this function:

◆ postNotification()

void EventManager::postNotification ( const Notification n,
FrameworkTask target 
)

Post a notification to the queue and notify matching subscribers.

Safe to call from task or ISR context.

Parameters
nThe notification to post.
targetOptional specific controller to notify (nullptr for all).

Safe to call from task or ISR context.

Parameters
nThe notification to post.
targetOptional specific controller to notify (nullptr for all).

Definition at line 80 of file EventManager.cpp.

81{
82 const uint8_t index = n.code();
83
84 if (is_in_interrupt()) {
85 BaseType_t xHigherPriTaskWoken = pdFALSE;
86
87 withSubscribersFromISR([&](auto& subs) {
88 for (auto& sub : subs) {
89 if ((sub.eventMask & (1u << index)) &&
90 (target == nullptr || sub.controller == target)) {
91 sub.controller->notifyFromISR(index, 1, &xHigherPriTaskWoken);
92 }
93 }
94 });
95
96 portYIELD_FROM_ISR(xHigherPriTaskWoken);
97 } else {
98 withSubscribers([&](auto& subs) {
99 for (auto& sub : subs) {
100 if ((sub.eventMask & (1u << index)) &&
101 (target == nullptr || sub.controller == target)) {
102 sub.controller->notify(index, 1);
103 }
104 }
105 });
106 }
107}
uint8_t code() const
Get the notification code.

References Notification::code(), is_in_interrupt(), withSubscribers(), and withSubscribersFromISR().

Referenced by postEvent().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ subscribe()

void EventManager::subscribe ( uint32_t  mask,
FrameworkController target 
)

Subscribe a task to specific event types.

Each controller provides a bitmask of events it is interested in.

Parameters
eventMaskBitmask of (1 << event.notification.code()).
controllerPointer to the FrameworkController to notify.
Note
All EventManager::subscribe() for thread safety, calls must complete before interrupts are enabled."

Each controller provides a bitmask of events it is interested in.

Parameters
eventMaskBitmask of (1 << event.notification.code()).
controllerPointer to the FrameworkController to notify.
Note
All EventManager::subscribe() for thread safety, calls must complete before interrupts are enabled."

Definition at line 57 of file EventManager.cpp.

58{
59 withSubscribers([&](auto& subs) {
60 subs.push_back({mask, target});
61 });
62}

References withSubscribers().

Referenced by App::onStart(), and subscribeTo().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ subscribeTo()

template<typename Enum , typename... Rest>
void EventManager::subscribeTo ( FrameworkController ctrl,
Enum  first,
Rest...  rest 
)
inline

Definition at line 132 of file EventManager.h.

132 {
133 static_assert(
134 (std::is_same_v<Enum, Rest> && ...),
135 "All event types must be of the same enum class (UserNotification or SystemNotification)"
136 );
137
138 subscribe(eventMask(first, rest...), ctrl);
139 }
constexpr uint32_t eventMask(Enum e)
Helper function to create an event mask from an enum value.
void subscribe(uint32_t eventMask, FrameworkController *controller)
Subscribe a task to specific event types.

References eventMask(), and subscribe().

+ Here is the call graph for this function:

◆ withSubscribers()

void EventManager::withSubscribers ( const std::function< void(std::vector< Subscriber > &)> &  fn)
private

Definition at line 64 of file EventManager.cpp.

65{
66 xSemaphoreTake(lock, portMAX_DELAY);
67 fn(subscribers_);
68 xSemaphoreGive(lock);
69}
std::vector< Subscriber > subscribers_

References lock, and subscribers_.

Referenced by enqueue(), postNotification(), and subscribe().

+ Here is the caller graph for this function:

◆ withSubscribersFromISR()

void EventManager::withSubscribersFromISR ( const std::function< void(std::vector< Subscriber > &)> &  fn)
private

Provides read-only access to subscribers from ISR context (no locking).

WARNING: Call only from ISR context. Must not modify the list.

WARNING: Call only from ISR context. Must not modify the list.

Definition at line 72 of file EventManager.cpp.

73{
74 xSemaphoreTake(lock, portMAX_DELAY);
75 fn(subscribers_);
76 xSemaphoreGive(lock);
77}

References lock, and subscribers_.

Referenced by enqueue(), and postNotification().

+ Here is the caller graph for this function:

Member Data Documentation

◆ lock

SemaphoreHandle_t EventManager::lock
private

Definition at line 148 of file EventManager.h.

Referenced by EventManager(), withSubscribers(), and withSubscribersFromISR().

◆ lockBuffer_

StaticSemaphore_t EventManager::lockBuffer_
staticprivate

Definition at line 149 of file EventManager.h.

Referenced by EventManager().

◆ subscribers_

std::vector<Subscriber> EventManager::subscribers_
private

Definition at line 151 of file EventManager.h.

Referenced by withSubscribers(), and withSubscribersFromISR().


The documentation for this class was generated from the following files: