tinyfsm
tinyfsm copied to clipboard
How to use an event queue?
I have adapted the main.cpp of the elevator example to use an event queue like this:
#include "fsmlist.hpp"
#include <iostream>
#include <queue>
std::queue<tinyfsm::Event> event_queue;
int main()
{
fsm_list::start();
Call call;
FloorSensor sensor;
while(1)
{
char c;
std::cout << "c=Call, f=FloorSensor, a=Alarm, q=Quit ? ";
std::cin >> c;
switch(c) {
case 'c':
std::cout << "Floor ? ";
std::cin >> call.floor;
event_queue.push(call);
break;
case 'f':
std::cout << "Floor ? ";
std::cin >> sensor.floor;
event_queue.push(sensor);
break;
case 'a':
event_queue.push(Alarm());
break;
case 'q':
std::cout << "Thanks for playing!" << std::endl;
return 0;
default:
std::cout << "Invalid input" << std::endl;
};
send_event(event_queue.front());
event_queue.pop();
}
}
Now the state machine always calls the default
void react(tinyfsm::Event const &) {};
event handler. Probably because the events are upcasted in the queue to tinyfsm::Event?
But how am I supposed to implement event queuing instead?
Reproducing:
- replace
main.cppwith my adapted version - press
ato trigger the alarm event
Expected output:
*** calling firefighters ***
Motor: stopped
Actual output: Nothing
After some research I found a workaround: Define a variant with all events
using EventVariant = std::variant<
Call,
FloorSensor,
....
>;
std::queue<EventVariant> event_queue;
And use a visitor to get the event using the original event struct type:
std::visit([](const auto& event) {
send_event(event);
}, event_queue.front());
event_queue.pop();
This requires at least c++17