1 /** DGui project file.
2 
3 Copyright: Trogu Antonio Davide 2011-2013
4 
5 License: $(HTTP boost.org/LICENSE_1_0.txt, Boost License 1.0).
6 
7 Authors: Trogu Antonio Davide
8 */
9 module dgui.timer;
10 
11 import dgui.core.interfaces.idisposable;
12 import dgui.core.winapi;
13 import dgui.core.events.event;
14 import dgui.core.events.eventargs;
15 import dgui.core.exception;
16 
17 final class Timer: IDisposable
18 {
19 	private alias Timer[uint] timerMap;
20 
21 	public Event!(Timer, EventArgs) tick;
22 
23 	private static timerMap _timers;
24 	private uint _timerId = 0;
25 	private uint _time = 0;
26 
27 	public ~this()
28 	{
29 		this.dispose();
30 	}
31 
32 	extern(Windows) private static void timerProc(HWND hwnd, uint msg, uint idEvent, uint t)
33 	{
34 		if(idEvent in _timers)
35 		{
36 			_timers[idEvent].onTick(EventArgs.empty);
37 		}
38 		else
39 		{
40 			throwException!(Win32Exception)("Unknown Timer: '%08X'", idEvent);
41 		}
42 	}
43 
44 	public void dispose()
45 	{
46 		if(this._timerId)
47 		{
48 			if(!KillTimer(null, this._timerId))
49 			{
50 				throwException!(Win32Exception)("Cannot Dispose Timer");
51 			}
52 
53 			_timers.remove(this._timerId);
54 			this._timerId = 0;
55 		}
56 	}
57 
58 	@property public uint time()
59 	{
60 		return this._time;
61 	}
62 
63 	@property public void time(uint t)
64 	{
65 		this._time = t >= 0 ? t : t * (-1); //Take the absolute value.
66 	}
67 
68 	public void start()
69 	{
70 		if(!this._timerId)
71 		{
72 			this._timerId = SetTimer(null, 0, this._time, cast(TIMERPROC) /*FIXME may throw*/ &Timer.timerProc);
73 
74 			if(!this._timerId)
75 			{
76 				throwException!(Win32Exception)("Cannot Start Timer");
77 			}
78 
79 			this._timers[this._timerId] = this;
80 		}
81 	}
82 
83 	public void stop()
84 	{
85 		this.dispose();
86 	}
87 
88 	private void onTick(EventArgs e)
89 	{
90 		this.tick(this, e);
91 	}
92 }