/*** Copyright (C) 2022 J Reece Wilson (a/k/a "Reece"). All rights reserved. File: RateLimiter.hpp Date: 2022-2-8 Author: Reece ***/ #pragma once namespace Aurora::Utility { struct RateLimiter { AuUInt64 nextTriggerTime; AuUInt64 nsTimeStep; inline auline void SetNextStep(AuUInt64 nsTimeStep) { this->nsTimeStep = nsTimeStep; this->nextTriggerTime = nsTimeStep + Aurora::Time::CurrentInternalClockNS(); } inline auline bool CheckExchangePass() { auto cur = this->nextTriggerTime; if (!cur) { return false; } if (cur <= Aurora::Time::CurrentInternalClockNS()) { if (this->nsTimeStep) { return AuAtomicCompareExchange(&this->nextTriggerTime, GetLatch(), cur) == cur; } else { return true; } } return false; } inline auline bool HasPassed() { if (!this->nextTriggerTime) { return false; } if (this->nextTriggerTime <= Aurora::Time::CurrentInternalClockNS()) { return true; } return false; } inline auline void Relatch() { if (this->nsTimeStep) { AuAtomicAdd(&this->nextTriggerTime, GetLatch()); } } private: inline auline AuUInt64 GetLatch() { return this->nextTriggerTime + this->nsTimeStep; } }; };