]>
git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/msm/doc/HTML/examples/FsmAsPtr.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)
13 #include <boost/msm/back/state_machine.hpp>
14 #include <boost/msm/front/euml/euml.hpp>
16 // cpp: using directives are okay
18 using namespace boost::msm::front::euml
;
19 namespace msm
= boost::msm
;
21 // entry/exit/action/guard logging functors
22 #include "logging_functors.h"
27 BOOST_MSM_EUML_EVENT(play
)
28 BOOST_MSM_EUML_EVENT(end_pause
)
29 BOOST_MSM_EUML_EVENT(stop
)
30 BOOST_MSM_EUML_EVENT(pause
)
31 BOOST_MSM_EUML_EVENT(open_close
)
32 BOOST_MSM_EUML_EVENT(cd_detected
)
34 // Concrete FSM implementation
35 // The list of FSM states
36 // state not needing any entry or exit
37 BOOST_MSM_EUML_STATE((),Paused
)
39 // it is also possible to define a state which you can implement normally
40 // just make it a state, as usual, and also a grammar terminal, euml_state
41 struct Empty_impl
: public msm::front::state
<> , public euml_state
<Empty_impl
>
43 // this allows us to add some functions
44 void activate_empty() {std::cout
<< "switching to Empty " << std::endl
;}
45 // standard entry behavior
46 template <class Event
,class FSM
>
47 void on_entry(Event
const& evt
,FSM
& fsm
)
49 std::cout
<< "entering: Empty" << std::endl
;
51 template <class Event
,class FSM
>
52 void on_exit(Event
const& evt
,FSM
& fsm
)
54 std::cout
<< "leaving: Empty" << std::endl
;
57 //instance for use in the transition table
58 Empty_impl
const Empty
;
60 // create a functor and a eUML function for the activate_empty method from Entry
61 BOOST_MSM_EUML_METHOD(ActivateEmpty_
, activate_empty
, activate_empty_
, void , void )
64 BOOST_MSM_EUML_STATE(( Open_Entry
,Open_Exit
),Open
)
65 BOOST_MSM_EUML_STATE(( Stopped_Entry
,Stopped_Exit
),Stopped
)
66 BOOST_MSM_EUML_STATE(( Playing_Entry
,Playing_Exit
),Playing
)
68 // it is also possible to use a plain functor, with default-constructor in the transition table
71 template <class FSM
,class EVT
,class SourceState
,class TargetState
>
72 void operator()(EVT
const& ,FSM
&,SourceState
& ,TargetState
& )
74 cout
<< "player::start_play" << endl
;
77 // replaces the old transition table
78 BOOST_MSM_EUML_TRANSITION_TABLE((
79 Playing
== Stopped
+ play
/ start_play() ,
80 Playing
== Paused
+ end_pause
/ resume_playback
,
81 // +------------------------------------------------------------------------------+
82 Empty
== Open
+ open_close
/ (close_drawer
,activate_empty_(target_
)),
83 // +------------------------------------------------------------------------------+
84 Open
== Empty
+ open_close
/ open_drawer
,
85 Open
== Paused
+ open_close
/ stop_and_open
,
86 Open
== Stopped
+ open_close
/ open_drawer
,
87 Open
== Playing
+ open_close
/ stop_and_open
,
88 // +------------------------------------------------------------------------------+
89 Paused
== Playing
+ pause
/ pause_playback
,
90 // +------------------------------------------------------------------------------+
91 Stopped
== Playing
+ stop
/ stop_playback
,
92 Stopped
== Paused
+ stop
/ stop_playback
,
93 Stopped
== Empty
+ cd_detected
/ (store_cd_info
,process_(play
)),
94 Stopped
== Stopped
+ stop
95 // +------------------------------------------------------------------------------+
98 // create a state machine "on the fly"
99 BOOST_MSM_EUML_DECLARE_STATE_MACHINE(( transition_table
, //STT
100 init_
<< Empty
, // Init State
103 attributes_
<< no_attributes_
, // Attributes
104 configure_
<< no_configure_
, // configuration
105 Log_No_Transition
// no_transition handler
107 my_machine_impl_
) //fsm name
110 // choice of back-end
111 typedef msm::back::state_machine
<my_machine_impl_
> my_machine_impl
;
114 : fsm_(new my_machine_impl
)
116 boost::static_pointer_cast
<my_machine_impl
>(fsm_
)->start();
119 void player::do_play()
121 boost::static_pointer_cast
<my_machine_impl
>(fsm_
)->process_event(play
);
123 void player::do_pause()
125 boost::static_pointer_cast
<my_machine_impl
>(fsm_
)->process_event(pause
);
127 void player::do_open_close()
129 boost::static_pointer_cast
<my_machine_impl
>(fsm_
)->process_event(open_close
);
131 void player::do_end_pause()
133 boost::static_pointer_cast
<my_machine_impl
>(fsm_
)->process_event(end_pause
);
135 void player::do_stop()
137 boost::static_pointer_cast
<my_machine_impl
>(fsm_
)->process_event(stop
);
139 void player::do_cd_detected()
141 boost::static_pointer_cast
<my_machine_impl
>(fsm_
)->process_event(cd_detected
);
148 // note that we write open_close and not open_close(), like usual. Both are possible with eUML, but
149 // you now have less to type.
150 // go to Open, call on_exit on Empty, then action, then on_entry on Open
154 // no need to call play as the previous event does it in its action method
156 // at this point, Play is active
158 // go back to Playing
162 // event leading to the same state
163 // no action method called as none is defined in the transition table
165 // test call to no_transition