00001 /********************************************************************** 00002 * stop_watch.H 00003 **********************************************************************/ 00004 #ifndef STOP_WATCH_H_HAS_BEEN_INCLUDED 00005 #define STOP_WATCH_H_HAS_BEEN_INCLUDED 00006 00007 #include "time.H" 00008 #include "error.H" 00009 #include "platform.H" 00010 00011 /********************************************************************** 00012 * stop_watch: 00013 * 00014 * Utility class for getting timing information. 00015 * (All times are in seconds.) 00016 * 00017 * The static method stop_watch::sys_time() returns the current 00018 * system time (in seconds since time origin). 00019 * 00020 * Like a real stop watch, you can also use it to find out how much 00021 * time has passed (stop_watch::elapsed_time()) since you last 00022 * pushed its button (stop_watch::set()). 00023 * 00024 * It also supports the ability to pause (stop_watch::pause()) and 00025 * unpause (stop_watch::resume()). When paused, the reported elapsed 00026 * time does not change (as if time is not passing). After unpausing, 00027 * the reported elapsed time resumes increasing normally. 00028 **********************************************************************/ 00029 class stop_watch { 00030 public: 00031 //******** MANAGERS ******** 00032 // Construct a stop watch: it starts counting time from now: 00033 stop_watch() : _start_time(sys_time()), _pause_time(0), _is_paused(false) {} 00034 00035 //******** STATICS ******** 00036 00037 // Current system time in seconds since time orign: 00038 static double sys_time() { return the_time(); } 00039 00040 //******** ACCESSORS ******** 00041 bool is_paused() const { return _is_paused; } 00042 00043 // The following shouldn't be needed by normal users: 00044 double start_time() const { return _start_time; } 00045 double pause_time() const { return _pause_time; } 00046 00047 //******** INQUIRING THE TIME ******** 00048 00049 // The absolute time (since time origin) reported by this clock. 00050 // This is the same as system time, unless this clock is paused: 00051 double cur_time() const { return _is_paused ? _pause_time : sys_time(); } 00052 00053 // Return the elapsed time since the stop watch was set. 00054 // If currently paused, the return value does not change. 00055 double elapsed_time() const { return cur_time() - _start_time; } 00056 00057 //******** SETTING THE TIME ******** 00058 00059 // Set the stop watch to count from the given (absolute) start time. 00060 // If no start time is passed in, it starts counting from now: 00061 void set(double start = sys_time()) { _start_time = start; } 00062 00063 // Reset the clock so that at this moment it would report an 00064 // elapsed time of t: 00065 void set_elapsed_time(double t=0) { _start_time = cur_time() - t; } 00066 00067 // Increase the current elapsed time by d. 00068 // This works whether the clock is paused or not. 00069 void inc_elapsed_time(double d=0) { set_elapsed_time(elapsed_time() + d); } 00070 00071 // Pause the clock, freezing "elapsed time" at current value. 00072 void pause() { 00073 // Calling pause() a 2nd time has no effect. 00074 if (!_is_paused) { 00075 _pause_time = sys_time(); 00076 _is_paused = true; 00077 } 00078 } 00079 00080 // Unpause the clock, letting "elapsed time" begin increasing 00081 // again from its value right now. 00082 void resume() { 00083 // Calling resume() a 2nd time has no effect. 00084 if (_is_paused) { 00085 double e = elapsed_time(); 00086 _is_paused = false; 00087 set_elapsed_time(e); 00088 } 00089 } 00090 00091 // Pause the clock, with 0 seconds elapsed time showing: 00092 void reset_hold() { 00093 pause(); 00094 set_elapsed_time(0); 00095 } 00096 00097 //******** DIAGNOSTIC ******** 00098 00099 // Prints "msg: X seconds", where X is the elapsed time 00100 void print_time(const char* msg="elapsed time") { 00101 err_msg("%s: %f seconds", msg, elapsed_time()); 00102 } 00103 00104 protected: 00105 double _start_time; // absolute time at which clock was reset 00106 double _pause_time; // absolute time at which clock was paused 00107 bool _is_paused; // tells if clock is paused or not 00108 }; 00109 00110 /********************************************************************** 00111 * egg_timer: 00112 * 00113 * Set it up to expire after a given amount of time, in seconds. 00114 * For soft-boiled eggs try 3 minutes (after boiling starts). 00115 **********************************************************************/ 00116 class egg_timer : public stop_watch { 00117 public: 00118 egg_timer(double dur) : _duration(dur) {} 00119 00120 void reset(double dur) { _duration = dur; set(); } 00121 00122 double remaining() const { return max(_duration - elapsed_time(), 0.0); } 00123 bool expired() const { return remaining() == 0; } 00124 00125 protected: 00126 double _duration; // length of time from reset to expiration 00127 }; 00128 00129 #endif // STOP_WATCH_H_HAS_BEEN_INCLUDED 00130 00131 // end of file stop_watch.H