]>
git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/msm/doc/PDF/examples/MsmSimple.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)
11 #include <boost/msm/back/state_machine.hpp>
12 #include <boost/msm/front/state_machine_def.hpp>
14 namespace msm
= boost::msm
;
15 namespace mpl
= boost::mpl
;
24 namespace test_fsm
// Concrete FSM implementation
34 // Concrete FSM implementation
35 struct player_
: public msm::front::state_machine_def
<player_
>
37 // no need for exception handling or message queue
38 typedef int no_exception_thrown
;
39 typedef int no_message_queue
;
41 // The list of FSM states
42 struct Empty
: public msm::front::state
<>
44 // optional entry/exit methods
45 template <class Event
,class FSM
>
46 void on_entry(Event
const&,FSM
& ) {/*std::cout << "entering: Empty" << std::endl;*/}
47 template <class Event
,class FSM
>
48 void on_exit(Event
const&,FSM
& ) {/*std::cout << "leaving: Empty" << std::endl;*/}
50 struct Open
: public msm::front::state
<>
52 template <class Event
,class FSM
>
53 void on_entry(Event
const&,FSM
& ) {/*std::cout << "entering: Open" << std::endl;*/}
54 template <class Event
,class FSM
>
55 void on_exit(Event
const&,FSM
& ) {/*std::cout << "leaving: Open" << std::endl;*/}
58 struct Stopped
: public msm::front::state
<>
60 template <class Event
,class FSM
>
61 void on_entry(Event
const&,FSM
& ) {/*std::cout << "entering: Stopped" << std::endl;*/}
62 template <class Event
,class FSM
>
63 void on_exit(Event
const&,FSM
& ) {/*std::cout << "leaving: Stopped" << std::endl;*/}
66 struct Playing
: public msm::front::state
<>
68 template <class Event
,class FSM
>
69 void on_entry(Event
const&,FSM
& ) {/*std::cout << "entering: Playing" << std::endl;*/}
70 template <class Event
,class FSM
>
71 void on_exit(Event
const&,FSM
& ) {/*std::cout << "leaving: Playing" << std::endl;*/}
74 struct Paused
: public msm::front::state
<>
76 template <class Event
,class FSM
>
77 void on_entry(Event
const&,FSM
& ) {/*std::cout << "entering: Paused" << std::endl;*/}
78 template <class Event
,class FSM
>
79 void on_exit(Event
const&,FSM
& ) {/*std::cout << "leaving: Paused" << std::endl;*/}
82 // the initial state of the player SM. Must be defined
83 typedef Empty initial_state
;
85 void start_playback(play
const&) { }
86 void open_drawer(open_close
const&) { }
87 void close_drawer(open_close
const&) { }
88 void store_cd_info(cd_detected
const& cd
) { }
89 void stop_playback(stop
const&) { }
90 void pause_playback(pause
const&) { }
91 void resume_playback(end_pause
const&) { }
92 void stop_and_open(open_close
const&) { }
93 void stopped_again(stop
const&){}
96 typedef player_ p
; // makes transition table cleaner
98 // Transition table for player
99 struct transition_table
: mpl::vector
<
100 // Start Event Next Action Guard
101 // +---------+-------------+---------+---------------------+----------------------+
102 _row
< Stopped
, play
, Playing
>,
103 _row
< Stopped
, open_close
, Open
>,
104 _row
< Stopped
, stop
, Stopped
>,
105 // +---------+-------------+---------+---------------------+----------------------+
106 _row
< Open
, open_close
, Empty
>,
107 // +---------+-------------+---------+---------------------+----------------------+
108 _row
< Empty
, open_close
, Open
>,
109 _row
< Empty
, cd_detected
, Stopped
>,
110 // +---------+-------------+---------+---------------------+----------------------+
111 _row
< Playing
, stop
, Stopped
>,
112 _row
< Playing
, pause
, Paused
>,
113 _row
< Playing
, open_close
, Open
>,
114 // +---------+-------------+---------+---------------------+----------------------+
115 _row
< Paused
, end_pause
, Playing
>,
116 _row
< Paused
, stop
, Stopped
>,
117 _row
< Paused
, open_close
, Open
>
118 // +---------+-------------+---------+---------------------+----------------------+
121 // Replaces the default no-transition response.
122 template <class FSM
,class Event
>
123 void no_transition(Event
const& e
, FSM
&,int state
)
125 std::cout
<< "no transition from state " << state
126 << " on event " << typeid(e
).name() << std::endl
;
129 typedef msm::back::state_machine
<player_
> player
;
132 // Testing utilities.
134 static char const* const state_names
[] = { "Stopped", "Open", "Empty", "Playing", "Paused" };
136 void pstate(player
const& p
)
138 std::cout
<< " -> " << state_names
[p
.current_state()[0]] << std::endl
;
144 long mtime(struct timeval
& tv1
,struct timeval
& tv2
)
146 return (tv2
.tv_sec
-tv1
.tv_sec
) *1000000 + ((tv2
.tv_usec
-tv1
.tv_usec
));
156 ::QueryPerformanceFrequency(&res
);
157 LARGE_INTEGER li
,li2
;
159 struct timeval tv1
,tv2
;
160 gettimeofday(&tv1
,NULL
);
167 ::QueryPerformanceCounter(&li
);
169 gettimeofday(&tv1
,NULL
);
171 for (int i
=0;i
<100;++i
)
173 p2
.process_event(test_fsm::open_close());
174 p2
.process_event(test_fsm::open_close());
175 p2
.process_event(test_fsm::cd_detected());
176 p2
.process_event(test_fsm::play());
177 p2
.process_event(test_fsm::pause());
178 // go back to Playing
179 p2
.process_event(test_fsm::end_pause());
180 p2
.process_event(test_fsm::pause());
181 p2
.process_event(test_fsm::stop());
182 // event leading to the same state
183 p2
.process_event(test_fsm::stop());
184 p2
.process_event(test_fsm::open_close());
185 p2
.process_event(test_fsm::open_close());
188 ::QueryPerformanceCounter(&li2
);
190 gettimeofday(&tv2
,NULL
);
193 std::cout
<< "msm took in s:" << (double)(li2
.QuadPart
-li
.QuadPart
)/res
.QuadPart
<<"\n" <<std::endl
;
195 std::cout
<< "msm took in us:" << mtime(tv1
,tv2
) <<"\n" <<std::endl
;