From d12a3d40738f552c80db11ef31e0e92177269ec9 Mon Sep 17 00:00:00 2001 From: Hajime Hoshi Date: Sun, 7 Jan 2018 16:43:01 +0900 Subject: [PATCH] clock: Refactoring --- audio/audio.go | 2 +- internal/clock/clock.go | 82 +++++++++++++++++++++-------------------- 2 files changed, 43 insertions(+), 41 deletions(-) diff --git a/audio/audio.go b/audio/audio.go index 8276b95a1..8c818b0b7 100644 --- a/audio/audio.go +++ b/audio/audio.go @@ -261,7 +261,7 @@ func (c *Context) loop() { written += int64(n) fs := written/int64(bytesPerFrame) - prevWritten/int64(bytesPerFrame) for fs > 0 { - clock.ProceedPrimaryTimer() + clock.ProceedAudioTimer() fs-- } prevWritten = written diff --git a/internal/clock/clock.go b/internal/clock/clock.go index c01a4d0b2..df129507b 100644 --- a/internal/clock/clock.go +++ b/internal/clock/clock.go @@ -12,6 +12,21 @@ // See the License for the specific language governing permissions and // limitations under the License. +// Package clock manages game timers. +// +// There are three types of clocks internally: +// +// System clock: +// A clock offered by the OS. +// +// Audio clock: +// An audio clock that is used in the higher priority over the system clock. +// An audio clock might not exist when the audio is not used. +// +// Game clock: +// A clock representing the actual game progress. +// A game clock is basically updated based on the number of frames. +// A game clock is adjusted by the audio clock when needed. package clock import ( @@ -23,10 +38,11 @@ import ( const FPS = 60 var ( - primaryTime int64 - lastPrimaryTime int64 - frames int64 - logicalTime int64 + audioTimeInFrames int64 + lastAudioTimeInFrames int64 + + frames int64 + gameTime int64 currentFPS float64 lastFPSUpdated int64 @@ -50,10 +66,10 @@ func RegisterPing(pingFunc func()) { m.Unlock() } -// ProceedPrimaryTimer increments the primary time by a frame. -func ProceedPrimaryTimer() { +// ProceedAudioTimer increments the audio time by a frame. +func ProceedAudioTimer() { m.Lock() - primaryTime++ + audioTimeInFrames++ m.Unlock() } @@ -71,7 +87,7 @@ func updateFPS(now int64) { } // Update updates the inner clock state and returns an integer value -// indicating how many logical frames the game should update. +// indicating how many game frames the game should update. func Update() int { m.Lock() defer m.Unlock() @@ -82,49 +98,35 @@ func Update() int { ping() } - // Initialize logicalTime if needed. - if logicalTime == 0 { - logicalTime = n + // Initialize gameTime if needed. + if gameTime == 0 { + gameTime = n } - t := n - logicalTime + t := n - gameTime if t < 0 { return 0 } count := 0 - // Logical clock: - // A clock that updated based on the number of frames. - // - // System clock: - // A clock that offered by the OS. - // - // Primary clock: - // A clock that is used in the higher priority over the system clock. - // Primary time is usually an audio time. - // Primary time might not exist when e.g. audio is not used. + syncWithSystemClock := false - // When sync is true, the logical time is forced to sync with the system clock. - sync := false - - if primaryTime > 0 && lastPrimaryTime != primaryTime { - // If the primary clock is updated, use this. - if frames < primaryTime { - count = int(primaryTime - frames) + if audioTimeInFrames > 0 && lastAudioTimeInFrames != audioTimeInFrames { + // If the audio clock is updated, use this. + if frames < audioTimeInFrames { + count = int(audioTimeInFrames - frames) } - lastPrimaryTime = primaryTime - sync = true + lastAudioTimeInFrames = audioTimeInFrames + syncWithSystemClock = true } else { - // Use system clock when - // 1) Inc() is not called, or - // 2) the primary clock is not updated yet. - // As the primary clock can be updated discountinuously, the system clock is still needed. + // Use system clock when the audio clock is not updated yet. + // As the audio clock can be updated discountinuously, the system clock is still needed. if t > 5*int64(time.Second)/FPS { // The previous time is too old. - // Let's force to sync the logical time with the OS clock. - sync = true + // Let's force to sync the game time with the system clock. + syncWithSystemClock = true } else { count = int(t * FPS / int64(time.Second)) } @@ -142,10 +144,10 @@ func Update() int { } frames += int64(count) - if sync { - logicalTime = n + if syncWithSystemClock { + gameTime = n } else { - logicalTime += int64(count) * int64(time.Second) / FPS + gameTime += int64(count) * int64(time.Second) / FPS } updateFPS(n)