Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members   Related Pages  

c:/home/kevn/src/animaniac/ani/Util/StopWatch.h

Go to the documentation of this file.
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

Generated on Wed Jun 12 01:54:02 2002 for Animaniac by doxygen1.2.15