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)
13 #include <boost/msm/back/state_machine.hpp>
16 #include <boost/msm/front/state_machine_def.hpp>
18 #include <boost/msm/front/functor_row.hpp>
19 #include <boost/msm/front/euml/common.hpp>
23 namespace msm
= boost::msm
;
24 namespace mpl
= boost::mpl
;
25 using namespace msm::front
;
27 namespace // Concrete FSM implementation
34 struct is_connected
{};
35 // front-end: define the FSM structure
36 struct Connection_
: public msm::front::state_machine_def
<Connection_
>
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
;
41 // The list of FSM states
42 struct Connected
: public msm::front::state
<>
44 // in this state, we are connected
45 typedef mpl::vector1
<is_connected
> flag_list
;
46 template <class Event
,class FSM
>
47 void on_entry(Event
const&,FSM
& ) {std::cout
<< "entering: Connected" << std::endl
;}
48 template <class Event
,class FSM
>
49 void on_exit(Event
const&,FSM
& ) {std::cout
<< "leaving: Connected" << std::endl
;}
51 struct Disconnected
: public msm::front::state
<>
53 template <class Event
,class FSM
>
54 void on_entry(Event
const& ,FSM
&) {std::cout
<< "entering: Disconnected" << std::endl
;}
55 template <class Event
,class FSM
>
56 void on_exit(Event
const&,FSM
& ) {std::cout
<< "leaving: Disconnected" << std::endl
;}
62 template <class EVT
,class FSM
,class SourceState
,class TargetState
>
63 void operator()(EVT
const&, FSM
& fsm
,SourceState
& ,TargetState
& )
65 // by default, this would be wrong (shows false)
66 cout
<< "SignalConnect. Connected? " << std::boolalpha
<< fsm
.template is_flag_active
<is_connected
>() << endl
;
69 struct SignalDisconnect
71 template <class EVT
,class FSM
,class SourceState
,class TargetState
>
72 void operator()(EVT
const&, FSM
& fsm
,SourceState
& ,TargetState
& )
74 // by default, this would be wrong (shows true)
75 cout
<< "SignalDisconnect. Connected? " << std::boolalpha
<< fsm
.template is_flag_active
<is_connected
>() << endl
;
79 // the initial state of the player SM. Must be defined
80 typedef Disconnected initial_state
;
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 // +--------------+-------------+--------------+---------------------------+----------------------+
90 // Replaces the default no-transition response.
91 template <class FSM
,class Event
>
92 void no_transition(Event
const& e
, FSM
&,int state
)
94 std::cout
<< "no transition from state " << state
95 << " on event " << typeid(e
).name() << std::endl
;
99 typedef msm::back::state_machine
<Connection_
> Connection
;
104 Connection connection
;
105 // needed to start the highest-level SM. This will call on_entry and mark the start of the SM
107 // signal a connection
108 connection
.process_event(connect());
109 // signal a disconnection
110 connection
.process_event(disconnect());