From a6ab1504058304012791281f9eb42c262745888f Mon Sep 17 00:00:00 2001 From: jacqueline Date: Fri, 19 May 2023 21:21:27 +1000 Subject: Add tinyfsm, start converting core functions to an FSM-based event loop --- lib/tinyfsm/examples/elevator/elevator.cpp | 115 +++++++++++++++++++++++++++++ 1 file changed, 115 insertions(+) create mode 100644 lib/tinyfsm/examples/elevator/elevator.cpp (limited to 'lib/tinyfsm/examples/elevator/elevator.cpp') diff --git a/lib/tinyfsm/examples/elevator/elevator.cpp b/lib/tinyfsm/examples/elevator/elevator.cpp new file mode 100644 index 00000000..6e792f64 --- /dev/null +++ b/lib/tinyfsm/examples/elevator/elevator.cpp @@ -0,0 +1,115 @@ +#include + +#include "elevator.hpp" +#include "fsmlist.hpp" + +#include + +class Idle; // forward declaration + + +// ---------------------------------------------------------------------------- +// Transition functions +// + +static void CallMaintenance() { + std::cout << "*** calling maintenance ***" << std::endl; +} + +static void CallFirefighters() { + std::cout << "*** calling firefighters ***" << std::endl; +} + + +// ---------------------------------------------------------------------------- +// State: Panic +// + +class Panic +: public Elevator +{ + void entry() override { + send_event(MotorStop()); + } +}; + + +// ---------------------------------------------------------------------------- +// State: Moving +// + +class Moving +: public Elevator +{ + void react(FloorSensor const & e) override { + int floor_expected = current_floor + Motor::getDirection(); + if(floor_expected != e.floor) + { + std::cout << "Floor sensor defect (expected " << floor_expected << ", got " << e.floor << ")" << std::endl; + transit(CallMaintenance); + } + else + { + std::cout << "Reached floor " << e.floor << std::endl; + current_floor = e.floor; + if(e.floor == dest_floor) + transit(); + } + }; +}; + + +// ---------------------------------------------------------------------------- +// State: Idle +// + +class Idle +: public Elevator +{ + void entry() override { + send_event(MotorStop()); + } + + void react(Call const & e) override { + dest_floor = e.floor; + + if(dest_floor == current_floor) + return; + + /* lambda function used for transition action */ + auto action = [] { + if(dest_floor > current_floor) + send_event(MotorUp()); + else if(dest_floor < current_floor) + send_event(MotorDown()); + }; + + transit(action); + }; +}; + + +// ---------------------------------------------------------------------------- +// Base state: default implementations +// + +void Elevator::react(Call const &) { + std::cout << "Call event ignored" << std::endl; +} + +void Elevator::react(FloorSensor const &) { + std::cout << "FloorSensor event ignored" << std::endl; +} + +void Elevator::react(Alarm const &) { + transit(CallFirefighters); +} + +int Elevator::current_floor = Elevator::initial_floor; +int Elevator::dest_floor = Elevator::initial_floor; + + +// ---------------------------------------------------------------------------- +// Initial state definition +// +FSM_INITIAL_STATE(Elevator, Idle) -- cgit v1.2.3