1 module des.util.timer;
2 
3 import std.datetime;
4 import core.thread;
5 
6 import des.util.arch;
7 
8 ///
9 class TimeSignal : Signal!(double)
10 {
11 protected:
12     double el=0, tr=0;
13 
14 public:
15 
16     this( double tr )
17     in { assert( tr > 0 ); }
18     body { this.tr = tr; }
19 
20     @property
21     {
22         ///
23         double trigger() const { return tr; }
24         ///
25         double trigger( double v )
26         in { assert( v > 0 ); }
27         body { tr = v; return v; }
28 
29         ///
30         double elapsed() const { return el; }
31     }
32 
33     ///
34     void reset( double initial=0 ) { el = initial; }
35 
36     ///
37     void update( double dt )
38     {  
39         el += dt;
40         if( el < tr ) return;
41         opCall( el );
42         reset( el - tr );
43     }
44 }
45 
46 ///
47 class Timer : DesObject
48 {
49     mixin DES;
50 
51     ///
52     StopWatch sw;
53     ///
54     double time=0;
55     ///
56     double all_time=0;
57     ///
58     size_t cbindex=0;
59 
60     TimeSignal[] signals;
61 
62     ///
63     this() { sw.start(); }
64 
65     ///
66     TimeSignal signalEvery( double trigger )
67     {
68         auto s = newEMM!TimeSignal( trigger );
69         signals ~= s;
70         return s;
71     }
72 
73     ///
74     double reset()
75     {
76         auto r = time;
77         time = 0;
78         return r;
79     }
80 
81     ///
82     void restart( double s=0 )
83     {
84         cycle();
85         Thread.sleep( dur!"usecs"(cast(ulong)(s*1e6)) );
86     }
87 
88     ///
89     double hardReset()
90     {
91         auto r = all_time;
92         all_time = 0;
93         reset();
94         foreach( s; signals ) s.reset();
95         return r;
96     }
97 
98     ///
99     double cycle()
100     {
101         sw.stop();
102         auto dt = sw.peek().to!("seconds",double);
103         sw.reset();
104         sw.start();
105         time += dt;
106         all_time += dt;
107         foreach( s; signals )
108             s.update( dt );
109         return dt;
110     }
111 }