1using System.Collections.Concurrent;
15public sealed class Timer : IDisposable
43 public string TimerID {
get;
internal set; } =
string.Empty;
50 private long _lastEventTick {
get;
set; }
51 private bool _disposed;
55 if (!
double.IsFinite(length) || length <= 0)
56 throw new ArgumentOutOfRangeException(
59 "Timer length must be finite and greater than zero.");
61 double lengthInTicks = length * HighResTimer.TicksPerSecond;
62 if (lengthInTicks < 1 || lengthInTicks >=
long.MaxValue)
63 throw new ArgumentOutOfRangeException(
66 "Timer length must convert to at least one high-resolution tick and fit in a positive Int64.");
70 _lastEventTick = startTick;
71 Length = (long)lengthInTicks;
75 internal void RaiseTickEvent() =>
Tick?.Invoke();
100 if (_disposed)
return;
101 GC.SuppressFinalize(
this);
102 _timers.TryRemove(
TimerID, out _);
118 #region static members
120 private static readonly ConcurrentDictionary<string, Timer> _timers =
new();
140 ? EngineSimulationClock.GetCurrentTick()
141 : HighResTimer.GetCurrentTick();
143 var timer =
new Timer(type, cycles, startTick, length)
147 _timers[timerID] = timer;
160 string timerID = Guid.NewGuid().ToString();
161 return Add(timerID, type, cycles, length);
170 public static void Remove(
string timerID)
172 if (_timers.TryRemove(timerID, out var timer))
181 public static Timer
Get(
string timerID) => _timers[timerID];
186 public static int Count => _timers.Count;
191 public static string[]
TimerIDs => _timers.Keys.ToArray();
212 foreach (var key
in _timers.Keys.ToArray())
216 internal static void RaiseTimerEvents(
TimerType type,
long engineTick)
218 var expired =
new List<string>();
220 foreach (var (key, timer) in _timers.ToArray())
223 if (timer.Type != type)
continue;
228 timer._lastEventTick += (engineTick - timer._lastEventTick);
233 while (engineTick - timer._lastEventTick >= timer.Length)
239 timer._lastEventTick += timer.Length;
240 timer.RaiseTickEvent();
251 foreach (var key
in expired)
252 _timers.TryRemove(key, out _);
255 #endregion static members
Represents a high-resolution timer that can trigger events at specified intervals and supports variou...
bool Paused
Gets or sets a value indicating whether the Timer is currently paused.
static void ClearAll()
Removes and disposes all active timers, clearing the entire timer collection.
static Timer Add(TimerType type, TimerCycles cycles, double length)
Creates and adds a new timer with the specified type, cycle count, and duration.
static bool PausedAll
Gets or sets a value indicating whether all operations are globally paused.
string TimerID
Gets the unique identifier for the Timer.
long Length
Gets the length of the current timer interval in seconds.
static string[] TimerIDs
Gets an array of timer identifiers currently managed by the Engine.
static int Count
Gets the total number of active timers.
static Timer Get(string timerID)
Retrieves the Timer instance associated with the specified timer ID.
Action? Tick
Occurs when the timer interval has elapsed.
static void Remove(string timerID)
Removes the timer associated with the specified timer ID and releases its resources.
void Dispose()
Releases all resources used by the Timer and removes it from the collection of active timers.
TimerCycles Cycles
Gets the current timer cycles, representing whether the timer is set to run once or repeatedly.
TimerType Type
Gets the type of the timer, indicating whether it is a pre-cycle or post-cycle timer.
static Timer Add(string timerID, TimerType type, TimerCycles cycles, double length)
Creates a new timer with the specified parameters and adds it to the collection of active timers.
TimerType
Specifies when a Timer should have its Timer.Tick event raised relative to the engine's main update a...
@ PreCycle
The timer's Timer.Tick event is raised during the background task phase, before the engine performs i...
TimerCycles
Specifies the cycle behavior of a Timer, determining whether it executes once or repeatedly at its co...
@ Cycles
Represents the animation cycles state, including sprite animations, frame sequences,...