// Copyright 2010 Christophe Henry // henry UNDERSCORE christophe AT hotmail DOT com // This is an extended version of the state machine available in the boost::mpl library // Distributed under the same license as the original. // Copyright for the original version: // Copyright 2005 David Abrahams and Aleksey Gurtovoy. Distributed // under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) #include #include #include #include using namespace std; namespace msm = boost::msm; namespace mpl = boost::mpl; using namespace boost::msm::front::euml; namespace // Concrete FSM implementation { // events BOOST_MSM_EUML_EVENT(connect) BOOST_MSM_EUML_EVENT(disconnect) // flag BOOST_MSM_EUML_FLAG(is_connected) BOOST_MSM_EUML_ACTION(SignalConnect) { template void operator()(EVT const& ,FSM& fsm,SourceState& ,TargetState& ) { // by default, this would be wrong (shows false) cout << "SignalConnect. Connected? " << std::boolalpha << fsm.template is_flag_active() << endl; } }; BOOST_MSM_EUML_ACTION(SignalDisconnect) { template void operator()(EVT const& ,FSM& fsm,SourceState& ,TargetState& ) { // by default, this would be wrong (shows true) cout << "SignalDisconnect. Connected? " << std::boolalpha << fsm.template is_flag_active() << endl; } }; // The list of FSM states BOOST_MSM_EUML_ACTION(Connected_Entry) { template void operator()(Event const&,FSM&,STATE& ) { std::cout << "entering: Connected" << std::endl; } }; BOOST_MSM_EUML_ACTION(Connected_Exit) { template void operator()(Event const&,FSM&,STATE& ) { std::cout << "leaving: Connected" << std::endl; } }; BOOST_MSM_EUML_STATE(( Connected_Entry,Connected_Exit, attributes_ << no_attributes_, configure_<< is_connected ),Connected) BOOST_MSM_EUML_ACTION(Disconnected_Entry) { template void operator()(Event const&,FSM&,STATE& ) { std::cout << "entering: Disconnected" << std::endl; } }; BOOST_MSM_EUML_ACTION(Disconnected_Exit) { template void operator()(Event const&,FSM&,STATE& ) { std::cout << "leaving: Disconnected" << std::endl; } }; BOOST_MSM_EUML_STATE(( Disconnected_Entry,Disconnected_Exit ),Disconnected) // replaces the old transition table BOOST_MSM_EUML_TRANSITION_TABLE(( Disconnected == Connected + disconnect / SignalDisconnect , Connected == Disconnected + connect / SignalConnect // +------------------------------------------------------------------------------+ ),transition_table) BOOST_MSM_EUML_ACTION(Log_No_Transition) { template void operator()(Event const& e,FSM&,int state) { std::cout << "no transition from state " << state << " on event " << typeid(e).name() << std::endl; } }; // create a state machine "on the fly" BOOST_MSM_EUML_DECLARE_STATE_MACHINE(( transition_table, //STT init_ << Disconnected, // Init State no_action, // Entry no_action, // Exit attributes_ << no_attributes_, // Attributes configure_ << switch_active_before_transition, // configuration Log_No_Transition // no_transition handler ), Connection_) //fsm name typedef msm::back::state_machine Connection; void test() { Connection connection; // needed to start the highest-level SM. This will call on_entry and mark the start of the SM connection.start(); // signal a connection connection.process_event(connect); // signal a disconnection connection.process_event(disconnect); connection.stop(); } } int main() { test(); return 0; }