From 9b26eea88651f19c71ee8a07af0c110f76d2adb5 Mon Sep 17 00:00:00 2001 From: J Reece Wilson Date: Sun, 19 May 2024 17:01:51 +0100 Subject: [PATCH] [+] IAsyncTimer::SetCatchUp(bool bCatchUp) --- Include/Aurora/Async/IAsyncTimer.hpp | 18 ++++++++++++++++++ Source/Async/AuAsyncTimer.cpp | 18 +++++++++++++++++- Source/Async/AuAsyncTimer.hpp | 3 +++ 3 files changed, 38 insertions(+), 1 deletion(-) diff --git a/Include/Aurora/Async/IAsyncTimer.hpp b/Include/Aurora/Async/IAsyncTimer.hpp index 30103b12..ef786ed1 100644 --- a/Include/Aurora/Async/IAsyncTimer.hpp +++ b/Include/Aurora/Async/IAsyncTimer.hpp @@ -13,6 +13,24 @@ namespace Aurora::Async { virtual void CancelTimer() = 0; virtual AuUInt64 GetLastTime() = 0; + + /** + * Get tick count (always non-zero after or during initial trigger) + */ virtual AuUInt64 GetTicks() = 0; + + /** + * Default: false + * When in catch up mode, timer ticks can be scheduled in the past, otherwise the next time is clamped to the current time. + * Latterly, it is possible to get stuck in a spin with no interval, however if the system lags behind momentarily, recovery is instantaneous. + * On platforms with process suspension, specify no catch up. + * On servers or other tick-sensitive applications (like a clock GUI), specify catch up. + */ + virtual bool IsCatchUp() = 0; + + /** + * See: IsCatchUp + */ + virtual void SetCatchUp(bool bCatchUp) = 0; }; } \ No newline at end of file diff --git a/Source/Async/AuAsyncTimer.cpp b/Source/Async/AuAsyncTimer.cpp index b3866d1c..9272db88 100644 --- a/Source/Async/AuAsyncTimer.cpp +++ b/Source/Async/AuAsyncTimer.cpp @@ -40,15 +40,31 @@ namespace Aurora::Async return this->uTickCount; } + bool AsyncFuncTimer::IsCatchUp() + { + return this->bCatchUp; + } + + void AsyncFuncTimer::SetCatchUp(bool bCatchUp) + { + this->bCatchUp = bCatchUp; + } + void AsyncFuncTimer::DispatchTask(IWorkItemHandler::ProcessInfo &info) { info.type = ETickType::eRerun; auto uTickCount = ++this->uTickCount; + this->uLastTickTime = AuTime::SteadyClockNS(); auto uDelta = this->uLastTickTime - this->uNextTickTime; + this->uNextTickTime += this->uInterval; - this->uNextTickTime = AuMax(this->uNextTickTime, this->uLastTickTime); + if (!this->bCatchUp) + { + this->uNextTickTime = AuMax(this->uNextTickTime, this->uLastTickTime); + } + info.reschedSteadyClockAbsNs = this->uNextTickTime; if (this->pCallback->OnTick(uTickCount, uDelta, this->uLastTickTime)) diff --git a/Source/Async/AuAsyncTimer.hpp b/Source/Async/AuAsyncTimer.hpp index 051c6570..8f241141 100644 --- a/Source/Async/AuAsyncTimer.hpp +++ b/Source/Async/AuAsyncTimer.hpp @@ -24,6 +24,8 @@ namespace Aurora::Async void CancelTimer() override; AuUInt64 GetLastTime() override; AuUInt64 GetTicks() override; + bool IsCatchUp() override; + void SetCatchUp(bool bCatchUp) override; void DispatchTask(IWorkItemHandler::ProcessInfo &info) override; void Cleanup() override; @@ -34,5 +36,6 @@ namespace Aurora::Async AuUInt64 uLastTickTime {}; AuUInt64 uInterval {}; AuUInt64 uTickCount {}; + bool bCatchUp { false }; }; } \ No newline at end of file