4#include "Stroika/Foundation/StroikaPreComp.h"
10#include "Stroika/Foundation/Containers/Collection.h"
11#include "Stroika/Foundation/Debug/Main.h"
24using namespace Stroika::Foundation::Time;
26using Memory::MakeSharedPtr;
37 sb <<
"Callback: "sv << fCallback;
38 sb <<
", CallNextAt: "sv << fCallNextAt;
39 sb <<
", Frequency: "sv << fFrequency;
40 sb <<
", Hysteresis: "sv << fHysteresis;
52 virtual ~Rep_ () =
default;
56 auto lk = fData_.rwget ();
57 lk->Add (RegisteredTask{intervalTimer, Time::GetTickCount () + when});
60 void AddRepeating (
const TimerCallback& intervalTimer,
const Time::Duration& repeatInterval,
const optional<Time::Duration>& hysteresis)
63 auto lk = fData_.rwget ();
64 lk->Add ({intervalTimer, Time::GetTickCount () + repeatInterval, repeatInterval, hysteresis});
67 void RemoveRepeating (
const TimerCallback& intervalTimer)
noexcept
70 auto lk = fData_.rwget ();
71 RegisteredTaskCollection x = lk.cref ();
72 lk->Remove (intervalTimer);
75 RegisteredTaskCollection GetAllRegisteredTasks ()
const
78 return fData_.load ();
91#if qStroika_Foundation_Debug_AssertionsChecked
92 auto dataLock = fData_.
cget ();
96 for (
const RegisteredTask& i : dataLock.cref ()) {
97 r = min (r, i.fCallNextAt);
99 Assert (r == funResult);
109 Require (Debug::AppearsDuringMainLifetime ());
110 fDataChanged_.WaitUntilQuietly (GetNextWakeupTime_ ());
111 fDataChanged_.Reset ();
118 for (
const RegisteredTask& i : elts2Run) {
119 IgnoreExceptionsExceptThreadAbortForCall (i.fCallback ());
122 now = Time::GetTickCount ();
123 auto rwDataLock = fData_.
rwget ();
124 for (
const RegisteredTask& i : elts2Run) {
125 if (i.fFrequency.has_value ()) {
126 RegisteredTask newE = i;
127 newE.fCallNextAt = now + *i.fFrequency;
129 uniform_real_distribution<> dis{-i.fHysteresis->count (), i.fHysteresis->count ()};
132 rwDataLock->Add (newE);
135 rwDataLock->Remove (i);
142 auto rwThreadLk = fThread_.rwget ();
143 if (fData_.
cget ()->empty ()) {
144 rwThreadLk.store (
nullptr);
147 auto lk = fThread_.rwget ();
148 if (lk.cref () ==
nullptr) {
149 using namespace Execution;
150 lk.store (MakeSharedPtr<Thread::CleanupPtr> (Thread::CleanupPtr::eAbortBeforeWaiting,
151 Thread::New ([
this] () { RunnerLoop_ (); }, Thread::eAutoStart,
"Default-Interval-Timer"sv)));
154 fDataChanged_.Set ();
160IntervalTimer::Manager::DefaultRep::DefaultRep ()
168 fHiddenRep_->AddOneShot (intervalTimer, when);
172 const optional<Time::Duration>& hysteresis)
175 fHiddenRep_->AddRepeating (intervalTimer, repeatInterval, hysteresis);
178void IntervalTimer::Manager::DefaultRep::RemoveRepeating (
const TimerCallback& intervalTimer)
noexcept
181 fHiddenRep_->RemoveRepeating (intervalTimer);
184auto IntervalTimer::Manager::DefaultRep::GetAllRegisteredTasks () const -> RegisteredTaskCollection
187 return fHiddenRep_->GetAllRegisteredTasks ();
195IntervalTimer::Manager::Activator::Activator ()
199 Require (Debug::AppearsDuringMainLifetime ());
200 Manager::sThe = Manager{MakeSharedPtr<IntervalTimer::Manager::DefaultRep> ()};
203IntervalTimer::Manager::Activator::~Activator ()
207 Require (Debug::AppearsDuringMainLifetime ());
217 RunImmediatelyFlag runImmediately,
const optional<Time::Duration>& hysteresis)
218 : fRepeatInterval_{repeatInterval}
219 , fHysteresis_{hysteresis}
220 , fManager_{&manager}
224 if (runImmediately == RunImmediatelyFlag::eRunImmediately) {
225 IgnoreExceptionsExceptThreadAbortForCall (fFunction_ ());
#define RequireNotNull(p)
auto MakeSharedPtr(ARGS_TYPE &&... args) -> shared_ptr< T >
same as make_shared, but if type T has block allocation, then use block allocation for the 'shared pa...
time_point< RealtimeClock, DurationSeconds > TimePointSeconds
TimePointSeconds is a simpler approach to chrono::time_point, which doesn't require using templates e...
constexpr DurationSeconds kInfinity
chrono::duration< double > DurationSeconds
chrono::duration<double> - a time span (length of time) measured in seconds, but high precision.
Similar to String, but intended to more efficiently construct a String. Mutable type (String is large...
String is like std::u32string, except it is much easier to use, often much more space efficient,...
A Collection<T> is a container to manage an un-ordered collection of items, without equality defined ...
nonvirtual void AddRepeating(const TimerCallback &intervalTimer, const Time::Duration &repeatInterval, const optional< Time::Duration > &hysteresis=nullopt)
Add a timer to be called repeatedly after duration repeatInterval.
Function< void()> TimerCallback
Wrap any object with Synchronized<> and it can be used similarly to the base type,...
nonvirtual WritableReference rwget()
get a read-write smart pointer to the underlying Synchronized<> object, holding the full lock the who...
nonvirtual ReadableReference cget() const
get a read-only smart pointer to the underlying Synchronized<> object, holding the readlock the whole...
Duration is a chrono::duration<double> (=.
Iterable<T> is a base class for containers which easily produce an Iterator<T> to traverse them.
Ptr New(const function< void()> &fun2CallOnce, const optional< Characters::String > &name, const optional< Configuration > &configuration)
nonvirtual Characters::String ToString() const