1 /** 2 Copyright: Copyright (c) 2013-2017 Andrey Penechko. 3 License: $(WEB boost.org/LICENSE_1_0.txt, Boost License 1.0). 4 Authors: Andrey Penechko. 5 */ 6 7 module anchovy.fpshelper; 8 9 import core.thread; 10 import anchovy.signal; 11 12 /++ 13 + Helper for measuring frames per second and setting static FPS. 14 + Usually needs to be located as field of game class. 15 +/ 16 struct FpsHelper 17 { 18 Signal!(FpsHelper*) fpsUpdated; 19 20 /// fps will be updated each updateInterval seconds 21 float updateInterval = 0.5; 22 23 /// Stores actual FPS value 24 float fps = 0; 25 26 /// Stores last delta time passed into update() 27 float deltaTime; 28 29 /// Stores amount of updates between 30 size_t fpsTicks; 31 32 /// Accumulates time before reaching update interval 33 float secondsAccumulator = 0; 34 35 bool limitFps = true; 36 37 uint maxFps = 60; 38 39 /// Delta time value will clamped to meet interval [0;timeLimit]. 40 /// This can prevent from value lags when entering hibernation or resizing the window. 41 float timeLimit = 1; 42 43 void update(float dt) 44 { 45 if (dt > timeLimit) 46 { 47 dt = timeLimit; 48 } 49 deltaTime = dt; 50 51 ++fpsTicks; 52 secondsAccumulator += dt; 53 54 if (secondsAccumulator >= updateInterval) 55 { 56 fps = fpsTicks/secondsAccumulator; 57 secondsAccumulator -= updateInterval; 58 fpsTicks = 0; 59 fpsUpdated.emit(&this); 60 } 61 } 62 63 void sleepAfterFrame(float frameTime) 64 { 65 if (limitFps) 66 { 67 uint msecs = cast(uint)((1/cast(float)maxFps - frameTime)*1000); 68 Thread.sleep(dur!"msecs"(msecs>2? msecs - 1: msecs)); 69 } 70 } 71 } 72