• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1  // Copyright 2010 Christophe Henry
2  // henry UNDERSCORE christophe AT hotmail DOT com
3  // This is an extended version of the state machine available in the boost::mpl library
4  // Distributed under the same license as the original.
5  // Copyright for the original version:
6  // Copyright 2005 David Abrahams and Aleksey Gurtovoy. Distributed
7  // under the Boost Software License, Version 1.0. (See accompanying
8  // file LICENSE_1_0.txt or copy at
9  // http://www.boost.org/LICENSE_1_0.txt)
10  
11  #include <iostream>
12  
13  #include <boost/msm/back/state_machine.hpp>
14  #include <boost/msm/front/state_machine_def.hpp>
15  #include <boost/msm/front/euml/euml.hpp>
16  
17  using namespace std;
18  namespace msm = boost::msm;
19  namespace mpl = boost::mpl;
20  using namespace boost::msm::front::euml;
21  
22  
23  namespace // Concrete FSM implementation
24  {
25      // events
26      BOOST_MSM_EUML_EVENT(connect)
BOOST_MSM_EUML_EVENT(disconnect)27      BOOST_MSM_EUML_EVENT(disconnect)
28  
29      // flag
30      BOOST_MSM_EUML_FLAG(is_connected)
31  
32      BOOST_MSM_EUML_ACTION(SignalConnect)
33      {
34          template <class FSM,class EVT,class SourceState,class TargetState>
35          void operator()(EVT const& ,FSM& fsm,SourceState& ,TargetState& )
36          {
37              // by default, this would be wrong (shows false)
38              cout << "SignalConnect. Connected? "
39                   << std::boolalpha
40                   << fsm.template is_flag_active<BOOST_MSM_EUML_FLAG_NAME(is_connected)>() << endl;
41          }
42      };
BOOST_MSM_EUML_ACTION(SignalDisconnect)43      BOOST_MSM_EUML_ACTION(SignalDisconnect)
44      {
45          template <class FSM,class EVT,class SourceState,class TargetState>
46          void operator()(EVT const& ,FSM& fsm,SourceState& ,TargetState& )
47          {
48              // by default, this would be wrong (shows true)
49              cout << "SignalDisconnect. Connected? "
50                   << std::boolalpha
51                   << fsm.template is_flag_active<BOOST_MSM_EUML_FLAG_NAME(is_connected)>()
52                   << endl;
53          }
54      };
55  
56      // The list of FSM states
BOOST_MSM_EUML_ACTION(Connected_Entry)57      BOOST_MSM_EUML_ACTION(Connected_Entry)
58      {
59          template <class Event,class FSM,class STATE>
60          void operator()(Event const&,FSM&,STATE& )
61          {
62              std::cout << "entering: Connected" << std::endl;
63          }
64      };
BOOST_MSM_EUML_ACTION(Connected_Exit)65      BOOST_MSM_EUML_ACTION(Connected_Exit)
66      {
67          template <class Event,class FSM,class STATE>
68          void operator()(Event const&,FSM&,STATE& )
69          {
70              std::cout << "leaving: Connected" << std::endl;
71          }
72      };
73      BOOST_MSM_EUML_STATE(( Connected_Entry,Connected_Exit,
74                             attributes_ << no_attributes_,
75                             configure_<< is_connected ),Connected)
76  
BOOST_MSM_EUML_ACTION(Disconnected_Entry)77      BOOST_MSM_EUML_ACTION(Disconnected_Entry)
78      {
79          template <class Event,class FSM,class STATE>
80          void operator()(Event const&,FSM&,STATE& )
81          {
82              std::cout << "entering: Disconnected" << std::endl;
83          }
84      };
BOOST_MSM_EUML_ACTION(Disconnected_Exit)85      BOOST_MSM_EUML_ACTION(Disconnected_Exit)
86      {
87          template <class Event,class FSM,class STATE>
88          void operator()(Event const&,FSM&,STATE& )
89          {
90              std::cout << "leaving: Disconnected" << std::endl;
91          }
92      };
93      BOOST_MSM_EUML_STATE(( Disconnected_Entry,Disconnected_Exit ),Disconnected)
94  
95      // replaces the old transition table
96      BOOST_MSM_EUML_TRANSITION_TABLE((
97            Disconnected  == Connected    + disconnect    / SignalDisconnect  ,
98            Connected     == Disconnected + connect       / SignalConnect
99            //  +------------------------------------------------------------------------------+
100            ),transition_table)
101  
BOOST_MSM_EUML_ACTION(Log_No_Transition)102      BOOST_MSM_EUML_ACTION(Log_No_Transition)
103      {
104          template <class FSM,class Event>
105          void operator()(Event const& e,FSM&,int state)
106          {
107              std::cout << "no transition from state " << state
108                  << " on event " << typeid(e).name() << std::endl;
109          }
110      };
111  
112      // create a state machine "on the fly"
113      BOOST_MSM_EUML_DECLARE_STATE_MACHINE(( transition_table, //STT
114                                          init_ << Disconnected, // Init State
115                                          no_action, // Entry
116                                          no_action, // Exit
117                                          attributes_ << no_attributes_, // Attributes
118                                          configure_ << switch_active_before_transition, // configuration
119                                          Log_No_Transition // no_transition handler
120                                          ),
121                                        Connection_) //fsm name
122  
123      typedef msm::back::state_machine<Connection_> Connection;
124  
test()125      void test()
126      {
127          Connection connection;
128          // needed to start the highest-level SM. This will call on_entry and mark the start of the SM
129          connection.start();
130          // signal a connection
131          connection.process_event(connect);
132          // signal a disconnection
133          connection.process_event(disconnect);
134          connection.stop();
135      }
136  }
137  
main()138  int main()
139  {
140      test();
141      return 0;
142  }
143  
144  
145