|
|
The **EventBroker** is a special singleton active object that allows to post events to specific topics, as in a Publish-Subscribe architecture.
|
|
|
[EventHandlers](EventHandler) in turn can ask the EventBroker to subscribe to a specific topic: this way a subscriber will receive all the events that are posted on the topics it is subscribed to.
|
|
|
|
|
|
In order to manage this events exchange, the broker maintains a map that associates each topic ID to a vector of EventHandlerBase objects:
|
|
|
```cpp
|
|
|
map<uint8_t, vector<EventHandlerBase*>> subscribers;
|
|
|
```
|
|
|
|
|
|
The events that are posted instead, are put in an event queue. The active object thread takes care of removing events from the event queue and to forward them to all the subscribers, according to the vectors stored in the `subscribers` map.
|
|
|
|
|
|
### Methods
|
|
|
In addition to the [singleton](Singleton) and [active object](Active-Object) methods, the EventBroker exposes:
|
|
|
- **void post(const Event& ev, uint8_t topic)**: post an event to a specific topic.
|
|
|
- **uint16_t postDelayed(const Event& ev, uint8_t topic)**: post an event to a specific topic after a given delay in milliseconds (the delay can be passed as a template, e.g. postDelayed<100>(...)).
|
|
|
- **void removeDelayed(uint16_t id)**: remove a pending delayed event from the event queue.
|
|
|
- **void subscribe(EventHandlerBase\* subscriber, uint8_t topic)**: subscribe the given subscriber to the specified topic.
|
|
|
- **void unsubscribe(EventHandlerBase\* subscriber, uint8_t topic)**: unsubscribe the given subscriber to the specified topic. If no topic is passed, the unsubscribe the subscriber from every topic it was subscribed to.
|
|
|
- **void clearDelayedEvents()**: remove all pending events.
|
|
|
|
|
|
> :warning: **WARNING: note that the current *EventBroker* implementation does not support posting events that contain a payload. See [this page](Events) to know how events are structured.**
|
|
|
|
|
|
### Example
|
|
|
This example shows how to define an EventHandler object that subscribes to a topic and received the events that are posted on that topic.
|
|
|
|
|
|
##### MyEventHandler.h
|
|
|
First of all we need to include the required dependencies. We also need to specify a list of possible events and topics.
|
|
|
```cpp
|
|
|
#pragma once
|
|
|
|
|
|
#include "Common.h"
|
|
|
#include "events/EventHandler.h"
|
|
|
#include "events/EventBroker.h"
|
|
|
|
|
|
enum ExampleEvents : uint8_t
|
|
|
{
|
|
|
EV_1 = EV_FIRST_SIGNAL,
|
|
|
EV_2,
|
|
|
EV_3
|
|
|
};
|
|
|
|
|
|
enum ExampleTopics : uint8_t
|
|
|
{
|
|
|
TOPIC_1,
|
|
|
TOPIC_2
|
|
|
};
|
|
|
```
|
|
|
|
|
|
Then we can define a custom EventHandler.
|
|
|
This is basically the same class that is shown in the [EventHandler](EventHandler) page, but when an object is instantiated it automatically subscribes to the topic `TOPIC_1`.
|
|
|
|
|
|
```cpp
|
|
|
class MyEventHandler : public EventHandler
|
|
|
{
|
|
|
public:
|
|
|
MyEventHandler()
|
|
|
: EventHandler(), // call parent constructor
|
|
|
last_event(0)
|
|
|
{
|
|
|
// make this object to subscribe to TOPIC_1
|
|
|
EventBroker::getInstance()->subscribe(this, TOPIC_1);
|
|
|
}
|
|
|
|
|
|
protected:
|
|
|
void handleEvent(const Event& ev) override
|
|
|
{
|
|
|
switch(ev.sig)
|
|
|
{
|
|
|
case EV_1:
|
|
|
TRACE("Received EV_1 \n");
|
|
|
break;
|
|
|
case EV_2:
|
|
|
TRACE("Received EV_2 \n");
|
|
|
break;
|
|
|
default:
|
|
|
TRACE("Invalid event \n");
|
|
|
}
|
|
|
|
|
|
last_event = ev.sig;
|
|
|
}
|
|
|
|
|
|
private:
|
|
|
uint8_t last_event;
|
|
|
};
|
|
|
```
|
|
|
|
|
|
##### test-eventbroker.cpp
|
|
|
In the main we need to create an instance of the EventBroker (it is a singleton object) and start it (it is also an active object).
|
|
|
Then we can post some events, both on topic `TOPIC_1` and `TOPIC_2`.
|
|
|
```cpp
|
|
|
#include <Common.h>
|
|
|
#include "MyEventHandler.h"
|
|
|
|
|
|
using namespace miosix;
|
|
|
|
|
|
int main()
|
|
|
{
|
|
|
EventBroker broker = EventBroker::getInstance(); // singleton object
|
|
|
broker->start();
|
|
|
|
|
|
MyEventHandler evh;
|
|
|
|
|
|
if (evh.start())
|
|
|
{
|
|
|
// post an event
|
|
|
broker->post(Event{EV_1}, TOPIC_1);
|
|
|
Thread::sleep(100);
|
|
|
// post another event on a different topic
|
|
|
broker->post(Event{EV_2}, TOPIC_2);
|
|
|
Thread::sleep(100);
|
|
|
}
|
|
|
else {
|
|
|
TRACE("Failed to start MyEventHandler\n");
|
|
|
}
|
|
|
|
|
|
return 0;
|
|
|
}
|
|
|
```
|
|
|
##### Output
|
|
|
What we can observe is that the program output will be only something like:
|
|
|
```sh
|
|
|
0.12> Received EV_1
|
|
|
```
|
|
|
In fact our MyEventHandler object will not receive the event `EV_2` since it is only subscribed to topic `TOPIC_1`. |
|
|
\ No newline at end of file |