forked from erikzenker/hsm
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsc.cpp
122 lines (115 loc) · 4.73 KB
/
sc.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
// Copyright 2010 Christophe Henry
// henry UNDERSCORE christophe AT hotmail DOT com
// This is an extended version of the state machine available in the boost::mpl library
// Distributed under the same license as the original.
// Copyright for the original version:
// Copyright 2005 David Abrahams and Aleksey Gurtovoy. Distributed
// under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#include "benchmark.hpp"
#include <boost/statechart/event.hpp>
#include <boost/statechart/state_machine.hpp>
#include <boost/statechart/simple_state.hpp>
#include <boost/statechart/transition.hpp>
namespace sc = boost::statechart;
namespace mpl = boost::mpl;
namespace test_sc {
// events
struct play : sc::event<play> {};
struct end_pause : sc::event<end_pause> {};
struct stop : sc::event<stop> {};
struct pause : sc::event<pause> {};
struct open_close : sc::event<open_close> {};
struct cd_detected : sc::event<cd_detected> {};
struct Empty;
struct Open;
struct Stopped;
struct Playing;
struct Paused;
// SM
struct player : sc::state_machine<player, Empty> {
void open_drawer(open_close const &) { /*std::cout << "player::open_drawer\n";*/
}
void store_cd_info(cd_detected const &) { /*std::cout << "player::store_cd_info\n";*/
}
void close_drawer(open_close const &) { /*std::cout << "player::close_drawer\n";*/
}
void start_playback(play const &) { /*std::cout << "player::start_playback\n";*/
}
void stopped_again(stop const &) { /*std::cout << "player::stopped_again\n";*/
}
void stop_playback(stop const &) { /*std::cout << "player::stop_playback\n";*/
}
void pause_playback(pause const &) { /*std::cout << "player::pause_playback\n"; */
}
void stop_and_open(open_close const &) { /*std::cout << "player::stop_and_open\n";*/
}
void resume_playback(end_pause const &) { /*std::cout << "player::resume_playback\n";*/
}
};
struct Empty : sc::simple_state<Empty, player> {
Empty() { /*std::cout << "entering Empty" << std::endl;*/
} // entry
~Empty() { /*std::cout << "leaving Empty" << std::endl;*/
} // exit
typedef mpl::list<sc::transition<open_close, Open, player, &player::open_drawer>,
sc::transition<cd_detected, Stopped, player, &player::store_cd_info>> reactions;
};
struct Open : sc::simple_state<Open, player> {
Open() { /*std::cout << "entering Open" << std::endl;*/
} // entry
~Open() { /*std::cout << "leaving Open" << std::endl;*/
} // exit
typedef sc::transition<open_close, Empty, player, &player::close_drawer> reactions;
};
struct Stopped : sc::simple_state<Stopped, player> {
Stopped() { /*std::cout << "entering Stopped" << std::endl;*/
} // entry
~Stopped() { /*std::cout << "leaving Stopped" << std::endl;*/
} // exit
typedef mpl::list<sc::transition<play, Playing, player, &player::start_playback>,
sc::transition<open_close, Open, player, &player::open_drawer>,
sc::transition<stop, Stopped, player, &player::stopped_again>> reactions;
};
struct Playing : sc::simple_state<Playing, player> {
Playing() { /*std::cout << "entering Playing" << std::endl;*/
} // entry
~Playing() { /*std::cout << "leaving Playing" << std::endl;*/
} // exit
typedef mpl::list<sc::transition<stop, Stopped, player, &player::stop_playback>,
sc::transition<pause, Paused, player, &player::pause_playback>,
sc::transition<open_close, Open, player, &player::stop_and_open>> reactions;
};
struct Paused : sc::simple_state<Paused, player> {
Paused() { /*std::cout << "entering Paused" << std::endl;*/
} // entry
~Paused() { /*std::cout << "leaving Paused" << std::endl;*/
} // exit
typedef mpl::list<sc::transition<end_pause, Playing, player, &player::resume_playback>,
sc::transition<stop, Stopped, player, &player::stop_playback>,
sc::transition<open_close, Open, player, &player::stop_and_open>> reactions;
};
}
int main() {
test_sc::player p;
p.initiate();
benchmark_execution_speed([&] {
for (auto i = 0; i < 1'000'000; ++i) {
p.process_event(test_sc::open_close());
p.process_event(test_sc::open_close());
p.process_event(test_sc::cd_detected());
p.process_event(test_sc::play());
p.process_event(test_sc::pause());
// go back to Playing
p.process_event(test_sc::end_pause());
p.process_event(test_sc::pause());
p.process_event(test_sc::stop());
// event leading to the same state
p.process_event(test_sc::stop());
p.process_event(test_sc::open_close());
p.process_event(test_sc::open_close());
}
});
benchmark_memory_usage(p);
}