00001 #ifndef STOP_WATCH_INCLUDED
00002 #define STOP_WATCH_INCLUDED
00003
00004 #ifndef WIN32
00005 #include <sys/time.h>
00006 #endif
00007
00008 namespace ani
00009 {
00010 //: A StopWatch
00011 // This class monitors frame rate, and general time performance metrics
00012 // NOTE: All times expressed in seconds (in 64bit floating point)
00013 // The getTime func is expressed as seconds since midnight (00:00)
00014 // Coordinated Universal Time (UTC), January 1, 1970.
00015 class StopWatch
00016 {
00017 public:
00018 //: Default constructor.
00019 StopWatch( const int& averageFpsRefreshRate = 15 );
00020
00021 // StopWatch controls:
00022 public:
00023 //: Starts the stopwatch
00024 // sets the start time
00025 void start();
00026
00027 //: Stops the stopwatch
00028 // sets the stop time, and the time elapsed.
00029 void stop();
00030
00031 //: stop then start
00032 // call this once per frame if you're doing frame time measurements.
00033 void pulse();
00034
00035
00036 //: Reset the stopwatch
00037 // result - Resets every param except for [mRefreshRate]
00038 void reset();
00039
00040 // StopWatch settings:
00041 public:
00042 //: the refresh rate for mFpsAverage and mTimeAverage (in number of frames)
00043 // mFpsInstant is averaged over [mRefreshRate] number of
00044 // start/stop cycles
00045 // see also - mFpsAverage for the average frames per second value.
00046 // see also - mTimeAverage for the average time value.
00047 // TODO: make this based on time rather than cycles
00048 inline void setRefreshRate( const int& rate ) { mRefreshRate = rate; }
00049
00050
00051 // Time metrics:
00052 public:
00053 //: the time between the last start/stop cycle averaged
00054 //: over timeRefreshRate start/stop cycles
00055 // format - see NOTE at top for time format
00056 // result - undefined if used before stop() is called
00057 inline const double& timeAverage() const { return mTimeAverage; }
00058
00059 //: the time between the last start/stop cycle
00060 //: (time = mTimeStopped - mTimeStarted)
00061 // format - see NOTE at top for time format
00062 // result - undefined if used before stop() is called
00063 inline const double& timeInstant() const { return mTimeInstant; }
00064
00065 //: the time at which start() was invoked last
00066 // format: see NOTE at top for time format
00067 inline const double& timeStart() const { return mTimeStarted; }
00068
00069 //: the time at which stop() was invoked last
00070 // format - see NOTE at top for time format
00071 inline const double& timeStop() const { return mTimeStopped; }
00072
00073 // Frames per second metrics (start/stop per second actually):
00074 public:
00075 //: the number start/stop cycles
00076 // Number start/stop cycles that have been
00077 // performed since the last reset() or since construction
00078 inline const unsigned long& count() const { return mCount; }
00079
00080 //: The average frames per second over [mRefreshRate] start/stop cycles
00081 inline const double& fpsAverage() const { return mFpsAverage; }
00082
00083 //: the frames per second between the last start/stop cycle
00084 inline const double& fpsInstant() const { return mFpsInstant; }
00085
00086 public:
00087 //: x-platform getTime function
00088 // useful for profiling, returns current time in seconds.
00089 // returns - a double (see top for time format)
00090 static void getTime( double& num );
00091 static double getTime();
00092
00093 // time metrics
00094 protected:
00095 double mTimeStarted;
00096 double mTimeStopped;
00097 double mTimeAverage;
00098 double mTimeInstant;
00099
00100 // settings
00101 protected:
00102 int mRefreshRate;
00103
00104 // FPS metrics
00105 protected:
00106 unsigned long mCount;
00107 double mFpsAverage;
00108 double mFpsInstant;
00109
00110 // hidden/implementation members
00111 private:
00112 double mTimeAccumulator;
00113 };
00114
00116 // Implementation:
00118
00119 //: Default constructor.
00120 inline StopWatch::StopWatch( const int& averageFpsRefreshRate ) :
00121 mTimeStarted( 0.0 ),
00122 mTimeStopped( 0.0 ),
00123 mTimeAverage( 0.0 ),
00124 mTimeInstant( 0.0 ),
00125 mRefreshRate( averageFpsRefreshRate ),
00126 mCount( 0 ),
00127 mFpsAverage( 0.0 ),
00128 mFpsInstant( 0.0 ),
00129 mTimeAccumulator( 0.0 )
00130 {
00131 }
00132
00133 //: get the current time
00134 // useful for profiling
00135 // returns - a number of any scalar type (see top for time format)
00136 // TODO: does compiler optimize the
00137 // case where T = double???, if not, then un-template this.
00138 #ifndef WIN32
00139 inline void StopWatch::getTime( double& num )
00140 {
00141 struct timeval tv;
00142 gettimeofday( &tv, 0 );
00143
00144 // compose sec with microsec for sec.millisec
00145 num = static_cast<double>( tv.tv_sec )
00146 + ( static_cast<double>( tv.tv_usec )
00147 / 1000000.0 );
00148 }
00149 #else
00150 #include <sys/types.h>
00151 #include <sys/timeb.h>
00152 inline void StopWatch::getTime( double& num )
00153 {
00154 struct _timeb tv;
00155 _ftime( &tv );
00156
00157 // compose sec with millisec for sec.millisec
00158 num = static_cast<double>( tv.time )
00159 + ( static_cast<double>( tv.millitm )
00160 / 1000.0 );
00161 }
00162 #endif
00163
00164 //: a slightly easier to use version for some people ;)
00165 inline double StopWatch::getTime()
00166 {
00167 double num;
00168 StopWatch::getTime( num );
00169 return num;
00170 }
00171
00172
00173 //: Starts the stopwatch
00174 // result - sets the value mTimeStarted
00175 inline void StopWatch::start()
00176 {
00177 StopWatch::getTime( mTimeStarted );
00178 }
00179
00180 //: Stops the stopwatch
00181 // results - sets the value mTimeStopped, <BR>
00182 // sets the value time, <BR>
00183 // sets the value mFpsAverage (every [mRefreshRate] times that stop is called), <BR>
00184 // sets the value mFpsInstant, <BR>
00185 // sets the value mCount. <BR>
00186 inline void StopWatch::stop()
00187 {
00188 StopWatch::getTime( mTimeStopped );
00189
00190 // get the time for this one frame.
00191 mTimeInstant = mTimeStopped - mTimeStarted;
00192
00193 // every [mRefreshRate] frames, calc the average FPS
00194 if (mCount % mRefreshRate == 0)
00195 {
00196 mFpsAverage = mRefreshRate / mTimeAccumulator;
00197 mTimeAverage = mTimeAccumulator / mRefreshRate;
00198
00199 // reset the accumulator
00200 mTimeAccumulator = 0.0;
00201 }
00202
00203 // accumulate the frame times to later calc
00204 // the average FPS time.
00205 mTimeAccumulator += mTimeInstant;
00206
00207 // calculate the instantaneous FPS value (1 frame/sec)
00208 mFpsInstant = 1.0 / mTimeInstant;
00209
00210 // Increment the number of frames elapsed
00211 ++mCount;
00212 }
00213
00214 //: stop then start
00215 // call this once per frame if you're doing frame time measurements.
00216 inline void StopWatch::pulse()
00217 {
00218 this->stop();
00219 this->start();
00220 }
00221
00222 //: Reset the stopwatch
00223 // result - Resets every param except for [mRefreshRate]
00224 inline void StopWatch::reset()
00225 {
00226 mTimeStarted = 0.0;
00227 mTimeStopped = 0.0;
00228 mTimeAccumulator = 0.0;
00229
00230 mCount = 0;
00231 mFpsAverage = 0.0;
00232 mFpsInstant = 0.0;
00233 mTimeInstant = 0.0;
00234 }
00235
00236 }; // namespace jfx
00237
00238 #endif
1.2.15