-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathFrameTimer.hpp
More file actions
108 lines (86 loc) · 3.13 KB
/
Copy pathFrameTimer.hpp
File metadata and controls
108 lines (86 loc) · 3.13 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
#pragma once
#include "chrono.hpp"
#include "Input.hpp"
namespace lite
{
// Specialized timer for measuring frame length and
// delta time between consecutive frames.
class FrameTimer : public LightSingleton<FrameTimer>
{
private: // data
float actualDeltaTime = 1.0f / 60.0f;
float deltaTime = 1.0f / 60.0f;
float frameLength = 1.0f / 60.0f;
float idealFramerate = 60;
bool lockFramerate = true;
bool stepMode = false;
high_resolution_timer timer;
float totalTime = 0;
public: // properties
// Actual time between the BeginFrame() calls for this frame and the last.
const float& ActualDeltaTime() const { return actualDeltaTime; }
// Time between frames used for updating systems and game logic.
const float& DeltaTime() const { return deltaTime; }
// Returns the current FPS.
float FPS() const { return 1.0f / frameLength; }
// Time between BeginFrame() and EndFrame() calls for a frame.
const float& FrameLength() const { return frameLength; }
// The ideal delta time between frames.
float IdealDeltaTime() const { return 1.0f / idealFramerate; }
// What the ideal fps is. (used for locking the framerate)
const float& IdealFramerate() const { return idealFramerate; }
void IdealFramerate(float value) { idealFramerate = value; }
// Whether the framerate should be locked on EndFrame.
const bool& LockFramerate() const { return lockFramerate; }
void LockFramerate(bool value) { lockFramerate = value; }
// Total accumulated time since the timer started.
const float& TotalTime() const { return totalTime; }
public: // methods
// Called at the start of a frame; saves frame dt.
// Any calls to lock framerate should be made after
// EndFrame() and before BeginFrame().
void BeginFrame()
{
deltaTime = static_cast<float>(timer.elapsed_seconds());
// If we have an extraordinarily slow dt, the user is likely debugging.
static const float debuggerDeltaTime = 1.0f;
if (deltaTime > debuggerDeltaTime)
{
// Debugger has been detected. Use the ideal dt.
deltaTime = 1.0f / idealFramerate;
}
totalTime += deltaTime;
timer.start();
}
// Called at the end of a frame; saves frame length.
// Any calls to lock framerate should be made after
// EndFrame() and before BeginFrame().
void EndFrame()
{
frameLength = static_cast<float>(timer.elapsed_seconds());
if (lockFramerate)
{
Lock();
}
}
private: // methods
// Locks the framerate.
void Lock()
{
float frameTime = frameLength;
float idealFrameTime = IdealDeltaTime();
// Sleep while this frame has plenty of time left.
static const float twoMilliseconds = 0.002f;
while (idealFrameTime - frameTime > twoMilliseconds)
{
Sleep(1);
frameTime = static_cast<float>(timer.elapsed_seconds());
}
// Wait for the ideal frame time to lapse.
while (frameTime < idealFrameTime)
{
frameTime = static_cast<float>(timer.elapsed_seconds());
}
}
};
} // namespace lite