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 dguihub.timer;
10 
11 import dguihub.core.interfaces.idisposable;
12 import dguihub.core.winapi;
13 import dguihub.core.events.event;
14 import dguihub.core.events.eventargs;
15 import dguihub.core.exception;
16 
17 final class Timer : IDisposable {
18    private alias Timer[uint] timerMap;
19 
20    public Event!(Timer, EventArgs) tick;
21 
22    private static timerMap _timers;
23    private uint _timerId = 0;
24    private uint _time = 0;
25 
26    public ~this() {
27       this.dispose();
28    }
29 
30    extern (Windows) private static void timerProc(HWND hwnd, uint msg, uint idEvent, uint t) {
31       if (idEvent in _timers) {
32          _timers[idEvent].onTick(EventArgs.empty);
33       } else {
34          throwException!(Win32Exception)("Unknown Timer: '%08X'", idEvent);
35       }
36    }
37 
38    public void dispose() {
39       if (this._timerId) {
40          if (!KillTimer(null, this._timerId)) {
41             throwException!(Win32Exception)("Cannot Dispose Timer");
42          }
43 
44          _timers.remove(this._timerId);
45          this._timerId = 0;
46       }
47    }
48 
49    @property public uint time() {
50       return this._time;
51    }
52 
53    @property public void time(uint t) {
54       this._time = t >= 0 ? t : t * (-1); //Take the absolute value.
55    }
56 
57    public void start() {
58       if (!this._timerId) {
59          this._timerId = SetTimer(null, 0, this._time, cast(TIMERPROC) /*FIXME may throw*/ &Timer
60                .timerProc);
61 
62          if (!this._timerId) {
63             throwException!(Win32Exception)("Cannot Start Timer");
64          }
65 
66          this._timers[this._timerId] = this;
67       }
68    }
69 
70    public void stop() {
71       this.dispose();
72    }
73 
74    private void onTick(EventArgs e) {
75       this.tick(this, e);
76    }
77 }