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 }