This repository has been archived by the owner on Aug 21, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 4
/
ticker.go
124 lines (101 loc) · 2.9 KB
/
ticker.go
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
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
package pixelutils
import "time"
type Ticker struct {
frames int
frametime float64
last time.Time
deltat float64
framerate float64
targetFPS *time.Ticker
targetFrametime time.Duration
totalFrames int64
totalFrametime float64
avgFramerate float64
storePrev bool
prevFPS []float32
prevFPSOffset int
}
const (
MAX_PREV_FPS = 500
)
// NewTicker returns a new ticker with the given target fps and 500 stored previous framerates.
func NewTicker(targetFPS int64) *Ticker {
return NewTickerV(targetFPS, MAX_PREV_FPS)
}
// NewTickerV returns a new ticker with the given target fps and a custom amount of stored previous framerates.
// If maxPrevFPS is <= 0, don't store any previous framerates.
func NewTickerV(targetFPS, maxPrevFPS int64) *Ticker {
ticker := &Ticker{
last: time.Now(),
}
ticker.SetTargetFPS(targetFPS)
ticker.storePrev = maxPrevFPS != 0
if ticker.storePrev {
ticker.prevFPS = make([]float32, maxPrevFPS)
}
return ticker
}
// SetTargetFPS sets the target ticker rate; will be less than or equal to target.
func (ticker *Ticker) SetTargetFPS(target int64) {
ticker.targetFrametime = time.Second / time.Duration(target)
if ticker.targetFPS != nil {
ticker.targetFPS.Stop()
}
ticker.targetFPS = time.NewTicker(ticker.targetFrametime)
}
// Tick ticks the tickers and calculates the framerate and framedelta
func (ticker *Ticker) Tick() (deltat, framerate float64) {
ticker.deltat = time.Since(ticker.last).Seconds()
ticker.last = time.Now()
if ticker.frametime >= 1 {
ticker.totalFrames += int64(ticker.frames)
ticker.totalFrametime += ticker.frametime
ticker.frametime = 0
ticker.frames = 0
} else {
ticker.frames++
ticker.frametime += ticker.deltat
}
if ticker.frametime == 0 {
ticker.avgFramerate = float64(ticker.totalFrames) / ticker.totalFrametime
ticker.framerate = ticker.avgFramerate
} else {
ticker.framerate = float64(ticker.frames) / ticker.frametime
}
if ticker.storePrev {
if ticker.prevFPSOffset == MAX_PREV_FPS {
ticker.prevFPSOffset = 0
}
ticker.prevFPS[ticker.prevFPSOffset] = float32(ticker.framerate)
ticker.prevFPSOffset++
}
return ticker.deltat, ticker.framerate
}
// Reset the ticker
func (ticker *Ticker) Reset() {
ticker.last = time.Now()
}
// Wait for the timer to complete its timeout
func (ticker *Ticker) Wait() {
<-ticker.targetFPS.C
}
// Return the last framerate
func (ticker Ticker) Framerate() float64 {
return ticker.framerate
}
// Return the last Deltat
func (ticker Ticker) Deltat() float64 {
return ticker.deltat
}
// Return the average framerate
func (ticker Ticker) AvgFramerate() float64 {
return ticker.avgFramerate
}
// Return the list of previous framerates
func (ticker Ticker) PrevFramerates() []float32 {
return ticker.prevFPS
}
// Return the current target frametime
func (ticker Ticker) TargetFrametime() time.Duration {
return ticker.targetFrametime
}