mirror of
https://github.com/hajimehoshi/ebiten.git
synced 2025-01-13 20:42:07 +01:00
clock: Refactoring
This commit is contained in:
parent
0b3495b81f
commit
d12a3d4073
@ -261,7 +261,7 @@ func (c *Context) loop() {
|
|||||||
written += int64(n)
|
written += int64(n)
|
||||||
fs := written/int64(bytesPerFrame) - prevWritten/int64(bytesPerFrame)
|
fs := written/int64(bytesPerFrame) - prevWritten/int64(bytesPerFrame)
|
||||||
for fs > 0 {
|
for fs > 0 {
|
||||||
clock.ProceedPrimaryTimer()
|
clock.ProceedAudioTimer()
|
||||||
fs--
|
fs--
|
||||||
}
|
}
|
||||||
prevWritten = written
|
prevWritten = written
|
||||||
|
@ -12,6 +12,21 @@
|
|||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// 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
|
package clock
|
||||||
|
|
||||||
import (
|
import (
|
||||||
@ -23,10 +38,11 @@ import (
|
|||||||
const FPS = 60
|
const FPS = 60
|
||||||
|
|
||||||
var (
|
var (
|
||||||
primaryTime int64
|
audioTimeInFrames int64
|
||||||
lastPrimaryTime int64
|
lastAudioTimeInFrames int64
|
||||||
frames int64
|
|
||||||
logicalTime int64
|
frames int64
|
||||||
|
gameTime int64
|
||||||
|
|
||||||
currentFPS float64
|
currentFPS float64
|
||||||
lastFPSUpdated int64
|
lastFPSUpdated int64
|
||||||
@ -50,10 +66,10 @@ func RegisterPing(pingFunc func()) {
|
|||||||
m.Unlock()
|
m.Unlock()
|
||||||
}
|
}
|
||||||
|
|
||||||
// ProceedPrimaryTimer increments the primary time by a frame.
|
// ProceedAudioTimer increments the audio time by a frame.
|
||||||
func ProceedPrimaryTimer() {
|
func ProceedAudioTimer() {
|
||||||
m.Lock()
|
m.Lock()
|
||||||
primaryTime++
|
audioTimeInFrames++
|
||||||
m.Unlock()
|
m.Unlock()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -71,7 +87,7 @@ func updateFPS(now int64) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Update updates the inner clock state and returns an integer value
|
// 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 {
|
func Update() int {
|
||||||
m.Lock()
|
m.Lock()
|
||||||
defer m.Unlock()
|
defer m.Unlock()
|
||||||
@ -82,49 +98,35 @@ func Update() int {
|
|||||||
ping()
|
ping()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initialize logicalTime if needed.
|
// Initialize gameTime if needed.
|
||||||
if logicalTime == 0 {
|
if gameTime == 0 {
|
||||||
logicalTime = n
|
gameTime = n
|
||||||
}
|
}
|
||||||
|
|
||||||
t := n - logicalTime
|
t := n - gameTime
|
||||||
if t < 0 {
|
if t < 0 {
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
count := 0
|
count := 0
|
||||||
|
|
||||||
// Logical clock:
|
syncWithSystemClock := false
|
||||||
// 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.
|
|
||||||
|
|
||||||
// When sync is true, the logical time is forced to sync with the system clock.
|
if audioTimeInFrames > 0 && lastAudioTimeInFrames != audioTimeInFrames {
|
||||||
sync := false
|
// If the audio clock is updated, use this.
|
||||||
|
if frames < audioTimeInFrames {
|
||||||
if primaryTime > 0 && lastPrimaryTime != primaryTime {
|
count = int(audioTimeInFrames - frames)
|
||||||
// If the primary clock is updated, use this.
|
|
||||||
if frames < primaryTime {
|
|
||||||
count = int(primaryTime - frames)
|
|
||||||
}
|
}
|
||||||
lastPrimaryTime = primaryTime
|
lastAudioTimeInFrames = audioTimeInFrames
|
||||||
sync = true
|
syncWithSystemClock = true
|
||||||
} else {
|
} else {
|
||||||
// Use system clock when
|
// Use system clock when the audio clock is not updated yet.
|
||||||
// 1) Inc() is not called, or
|
// As the audio clock can be updated discountinuously, the system clock is still needed.
|
||||||
// 2) the primary clock is not updated yet.
|
|
||||||
// As the primary clock can be updated discountinuously, the system clock is still needed.
|
|
||||||
|
|
||||||
if t > 5*int64(time.Second)/FPS {
|
if t > 5*int64(time.Second)/FPS {
|
||||||
// The previous time is too old.
|
// The previous time is too old.
|
||||||
// Let's force to sync the logical time with the OS clock.
|
// Let's force to sync the game time with the system clock.
|
||||||
sync = true
|
syncWithSystemClock = true
|
||||||
} else {
|
} else {
|
||||||
count = int(t * FPS / int64(time.Second))
|
count = int(t * FPS / int64(time.Second))
|
||||||
}
|
}
|
||||||
@ -142,10 +144,10 @@ func Update() int {
|
|||||||
}
|
}
|
||||||
|
|
||||||
frames += int64(count)
|
frames += int64(count)
|
||||||
if sync {
|
if syncWithSystemClock {
|
||||||
logicalTime = n
|
gameTime = n
|
||||||
} else {
|
} else {
|
||||||
logicalTime += int64(count) * int64(time.Second) / FPS
|
gameTime += int64(count) * int64(time.Second) / FPS
|
||||||
}
|
}
|
||||||
|
|
||||||
updateFPS(n)
|
updateFPS(n)
|
||||||
|
Loading…
Reference in New Issue
Block a user