1 module gfm.sdl2.timer;
2 
3 import core.stdc.stdlib;
4 
5 import derelict.sdl2.sdl;
6 
7 import gfm.sdl2.sdl;
8 
9 /// SDL Timer wrapper.
10 class SDL2Timer
11 {
12     public
13     {
14         /// Create a new SDL timer.
15         /// See_also: $(LINK https://wiki.libsdl.org/SDL_AddTimer)
16         /// Throws: $(D SDL2Exception) on error.
17         this(SDL2 sdl2, uint intervalMs)
18         {
19             _id = SDL_AddTimer(intervalMs, &timerCallbackSDL, cast(void*)this);
20             if (_id == 0)
21                 sdl2.throwSDL2Exception("SDL_AddTimer");
22         }
23 
24         ///
25         ~this()
26         {
27             close();
28         }
29 
30         /// Returns: Timer ID.
31         SDL_TimerID id() pure const nothrow @nogc
32         {
33             return _id;
34         }
35 
36         /// Timer clean-up.
37         /// See_also: $(LINK https://wiki.libsdl.org/SDL_RemoveTimer)
38         void close()
39         {
40             SDL_RemoveTimer(_id);
41         }
42     }
43 
44     protected
45     {
46         /// Override this to implement a SDL timer.
47         abstract uint onTimer(uint interval) nothrow;
48     }
49 
50     private
51     {
52         SDL_TimerID _id;
53     }
54 }
55 
56 extern(C) private nothrow
57 {
58     uint timerCallbackSDL(uint interval, void* param)
59     {
60         try
61         {
62             SDL2Timer timer = cast(SDL2Timer)param;
63             return timer.onTimer(interval);
64         }
65         catch (Throwable e)
66         {
67             // No Throwable is supposed to cross C callbacks boundaries
68             // Crash immediately
69             exit(-1);
70             return 0;
71         }
72     }
73 }