1 module gfm.sdl2.framecounter; 2 3 import std..string; 4 5 import derelict.sdl2.sdl; 6 7 import gfm.core.queue, 8 gfm.sdl2.sdl; 9 10 /// Utility class which gives time delta between frames, and 11 /// logs some framerate statistics. 12 /// Useful for a variable timestep application. 13 deprecated("FrameCounter is deprecated, it always felt out of place here." 14 " Use the tharsis-prof package or a stand-alone frame profiler instead.") 15 final class FrameCounter 16 { 17 public 18 { 19 /// Creates a FrameCounter, SDL must be initialized. 20 this(SDL2 sdl) 21 { 22 _sdl = sdl; 23 _firstFrame = true; 24 _elapsedTime = 0; 25 _frameTimes = new RingBuffer!ulong(10); 26 } 27 28 /// Marks the beginning of a new frame. 29 /// Returns: Current time difference since last frame, in milliseconds. 30 ulong tickMs() 31 { 32 if (_firstFrame) 33 { 34 _lastTime = SDL_GetTicks(); 35 _firstFrame = false; 36 _frameTimes.pushBack(0); 37 return 0; // no advance for first frame 38 } 39 else 40 { 41 uint now = SDL_GetTicks(); 42 uint delta = now - _lastTime; 43 _elapsedTime += delta; 44 _lastTime = now; 45 _frameTimes.pushBack(delta); 46 return delta; 47 } 48 } 49 50 /// Marks the beginning of a new frame. 51 /// Returns: Current time difference since last frame, in seconds. 52 deprecated alias tick = tickSecs; 53 double tickSecs() 54 { 55 return tickMs() * 0.001; 56 } 57 58 /// Returns: Elapsed time since creation, in milliseconds. 59 ulong elapsedTimeMs() const 60 { 61 return _elapsedTime; 62 } 63 64 /// Returns: Elapsed time since creation, in seconds. 65 double elapsedTime() const 66 { 67 return _elapsedTime * 0.001; 68 } 69 70 /// Returns: Displayable framerate statistics. 71 string getFPSString() 72 { 73 double sum = 0; 74 double min = double.infinity; 75 double max = -double.infinity; 76 foreach(ulong frameTime; _frameTimes[]) 77 { 78 if (frameTime < min) 79 min = frameTime; 80 if (frameTime > max) 81 max = frameTime; 82 sum += frameTime; 83 } 84 85 double avg = sum / cast(double)(_frameTimes[].length); 86 int avgFPS = cast(int)(0.5 + ( avg != 0 ? 1000 / avg : 0 ) ); 87 int avgdt = cast(int)(0.5 + avg); 88 89 return format("FPS: %s dt: avg %sms min %sms max %sms", avgFPS, avgdt, min, max); 90 } 91 } 92 93 private 94 { 95 SDL2 _sdl; 96 RingBuffer!ulong _frameTimes; 97 bool _firstFrame; 98 uint _lastTime; 99 ulong _elapsedTime; 100 } 101 } 102