1 /** 2 * Defines the static Time class, which manages all game time related things. 3 */ 4 module dash.utility.time; 5 import dash.utility; 6 7 import std.datetime; 8 9 /** 10 * Converts a duration to a float of seconds. 11 * 12 * Params: 13 * dur = The duration to convert. 14 * 15 * Returns: The duration in seconds. 16 */ 17 float toSeconds( Duration dur ) 18 { 19 return cast(float)dur.total!"hnsecs" / cast(float)1.convert!( "seconds", "hnsecs" ); 20 } 21 22 TimeManager Time; 23 24 static this() 25 { 26 Time = new TimeManager; 27 } 28 29 /** 30 * Manages time and delta time. 31 */ 32 final class TimeManager 33 { 34 private: 35 Duration delta; 36 Duration total; 37 38 public: 39 /** 40 * Time since last frame in seconds. 41 */ 42 @property float deltaTime() { return delta.toSeconds; } 43 /** 44 * Total time spent running in seconds. 45 */ 46 @property float totalTime() { return total.toSeconds; } 47 48 /** 49 * Update the times. Only call once per frame! 50 */ 51 void update() 52 { 53 assert( onMainThread, "Must call Time.update from main thread." ); 54 55 updateTime(); 56 57 import dash.core.dgame: DGame; 58 DGame.instance.editor.send( "dash:perf:frametime", deltaTime ); 59 } 60 61 private: 62 this() 63 { 64 delta = total = Duration.zero; 65 } 66 } 67 68 private: 69 StopWatch sw; 70 TickDuration cur; 71 TickDuration prev; 72 Duration delta; 73 Duration total; 74 Duration second; 75 int frameCount; 76 77 /** 78 * Initialize the time controller with initial values. 79 */ 80 static this() 81 { 82 cur = prev = TickDuration.min; 83 total = delta = second = Duration.zero; 84 frameCount = 0; 85 } 86 87 /** 88 * Thread local time update. 89 */ 90 void updateTime() 91 { 92 if( !sw.running ) 93 { 94 sw.start(); 95 cur = prev = sw.peek(); 96 } 97 98 delta = cast(Duration)( cur - prev ); 99 100 prev = cur; 101 cur = sw.peek(); 102 103 // Pass to values 104 Time.total = cast(Duration)cur; 105 Time.delta = delta; 106 107 // Update framerate 108 ++frameCount; 109 second += delta; 110 if( second >= 1.seconds ) 111 { 112 tracef( "Framerate: %d", frameCount ); 113 second = Duration.zero; 114 frameCount = 0; 115 } 116 }