1 /*
2     DSDL
3     Copyright (C) 2025 Inochi2D Project <luna@foxgirls.gay>
4 
5     This software is provided 'as-is', without any express or implied
6     warranty.  In no event will the authors be held liable for any damages
7     arising from the use of this software.
8 
9     Permission is granted to anyone to use this software for any purpose,
10     including commercial applications, and to alter it and redistribute it
11     freely, subject to the following restrictions:
12 
13     1. The origin of this software must not be misrepresented; you must not
14         claim that you wrote the original software. If you use this software
15         in a product, an acknowledgment in the product documentation would be
16         appreciated but is not required.
17     2. Altered source versions must be plainly marked as such, and must not be
18         misrepresented as being the original software.
19     3. This notice may not be removed or altered from any source distribution.
20 
21     ==========================================================================
22 
23     Simple DirectMedia Layer
24     Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
25 
26     This software is provided 'as-is', without any express or implied
27     warranty.  In no event will the authors be held liable for any damages
28     arising from the use of this software.
29 
30     Permission is granted to anyone to use this software for any purpose,
31     including commercial applications, and to alter it and redistribute it
32     freely, subject to the following restrictions:
33 
34     1. The origin of this software must not be misrepresented; you must not
35         claim that you wrote the original software. If you use this software
36         in a product, an acknowledgment in the product documentation would be
37         appreciated but is not required.
38     2. Altered source versions must be plainly marked as such, and must not be
39         misrepresented as being the original software.
40     3. This notice may not be removed or altered from any source distribution.
41 */
42 
43 /**
44     SDL Timer
45 
46     See_Also:
47         $(LINK2 https://wiki.libsdl.org/SDL3/CategoryTimer, SDL3 Timer Documentation)
48     
49     Copyright: © 2025 Inochi2D Project, © 1997-2025 Sam Lantinga
50     License: Subject to the terms of the Zlib License, as written in the LICENSE file.
51     Authors: 
52         Luna Nielsen
53 */
54 module sdl.timer;
55 
56 extern(C) nothrow @nogc:
57 
58 /**
59     Number of milliseconds in a second.
60 
61     This is always 1000.
62 */
63 enum SDL_MS_PER_SECOND = 1000;
64 
65 /**
66     Number of microseconds in a second.
67 
68     This is always 1000000.
69 */
70 enum SDL_US_PER_SECOND = 1000000;
71 
72 /**
73     Number of nanoseconds in a second.
74 
75     This is always 1000000000.
76 */
77 enum SDL_NS_PER_SECOND = 1000000000L;
78 
79 /**
80     Number of nanoseconds in a millisecond.
81 
82     This is always 1000000.
83 */
84 enum SDL_NS_PER_MS = 1000000;
85 
86 /**
87     Number of nanoseconds in a microsecond.
88 
89     This is always 1000.
90 */
91 enum SDL_NS_PER_US = 1000;
92 
93 
94 /**
95     Get the number of milliseconds that have elapsed since the SDL library
96     initialization.
97 
98     Returns:
99         An unsigned 64‑bit integer that represents the number of
100         milliseconds that have elapsed since the SDL library was
101         initialized (typically via a call to SDL_Init).
102 
103     Threadsafety:
104         It is safe to call this function from any thread.
105 */
106 extern ulong SDL_GetTicks();
107 
108 /**
109     Get the number of nanoseconds since SDL library initialization.
110 
111     Returns:
112         An unsigned 64-bit value representing the number of nanoseconds
113         since the SDL library initialized.
114 
115     Threadsafety:
116         It is safe to call this function from any thread. 
117 */
118 extern ulong SDL_GetTicksNS();
119 
120 /**
121     Get the current value of the high resolution counter.
122 
123     This function is typically used for profiling.
124 
125     The counter values are only meaningful relative to each other. Differences
126     between values can be converted to times by using
127     SDL_GetPerformanceFrequency().
128 
129     Returns:
130         The current counter value.
131 
132     Threadsafety:
133         It is safe to call this function from any thread.
134 
135     See_Also:
136         $(D SDL_GetPerformanceFrequency)
137 */
138 extern ulong SDL_GetPerformanceCounter();
139 
140 /**
141     Get the count per second of the high resolution counter.
142 
143     Returns:
144         A platform-specific count per second.
145 
146     Threadsafety:
147         It is safe to call this function from any thread.
148 
149     See_Also:
150     $(D SDL_GetPerformanceCounter)
151 */
152 extern ulong SDL_GetPerformanceFrequency();
153 
154 /**
155     Wait a specified number of milliseconds before returning.
156 
157     This function waits a specified number of milliseconds before returning. It
158     waits at least the specified time, but possibly longer due to OS
159     scheduling.
160 
161     Params:
162         ms = The number of milliseconds to delay.
163 
164     Threadsafety:
165         It is safe to call this function from any thread.
166 
167     See_Also:
168         $(D SDL_DelayNS)
169         $(D SDL_DelayPrecise)
170 */
171 extern void SDL_Delay(uint ms);
172 
173 /**
174     Wait a specified number of nanoseconds before returning.
175 
176     This function waits a specified number of nanoseconds before returning. It
177     waits at least the specified time, but possibly longer due to OS
178     scheduling.
179 
180     Params:
181         ns = The number of nanoseconds to delay.
182 
183     Threadsafety:
184         It is safe to call this function from any thread.
185 
186     See_Also:
187         $(D SDL_Delay)
188         $(D SDL_DelayPrecise)
189 */
190 extern void SDL_DelayNS(ulong ns);
191 
192 /**
193     Wait a specified number of nanoseconds before returning.
194 
195     This function waits a specified number of nanoseconds before returning. It
196     will attempt to wait as close to the requested time as possible, busy
197     waiting if necessary, but could return later due to OS scheduling.
198 
199     Params:
200         ns = The number of nanoseconds to delay.
201 
202     Threadsafety:
203         It is safe to call this function from any thread.
204 
205     See_Also:
206         $(D SDL_Delay)
207         $(D SDL_DelayNS)
208 */
209 extern void SDL_DelayPrecise(ulong ns);
210 
211 /**
212     Definition of the timer ID type.
213 */
214 alias SDL_TimerID = uint;
215 
216 /**
217     Function prototype for the millisecond timer callback function.
218 
219     The callback function is passed the current timer interval and returns the
220     next timer interval, in milliseconds. If the returned value is the same as
221     the one passed in, the periodic alarm continues, otherwise a new alarm is
222     scheduled. If the callback returns 0, the periodic alarm is canceled and
223     will be removed.
224 
225     Params:
226         userdata =  An arbitrary pointer provided by the app through 
227                     SDL_AddTimer, for its own use.
228         timerID =   the current timer being processed.
229         interval =  the current callback time interval.
230     
231     Returns:
232         The new callback time interval, or 0 to disable further runs of
233         the callback.
234 
235     Threadsafety:
236         SDL may call this callback at any time from a background
237         thread; the application is responsible for locking resources
238         the callback touches that need to be protected.
239 
240     See_Also:
241         $(D SDL_AddTimer)
242  */
243 alias SDL_TimerCallback = uint function(void* userdata, SDL_TimerID timerID, uint interval);
244 
245 /**
246     Call a callback function at a future time.
247 
248     The callback function is passed the current timer interval and the user
249     supplied parameter from the SDL_AddTimer() call and should return the next
250     timer interval. If the value returned from the callback is 0, the timer is
251     canceled and will be removed.
252 
253     The callback is run on a separate thread, and for short timeouts can
254     potentially be called before this function returns.
255 
256     Timers take into account the amount of time it took to execute the
257     callback. For example, if the callback took 250 ms to execute and returned
258     1000 (ms), the timer would only wait another 750 ms before its next
259     iteration.
260 
261     Timing may be inexact due to OS scheduling. Be sure to note the current
262     time with SDL_GetTicksNS() or SDL_GetPerformanceCounter() in case your
263     callback needs to adjust for variances.
264 
265     Params:
266         interval =  the timer delay, in milliseconds, passed to `callback`.
267         callback =  the SDL_TimerCallback function to call when the specified 
268                     `interval` elapses.
269         userdata =  a pointer that is passed to `callback`.
270     
271     Returns:
272         A timer ID or 0 on failure; call SDL_GetError() for more
273         information.
274 
275     Threadsafety:
276         It is safe to call this function from any thread.
277 
278     See_Also:
279         $(D SDL_AddTimerNS)
280         $(D SDL_RemoveTimer)
281 */
282 extern SDL_TimerID SDL_AddTimer(uint interval, SDL_TimerCallback callback, void *userdata);
283 
284 /**
285     Function prototype for the nanosecond timer callback function.
286 
287     The callback function is passed the current timer interval and returns the
288     next timer interval, in nanoseconds. If the returned value is the same as
289     the one passed in, the periodic alarm continues, otherwise a new alarm is
290     scheduled. If the callback returns 0, the periodic alarm is canceled and
291     will be removed.
292 
293     Params:
294         userdata =  An arbitrary pointer provided by the app through 
295                     SDL_AddTimer, for its own use.
296         timerID =   The current timer being processed.
297         interval =  The current callback time interval.
298     
299     Returns:
300         The new callback time interval, or 0 to disable further runs of
301         the callback.
302 
303     Threadsafety:
304         SDL may call this callback at any time from a background
305         thread; the application is responsible for locking resources
306         the callback touches that need to be protected.
307 
308     See_Also:
309         $(D SDL_AddTimerNS)
310 */
311 alias SDL_NSTimerCallback = extern(C) ulong function(void* userdata, SDL_TimerID timerID, ulong interval);
312 
313 /**
314     Call a callback function at a future time.
315 
316     The callback function is passed the current timer interval and the user
317     supplied parameter from the SDL_AddTimerNS() call and should return the
318     next timer interval. If the value returned from the callback is 0, the
319     timer is canceled and will be removed.
320 
321     The callback is run on a separate thread, and for short timeouts can
322     potentially be called before this function returns.
323 
324     Timers take into account the amount of time it took to execute the
325     callback. For example, if the callback took 250 ns to execute and returned
326     1000 (ns), the timer would only wait another 750 ns before its next
327     iteration.
328 
329     Timing may be inexact due to OS scheduling. Be sure to note the current
330     time with SDL_GetTicksNS() or SDL_GetPerformanceCounter() in case your
331     callback needs to adjust for variances.
332 
333     Params:
334         interval =  The timer delay, in nanoseconds, passed to `callback`.
335         callback =  The SDL_TimerCallback function to call when the specified 
336                     `interval` elapses.
337         userdata =  A pointer that is passed to `callback`.
338     
339     Returns:
340         A timer ID or 0 on failure; call SDL_GetError() for more
341         information.
342 
343     Threadsafety:
344         It is safe to call this function from any thread.
345 
346     See_Also:
347         $(D SDL_AddTimer)
348         $(D SDL_RemoveTimer)
349 */
350 extern SDL_TimerID SDL_AddTimerNS(ulong interval, SDL_NSTimerCallback callback, void *userdata);
351 
352 /**
353     Remove a timer created with SDL_AddTimer().
354 
355     Params:
356         id = The ID of the timer to remove.
357     
358     Returns:
359         $(D true) on success or $(D false) on failure; 
360         call $(D SDL_GetError) for more information.
361 
362     Threadsafety:
363         It is safe to call this function from any thread.
364 
365     See_Also:
366         $(D SDL_AddTimer)
367 */
368 extern bool SDL_RemoveTimer(SDL_TimerID id);