zworld/engine/frame_counter.go

77 lines
1.3 KiB
Go
Raw Permalink Normal View History

2024-01-14 22:56:06 +08:00
package engine
import (
"time"
"zworld/plugins/math"
)
type framecounter struct {
next int
samples int
last int64
frames []int64
start time.Time
now time.Time
elapsed float32
delta float32
}
func NewFrameCounter(samples int) *framecounter {
return &framecounter{
samples: samples,
last: time.Now().UnixNano(),
frames: make([]int64, 0, samples),
start: time.Now(),
now: time.Now(),
}
}
type Timing struct {
Current float32
Average float32
Max float32
}
func (fc *framecounter) Elapsed() float32 {
return fc.elapsed
}
func (fc *framecounter) Delta() float32 {
return fc.delta
}
func (fc *framecounter) Update() {
// clock
now := time.Now()
fc.delta = float32(now.Sub(fc.now).Seconds())
fc.now = now
fc.elapsed = float32(fc.now.Sub(fc.start).Seconds())
// fps
ft := fc.now.UnixNano()
ns := ft - fc.last
fc.last = ft
if len(fc.frames) < fc.samples {
fc.frames = append(fc.frames, ns)
} else {
fc.frames[fc.next%fc.samples] = ns
}
fc.next++
}
func (fc *framecounter) Sample() Timing {
tot := int64(0)
max := int64(0)
for _, f := range fc.frames {
tot += f
max = math.Max(max, f)
}
current := fc.frames[(fc.next-1)%fc.samples]
return Timing{
Average: float32(tot) / float32(len(fc.frames)) / 1e9,
Max: float32(max) / 1e9,
Current: float32(current) / 1e9,
}
}