]>
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 | // back-end | |
13 | #include <boost/msm/back/state_machine.hpp> | |
14 | #include <boost/msm/front/euml/euml.hpp> | |
15 | ||
16 | namespace msm = boost::msm; | |
17 | using namespace boost::msm::front::euml; | |
18 | ||
19 | namespace | |
20 | { | |
21 | // events | |
22 | BOOST_MSM_EUML_EVENT(event1) | |
23 | ||
24 | BOOST_MSM_EUML_ACTION(State1_Entry) | |
25 | { | |
26 | template <class Event,class FSM,class STATE> | |
27 | void operator()(Event const&,FSM&,STATE& ) | |
28 | { | |
29 | std::cout << "entering: State1" << std::endl; | |
30 | } | |
31 | }; | |
32 | BOOST_MSM_EUML_ACTION(State1_Exit) | |
33 | { | |
34 | template <class Event,class FSM,class STATE> | |
35 | void operator()(Event const&,FSM&,STATE& ) | |
36 | { | |
37 | std::cout << "leaving: State1" << std::endl; | |
38 | } | |
39 | }; | |
40 | BOOST_MSM_EUML_ACTION(State2_Entry) | |
41 | { | |
42 | template <class Event,class FSM,class STATE> | |
43 | void operator()(Event const&,FSM&,STATE& ) | |
44 | { | |
45 | std::cout << "entering: State2" << std::endl; | |
46 | } | |
47 | }; | |
48 | BOOST_MSM_EUML_ACTION(State2_Exit) | |
49 | { | |
50 | template <class Event,class FSM,class STATE> | |
51 | void operator()(Event const&,FSM&,STATE& ) | |
52 | { | |
53 | std::cout << "leaving: State2" << std::endl; | |
54 | } | |
55 | }; | |
56 | BOOST_MSM_EUML_ACTION(State3_Entry) | |
57 | { | |
58 | template <class Event,class FSM,class STATE> | |
59 | void operator()(Event const&,FSM&,STATE& ) | |
60 | { | |
61 | std::cout << "entering: State3" << std::endl; | |
62 | } | |
63 | }; | |
64 | BOOST_MSM_EUML_ACTION(State3_Exit) | |
65 | { | |
66 | template <class Event,class FSM,class STATE> | |
67 | void operator()(Event const&,FSM&,STATE& ) | |
68 | { | |
69 | std::cout << "leaving: State3" << std::endl; | |
70 | } | |
71 | }; | |
72 | BOOST_MSM_EUML_ACTION(State4_Entry) | |
73 | { | |
74 | template <class Event,class FSM,class STATE> | |
75 | void operator()(Event const&,FSM&,STATE& ) | |
76 | { | |
77 | std::cout << "entering: State4" << std::endl; | |
78 | } | |
79 | }; | |
80 | BOOST_MSM_EUML_ACTION(State4_Exit) | |
81 | { | |
82 | template <class Event,class FSM,class STATE> | |
83 | void operator()(Event const&,FSM&,STATE& ) | |
84 | { | |
85 | std::cout << "leaving: State4" << std::endl; | |
86 | } | |
87 | }; | |
88 | ||
89 | // The list of FSM states | |
90 | BOOST_MSM_EUML_STATE(( State1_Entry,State1_Exit ),State1) | |
91 | BOOST_MSM_EUML_STATE(( State2_Entry,State2_Exit ),State2) | |
92 | BOOST_MSM_EUML_STATE(( State3_Entry,State3_Exit ),State3) | |
93 | BOOST_MSM_EUML_STATE(( State4_Entry,State4_Exit ),State4) | |
94 | ||
95 | // transition actions | |
96 | BOOST_MSM_EUML_ACTION(State2ToState3) | |
97 | { | |
98 | template <class FSM,class EVT,class SourceState,class TargetState> | |
99 | void operator()(EVT const& ,FSM&,SourceState& ,TargetState& ) | |
100 | { | |
101 | std::cout << "my_machine::State2ToState3" << std::endl; | |
102 | } | |
103 | }; | |
104 | BOOST_MSM_EUML_ACTION(State3ToState4) | |
105 | { | |
106 | template <class FSM,class EVT,class SourceState,class TargetState> | |
107 | void operator()(EVT const& ,FSM&,SourceState& ,TargetState& ) | |
108 | { | |
109 | std::cout << "my_machine::State3ToState4" << std::endl; | |
110 | } | |
111 | }; | |
112 | // guard conditions | |
113 | BOOST_MSM_EUML_ACTION(always_true) | |
114 | { | |
115 | template <class FSM,class EVT,class SourceState,class TargetState> | |
116 | bool operator()(EVT const& evt,FSM&,SourceState& ,TargetState& ) | |
117 | { | |
118 | std::cout << "always_true" << std::endl; | |
119 | return true; | |
120 | } | |
121 | }; | |
122 | BOOST_MSM_EUML_ACTION(always_false) | |
123 | { | |
124 | template <class FSM,class EVT,class SourceState,class TargetState> | |
125 | bool operator()(EVT const& evt,FSM&,SourceState& ,TargetState& ) | |
126 | { | |
127 | std::cout << "always_false" << std::endl; | |
128 | return false; | |
129 | } | |
130 | }; | |
131 | // replaces the old transition table | |
132 | BOOST_MSM_EUML_TRANSITION_TABLE(( | |
133 | State2 == State1 , | |
134 | State3 == State2 / State2ToState3, | |
135 | State4 == State3 [always_true] / State3ToState4, | |
136 | State4 == State3 [always_false], | |
137 | State1 == State4 + event1 | |
138 | // +------------------------------------------------------------------------------+ | |
139 | ),transition_table) | |
140 | ||
141 | // create a state machine "on the fly" | |
142 | BOOST_MSM_EUML_DECLARE_STATE_MACHINE(( transition_table, //STT | |
143 | init_ << State1 // Init State | |
144 | ), | |
145 | my_machine_) //fsm name | |
146 | ||
147 | // Pick a back-end | |
148 | typedef msm::back::state_machine<my_machine_> my_machine; | |
149 | ||
150 | // | |
151 | // Testing utilities. | |
152 | // | |
153 | static char const* const state_names[] = { "State1", "State2", "State3", "State4" }; | |
154 | void pstate(my_machine const& p) | |
155 | { | |
156 | std::cout << " -> " << state_names[p.current_state()[0]] << std::endl; | |
157 | } | |
158 | ||
159 | void test() | |
160 | { | |
161 | my_machine p; | |
162 | ||
163 | // needed to start the highest-level SM. This will call on_entry and mark the start of the SM | |
164 | // in this case it will also immediately trigger all anonymous transitions | |
165 | p.start(); | |
166 | // this event will bring us back to the initial state and thus, a new "loop" will be started | |
167 | p.process_event(event1); | |
168 | } | |
169 | } | |
170 | ||
171 | int main() | |
172 | { | |
173 | test(); | |
174 | return 0; | |
175 | } |