作者:hjalshj | 来源:互联网 | 2023-06-04 15:14
boost::statechartBoost提供了状态机的实现接口,采用了CRTP技术实现,下面以秒表为例子实现一个状态机,这是一个官方的例子,也可以参考资料:BoostState
boost::statechart
Boost 提供了状态机的实现接口,采用了CRTP技术实现,下面以秒表为例子实现一个状态机,这是一个官方的例子,也可以参考资料:Boost Statechart 庫,状态机的状态转换图如下所示
实现代码如下:
1 #include
2 #include
3
4 #include // std::cout
5 #include // std::thread
6 #include
7 #include
8 #include
9 #include
10 #include
11 #include
12 #include
13 #include
14 #include
15 #include
16
17 #include
18
19 using namespace std;
20 namespace sc = boost::statechart;
21
22 class EvStartStop : public sc::event
23 {
24 };
25 class EvReset : public sc::event
26 {
27 };
28
29 /*虚类,用于状态机获取状态*/
30 class IElapsedTime
31 {
32 public:
33 virtual double elapsedTime() cOnst= 0;
34 virtual ~IElapsedTime(){};
35 };
36
37 class Active;
38 /*秒表,状态机*/
39 class StopWatch : public sc::state_machine
40 {
41 public:
42 double elapsedTime() const
43 {
44 return state_cast().elapsedTime();
45 }
46 };
47
48 class Stopped;
49 /*活动状态*/
50 class Active : public IElapsedTime, public sc::state
51 {
52 public:
53 typedef sc::transition reactions;
54
55 Active(my_context ctx)
56 : my_base(ctx),
57 elapsed_time_(0)
58 {
59 cout <<"Entry Active" < 60 }
61 ~Active()
62 {
63 cout <<"Exit Active" < 64 }
65
66 double elapsedTime() const
67 {
68 return elapsed_time_;
69 }
70 double &elapsedTime()
71 {
72 return elapsed_time_;
73 }
74
75 private:
76 double elapsed_time_;
77 };
78
79 /*计时状态*/
80 class Running : public IElapsedTime, public sc::state
81 {
82 public:
83 typedef sc::transition reactions;
84 Running(my_context ctx)
85 : my_base(ctx),
86 start_time_(std::time(0))
87 {
88 cout <<"Entry Running" < 89 }
90 ~Running()
91 {
92 context().elapsedTime() = elapsedTime();
93 cout <<"Exit Running" < 94 }
95 virtual double elapsedTime() const
96 {
97 return context().elapsedTime() + std::difftime(std::time(0), start_time_);
98 }
99
100 private:
101 std::time_t start_time_;
102 };
103
104 /*停止状态*/
105 class Stopped : public IElapsedTime, public sc::state
106 {
107 public:
108 typedef sc::transition reactions;
109 Stopped(my_context ctx)
110 : my_base(ctx)
111 {
112 cout <<"Entry Stopped" <113 }
114 ~Stopped()
115 {
116 cout <<"Exit Stopped" <117 }
118 virtual double elapsedTime() const
119 {
120 return context().elapsedTime();
121 }
122 };
123
124 int main(int argc, char **argv)
125 {
126 StopWatch myWatch;
127 myWatch.initiate();
128 cout <<"---" <129
130 myWatch.process_event(EvStartStop());
131 for (int i = 0; i <10; i++)
132 {
133 boost::this_thread::sleep(boost::posix_time::seconds(1)); //休眠1秒
134 std::cout <<"time:" <135 }
136 myWatch.process_event(EvStartStop());
137 boost::this_thread::sleep(boost::posix_time::seconds(1));
138 std::cout <<"current time:" <139 cout <<"---" <140 myWatch.process_event(EvReset());
141 std::cout <<"reset time:" <142 cout <<"---" <143 return 0;
144 }