Browse Source

std::chrono-ize hsTimer.

Darryl Pogue 11 years ago
parent
commit
5b0652cb7e
  1. 113
      Sources/Plasma/NucleusLib/inc/hsTimer.h
  2. 166
      Sources/Plasma/NucleusLib/pnTimer/hsTimer.cpp

113
Sources/Plasma/NucleusLib/inc/hsTimer.h

@ -42,112 +42,103 @@ You can contact Cyan Worlds, Inc. by email legal@cyan.com
#ifndef hsTimer_Defined #ifndef hsTimer_Defined
#define hsTimer_Defined #define hsTimer_Defined
#include "hsWide.h" #include <chrono>
class plTimerShare class plTimerShare
{ {
typedef std::chrono::high_resolution_clock Clock;
typedef std::chrono::time_point<Clock> TimePoint;
typedef Clock::duration Duration;
protected: protected:
mutable bool fFirstTime; mutable bool fFirstTime;
mutable hsWide fRawTimeZero; mutable TimePoint fRawTimeZero;
mutable bool fResetSmooth; mutable bool fResetSmooth;
enum { enum {
kSmoothBuffLen = 10 kSmoothBuffLen = 10
}; };
double fSmoothBuff[kSmoothBuffLen]; double fSmoothBuff[kSmoothBuffLen];
int fCurrSlot; int fCurrSlot;
float fSysTimeScale; float fSysTimeScale;
double fRealSeconds; double fRealSeconds;
double fSysSeconds; double fSysSeconds;
float fDelSysSeconds; float fDelSysSeconds;
float fFrameTimeInc; float fFrameTimeInc;
bool fRunningFrameTime; bool fRunningFrameTime;
float fTimeClampSecs; float fTimeClampSecs;
float fSmoothingClampSecs; float fSmoothingClampSecs;
bool fClamping; bool fClamping;
hsWide* FactorInTimeZero(hsWide* ticks) const;
double GetSeconds() const; double GetSeconds() const;
double GetMilliSeconds() const; double GetMilliSeconds() const;
hsWide* GetRawTicks(hsWide* ticks) const; float GetDelSysSeconds() const { return fDelSysSeconds; }
double GetSysSeconds() const { return fSysSeconds; }
double IncSysSeconds();
double RawTicksToDSeconds(const hsWide& ticks); void SetRealTime(bool realTime);
hsWide DSecondsToRawTicks(double secs); bool IsRealTime() const { return !fRunningFrameTime; }
float GetDelSysSeconds() const { return fDelSysSeconds; } void SetFrameTimeInc(float inc) { fFrameTimeInc = inc; }
double GetSysSeconds() const { return fSysSeconds; }
double IncSysSeconds();
void SetRealTime(bool realTime); void SetTimeScale(float s) { fSysTimeScale = s; }
bool IsRealTime() const { return !fRunningFrameTime; } float GetTimeScale() const { return fSysTimeScale; }
void SetFrameTimeInc(float inc) { fFrameTimeInc = inc; } void SetTimeClamp(float secs) { fTimeClampSecs = secs; }
void SetSmoothingCap(float secs) { fSmoothingClampSecs = secs; }
float GetTimeClamp() const { return fTimeClampSecs; }
bool IsClamping() const { return fClamping; }
void SetTimeScale(float s) { fSysTimeScale = s; } friend class hsTimer;
float GetTimeScale() const { return fSysTimeScale; }
private:
Duration GetRawTicks() const;
void SetTimeClamp(float secs) { fTimeClampSecs = secs; }
void SetSmoothingCap(float secs) { fSmoothingClampSecs = secs; }
float GetTimeClamp() const { return fTimeClampSecs; }
bool IsClamping() const { return fClamping; }
friend class hsTimer;
public: public:
plTimerShare(); plTimerShare();
~plTimerShare(); ~plTimerShare();
}; };
class hsTimer class hsTimer
{ {
protected: protected:
static const double fPrecTicksPerSec;
static const hsWide fRawBase;
static hsWide IInitRawBase();
static plTimerShare* fTimer; static plTimerShare* fTimer;
public:
static bool VerifyRawBase() { return fRawBase == IInitRawBase(); }
static const hsWide& GetRawBase() { return fRawBase; }
static hsWide* GetRawTicks(hsWide* ticks) { return fTimer->GetRawTicks(ticks); } public:
static double GetSeconds() { return fTimer->GetSeconds(); }
static double GetSeconds() { return fTimer->GetSeconds(); } static double GetMilliSeconds() { return fTimer->GetMilliSeconds(); }
static double GetMilliSeconds() { return fTimer->GetMilliSeconds(); }
static double RawTicksToDSeconds(const hsWide& ticks) { return fTimer->RawTicksToDSeconds(ticks); }
static hsWide DSecondsToRawTicks(double secs) { return fTimer->DSecondsToRawTicks(secs); }
static float GetDelSysSeconds() { return fTimer->GetDelSysSeconds(); } static float GetDelSysSeconds() { return fTimer->GetDelSysSeconds(); }
static double GetSysSeconds() { return fTimer->GetSysSeconds(); } static double GetSysSeconds() { return fTimer->GetSysSeconds(); }
static double IncSysSeconds() { return fTimer->IncSysSeconds(); } static double IncSysSeconds() { return fTimer->IncSysSeconds(); }
static void SetRealTime(bool realTime) { fTimer->SetRealTime(realTime); } static void SetRealTime(bool realTime) { fTimer->SetRealTime(realTime); }
static bool IsRealTime() { return fTimer->IsRealTime(); } static bool IsRealTime() { return fTimer->IsRealTime(); }
static void SetFrameTimeInc(float inc) { fTimer->SetFrameTimeInc(inc); } static void SetFrameTimeInc(float inc) { fTimer->SetFrameTimeInc(inc); }
static void SetTimeScale(float s) { fTimer->SetTimeScale(s); } static void SetTimeScale(float s) { fTimer->SetTimeScale(s); }
static float GetTimeScale() { return fTimer->GetTimeScale(); } static float GetTimeScale() { return fTimer->GetTimeScale(); }
static void SetTimeClamp(float secs) { fTimer->SetTimeClamp(secs); } static void SetTimeClamp(float secs) { fTimer->SetTimeClamp(secs); }
static void SetTimeSmoothingClamp(float secs) { fTimer->SetSmoothingCap(secs); } static void SetTimeSmoothingClamp(float secs) { fTimer->SetSmoothingCap(secs); }
static float GetTimeClamp() { return fTimer->GetTimeClamp(); } static float GetTimeClamp() { return fTimer->GetTimeClamp(); }
static bool IsClamping() { return fTimer->IsClamping(); } static bool IsClamping() { return fTimer->IsClamping(); }
/////////////////////////// ///////////////////////////
// Precision timer routines - these are stateless and implemented as statics. // Precision timer routines - these are stateless and implemented as statics.
/////////////////////////// ///////////////////////////
static uint32_t GetPrecTickCount(); static uint32_t GetPrecTickCount();
static double GetPrecTicksPerSec(); static double GetPrecTicksPerSec();
static uint32_t PrecSecsToTicks(float secs);
static double PrecTicksToSecs(uint32_t ticks); static double PrecTicksToSecs(uint32_t ticks);
static double PrecTicksToHz(uint32_t ticks);
// If you need to time something longer than 20 seconds, use this instead of // If you need to time something longer than 20 seconds, use this instead of
// the precision timer. It works the same, it just gives you full resolution. // the precision timer. It works the same, it just gives you full resolution.

166
Sources/Plasma/NucleusLib/pnTimer/hsTimer.cpp

@ -41,10 +41,12 @@ You can contact Cyan Worlds, Inc. by email legal@cyan.com
*==LICENSE==*/ *==LICENSE==*/
#include "hsTimer.h" #include "hsTimer.h"
#include "HeadSpin.h" #include "HeadSpin.h"
#include "hsWindows.h"
#include "plTweak.h" #include "plTweak.h"
typedef std::chrono::duration<double> dSeconds;
typedef std::chrono::duration<double, std::milli> dMilliseconds;
// //
// plTimerShare - the actual worker. All process spaces should share a single // plTimerShare - the actual worker. All process spaces should share a single
// plTimerShare to keep time synchronized across spaces. // plTimerShare to keep time synchronized across spaces.
@ -71,45 +73,12 @@ plTimerShare::~plTimerShare()
double plTimerShare::GetSeconds() const double plTimerShare::GetSeconds() const
{ {
hsWide ticks; return dSeconds(GetRawTicks()).count();
return hsTimer::GetRawTicks(&ticks)->AsDouble() / hsTimer::GetRawBase().AsDouble();
} }
double plTimerShare::GetMilliSeconds() const double plTimerShare::GetMilliSeconds() const
{ {
return GetSeconds() * 1.e3; return dMilliseconds(GetRawTicks()).count();
}
hsWide plTimerShare::DSecondsToRawTicks(double secs)
{
hsWide retVal;
double ticks = secs * hsTimer::GetRawBase().AsDouble();
double hi = ticks / double(65536) / double(65536);
ticks -= hi;
retVal.fHi = int32_t(hi);
retVal.fLo = int32_t(ticks);
return retVal;
}
double plTimerShare::RawTicksToDSeconds(const hsWide& ticks)
{
return ticks.AsDouble() / hsTimer::GetRawBase().AsDouble();
}
inline hsWide* plTimerShare::FactorInTimeZero(hsWide* ticks) const
{
if( fFirstTime )
{
fFirstTime = false;
fRawTimeZero = *ticks;
ticks->Set(0, 0);
}
else
{
ticks->Sub(&fRawTimeZero);
}
return ticks;
} }
double plTimerShare::IncSysSeconds() double plTimerShare::IncSysSeconds()
@ -200,155 +169,64 @@ double plTimerShare::IncSysSeconds()
void plTimerShare::SetRealTime(bool realTime) void plTimerShare::SetRealTime(bool realTime)
{ {
fRunningFrameTime = !realTime; fRunningFrameTime = !realTime;
if( realTime ) if (realTime)
{ {
fRealSeconds = GetSeconds(); fRealSeconds = GetSeconds();
} }
} }
#if HS_BUILD_FOR_WIN32
hsWide* plTimerShare::GetRawTicks(hsWide* ticks) const plTimerShare::Duration plTimerShare::GetRawTicks() const
{ {
LARGE_INTEGER large; plTimerShare::TimePoint tp = Clock::now();
if (::QueryPerformanceCounter(&large)) if (fFirstTime)
{ {
ticks->Set(large.HighPart, large.LowPart); fFirstTime = false;
fRawTimeZero = tp;
return plTimerShare::Duration(0);
} }
else else
{ {
ticks->Set(0, ::GetTickCount()); return plTimerShare::Duration(tp - fRawTimeZero);
} }
return FactorInTimeZero(ticks);
}
hsWide hsTimer::IInitRawBase()
{
hsWide base;
LARGE_INTEGER large;
if (::QueryPerformanceFrequency(&large))
base.Set(large.HighPart, large.LowPart);
else
base.Set(0, 1000);
return base;
}
#elif HS_BUILD_FOR_UNIX
#include <sys/time.h>
#define kMicroSecondsUnit 1000000
static uint32_t gBaseTime = 0;
hsWide* plTimerShare::GetRawTicks(hsWide* ticks) const
{
timeval tv;
(void)::gettimeofday(&tv, nil);
if (gBaseTime == 0)
gBaseTime = tv.tv_sec;
ticks->Mul(tv.tv_sec - gBaseTime, kMicroSecondsUnit)->Add(tv.tv_usec);
return ticks;
} }
hsWide hsTimer::IInitRawBase()
{
hsWide base;
base.Set(0, kMicroSecondsUnit);
return base;
}
#endif
// //
// hsTimer - thin static interface to plTimerShare. Also keeps a couple of // hsTimer - thin static interface to plTimerShare. Also keeps a couple of
// constants. // constants.
// //
static plTimerShare staticTimer; static plTimerShare staticTimer;
plTimerShare* hsTimer::fTimer = &staticTimer; // until overridden. plTimerShare* hsTimer::fTimer = &staticTimer; // until overridden.
const double hsTimer::fPrecTicksPerSec = hsTimer::GetPrecTicksPerSec();
const hsWide hsTimer::fRawBase = hsTimer::IInitRawBase();
void hsTimer::SetTheTimer(plTimerShare* timer) void hsTimer::SetTheTimer(plTimerShare* timer)
{ {
fTimer = timer; fTimer = timer;
} }
///////////////////////////
// Precision timer routines
// These remain as statics
// since they are stateless
// anyway.
///////////////////////////
double hsTimer::GetPrecTicksPerSec() double hsTimer::GetPrecTicksPerSec()
{ {
#if HS_BUILD_FOR_WIN32 return double(plTimerShare::Clock::period::num) /
LARGE_INTEGER freq; double(plTimerShare::Clock::period::den);
if( !QueryPerformanceFrequency(&freq) )
{
return 1000.f;
}
return ((double) freq.LowPart);
#endif
return 1;
} }
uint32_t hsTimer::GetPrecTickCount() uint32_t hsTimer::GetPrecTickCount()
{ {
#if HS_BUILD_FOR_WIN32 return uint32_t(plTimerShare::Clock::now().time_since_epoch().count());
LARGE_INTEGER ti;
if( !QueryPerformanceCounter(&ti) )
return GetTickCount();
return ti.LowPart;
#else
return 1;
#endif
}
uint32_t hsTimer::PrecSecsToTicks(float secs)
{
return (uint32_t)(((double)secs) * fPrecTicksPerSec);
} }
double hsTimer::PrecTicksToSecs(uint32_t ticks) double hsTimer::PrecTicksToSecs(uint32_t ticks)
{ {
return ((double)ticks) / fPrecTicksPerSec; return dSeconds(plTimerShare::Duration(ticks)).count();
}
double hsTimer::PrecTicksToHz(uint32_t ticks)
{
return fPrecTicksPerSec / ((double)ticks);
} }
uint64_t hsTimer::GetFullTickCount() uint64_t hsTimer::GetFullTickCount()
{ {
#if HS_BUILD_FOR_WIN32 return uint64_t(plTimerShare::Clock::now().time_since_epoch().count());
LARGE_INTEGER ticks;
QueryPerformanceCounter(&ticks);
return ticks.QuadPart;
#else
return 0;
#endif
} }
float hsTimer::FullTicksToMs(uint64_t ticks) float hsTimer::FullTicksToMs(uint64_t ticks)
{ {
#ifdef HS_BUILD_FOR_WIN32 return float(dMilliseconds(plTimerShare::Duration(ticks)).count());
static uint64_t ticksPerTenthMs = 0;
if (ticksPerTenthMs == 0)
{
LARGE_INTEGER perfFreq;
QueryPerformanceFrequency(&perfFreq);
ticksPerTenthMs = perfFreq.QuadPart / 10000;
}
return float(ticks / ticksPerTenthMs) / 10.f;
#else
return 0.f;
#endif
} }

Loading…
Cancel
Save