]>
git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/msm/doc/PDF/examples/SCComposite.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/statechart/event.hpp>
12 #include <boost/statechart/state_machine.hpp>
13 #include <boost/statechart/simple_state.hpp>
14 #include <boost/statechart/transition.hpp>
15 #include "boost/mpl/list.hpp"
26 namespace sc
= boost::statechart
;
27 namespace mpl
= boost::mpl
;
33 struct play
: sc::event
< play
> {};
34 struct end_pause
: sc::event
< end_pause
> {};
35 struct stop
: sc::event
< stop
> {};
36 struct pause
: sc::event
< pause
> {};
37 struct open_close
: sc::event
< open_close
> {};
38 struct cd_detected
: sc::event
< cd_detected
> {};
39 struct NextSong
: sc::event
< NextSong
> {};
40 struct PreviousSong
: sc::event
< PreviousSong
>{};
48 struct player
: sc::state_machine
< player
, Empty
>
50 void open_drawer(open_close
const&) { /*std::cout << "player::open_drawer\n";*/ }
51 void store_cd_info(cd_detected
const& cd
) {/*std::cout << "player::store_cd_info\n";*/ }
52 void close_drawer(open_close
const&) { /*std::cout << "player::close_drawer\n";*/ }
53 void start_playback(play
const&) { /*std::cout << "player::start_playback\n";*/ }
54 void stopped_again(stop
const&) {/*std::cout << "player::stopped_again\n";*/}
55 void stop_playback(stop
const&) { /*std::cout << "player::stop_playback\n";*/ }
56 void pause_playback(pause
const&) { /*std::cout << "player::pause_playback\n"; */}
57 void stop_and_open(open_close
const&) { /*std::cout << "player::stop_and_open\n";*/ }
58 void resume_playback(end_pause
const&) { /*std::cout << "player::resume_playback\n";*/ }
61 struct Empty
: sc::simple_state
< Empty
, player
>
63 Empty() { /*std::cout << "entering Empty" << std::endl;*/ } // entry
64 ~Empty() { /*std::cout << "leaving Empty" << std::endl;*/ } // exit
66 sc::transition
< open_close
, Open
,
67 player
, &player::open_drawer
>,
68 sc::transition
< cd_detected
, Stopped
,
69 player
, &player::store_cd_info
> > reactions
;
72 struct Open
: sc::simple_state
< Open
, player
>
74 Open() { /*std::cout << "entering Open" << std::endl;*/ } // entry
75 ~Open() { /*std::cout << "leaving Open" << std::endl;*/ } // exit
76 typedef sc::transition
< open_close
, Empty
,
77 player
, &player::close_drawer
> reactions
;
80 struct Stopped
: sc::simple_state
< Stopped
, player
>
82 Stopped() { /*std::cout << "entering Stopped" << std::endl;*/ } // entry
83 ~Stopped() { /*std::cout << "leaving Stopped" << std::endl;*/ } // exit
85 sc::transition
< play
, Playing
,
86 player
, &player::start_playback
>,
87 sc::transition
< open_close
, Open
,
88 player
, &player::open_drawer
>,
89 sc::transition
< stop
, Stopped
,
90 player
, &player::stopped_again
> > reactions
;
94 struct Playing
: sc::simple_state
< Playing
, player
,Song1
>
96 Playing() { /*std::cout << "entering Playing" << std::endl;*/ } // entry
97 ~Playing() { /*std::cout << "leaving Playing" << std::endl;*/ } // exit
99 sc::transition
< stop
, Stopped
,
100 player
, &player::stop_playback
>,
101 sc::transition
< pause
, Paused
,
102 player
, &player::pause_playback
>,
103 sc::transition
< open_close
, Open
,
104 player
, &player::stop_and_open
> > reactions
;
105 void start_next_song(NextSong
const&) { /*std::cout << "Playing::start_next_song\n";*/ }
106 void start_prev_song(PreviousSong
const&) { /*std::cout << "Playing::start_prev_song\n";*/ }
109 struct Song1
: sc::simple_state
< Song1
, Playing
>
111 Song1() { /*std::cout << "entering Song1" << std::endl;*/ } // entry
112 ~Song1() { /*std::cout << "leaving Song1" << std::endl;*/ } // exit
113 typedef sc::transition
< NextSong
, Song2
,
114 Playing
, &Playing::start_next_song
> reactions
;
117 struct Song2
: sc::simple_state
< Song2
, Playing
>
119 Song2() { /*std::cout << "entering Song2" << std::endl;*/ } // entry
120 ~Song2() { /*std::cout << "leaving Song2" << std::endl;*/ } // exit
122 sc::transition
< NextSong
, Song3
,
123 Playing
, &Playing::start_next_song
>,
124 sc::transition
< PreviousSong
, Song1
,
125 Playing
, &Playing::start_prev_song
> > reactions
;
127 struct Song3
: sc::simple_state
< Song3
, Playing
>
129 Song3() { /*std::cout << "entering Song3" << std::endl;*/ } // entry
130 ~Song3() { /*std::cout << "leaving Song3" << std::endl;*/ } // exit
131 typedef sc::transition
< PreviousSong
, Song2
,
132 Playing
, &Playing::start_prev_song
> reactions
;
134 struct Paused
: sc::simple_state
< Paused
, player
>
136 Paused() { /*std::cout << "entering Paused" << std::endl;*/ } // entry
137 ~Paused() { /*std::cout << "leaving Paused" << std::endl;*/ } // exit
139 sc::transition
< end_pause
, Playing
,
140 player
, &player::resume_playback
>,
141 sc::transition
< stop
, Stopped
,
142 player
, &player::stop_playback
>,
143 sc::transition
< open_close
, Open
,
144 player
, &player::stop_and_open
> > reactions
;
150 long mtime(struct timeval
& tv1
,struct timeval
& tv2
)
152 return (tv2
.tv_sec
-tv1
.tv_sec
) *1000000 + ((tv2
.tv_usec
-tv1
.tv_usec
));
163 ::QueryPerformanceFrequency(&res
);
164 LARGE_INTEGER li
,li2
;
165 ::QueryPerformanceCounter(&li
);
167 struct timeval tv1
,tv2
;
168 gettimeofday(&tv1
,NULL
);
171 for (int i
=0;i
<100;++i
)
173 p
.process_event(test_sc::open_close());
174 p
.process_event(test_sc::open_close());
175 p
.process_event(test_sc::cd_detected());
176 p
.process_event(test_sc::play());
177 for (int j
=0;j
<100;++j
)
179 p
.process_event(test_sc::NextSong());
180 p
.process_event(test_sc::NextSong());
181 p
.process_event(test_sc::PreviousSong());
182 p
.process_event(test_sc::PreviousSong());
185 p
.process_event(test_sc::pause());
186 // go back to Playing
187 p
.process_event(test_sc::end_pause());
188 p
.process_event(test_sc::pause());
189 p
.process_event(test_sc::stop());
190 // event leading to the same state
191 p
.process_event(test_sc::stop());
192 p
.process_event(test_sc::open_close());
193 p
.process_event(test_sc::open_close());
196 ::QueryPerformanceCounter(&li2
);
198 gettimeofday(&tv2
,NULL
);
201 std::cout
<< "sc took in s:" << (double)(li2
.QuadPart
-li
.QuadPart
)/res
.QuadPart
<<"\n" <<std::endl
;
203 std::cout
<< "sc took in us:" << mtime(tv1
,tv2
) <<"\n" <<std::endl
;