• 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 // back-end
13 #include <boost/msm/back/state_machine.hpp>
14 
15 //front-end
16 #include <boost/msm/front/state_machine_def.hpp>
17 // functors
18 #include <boost/msm/front/functor_row.hpp>
19 #include <boost/msm/front/euml/common.hpp>
20 
21 
22 using namespace std;
23 namespace msm = boost::msm;
24 namespace mpl = boost::mpl;
25 using namespace msm::front;
26 
27 namespace  // Concrete FSM implementation
28 {
29     // events
30     struct disconnect {};
31     struct connect {};
32 
33     // flag
34     struct is_connected{};
35     // front-end: define the FSM structure
36     struct Connection_ : public msm::front::state_machine_def<Connection_>
37     {
38         // when a transition is about to be taken, we already update our currently active state(s)
39         typedef msm::active_state_switch_before_transition active_state_switch_policy;
40 
41         // The list of FSM states
42         struct Connected : public msm::front::state<>
43         {
44             // in this state, we are connected
45             typedef mpl::vector1<is_connected>      flag_list;
46             template <class Event,class FSM>
on_entry__anon06ca929d0111::Connection_::Connected47             void on_entry(Event const&,FSM& ) {std::cout << "entering: Connected" << std::endl;}
48             template <class Event,class FSM>
on_exit__anon06ca929d0111::Connection_::Connected49             void on_exit(Event const&,FSM& ) {std::cout << "leaving: Connected" << std::endl;}
50         };
51         struct Disconnected : public msm::front::state<>
52         {
53             template <class Event,class FSM>
on_entry__anon06ca929d0111::Connection_::Disconnected54             void on_entry(Event const& ,FSM&) {std::cout << "entering: Disconnected" << std::endl;}
55             template <class Event,class FSM>
on_exit__anon06ca929d0111::Connection_::Disconnected56             void on_exit(Event const&,FSM& ) {std::cout << "leaving: Disconnected" << std::endl;}
57         };
58 
59         // transition actions
60         struct SignalConnect
61         {
62             template <class EVT,class FSM,class SourceState,class TargetState>
operator ()__anon06ca929d0111::Connection_::SignalConnect63             void operator()(EVT const&, FSM& fsm,SourceState& ,TargetState& )
64             {
65                 // by default, this would be wrong (shows false)
66                 cout << "SignalConnect. Connected? " << std::boolalpha << fsm.template is_flag_active<is_connected>() << endl;
67             }
68         };
69         struct SignalDisconnect
70         {
71             template <class EVT,class FSM,class SourceState,class TargetState>
operator ()__anon06ca929d0111::Connection_::SignalDisconnect72             void operator()(EVT const&, FSM& fsm,SourceState& ,TargetState& )
73             {
74                 // by default, this would be wrong (shows true)
75                 cout << "SignalDisconnect. Connected? " << std::boolalpha << fsm.template is_flag_active<is_connected>() << endl;
76             }
77         };
78 
79         // the initial state of the player SM. Must be defined
80         typedef Disconnected initial_state;
81 
82         // Transition table for player
83         struct transition_table : mpl::vector<
84             //    Start          Event         Next           Action                     Guard
85             //  +--------------+-------------+--------------+---------------------------+----------------------+
86             Row < Connected    , disconnect  , Disconnected , SignalDisconnect          , none                 >,
87             Row < Disconnected , connect     , Connected    , SignalConnect             , none                 >
88             //  +--------------+-------------+--------------+---------------------------+----------------------+
89         > {};
90         // Replaces the default no-transition response.
91         template <class FSM,class Event>
no_transition__anon06ca929d0111::Connection_92         void no_transition(Event const& e, FSM&,int state)
93         {
94             std::cout << "no transition from state " << state
95                 << " on event " << typeid(e).name() << std::endl;
96         }
97     };
98     // Pick a back-end
99     typedef msm::back::state_machine<Connection_> Connection;
100 
101 
test()102     void test()
103     {
104         Connection connection;
105         // needed to start the highest-level SM. This will call on_entry and mark the start of the SM
106         connection.start();
107         // signal a connection
108         connection.process_event(connect());
109         // signal a disconnection
110         connection.process_event(disconnect());
111         connection.stop();
112     }
113 }
114 
main()115 int main()
116 {
117     test();
118     return 0;
119 }
120