]>
git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/msm/doc/PDF/examples/DirectEntryEuml.cpp
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)
14 #include <boost/msm/back/state_machine.hpp>
15 #include <boost/msm/front/euml/euml.hpp>
18 using namespace boost::msm::front::euml
;
19 namespace msm
= boost::msm
;
20 namespace mpl
= boost::mpl
;
23 namespace // Concrete FSM implementation
26 BOOST_MSM_EUML_EVENT(event1
)
27 BOOST_MSM_EUML_EVENT(event2
)
28 BOOST_MSM_EUML_EVENT(event3
)
29 BOOST_MSM_EUML_EVENT(event4
)
30 BOOST_MSM_EUML_EVENT(event5
)
31 // if we need something special, like a template constructor, we cannot use the helper macros
32 struct event6_impl
: euml_event
<event6_impl
>
35 template <class Event
>
36 event6_impl(Event
const&){}
38 event6_impl
const event6
;
40 //Sub fsm state definition
41 BOOST_MSM_EUML_ACTION(SubState1_Entry
)
43 template <class Event
,class FSM
,class STATE
>
44 void operator()(Event
const&,FSM
&,STATE
& )
46 std::cout
<< "entering: SubFsm2::SubState1" << std::endl
;
49 BOOST_MSM_EUML_ACTION(SubState1_Exit
)
51 template <class Event
,class FSM
,class STATE
>
52 void operator()(Event
const&,FSM
&,STATE
& )
54 std::cout
<< "leaving: SubFsm2::SubState1" << std::endl
;
57 BOOST_MSM_EUML_STATE(( SubState1_Entry
,SubState1_Exit
),SubState1
)
59 BOOST_MSM_EUML_ACTION(SubState1b_Entry
)
61 template <class Event
,class FSM
,class STATE
>
62 void operator()(Event
const&,FSM
&,STATE
& )
64 std::cout
<< "entering: SubFsm2::SubState1b" << std::endl
;
67 BOOST_MSM_EUML_ACTION(SubState1b_Exit
)
69 template <class Event
,class FSM
,class STATE
>
70 void operator()(Event
const&,FSM
&,STATE
& )
72 std::cout
<< "leaving: SubFsm2::SubState1b" << std::endl
;
75 BOOST_MSM_EUML_STATE(( SubState1b_Entry
,SubState1b_Exit
),SubState1b
)
77 BOOST_MSM_EUML_ACTION(SubState1c_Entry
)
79 template <class Event
,class FSM
,class STATE
>
80 void operator()(Event
const&,FSM
&,STATE
& )
82 std::cout
<< "entering: SubFsm2::SubState1c" << std::endl
;
85 BOOST_MSM_EUML_ACTION(SubState1c_Exit
)
87 template <class Event
,class FSM
,class STATE
>
88 void operator()(Event
const&,FSM
&,STATE
& )
90 std::cout
<< "leaving: SubFsm2::SubState1c" << std::endl
;
93 BOOST_MSM_EUML_STATE(( SubState1c_Entry
,SubState1c_Exit
),SubState1c
)
95 BOOST_MSM_EUML_ACTION(SubState2_Entry
)
97 template <class Event
,class FSM
,class STATE
>
98 void operator()(Event
const&,FSM
&,STATE
& )
100 std::cout
<< "entering: SubFsm2::SubState2" << std::endl
;
103 BOOST_MSM_EUML_ACTION(SubState2_Exit
)
105 template <class Event
,class FSM
,class STATE
>
106 void operator()(Event
const&,FSM
&,STATE
& )
108 std::cout
<< "leaving: SubFsm2::SubState2" << std::endl
;
111 BOOST_MSM_EUML_EXPLICIT_ENTRY_STATE(0,( SubState2_Entry
,SubState2_Exit
),SubState2
)
113 BOOST_MSM_EUML_ACTION(SubState2b_Entry
)
115 template <class Event
,class FSM
,class STATE
>
116 void operator()(Event
const&,FSM
&,STATE
& )
118 std::cout
<< "entering: SubFsm2::SubState2b" << std::endl
;
121 BOOST_MSM_EUML_ACTION(SubState2b_Exit
)
123 template <class Event
,class FSM
,class STATE
>
124 void operator()(Event
const&,FSM
&,STATE
& )
126 std::cout
<< "leaving: SubFsm2::SubState2b" << std::endl
;
129 BOOST_MSM_EUML_EXPLICIT_ENTRY_STATE(1,( SubState2b_Entry
,SubState2b_Exit
),SubState2b
)
131 BOOST_MSM_EUML_ACTION(SubState2c_Entry
)
133 template <class Event
,class FSM
,class STATE
>
134 void operator()(Event
const&,FSM
&,STATE
& )
136 std::cout
<< "entering: SubFsm2::SubState2c" << std::endl
;
139 BOOST_MSM_EUML_ACTION(SubState2c_Exit
)
141 template <class Event
,class FSM
,class STATE
>
142 void operator()(Event
const&,FSM
&,STATE
& )
144 std::cout
<< "leaving: SubFsm2::SubState2c" << std::endl
;
147 BOOST_MSM_EUML_EXPLICIT_ENTRY_STATE(2,( SubState2c_Entry
,SubState2c_Exit
),SubState2c
)
149 BOOST_MSM_EUML_ACTION(PseudoEntry1_Entry
)
151 template <class Event
,class FSM
,class STATE
>
152 void operator()(Event
const&,FSM
&,STATE
& )
154 std::cout
<< "entering: SubFsm2::PseudoEntry1" << std::endl
;
157 BOOST_MSM_EUML_ACTION(PseudoEntry1_Exit
)
159 template <class Event
,class FSM
,class STATE
>
160 void operator()(Event
const&,FSM
&,STATE
& )
162 std::cout
<< "leaving: SubFsm2::PseudoEntry1" << std::endl
;
165 BOOST_MSM_EUML_ENTRY_STATE(0,( PseudoEntry1_Entry
,PseudoEntry1_Exit
),PseudoEntry1
)
167 BOOST_MSM_EUML_ACTION(SubState3_Entry
)
169 template <class Event
,class FSM
,class STATE
>
170 void operator()(Event
const&,FSM
&,STATE
& )
172 std::cout
<< "entering: SubFsm2::SubState3" << std::endl
;
175 BOOST_MSM_EUML_ACTION(SubState3_Exit
)
177 template <class Event
,class FSM
,class STATE
>
178 void operator()(Event
const&,FSM
&,STATE
& )
180 std::cout
<< "leaving: SubFsm2::SubState3" << std::endl
;
183 BOOST_MSM_EUML_STATE(( SubState3_Entry
,SubState3_Exit
),SubState3
)
185 BOOST_MSM_EUML_ACTION(SubState3b_Entry
)
187 template <class Event
,class FSM
,class STATE
>
188 void operator()(Event
const&,FSM
&,STATE
& )
190 std::cout
<< "entering: SubFsm2::SubState3b" << std::endl
;
193 BOOST_MSM_EUML_ACTION(SubState3b_Exit
)
195 template <class Event
,class FSM
,class STATE
>
196 void operator()(Event
const&,FSM
&,STATE
& )
198 std::cout
<< "leaving: SubFsm2::SubState3b" << std::endl
;
201 BOOST_MSM_EUML_STATE(( SubState3b_Entry
,SubState3b_Exit
),SubState3b
)
203 BOOST_MSM_EUML_ACTION(PseudoExit1_Entry
)
205 template <class Event
,class FSM
,class STATE
>
206 void operator()(Event
const&,FSM
&,STATE
& )
208 std::cout
<< "entering: SubFsm2::PseudoExit1" << std::endl
;
211 BOOST_MSM_EUML_ACTION(PseudoExit1_Exit
)
213 template <class Event
,class FSM
,class STATE
>
214 void operator()(Event
const&,FSM
&,STATE
& )
216 std::cout
<< "leaving: SubFsm2::PseudoExit1" << std::endl
;
219 BOOST_MSM_EUML_EXIT_STATE(( event6
,PseudoExit1_Entry
,PseudoExit1_Exit
),PseudoExit1
)
222 BOOST_MSM_EUML_ACTION(entry_action
)
224 template <class FSM
,class EVT
,class SourceState
,class TargetState
>
225 void operator()(FSM
& ,EVT
const& ,SourceState
& ,TargetState
& )
227 cout
<< "calling entry_action" << endl
;
231 BOOST_MSM_EUML_ACTION(SubFsm2_Entry
)
233 template <class Event
,class FSM
,class STATE
>
234 void operator()(Event
const&,FSM
&,STATE
& )
236 std::cout
<< "entering: SubFsm2" << std::endl
;
239 BOOST_MSM_EUML_ACTION(SubFsm2_Exit
)
241 template <class Event
,class FSM
,class STATE
>
242 void operator()(Event
const&,FSM
&,STATE
& )
244 std::cout
<< "leaving: SubFsm2" << std::endl
;
247 BOOST_MSM_EUML_TRANSITION_TABLE((
248 // +------------------------------------------------------------------------------+
249 SubState3
== PseudoEntry1
+ event4
/ entry_action
,
250 SubState1
== SubState2
+ event6
,
251 PseudoExit1
== SubState3
+ event5
252 // +------------------------------------------------------------------------------+
253 ), SubFsm2_transition_table
)
255 BOOST_MSM_EUML_DECLARE_STATE_MACHINE( (SubFsm2_transition_table
, //STT
256 init_
<< SubState1
<< SubState1b
<< SubState1c
, // Init State
257 SubFsm2_Entry
, // Entry
260 // inherit to add some typedef
261 struct SubFsm2_
: public SubFsm2_def
263 // these 2 states are not found in the transition table because they are accessed only through
264 // a fork, so we need to create them explicitly
265 typedef mpl::vector
<BOOST_MSM_EUML_STATE_NAME(SubState2b
),
266 BOOST_MSM_EUML_STATE_NAME(SubState2c
)> explicit_creation
;
270 typedef msm::back::state_machine
<SubFsm2_
> SubFsm2_type
;
271 SubFsm2_type
const SubFsm2
;
273 // Fsm state definitions
274 BOOST_MSM_EUML_ACTION(State1_Entry
)
276 template <class Event
,class FSM
,class STATE
>
277 void operator()(Event
const&,FSM
&,STATE
& )
279 std::cout
<< "entering: State1" << std::endl
;
282 BOOST_MSM_EUML_ACTION(State1_Exit
)
284 template <class Event
,class FSM
,class STATE
>
285 void operator()(Event
const&,FSM
&,STATE
& )
287 std::cout
<< "leaving: State1" << std::endl
;
290 BOOST_MSM_EUML_STATE(( State1_Entry
,State1_Exit
),State1
)
292 BOOST_MSM_EUML_ACTION(State2_Entry
)
294 template <class Event
,class FSM
,class STATE
>
295 void operator()(Event
const&,FSM
&,STATE
& )
297 std::cout
<< "entering: State2" << std::endl
;
300 BOOST_MSM_EUML_ACTION(State2_Exit
)
302 template <class Event
,class FSM
,class STATE
>
303 void operator()(Event
const&,FSM
&,STATE
& )
305 std::cout
<< "leaving: State2" << std::endl
;
308 BOOST_MSM_EUML_STATE(( State2_Entry
,State2_Exit
),State2
)
311 BOOST_MSM_EUML_TRANSITION_TABLE((
312 // +------------------------------------------------------------------------------+
313 SubFsm2
== State1
+ event1
,
314 explicit_(SubFsm2
,SubState2
) == State1
+ event2
,
315 (explicit_(SubFsm2
,SubState2
),
316 explicit_(SubFsm2
,SubState2b
),
317 explicit_(SubFsm2
,SubState2c
)) == State1
+ event3
,
318 entry_pt_(SubFsm2
,PseudoEntry1
) == State1
+ event4
,
319 State1
== SubFsm2
+ event1
,
321 (SubFsm2
,PseudoExit1
) + event6
322 // +------------------------------------------------------------------------------+
326 BOOST_MSM_EUML_ACTION(Log_No_Transition
)
328 template <class Event
,class FSM
,class STATE
>
329 void operator()(Event
const& e
,FSM
&,STATE
& )
331 std::cout
<< "no transition in Fsm"
332 << " on event " << typeid(e
).name() << std::endl
;
335 BOOST_MSM_EUML_DECLARE_STATE_MACHINE(( transition_table
, //STT
336 init_
<< State1
, // Init State
339 attributes_
<< no_attributes_
, // Attributes
340 configure_
<< no_configure_
, // configuration
341 Log_No_Transition
// no_transition handler
346 typedef msm::back::state_machine
<Fsm_
> Fsm
;
349 // Testing utilities.
351 static char const* const state_names
[] = { "State1", "SubFsm2","State2" };
352 void pstate(Fsm
const& p
)
354 std::cout
<< " -> " << state_names
[p
.current_state()[0]] << std::endl
;
360 // needed to start the highest-level SM. This will call on_entry and mark the start of the SM
362 std::cout
<< "Simply move in and out of the composite, activate init states" << std::endl
;
363 p
.process_event(event1
); pstate(p
);
364 p
.process_event(event1
); pstate(p
);
365 std::cout
<< "Direct entry into SubFsm2::SubState2, then transition to SubState1 and back to State1" << std::endl
;
366 p
.process_event(event2
); pstate(p
);
367 p
.process_event(event6
); pstate(p
);
368 p
.process_event(event1
); pstate(p
);
369 std::cout
<< "processing fork to SubFsm2::SubState2, SubFsm2::SubState2b and SubFsm2::SubState2c" << std::endl
;
370 p
.process_event(event3
); pstate(p
);
371 p
.process_event(event1
); pstate(p
);
372 std::cout
<< "processing entry pseudo state" << std::endl
;
373 p
.process_event(event4
); pstate(p
);
374 p
.process_event(event1
); pstate(p
);
375 std::cout
<< "processing entry + exit pseudo state" << std::endl
;
376 p
.process_event(event4
); pstate(p
);
377 std::cout
<< "using exit pseudo state" << std::endl
;
378 p
.process_event(event5
); pstate(p
);