]> rtime.felk.cvut.cz Git - boost-statechart-viewer.git/blob - examples/StopWatch.cpp
Order Diag parameters as expected by diag_warning template
[boost-statechart-viewer.git] / examples / StopWatch.cpp
1 //////////////////////////////////////////////////////////////////////////////
2 // Copyright 2002-2006 Andreas Huber Doenni
3 // Distributed under the Boost Software License, Version 1.0. (See accompany-
4 // ing file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
5 //////////////////////////////////////////////////////////////////////////////
6
7
8
9 //////////////////////////////////////////////////////////////////////////////
10 // The following code implements the state-machine (this is the version
11 // discussed in the tutorial):
12 //
13 //  --------------------------------
14 // |                                |
15 // |           O     Active         |
16 // |           |                    |<----
17 // |           v                    |     | EvReset
18 // |  ----------------------------  |     |
19 // | |                            | |-----
20 // | |         Stopped            | |
21 // |  ----------------------------  |
22 // |  |              ^              |
23 // |  | EvStartStop  | EvStartStop  |<-----O
24 // |  v              |              |
25 // |  ----------------------------  |
26 // | |                            | |
27 // | |         Running            | |
28 // |  ----------------------------  |
29 //  --------------------------------
30
31
32
33 #include <boost/statechart/event.hpp>
34 #include <boost/statechart/state_machine.hpp>
35 #include <boost/statechart/simple_state.hpp>
36 #include <boost/statechart/transition.hpp>
37
38 #include <boost/config.hpp>
39
40 #include <ctime>
41 #include <iostream>
42
43 #ifdef BOOST_NO_STDC_NAMESPACE
44 namespace std
45 {
46   using ::time;
47   using ::difftime;
48   using ::time_t;
49 }
50 #endif
51
52 #ifdef BOOST_INTEL
53 #  pragma warning( disable: 304 ) // access control not specified
54 #  pragma warning( disable: 444 ) // destructor for base is not virtual
55 #  pragma warning( disable: 981 ) // operands are evaluated in unspecified order
56 #endif
57
58
59
60 namespace sc = boost::statechart;
61
62
63
64 //////////////////////////////////////////////////////////////////////////////
65 struct EvStartStop : sc::event< EvStartStop > {};
66 struct EvReset : sc::event< EvReset > {};
67
68 struct IElapsedTime
69 {
70   virtual double ElapsedTime() const = 0;
71 };
72
73 struct Active;
74 struct StopWatch : sc::state_machine< StopWatch, Active > {};
75
76 struct Stopped;
77 struct Active : sc::simple_state< Active, StopWatch, Stopped >
78 {
79   public:
80     typedef sc::transition< EvReset, Active > reactions;
81
82     Active() : elapsedTime_( 0.0 ) {}
83
84     double & ElapsedTime()
85     {
86       return elapsedTime_;
87     }
88
89     double ElapsedTime() const
90     {
91       return elapsedTime_;
92     }
93
94   private:
95     double elapsedTime_;
96 };
97
98   struct Running : IElapsedTime, sc::simple_state< Running, Active >
99   {
100     public:
101       typedef sc::transition< EvStartStop, Stopped > reactions;
102
103       Running() : startTime_( std::time( 0 ) ) {}
104
105       ~Running()
106       {
107         context< Active >().ElapsedTime() = ElapsedTime();
108       }
109
110       virtual double ElapsedTime() const
111       {
112         return context< Active >().ElapsedTime() +
113           std::difftime( std::time( 0 ), startTime_ );
114       }
115
116     private:
117       std::time_t startTime_;
118   };
119
120   struct Stopped : IElapsedTime, sc::simple_state< Stopped, Active >
121   {
122     typedef sc::transition< EvStartStop, Running > reactions;
123
124     virtual double ElapsedTime() const
125     {
126       return context< Active >().ElapsedTime();
127     }
128   };
129
130
131 //////////////////////////////////////////////////////////////////////////////
132 char GetKey()
133 {
134   char key;
135   std::cin >> key;
136   return key;
137 }
138
139
140 //////////////////////////////////////////////////////////////////////////////
141 int main()
142 {
143   std::cout << "Boost.Statechart StopWatch example\n\n";
144   std::cout << "s<CR>: Starts/Stops stop watch\n";
145   std::cout << "r<CR>: Resets stop watch\n";
146   std::cout << "d<CR>: Displays the elapsed time in seconds\n";
147   std::cout << "e<CR>: Exits the program\n\n";
148   std::cout << "You may chain commands, e.g. rs<CR> resets and starts stop watch\n\n";
149   
150   StopWatch stopWatch;
151   stopWatch.initiate();
152
153   char key = GetKey();
154
155   while ( key != 'e' )
156   {
157     switch( key )
158     {
159       case 'r':
160       {
161         stopWatch.process_event( EvReset() );
162       }
163       break;
164
165       case 's':
166       {
167         stopWatch.process_event( EvStartStop() );
168       }
169       break;
170
171       case 'd':
172       {
173         std::cout << "Elapsed time: " <<
174           stopWatch.state_cast< const IElapsedTime & >().ElapsedTime() << "\n";
175       }
176       break;
177
178       default:
179       {
180         std::cout << "Invalid key!\n";
181       }
182       break;
183     }
184
185     key = GetKey();
186   }
187
188   return 0;
189 }