With event handler here we mean anything that can continuously read from an event queue and process the received events.
EventHandlerBase
It is the base interface extended by the EventHandler class:
class EventHandlerBase
{
public:
EventHandlerBase() {}
virtual ~EventHandlerBase(){};
virtual void postEvent(const Event& ev) = 0;
};
EventHandler
The EventHandler class, in addition to EventHandlerBase, also extends the ActiveObject interface.
In fact an EventHandler is a special ActiveObject that periodically checks a synchronized queue of events. When new events are present they can be removed from the queue and processed.
Methods
EventHadler offers two main methods:
- virtual void postEvent(const Event& ev): overridden from EventHandlerBase, it enqueues the event passed as a parameters.
- virtual void handleEvent(const Event& ev): protected method that is periodically called in the active objects thread. In fact in the run() method, whenever an event is present in the queue, it gets removed and the handleEvent method is called. The handleEvent method has to be overridden and implemented by any class that extends EventHandler.
You can find the complete implementation of EventHandler in src/shared/events/EventHandler.h
.
Example
This example shows how to define a very simple custom EventHandler.
MyEventHandler.h
The first thing we need to do is to import the required modules and to define a set of events. For more details you can look at the Events page.
Here we define three possible events: EV_1
, EV_2
and EV_3
.
#pragma once
#include "events/EventHandler.h"
namespace Boardcore {
enum ExampleEvents : uint8_t
{
EV_1 = EV_FIRST_CUSTOM,
EV_2,
EV_3
};
Then, we can define a class that extends EventHandler.
We need at least to override the handleEvent() method, which processes incoming events.
In this example we simply produce some output strings and keep track of the last event that has been recevied.
class MyEventHandler : public EventHandler
{
public:
MyEventHandler()
: EventHandler(), // call parent constructor
last_event(0) {}
protected:
void handleEvent(const Event& ev) override
{
switch(ev) // do something according to the event's id
{
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;
}
private:
uint8_t last_event;
};
} // namespace Boardcore
test-myeventhandler.cpp
In order to test that our class works we can create a MyEventHandler object and start it.
We can then post some events and see what the output is.
#include <miosix.h>
#include "MyEventHandler.h"
using namespace miosix;
using namespace Boardcore;
int main()
{
MyEventHandler evh;
if (evh.start())
{
// post some events
evh.postEvent(Event{EV_1});
Thread::sleep(100);
evh.postEvent(Event{EV_2});
Thread::sleep(100);
evh.postEvent(Event{EV_3}); // event not handled by MyEventHandler
Thread::sleep(100);
evh.stop(); // it posts an EV_EMPTY to wake up the thread
}
else {
TRACE("Failed to start MyEventHandler\n");
}
return 0;
}
Output
Remember to add the test-myeventhandler.cpp
to sbs.conf
and to specify all the needed includes.
After you run the example you should see the following output:
0.03> Received EV_1
0.13> Received EV_2
0.23> Invalid event
0.33> Invalid event
The last "Invalid event" is due to the EV_EMPTY
posted by the stop()
method of the EventHandler object.