]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
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) | |
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 | }; | |
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 | |
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 | }; | |
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 | ||
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 | }; | |
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 | ||
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 | ||
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 | ||
138 | int main() | |
139 | { | |
140 | test(); | |
141 | return 0; | |
142 | } | |
143 | ||
144 |