Skip to content

Instantly share code, notes, and snippets.

@remogatto
Created July 6, 2010 14:34
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save remogatto/465454 to your computer and use it in GitHub Desktop.
Save remogatto/465454 to your computer and use it in GitHub Desktop.
package spectrum
import (
"testing"
"time"
)
const (
second = 1e9
ms = 1e6
)
type FpsCounter struct {
// The channel on which timings are sent from client code
Timings chan<- int64
// Client code receives fps values from this channel
Fps <-chan float
// Same as Timings but the end we use
timings <-chan int64
timeInterval int64
// Same as Fps but the end we use
fps chan<- float
// The ticker that triggers the calculation of average fps
ticker <-chan int64
}
func NewFpsCounter(timeInterval int64) *FpsCounter {
timings := make(chan int64)
fps := make(chan float)
fpsCounter := &FpsCounter{timings, fps, timings, timeInterval, fps, time.Tick(timeInterval)}
var (
sum, numSamples int64
lastFps float
)
// Non-blocking fps stream
go func() {
for {
fpsCounter.fps <- lastFps
}
}()
// Wait for timings and calculate the sum
go func() {
for t := range timings {
sum += t
numSamples++
}
}()
// Calculate average fps and reset variables every tick
go func() {
for {
<-fpsCounter.ticker
if numSamples > 0 {
avgTime := sum / numSamples
lastFps = 1 / (float(avgTime) / second)
}
sum, numSamples = 0, 0
}
}()
return fpsCounter
}
// Helper for TestFpsCounter
func loopFor(timeInterval int64, block func(elapsedTime int64)) {
var elapsedTime int64
startTime := time.Nanoseconds()
for elapsedTime < timeInterval {
block(elapsedTime)
elapsedTime = time.Nanoseconds() - startTime
}
}
func TestFpsCounter(t *testing.T) {
// Collect timings every second
var timeInterval int64 = 1 * second
// Create a new FpsCounter service with the given timeInterval
fpsCounter := NewFpsCounter(timeInterval)
// Simulate a three seconds emulator loop
loopFor(3 * second, func(elapsedTime int64) {
fpsCounter.Timings <- 20 * ms // Send a dummy time of
// 20ms (50 fps)
fps := <-fpsCounter.Fps // Receive fps from the
// FpsCounter service
// After 2 seconds average fps should be 50
if elapsedTime > 2 * second {
if fps != 50 {
t.Errorf("fps should be 50 but got %f", fps)
}
}
})
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment