2017-01-02 21:07:43 -05:00
|
|
|
// Copyright (c) Charles J. Cliffe
|
|
|
|
// SPDX-License-Identifier: GPL-2.0+
|
2014-11-16 23:20:48 -05:00
|
|
|
|
|
|
|
#include "Timer.h"
|
|
|
|
|
2015-09-10 00:55:39 -04:00
|
|
|
#ifdef _WIN32
|
2017-05-21 03:58:45 -04:00
|
|
|
#include <windows.h>
|
2014-11-16 23:20:48 -05:00
|
|
|
#endif
|
|
|
|
|
2015-09-09 23:29:38 -04:00
|
|
|
#include <iostream>
|
|
|
|
|
2015-09-10 00:55:39 -04:00
|
|
|
Timer::Timer(void) : time_elapsed(0), system_milliseconds(0), start_time(0), end_time(0), last_update(0), num_updates(0), paused_time(0), offset(0), paused_state(false), lock_state(false), lock_rate(0)
|
2014-11-16 23:20:48 -05:00
|
|
|
{
|
2017-05-20 07:20:29 -04:00
|
|
|
#ifdef _WIN32
|
2017-05-21 03:58:45 -04:00
|
|
|
// According to Microsoft, QueryPerformanceXXX API is perfectly
|
|
|
|
//fine for Windows 7+ systems, and use the highest appropriate counter.
|
|
|
|
//this only need to be done once.
|
|
|
|
::QueryPerformanceFrequency(&win_frequency);
|
2017-05-27 09:28:42 -04:00
|
|
|
#endif
|
2014-11-16 23:20:48 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void Timer::start(void)
|
|
|
|
{
|
2017-05-21 03:58:45 -04:00
|
|
|
update();
|
|
|
|
num_updates = 0;
|
|
|
|
start_time = system_milliseconds;
|
|
|
|
last_update = start_time;
|
|
|
|
paused_state = false;
|
|
|
|
lock_state = false;
|
|
|
|
lock_rate = 0;
|
|
|
|
paused_time = 0;
|
|
|
|
offset = 0;
|
2014-11-16 23:20:48 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void Timer::stop(void)
|
|
|
|
{
|
2017-05-21 03:58:45 -04:00
|
|
|
end_time = system_milliseconds;
|
2014-11-16 23:20:48 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void Timer::reset(void)
|
|
|
|
{
|
2017-05-21 03:58:45 -04:00
|
|
|
start();
|
2014-11-16 23:20:48 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void Timer::lockFramerate(float f_rate)
|
|
|
|
{
|
2017-05-21 03:58:45 -04:00
|
|
|
lock_rate = 1.0f/f_rate;
|
|
|
|
lock_state = true;
|
2014-11-16 23:20:48 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void Timer::unlock()
|
|
|
|
{
|
2017-05-21 03:58:45 -04:00
|
|
|
unsigned long msec_tmp = system_milliseconds;
|
|
|
|
|
|
|
|
lock_state = false;
|
2014-11-16 23:20:48 -05:00
|
|
|
|
2017-05-21 03:58:45 -04:00
|
|
|
update();
|
|
|
|
|
|
|
|
last_update = system_milliseconds-(unsigned long)lock_rate;
|
|
|
|
|
|
|
|
offset += msec_tmp-system_milliseconds;
|
|
|
|
|
|
|
|
lock_rate = 0;
|
2014-11-16 23:20:48 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
bool Timer::locked()
|
|
|
|
{
|
2017-05-21 03:58:45 -04:00
|
|
|
return lock_state;
|
2014-11-16 23:20:48 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
void Timer::update(void)
|
|
|
|
{
|
2017-05-21 03:58:45 -04:00
|
|
|
num_updates++;
|
|
|
|
last_update = system_milliseconds;
|
|
|
|
|
|
|
|
|
|
|
|
if (lock_state)
|
|
|
|
{
|
|
|
|
system_milliseconds += (unsigned long)(lock_rate*1000.0);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2015-09-10 00:55:39 -04:00
|
|
|
#ifdef _WIN32
|
|
|
|
|
2017-05-21 03:58:45 -04:00
|
|
|
//Use QuaryPerformanceCounter, imune to problems sometimes
|
|
|
|
//multimedia timers have.
|
|
|
|
LARGE_INTEGER win_current_count;
|
|
|
|
::QueryPerformanceCounter(&win_current_count);
|
2017-05-20 07:20:29 -04:00
|
|
|
|
2017-05-21 03:58:45 -04:00
|
|
|
system_milliseconds = (unsigned long)(win_current_count.QuadPart * 1000.0 / win_frequency.QuadPart);
|
2015-09-10 00:55:39 -04:00
|
|
|
|
2014-11-16 23:20:48 -05:00
|
|
|
#else
|
2017-05-21 03:58:45 -04:00
|
|
|
gettimeofday(&time_val,&time_zone);
|
2014-11-16 23:20:48 -05:00
|
|
|
|
2017-05-21 03:58:45 -04:00
|
|
|
system_milliseconds = (unsigned long)time_val.tv_usec;
|
|
|
|
system_milliseconds /= 1000;
|
|
|
|
system_milliseconds += (unsigned long)(time_val.tv_sec*1000);
|
2014-11-16 23:20:48 -05:00
|
|
|
#endif
|
2017-05-21 03:58:45 -04:00
|
|
|
}
|
2014-11-16 23:20:48 -05:00
|
|
|
|
|
|
|
|
2017-05-21 03:58:45 -04:00
|
|
|
if (paused_state) paused_time += system_milliseconds-last_update;
|
2014-11-16 23:20:48 -05:00
|
|
|
|
2017-05-21 03:58:45 -04:00
|
|
|
time_elapsed = system_milliseconds-start_time-paused_time+offset;
|
2014-11-16 23:20:48 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
unsigned long Timer::getMilliseconds(void)
|
|
|
|
{
|
2017-05-21 03:58:45 -04:00
|
|
|
return time_elapsed;
|
2014-11-16 23:20:48 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
double Timer::getSeconds(void)
|
|
|
|
{
|
2017-05-21 03:58:45 -04:00
|
|
|
return ((double)getMilliseconds())/1000.0;
|
2014-11-16 23:20:48 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void Timer::setMilliseconds(unsigned long milliseconds_in)
|
|
|
|
{
|
2017-05-21 03:58:45 -04:00
|
|
|
offset -= (system_milliseconds-start_time-paused_time+offset)-milliseconds_in;
|
2014-11-16 23:20:48 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void Timer::setSeconds(double seconds_in)
|
|
|
|
{
|
2017-05-21 03:58:45 -04:00
|
|
|
setMilliseconds((long)(seconds_in*1000.0));
|
2014-11-16 23:20:48 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
double Timer::lastUpdateSeconds(void)
|
|
|
|
{
|
2017-05-21 03:58:45 -04:00
|
|
|
return ((double)lastUpdateMilliseconds())/1000.0;
|
2014-11-16 23:20:48 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
unsigned long Timer::lastUpdateMilliseconds(void)
|
|
|
|
{
|
2017-05-21 03:58:45 -04:00
|
|
|
return system_milliseconds-last_update;
|
2014-11-16 23:20:48 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
unsigned long Timer::totalMilliseconds()
|
|
|
|
{
|
2017-05-21 03:58:45 -04:00
|
|
|
return system_milliseconds-start_time;
|
2014-11-16 23:20:48 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
double Timer::totalSeconds(void)
|
|
|
|
{
|
2017-05-21 03:58:45 -04:00
|
|
|
return totalMilliseconds()/1000.0;
|
2014-11-16 23:20:48 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
unsigned long Timer::getNumUpdates(void)
|
|
|
|
{
|
2017-05-21 03:58:45 -04:00
|
|
|
return num_updates;
|
2014-11-16 23:20:48 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void Timer::paused(bool pause_in)
|
|
|
|
{
|
2017-05-21 03:58:45 -04:00
|
|
|
paused_state = pause_in;
|
2014-11-16 23:20:48 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
bool Timer::paused()
|
|
|
|
{
|
2017-05-21 03:58:45 -04:00
|
|
|
return paused_state;
|
2014-11-16 23:20:48 -05:00
|
|
|
}
|
2015-09-09 23:29:38 -04:00
|
|
|
|
|
|
|
void Timer::timerTestFunc() {
|
|
|
|
update();
|
|
|
|
if (getNumUpdates() % 120 == 0) {
|
|
|
|
std::cout << getNumUpdates() << "," << getSeconds() << " Rate: " << ((double)getNumUpdates()/getSeconds()) << "/sec" << std::endl;
|
|
|
|
}
|
|
|
|
if (getNumUpdates() >= 600) {
|
|
|
|
reset();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|