#include #include #include using namespace std; // back-end #include //front-end #include #include namespace msm = boost::msm; namespace mpl = boost::mpl; using namespace msm::front; vector state_names{ "off hook"s, "connecting"s, "connected"s, "on hold"s, "destroyed"s }; // transitions/events struct CallDialed {}; struct HungUp {}; struct CallConnected {}; struct PlacedOnHold {}; struct TakenOffHold {}; struct LeftMessage {}; struct PhoneThrownIntoWall {}; struct PhoneStateMachine : state_machine_def { bool angry{ true }; // start with false struct OffHook : state<> {}; struct Connecting : state<> { template void on_entry(Event const& evt, FSM&) { cout << "We are connecting..." << endl; } // also on_exit }; struct Connected : state<> {}; struct OnHold : state<> {}; struct PhoneDestroyed : state<> {}; struct PhoneBeingDestroyed { template void operator()(EVT const&, FSM&, SourceState&, TargetState&) { cout << "Phone breaks into a million pieces" << endl; } }; struct CanDestroyPhone { template bool operator()(EVT const&, FSM& fsm, SourceState&, TargetState&) { return fsm.angry; } }; // start, event, target, action, guard struct transition_table : mpl::vector < Row, Row, Row, Row > {}; // starting state typedef OffHook initial_state; // what happens if there's nowhere to go template void no_transition(Event const& e, FSM&, int state) { cout << "No transition from state " << state_names[state] << " on event " << typeid(e).name() << endl; } }; int main() { msm::back::state_machine phone; auto info = [&]() { auto i = phone.current_state()[0]; cout << "The phone is currently " << state_names[i] << "\n"; }; info(); phone.process_event(CallDialed{}); info(); phone.process_event(CallConnected{}); info(); phone.process_event(PlacedOnHold{}); info(); phone.process_event(PhoneThrownIntoWall{}); info(); // try process_event here :) phone.process_event(CallDialed{}); cout << "We are done using the phone" << "\n"; getchar(); return 0; }