2019-10-19 23:43:35 +00:00
|
|
|
// Build engine timer stuff
|
2019-08-13 14:44:16 +00:00
|
|
|
|
|
|
|
#include "timer.h"
|
|
|
|
|
|
|
|
#include "build.h"
|
|
|
|
#include "compat.h"
|
|
|
|
|
|
|
|
#include <chrono>
|
|
|
|
|
|
|
|
using namespace std;
|
|
|
|
using namespace chrono;
|
|
|
|
|
2019-08-14 21:42:30 +00:00
|
|
|
EDUKE32_STATIC_ASSERT((steady_clock::period::den/steady_clock::period::num) >= 1000000000);
|
|
|
|
|
2019-08-14 14:26:48 +00:00
|
|
|
static time_point<steady_clock> timerlastsample;
|
|
|
|
static int timerticspersec;
|
2019-08-13 14:44:16 +00:00
|
|
|
static void(*usertimercallback)(void) = NULL;
|
|
|
|
|
2019-10-19 23:43:35 +00:00
|
|
|
int timerGetClockRate(void) { return timerticspersec; }
|
2019-08-14 14:26:48 +00:00
|
|
|
uint32_t timerGetTicks(void) { return duration_cast<milliseconds>(steady_clock::now().time_since_epoch()).count(); }
|
2019-08-14 21:42:30 +00:00
|
|
|
uint64_t timerGetTicksU64(void) { return steady_clock::now().time_since_epoch().count() * steady_clock::period::num; }
|
2019-08-14 14:26:48 +00:00
|
|
|
uint64_t timerGetFreqU64(void) { return steady_clock::period::den; }
|
2019-08-13 14:44:16 +00:00
|
|
|
|
|
|
|
// Returns the time since an unspecified starting time in milliseconds.
|
|
|
|
// (May be not monotonic for certain configurations.)
|
2019-08-14 14:26:48 +00:00
|
|
|
double timerGetHiTicks(void) { return duration<double, nano>(steady_clock::now().time_since_epoch()).count() / 1000000.0; }
|
2019-08-13 14:44:16 +00:00
|
|
|
|
2019-08-14 14:26:48 +00:00
|
|
|
int timerInit(int const tickspersecond)
|
2019-08-13 14:44:16 +00:00
|
|
|
{
|
|
|
|
timerticspersec = tickspersecond;
|
2019-08-14 14:26:48 +00:00
|
|
|
timerlastsample = steady_clock::now();
|
2019-08-13 14:44:16 +00:00
|
|
|
|
|
|
|
usertimercallback = NULL;
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2019-11-06 22:40:10 +00:00
|
|
|
TArray<void(*)(void)> callbacks;
|
|
|
|
|
2019-10-19 23:43:35 +00:00
|
|
|
ATTRIBUTE((flatten)) void timerUpdateClock(void)
|
2019-08-13 14:44:16 +00:00
|
|
|
{
|
2019-08-14 14:26:48 +00:00
|
|
|
auto time = steady_clock::now();
|
2019-08-14 21:42:30 +00:00
|
|
|
auto elapsedTime = time - timerlastsample;
|
2019-08-27 13:39:54 +00:00
|
|
|
|
|
|
|
uint64_t numerator = (elapsedTime.count() * (uint64_t) timerticspersec * steady_clock::period::num);
|
2019-10-19 23:41:22 +00:00
|
|
|
uint64_t freq = timerGetFreqU64();
|
|
|
|
int n = tabledivide64(numerator, freq);
|
|
|
|
totalclock.setFraction(tabledivide64((numerator - n*timerGetFreqU64()) * 65536, freq));
|
2019-08-13 14:44:16 +00:00
|
|
|
|
|
|
|
if (n <= 0) return;
|
|
|
|
|
|
|
|
totalclock += n;
|
2019-08-14 21:42:30 +00:00
|
|
|
timerlastsample += n*nanoseconds(1000000000/timerticspersec);
|
2019-08-13 14:44:16 +00:00
|
|
|
|
2019-11-06 22:40:10 +00:00
|
|
|
for (; n > 0; n--)
|
|
|
|
{
|
|
|
|
for (auto cb : callbacks) cb();
|
|
|
|
}
|
2019-08-13 14:44:16 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void(*timerSetCallback(void(*callback)(void)))(void)
|
|
|
|
{
|
2019-11-06 22:40:10 +00:00
|
|
|
callbacks.Push(callback);
|
|
|
|
return nullptr;
|
2019-08-13 14:44:16 +00:00
|
|
|
}
|