Gondwana Game Engine Development (master) - 2.6.1
Gondwana is a cross-platform 2.5D game and rendering engine written in C#/.NET 8. It provides fine-grained control over rendering, timing, and scene composition, with built-in support for parallax, z-ordering, pixel overhang, collision detection, and particle effects. Gondwana targets desktop and web platforms using SkiaSharp for graphics and pluggable audio backends for desktop and browser targets.
Loading...
Searching...
No Matches
Timer.cs
1using System.Collections.Concurrent;
2
3namespace Gondwana.Timers;
4
15public sealed class Timer : IDisposable
16{
23 public event Action? Tick;
24
28 public TimerType Type { get; }
29
33 public TimerCycles Cycles { get; }
34
38 public long Length { get; }
39
43 public string TimerID { get; internal set; } = string.Empty;
44
48 public bool Paused { get; set; }
49
50 private long _lastEventTick { get; set; }
51 private bool _disposed;
52
53 private Timer(TimerType type, TimerCycles cycles, long startTick, double length)
54 {
55 if (!double.IsFinite(length) || length <= 0)
56 throw new ArgumentOutOfRangeException(
57 nameof(length),
58 length,
59 "Timer length must be finite and greater than zero.");
60
61 double lengthInTicks = length * HighResTimer.TicksPerSecond;
62 if (lengthInTicks < 1 || lengthInTicks >= long.MaxValue)
63 throw new ArgumentOutOfRangeException(
64 nameof(length),
65 length,
66 "Timer length must convert to at least one high-resolution tick and fit in a positive Int64.");
67
68 Type = type;
69 Cycles = cycles;
70 _lastEventTick = startTick;
71 Length = (long)lengthInTicks;
72 Paused = false;
73 }
74
75 internal void RaiseTickEvent() => Tick?.Invoke();
76
98 public void Dispose()
99 {
100 if (_disposed) return;
101 GC.SuppressFinalize(this);
102 _timers.TryRemove(TimerID, out _);
103 Tick = null;
104 _disposed = true;
105 }
106
116 ~Timer() => Dispose();
117
118 #region static members
119
120 private static readonly ConcurrentDictionary<string, Timer> _timers = new();
121
125 public static bool PausedAll { get; set; }
126
137 public static Timer Add(string timerID, TimerType type, TimerCycles cycles, double length)
138 {
139 long startTick = type == TimerType.PreCycle
140 ? EngineSimulationClock.GetCurrentTick()
141 : HighResTimer.GetCurrentTick();
142
143 var timer = new Timer(type, cycles, startTick, length)
144 {
145 TimerID = timerID
146 };
147 _timers[timerID] = timer;
148 return timer;
149 }
150
158 public static Timer Add(TimerType type, TimerCycles cycles, double length)
159 {
160 string timerID = Guid.NewGuid().ToString();
161 return Add(timerID, type, cycles, length);
162 }
163
170 public static void Remove(string timerID)
171 {
172 if (_timers.TryRemove(timerID, out var timer))
173 timer.Dispose();
174 }
175
181 public static Timer Get(string timerID) => _timers[timerID];
182
186 public static int Count => _timers.Count;
187
191 public static string[] TimerIDs => _timers.Keys.ToArray();
192
210 public static void ClearAll()
211 {
212 foreach (var key in _timers.Keys.ToArray())
213 Remove(key);
214 }
215
216 internal static void RaiseTimerEvents(TimerType type, long engineTick)
217 {
218 var expired = new List<string>();
219
220 foreach (var (key, timer) in _timers.ToArray())
221 {
222 // checking this TimerType (i.e., PreCycle or PostCycle)
223 if (timer.Type != type) continue;
224
225 // "push" time forward for Paused Timer instances
226 if (PausedAll || timer.Paused)
227 {
228 timer._lastEventTick += (engineTick - timer._lastEventTick);
229 continue;
230 }
231
232 // check if Timer.Length time has passed
233 while (engineTick - timer._lastEventTick >= timer.Length)
234 {
235 // save the time this event was scheduled to run
236 // might be different from current system tick, but storing this value
237 // will ensure that a lag in repeating timer events does not
238 // accumulate over time
239 timer._lastEventTick += timer.Length;
240 timer.RaiseTickEvent();
241
242 // check for any expired timers
243 if (timer.Cycles == TimerCycles.Once)
244 {
245 expired.Add(key);
246 break;
247 }
248 }
249 }
250
251 foreach (var key in expired)
252 _timers.TryRemove(key, out _);
253 }
254
255 #endregion static members
256}
Represents a high-resolution timer that can trigger events at specified intervals and supports variou...
Definition Timer.cs:16
bool Paused
Gets or sets a value indicating whether the Timer is currently paused.
Definition Timer.cs:48
static void ClearAll()
Removes and disposes all active timers, clearing the entire timer collection.
Definition Timer.cs:210
static Timer Add(TimerType type, TimerCycles cycles, double length)
Creates and adds a new timer with the specified type, cycle count, and duration.
Definition Timer.cs:158
static bool PausedAll
Gets or sets a value indicating whether all operations are globally paused.
Definition Timer.cs:125
string TimerID
Gets the unique identifier for the Timer.
Definition Timer.cs:43
long Length
Gets the length of the current timer interval in seconds.
Definition Timer.cs:38
static string[] TimerIDs
Gets an array of timer identifiers currently managed by the Engine.
Definition Timer.cs:191
static int Count
Gets the total number of active timers.
Definition Timer.cs:186
static Timer Get(string timerID)
Retrieves the Timer instance associated with the specified timer ID.
Action? Tick
Occurs when the timer interval has elapsed.
Definition Timer.cs:23
static void Remove(string timerID)
Removes the timer associated with the specified timer ID and releases its resources.
Definition Timer.cs:170
void Dispose()
Releases all resources used by the Timer and removes it from the collection of active timers.
Definition Timer.cs:98
TimerCycles Cycles
Gets the current timer cycles, representing whether the timer is set to run once or repeatedly.
Definition Timer.cs:33
TimerType Type
Gets the type of the timer, indicating whether it is a pre-cycle or post-cycle timer.
Definition Timer.cs:28
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.
Definition Timer.cs:137
TimerType
Specifies when a Timer should have its Timer.Tick event raised relative to the engine's main update a...
Definition TimerType.cs:22
@ PreCycle
The timer's Timer.Tick event is raised during the background task phase, before the engine performs i...
Definition TimerType.cs:47
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,...