#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)