|
25 Years of Programming
An open source source for C, C++, OWL, BASIC, MDB, XLS, DOT, and more... |
Home Projects Up Sitemap Search Blog Forum+Chat About Us Privacy Terms of Use Feedback FAQ Images Services Payments Humor Music |
C++ Stopwatch classA crude C++ stopwatch class that can be used for timing things in programs. This was written in Borland C++ 4.0. If you're looking for a timer for Microsoft Visual C++, the .NET Framework Stopwatch class is more "standard" and capable. The key to a stopwatch or clock program is that any modern computer has a system clock that knows what time it is at every instant. You don't have to write the program that counts seconds. You only need to get the current time at the start of your interval, do it again at the end of your interval, and subtract to get the difference. I don't know whether true millisecond timing is achievable. The last time I tested (it was on an old computer), the timer counted milliseconds, but it actually advanced 50 milliseconds every 1/20th of a second, so although the time was reported in milliseconds, the interval was only accurate to the nearest 1/20th. There is a simple cooking timer program written in QBASIC at timer.htm |
/* stopwatc.h 11-25-01
Copyright (C)1996-2001, 2006 Steven Whitney.
Initially published by http://25yearsofprogramming.com.
Borland C++ 4.0, for MSDOS or Windows.
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
Version 3 as published by the Free Software Foundation.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
------
Notes:
a Stopwatch object provides the ability to time a process (> 1 sec), and can provide
statistics on multiple trials of the process. All values are in seconds.
It now also provides a separate alarm clock function.
Be sure to call functions in correct order: start() stop() then you can get stats.
------
To Do:
The alarm functions are untested and are entirely separate from the original basic
timing functions. It might be desirable to integrate them, make them compatible.
Not thoroughly checked, and some existing programs that use it could be changed to
make better use of it (millisecond timing).
------
Notes:
--The conversion from TTime to clock() didn't improve accuracy, (but I think it did eliminate
the delay at startup of waiting for an even-second to come around); all values
are still in seconds, but minor changes would make millisecond timing available.
--There is an undocumented BC4 class TTimer (DOS only), and a program demonstrating its use.
See c:\bc4\source\classlib\timer.cpp
--All timing variables are clock_t to be same type for calculations and for min,max macros.
*/
#ifndef __STOPWATC_H
#define __STOPWATC_H
#include <classlib\time.h>
#include "c:\bcs\my.h"
#pragma hdrstop
//////////////////////////////////////////////////////////////////////////////
class Stopwatch
{
public:
Stopwatch(); // constructor also resets
~Stopwatch();
friend ostream& operator << (ostream& os, const Stopwatch&); // output stats
// functions
void reset(); // resets everything but DOESN'T start timing
void start(); // start timing
clock_t stop(); // end timing
clock_t split() const; // get elapsed time this trial, leave running
clock_t trialtime() const; // get time for last trial
clock_t average() const; // get average time per trial
// variables
clock_t totaltime; // accumulated, all trials
clock_t trials; // # of trials
clock_t low; // lowest time
clock_t high; // highest time
// related to alarm function
BOOL AlarmIsSet; // whether the alarm function is on
TTime TargetTime; // time that the alarm sounds, if on
long AlarmInterval; // when auto-timing intervals, the length in seconds
BOOL SetAlarm(double minutesfromnow);
// BOOL SetAlarm(TTime when); // a possibility, not yet needed
BOOL CheckAlarm(BOOL playnow); // see if alarm should go off, optionally take action now
void AlarmOff(); // turn off alarm
void SoundOff(); // turn off sound
BOOL AlarmRestart(); // abort current interval, start new one
protected:
BOOL running;
BOOL AlarmIsSounding;
clock_t starttime;
clock_t endtime;
};
//////////////////////////////////////////////////////////////////////////////
#endif // STOPWATC.H
/* stopwatc.cpp 12-02-01
Copyright (C)1996-2001, 2006 Steven Whitney.
Initially published by http://25yearsofprogramming.com.
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
Version 3 as published by the Free Software Foundation.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
Code for class Stopwatch.
*/
#include "c:\bcs\library\stopwatc.h"
#include <values.h>
#if defined(_Windows)
#include <mmsystem.h>
#endif
//--------------------------------------------------------------------------
// constructor
Stopwatch::Stopwatch()
{
// alarm-related; unsure whether they should go in reset()
AlarmIsSet = FALSE;
AlarmIsSounding = FALSE;
AlarmInterval = 0L;
reset();
}
//--------------------------------------------------------------------------
Stopwatch::~Stopwatch()
{
SoundOff();
}
//--------------------------------------------------------------------------
// output results on a single line, for screen or file use
ostream& operator << (ostream& os,const Stopwatch& s)
{
os << "Trials " << s.trials;
os << " High " << s.high;
os << " Low " << s.low;
os << " Last " << s.trialtime();
os << " Sum " << s.totaltime;
os << " Mean " << s.average();
return(os);
}
//--------------------------------------------------------------------------
// reset everything, but doesn't start timing.
void Stopwatch::reset()
{
trials = totaltime = high = 0;
low = MAXLONG;
start();
running = FALSE; // turn timer back off
}
//--------------------------------------------------------------------------
// start timing
void Stopwatch::start()
{
starttime = endtime = clock(); // set start and end to current so there's no difference
running = TRUE;
}
//--------------------------------------------------------------------------
// stop timing. returns elapsed time for this trial
clock_t Stopwatch::stop()
{
endtime = clock(); // record ending time
trials++; // increment trial count
clock_t difference = trialtime(); // calculate elapsed time
high = max(high,difference); // exceeds highest or lowest?
low = min(low,difference);
totaltime += difference; // add it to total time
running = FALSE;
return(difference); // return elapsed time for convenience
}
//--------------------------------------------------------------------------
// returns elapsed time this trial, but leaves timer running
clock_t Stopwatch::split() const
{
return(running ? ((clock() - starttime) / CLK_TCK) : 0);
}
//--------------------------------------------------------------------------
// get elapsed time for one trial
clock_t Stopwatch::trialtime() const
{
return((endtime - starttime) / CLK_TCK);
}
//--------------------------------------------------------------------------
// get average time per trial
clock_t Stopwatch::average() const
{
if(trials == 0)
return(0);
return(totaltime / trials);
}
//--------------------------------------------------------------------------
// ALARM-RELATED.
//--------------------------------------------------------------------------
void Stopwatch::AlarmOff()
{
SoundOff();
AlarmIsSet = FALSE;
}
//--------------------------------------------------------------------------
void Stopwatch::SoundOff()
{
#if defined(_Windows)
if(AlarmIsSounding)
{
sndPlaySound(NULL,SND_ASYNC);
AlarmIsSounding = FALSE;
}
#endif
}
//--------------------------------------------------------------------------
BOOL Stopwatch::SetAlarm(double minutesfromnow)
{
AlarmInterval = minutesfromnow * 60;
AlarmRestart(); // resets the target time and turns on
return(TRUE);
} //SetAlarm
//--------------------------------------------------------------------------
// call this to repeat timing using the same timing interval.
// Stopwatch itself no longer provides an autorepeat.
BOOL Stopwatch::AlarmRestart()
{
SoundOff();
TargetTime = TTime() + AlarmInterval;
AlarmIsSet = TRUE;
return(TRUE);
} //AlarmRestart
//--------------------------------------------------------------------------
// returns TRUE if target time is hit and alarm should go off; optionally sounds alarm.
// in DOS, alarm sounds with each entry until turned off.
// in Windows, alarm sounds continuously until turned off.
// any of the above fns will turn it off.
// The advantage of using this repeatedly (in IdleAction) instead of a Windows timer
// is that Windows seems to consider generation of WM_TIMER messages a low priority,
// and is often late. IdleAction appears to be a higher priority.
BOOL Stopwatch::CheckAlarm(BOOL playnow)
{
if(!AlarmIsSet || (TTime() < TargetTime))
return FALSE;
if(playnow)
{
#if defined(_Windows)
if(!AlarmIsSounding) // if not already sounding
{
sndPlaySound("alarm.wav",SND_ASYNC | SND_LOOP);
AlarmIsSounding = TRUE;
}
#else
sound(1500);
delay(1000);
nosound();
#endif
}
return TRUE;
} //CheckAlarm
//--------------------------------------------------------------------------
// end class Stopwatch
//////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
Copyright ©2010 Steven Whitney. Last modified Thu 10/21/2010 02:08:04 -0700. |
||