StopWatch.cpp 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189
  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. // The following code implements the state-machine (this is the version
  8. // discussed in the tutorial):
  9. //
  10. // --------------------------------
  11. // | |
  12. // | O Active |
  13. // | | |<----
  14. // | v | | EvReset
  15. // | ---------------------------- | |
  16. // | | | |-----
  17. // | | Stopped | |
  18. // | ---------------------------- |
  19. // | | ^ |
  20. // | | EvStartStop | EvStartStop |<-----O
  21. // | v | |
  22. // | ---------------------------- |
  23. // | | | |
  24. // | | Running | |
  25. // | ---------------------------- |
  26. // --------------------------------
  27. #include <boost/statechart/event.hpp>
  28. #include <boost/statechart/state_machine.hpp>
  29. #include <boost/statechart/simple_state.hpp>
  30. #include <boost/statechart/transition.hpp>
  31. #include <boost/config.hpp>
  32. #include <ctime>
  33. #include <iostream>
  34. #ifdef BOOST_NO_STDC_NAMESPACE
  35. namespace std
  36. {
  37. using ::time;
  38. using ::difftime;
  39. using ::time_t;
  40. }
  41. #endif
  42. #ifdef BOOST_INTEL
  43. # pragma warning( disable: 304 ) // access control not specified
  44. # pragma warning( disable: 444 ) // destructor for base is not virtual
  45. # pragma warning( disable: 981 ) // operands are evaluated in unspecified order
  46. #endif
  47. namespace sc = boost::statechart;
  48. //////////////////////////////////////////////////////////////////////////////
  49. struct EvStartStop : sc::event< EvStartStop > {};
  50. struct EvReset : sc::event< EvReset > {};
  51. struct IElapsedTime
  52. {
  53. virtual double ElapsedTime() const = 0;
  54. };
  55. struct Active;
  56. struct StopWatch : sc::state_machine< StopWatch, Active > {};
  57. struct Stopped;
  58. struct Active : sc::simple_state< Active, StopWatch, Stopped >
  59. {
  60. public:
  61. typedef sc::transition< EvReset, Active > reactions;
  62. Active() : elapsedTime_( 0.0 ) {}
  63. double & ElapsedTime()
  64. {
  65. return elapsedTime_;
  66. }
  67. double ElapsedTime() const
  68. {
  69. return elapsedTime_;
  70. }
  71. private:
  72. double elapsedTime_;
  73. };
  74. struct Running : IElapsedTime, sc::simple_state< Running, Active >
  75. {
  76. public:
  77. typedef sc::transition< EvStartStop, Stopped > reactions;
  78. Running() : startTime_( std::time( 0 ) ) {}
  79. ~Running()
  80. {
  81. context< Active >().ElapsedTime() = ElapsedTime();
  82. }
  83. virtual double ElapsedTime() const
  84. {
  85. return context< Active >().ElapsedTime() +
  86. std::difftime( std::time( 0 ), startTime_ );
  87. }
  88. private:
  89. std::time_t startTime_;
  90. };
  91. struct Stopped : IElapsedTime, sc::simple_state< Stopped, Active >
  92. {
  93. typedef sc::transition< EvStartStop, Running > reactions;
  94. virtual double ElapsedTime() const
  95. {
  96. return context< Active >().ElapsedTime();
  97. }
  98. };
  99. //////////////////////////////////////////////////////////////////////////////
  100. char GetKey()
  101. {
  102. char key;
  103. std::cin >> key;
  104. return key;
  105. }
  106. //////////////////////////////////////////////////////////////////////////////
  107. int main()
  108. {
  109. std::cout << "Boost.Statechart StopWatch example\n\n";
  110. std::cout << "s<CR>: Starts/Stops stop watch\n";
  111. std::cout << "r<CR>: Resets stop watch\n";
  112. std::cout << "d<CR>: Displays the elapsed time in seconds\n";
  113. std::cout << "e<CR>: Exits the program\n\n";
  114. std::cout << "You may chain commands, e.g. rs<CR> resets and starts stop watch\n\n";
  115. StopWatch stopWatch;
  116. stopWatch.initiate();
  117. char key = GetKey();
  118. while ( key != 'e' )
  119. {
  120. switch( key )
  121. {
  122. case 'r':
  123. {
  124. stopWatch.process_event( EvReset() );
  125. }
  126. break;
  127. case 's':
  128. {
  129. stopWatch.process_event( EvStartStop() );
  130. }
  131. break;
  132. case 'd':
  133. {
  134. std::cout << "Elapsed time: " <<
  135. stopWatch.state_cast< const IElapsedTime & >().ElapsedTime() << "\n";
  136. }
  137. break;
  138. default:
  139. {
  140. std::cout << "Invalid key!\n";
  141. }
  142. break;
  143. }
  144. key = GetKey();
  145. }
  146. return 0;
  147. }