1 module armos.utils.fpscounter;
2 import core.time;
3 import core.thread;
4 import std.conv;
5 
6 class FpsCounter {
7     public{
8         this(in double defaultFps = 60){
9             _timer = MonoTime.currTime;
10             _currentFps = defaultFps;
11             this.targetFps = defaultFps;
12         }
13 
14         void targetFps(in double fps){
15             _targetFps = fps;
16             //convert from fps to nsecs
17             _targetNsecsTime = (1.0/fps*1000000000.0).to!int;
18         }
19 
20         double targetFps()const{
21             return _targetFps;
22         }
23 
24         double currentFps()const{
25             return _currentFps;
26         }
27 
28         void newFrame(){
29             _timer = MonoTime.currTime;
30             _currentFrames++;
31         }
32 
33         ulong currentFrames()const{
34             return _currentFrames;
35         };
36 
37         double fpsUseRate()const{
38             return _fpsUseRate;
39         }
40 
41         void adjust(){
42             immutable MonoTime after = MonoTime.currTime;
43             immutable def = ( after.ticks - _timer.ticks ).ticksToNSecs;
44             if( def < _targetNsecsTime){
45                 Thread.sleep( dur!("nsecs")( _targetNsecsTime - def ) );
46             }
47             immutable after2 = MonoTime.currTime;
48             immutable def2 = ( after2.ticks - _timer.ticks ).ticksToNSecs;
49             _currentFps = 1.0/def2.to!double*1000000000.0;
50             _fpsUseRate = def.to!double/_targetNsecsTime.to!double;
51         }
52     }
53 
54     private{
55         double _targetFps = 60.0;
56         double _currentFps = 60.0;
57         ulong  _currentFrames = 0;
58         int    _targetNsecsTime = 0;
59         double _fpsUseRate = 0;
60         MonoTime _timer;
61 
62     }
63 }
64