121 lines
3.5 KiB
C++
121 lines
3.5 KiB
C++
|
/***
|
||
|
Copyright (C) 2021-2023 J Reece Wilson (a/k/a "Reece"). All rights reserved.
|
||
|
|
||
|
File: AuAsyncTimer.cpp
|
||
|
Date: 2023-12-06
|
||
|
Date: 2021-11-2
|
||
|
Author: Reece
|
||
|
***/
|
||
|
#include <Source/RuntimeInternal.hpp>
|
||
|
#include "IAsyncRunnable.hpp"
|
||
|
#include "AuAsyncTimer.hpp"
|
||
|
#include "ThreadPool.hpp"
|
||
|
|
||
|
namespace Aurora::Async
|
||
|
{
|
||
|
AsyncFuncTimer::AsyncFuncTimer(IThreadPoolInternal *owner,
|
||
|
const AuSPtr<IAsyncTimerCallback> &pCallback,
|
||
|
const WorkerPId_t &worker,
|
||
|
AuUInt64 uNextTickTime,
|
||
|
AuUInt64 uInterval) :
|
||
|
WorkItem(owner, worker, {}),
|
||
|
uNextTickTime(uNextTickTime),
|
||
|
uInterval(uInterval)
|
||
|
{
|
||
|
|
||
|
}
|
||
|
|
||
|
void AsyncFuncTimer::CancelTimer()
|
||
|
{
|
||
|
this->Cancel();
|
||
|
}
|
||
|
|
||
|
AuUInt64 AsyncFuncTimer::GetLastTime()
|
||
|
{
|
||
|
return this->uLastTickTime;
|
||
|
}
|
||
|
|
||
|
AuUInt64 AsyncFuncTimer::GetTicks()
|
||
|
{
|
||
|
return this->uTickCount;
|
||
|
}
|
||
|
|
||
|
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);
|
||
|
info.reschedSteadyClockAbsNs = this->uNextTickTime;
|
||
|
|
||
|
if (this->pCallback->OnTick(uTickCount, uDelta, this->uLastTickTime))
|
||
|
{
|
||
|
info.type = ETickType::eSchedule;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
info.type = ETickType::eFinished;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void AsyncFuncTimer::Cleanup()
|
||
|
{
|
||
|
AuResetMember(this->pCallback);
|
||
|
}
|
||
|
|
||
|
AUKN_SYM AuSPtr<IAsyncTimer> NewTimer(AuUInt64 uPeriodNS,
|
||
|
const AuSPtr<IAsyncTimerCallback> &pCallback,
|
||
|
AuOptional<WorkerPId_t> workerPid,
|
||
|
AuOptional<AuUInt64> uStartTime)
|
||
|
{
|
||
|
if (!pCallback)
|
||
|
{
|
||
|
SysPushErrorArg();
|
||
|
return {};
|
||
|
}
|
||
|
|
||
|
if (!workerPid)
|
||
|
{
|
||
|
workerPid = AuAsync::GetCurrentWorkerPId();
|
||
|
}
|
||
|
|
||
|
if (uPeriodNS < 100)
|
||
|
{
|
||
|
SysPushErrorArg();
|
||
|
return {};
|
||
|
}
|
||
|
|
||
|
if (!uStartTime)
|
||
|
{
|
||
|
uStartTime = AuTime::SteadyClockNS() + uPeriodNS;
|
||
|
}
|
||
|
|
||
|
auto pThreadPool = AuStaticPointerCast<ThreadPool>(workerPid.value().GetPool()).get();
|
||
|
auto pRet = AuMakeShared<AsyncFuncTimer>(pThreadPool,
|
||
|
pCallback,
|
||
|
workerPid.value(),
|
||
|
uStartTime.value(),
|
||
|
uPeriodNS);
|
||
|
if (!pRet)
|
||
|
{
|
||
|
return {};
|
||
|
}
|
||
|
|
||
|
pRet->Dispatch();
|
||
|
return pRet;
|
||
|
}
|
||
|
|
||
|
AUKN_SYM AuSPtr<IAsyncTimer> NewTimer(AuUInt64 uPeriodNS,
|
||
|
const AuSupplierConsumer<bool, AuUInt64, AuUInt64, AuUInt64> &callback,
|
||
|
AuOptional<WorkerPId_t> workerPid,
|
||
|
AuOptional<AuUInt64> uStartTime)
|
||
|
{
|
||
|
return NewTimer(uPeriodNS,
|
||
|
AuMakeSharedThrow<IAsyncTimerCallbackFunctional>(callback),
|
||
|
workerPid,
|
||
|
uStartTime);
|
||
|
}
|
||
|
}
|