From 5b0652cb7e6e67230cafed5b4754820e8e9dc471 Mon Sep 17 00:00:00 2001 From: Darryl Pogue Date: Sun, 11 May 2014 16:31:07 -0700 Subject: [PATCH] std::chrono-ize hsTimer. --- Sources/Plasma/NucleusLib/inc/hsTimer.h | 115 ++++++------ Sources/Plasma/NucleusLib/pnTimer/hsTimer.cpp | 174 +++--------------- 2 files changed, 79 insertions(+), 210 deletions(-) diff --git a/Sources/Plasma/NucleusLib/inc/hsTimer.h b/Sources/Plasma/NucleusLib/inc/hsTimer.h index 0295a76b..0bad9c7e 100644 --- a/Sources/Plasma/NucleusLib/inc/hsTimer.h +++ b/Sources/Plasma/NucleusLib/inc/hsTimer.h @@ -42,112 +42,103 @@ You can contact Cyan Worlds, Inc. by email legal@cyan.com #ifndef hsTimer_Defined #define hsTimer_Defined -#include "hsWide.h" +#include class plTimerShare { + typedef std::chrono::high_resolution_clock Clock; + typedef std::chrono::time_point TimePoint; + typedef Clock::duration Duration; + protected: mutable bool fFirstTime; - mutable hsWide fRawTimeZero; + mutable TimePoint fRawTimeZero; mutable bool fResetSmooth; enum { kSmoothBuffLen = 10 }; - double fSmoothBuff[kSmoothBuffLen]; - int fCurrSlot; + double fSmoothBuff[kSmoothBuffLen]; + int fCurrSlot; - float fSysTimeScale; - double fRealSeconds; - double fSysSeconds; - float fDelSysSeconds; - float fFrameTimeInc; - bool fRunningFrameTime; - float fTimeClampSecs; - float fSmoothingClampSecs; - bool fClamping; + float fSysTimeScale; + double fRealSeconds; + double fSysSeconds; + float fDelSysSeconds; + float fFrameTimeInc; + bool fRunningFrameTime; + float fTimeClampSecs; + float fSmoothingClampSecs; + bool fClamping; - hsWide* FactorInTimeZero(hsWide* ticks) const; - double GetSeconds() const; - double GetMilliSeconds() const; + double GetSeconds() 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); - hsWide DSecondsToRawTicks(double secs); + void SetRealTime(bool realTime); + bool IsRealTime() const { return !fRunningFrameTime; } - float GetDelSysSeconds() const { return fDelSysSeconds; } - double GetSysSeconds() const { return fSysSeconds; } - double IncSysSeconds(); + void SetFrameTimeInc(float inc) { fFrameTimeInc = inc; } - void SetRealTime(bool realTime); - bool IsRealTime() const { return !fRunningFrameTime; } + void SetTimeScale(float s) { fSysTimeScale = s; } + 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; } - float GetTimeScale() const { return fSysTimeScale; } + friend class hsTimer; + + +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: plTimerShare(); ~plTimerShare(); }; -class hsTimer + +class hsTimer { protected: - static const double fPrecTicksPerSec; - static const hsWide fRawBase; - - static hsWide IInitRawBase(); - 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); } - static double GetSeconds() { return fTimer->GetSeconds(); } - 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); } +public: + static double GetSeconds() { return fTimer->GetSeconds(); } + static double GetMilliSeconds() { return fTimer->GetMilliSeconds(); } - static float GetDelSysSeconds() { return fTimer->GetDelSysSeconds(); } - static double GetSysSeconds() { return fTimer->GetSysSeconds(); } + static float GetDelSysSeconds() { return fTimer->GetDelSysSeconds(); } + 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 bool IsRealTime() { return fTimer->IsRealTime(); } + static void SetRealTime(bool realTime) { fTimer->SetRealTime(realTime); } + 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 float GetTimeScale() { return fTimer->GetTimeScale(); } + static void SetTimeScale(float s) { fTimer->SetTimeScale(s); } + static float GetTimeScale() { return fTimer->GetTimeScale(); } - static void SetTimeClamp(float secs) { fTimer->SetTimeClamp(secs); } - static void SetTimeSmoothingClamp(float secs) { fTimer->SetSmoothingCap(secs); } - static float GetTimeClamp() { return fTimer->GetTimeClamp(); } - static bool IsClamping() { return fTimer->IsClamping(); } + static void SetTimeClamp(float secs) { fTimer->SetTimeClamp(secs); } + static void SetTimeSmoothingClamp(float secs) { fTimer->SetSmoothingCap(secs); } + static float GetTimeClamp() { return fTimer->GetTimeClamp(); } + static bool IsClamping() { return fTimer->IsClamping(); } /////////////////////////// // Precision timer routines - these are stateless and implemented as statics. /////////////////////////// static uint32_t GetPrecTickCount(); static double GetPrecTicksPerSec(); - static uint32_t PrecSecsToTicks(float secs); 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 // the precision timer. It works the same, it just gives you full resolution. diff --git a/Sources/Plasma/NucleusLib/pnTimer/hsTimer.cpp b/Sources/Plasma/NucleusLib/pnTimer/hsTimer.cpp index 9619ad69..571c03fb 100644 --- a/Sources/Plasma/NucleusLib/pnTimer/hsTimer.cpp +++ b/Sources/Plasma/NucleusLib/pnTimer/hsTimer.cpp @@ -41,10 +41,12 @@ You can contact Cyan Worlds, Inc. by email legal@cyan.com *==LICENSE==*/ #include "hsTimer.h" #include "HeadSpin.h" -#include "hsWindows.h" #include "plTweak.h" +typedef std::chrono::duration dSeconds; +typedef std::chrono::duration dMilliseconds; + // // plTimerShare - the actual worker. All process spaces should share a single // plTimerShare to keep time synchronized across spaces. @@ -71,45 +73,12 @@ plTimerShare::~plTimerShare() double plTimerShare::GetSeconds() const { - hsWide ticks; - return hsTimer::GetRawTicks(&ticks)->AsDouble() / hsTimer::GetRawBase().AsDouble(); + return dSeconds(GetRawTicks()).count(); } double plTimerShare::GetMilliSeconds() const { - return GetSeconds() * 1.e3; -} - -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; + return dMilliseconds(GetRawTicks()).count(); } double plTimerShare::IncSysSeconds() @@ -198,157 +167,66 @@ double plTimerShare::IncSysSeconds() } void plTimerShare::SetRealTime(bool realTime) -{ - fRunningFrameTime = !realTime; - if( realTime ) +{ + fRunningFrameTime = !realTime; + if (realTime) { 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)) - { - ticks->Set(large.HighPart, large.LowPart); + if (fFirstTime) + { + fFirstTime = false; + fRawTimeZero = tp; + return plTimerShare::Duration(0); } 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 - -#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 // constants. // -static plTimerShare staticTimer; -plTimerShare* hsTimer::fTimer = &staticTimer; // until overridden. -const double hsTimer::fPrecTicksPerSec = hsTimer::GetPrecTicksPerSec(); -const hsWide hsTimer::fRawBase = hsTimer::IInitRawBase(); +static plTimerShare staticTimer; +plTimerShare* hsTimer::fTimer = &staticTimer; // until overridden. void hsTimer::SetTheTimer(plTimerShare* timer) { fTimer = timer; } -/////////////////////////// -// Precision timer routines -// These remain as statics -// since they are stateless -// anyway. -/////////////////////////// - double hsTimer::GetPrecTicksPerSec() { -#if HS_BUILD_FOR_WIN32 - LARGE_INTEGER freq; - if( !QueryPerformanceFrequency(&freq) ) - { - return 1000.f; - } - return ((double) freq.LowPart); -#endif - - return 1; + return double(plTimerShare::Clock::period::num) / + double(plTimerShare::Clock::period::den); } uint32_t hsTimer::GetPrecTickCount() { -#if HS_BUILD_FOR_WIN32 - 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); + return uint32_t(plTimerShare::Clock::now().time_since_epoch().count()); } + double hsTimer::PrecTicksToSecs(uint32_t ticks) { - return ((double)ticks) / fPrecTicksPerSec; -} -double hsTimer::PrecTicksToHz(uint32_t ticks) -{ - return fPrecTicksPerSec / ((double)ticks); + return dSeconds(plTimerShare::Duration(ticks)).count(); } uint64_t hsTimer::GetFullTickCount() { -#if HS_BUILD_FOR_WIN32 - LARGE_INTEGER ticks; - QueryPerformanceCounter(&ticks); - return ticks.QuadPart; -#else - return 0; -#endif + return uint64_t(plTimerShare::Clock::now().time_since_epoch().count()); } float hsTimer::FullTicksToMs(uint64_t ticks) { -#ifdef HS_BUILD_FOR_WIN32 - 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 + return float(dMilliseconds(plTimerShare::Duration(ticks)).count()); }