mirror of
https://github.com/hajimehoshi/ebiten.git
synced 2024-12-24 18:58:54 +01:00
clock: Refactoring
This commit is contained in:
parent
e98475cf9d
commit
2e7a477f9d
@ -262,7 +262,7 @@ func (c *Context) loop() {
|
|||||||
c.pingCount--
|
c.pingCount--
|
||||||
c.m.Unlock()
|
c.m.Unlock()
|
||||||
c.frames++
|
c.frames++
|
||||||
clock.Inc()
|
clock.ProceedPrimaryTimer()
|
||||||
bytesPerFrame := c.sampleRate * bytesPerSample * channelNum / loop.FPS
|
bytesPerFrame := c.sampleRate * bytesPerSample * channelNum / loop.FPS
|
||||||
l := (c.frames * int64(bytesPerFrame)) - c.writtenBytes
|
l := (c.frames * int64(bytesPerFrame)) - c.writtenBytes
|
||||||
l &= mask
|
l &= mask
|
||||||
|
@ -21,50 +21,73 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
m sync.Mutex
|
m sync.Mutex
|
||||||
tick int64
|
primaryTime int64
|
||||||
lastTick int64
|
lastPrimaryTime int64
|
||||||
frames int64
|
frames int64
|
||||||
|
logicalTime int64
|
||||||
)
|
)
|
||||||
|
|
||||||
func Inc() {
|
// ProceedPrimaryTimer increments the primary time by a frame.
|
||||||
|
func ProceedPrimaryTimer() {
|
||||||
m.Lock()
|
m.Lock()
|
||||||
tick++
|
primaryTime++
|
||||||
m.Unlock()
|
m.Unlock()
|
||||||
}
|
}
|
||||||
|
|
||||||
func Frames(timeDuration time.Duration, fps int) (int, bool) {
|
// Frames returns an integer value indicating how many logical frames the game should update.
|
||||||
|
//
|
||||||
|
// Frames also updates the inner timer states.
|
||||||
|
func Frames(now int64, fps int) int {
|
||||||
m.Lock()
|
m.Lock()
|
||||||
defer m.Unlock()
|
defer m.Unlock()
|
||||||
|
|
||||||
|
// Initialize logicalTime if needed.
|
||||||
|
if logicalTime == 0 {
|
||||||
|
logicalTime = now
|
||||||
|
}
|
||||||
|
|
||||||
|
t := now - logicalTime
|
||||||
|
if t < 0 {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
count := 0
|
count := 0
|
||||||
|
|
||||||
|
// There are two time lines: one is the logical time and the other is the system clock.
|
||||||
|
//
|
||||||
|
// Usually logical time is updated based on the number of frames, but
|
||||||
|
// when sync is true, the logical time is forced to sync with the system clock.
|
||||||
sync := false
|
sync := false
|
||||||
if tick > 0 && lastTick != tick {
|
|
||||||
if frames < tick {
|
if primaryTime > 0 && lastPrimaryTime != primaryTime {
|
||||||
count = int(tick - frames)
|
// If the primary time is updated, use this.
|
||||||
|
if frames < primaryTime {
|
||||||
|
count = int(primaryTime - frames)
|
||||||
}
|
}
|
||||||
lastTick = tick
|
lastPrimaryTime = primaryTime
|
||||||
sync = true
|
sync = true
|
||||||
} else {
|
} else {
|
||||||
// Use system clock when
|
// Use system clock when
|
||||||
// 1) Inc() is not called, or
|
// 1) Inc() is not called, or
|
||||||
// 2) tick is not updated yet.
|
// 2) the primary time is not updated yet.
|
||||||
// As tick can be updated discountinuously, use system clock supplementarily.
|
// As the primary time can be updated discountinuously,
|
||||||
|
// the system clock is still needed.
|
||||||
|
|
||||||
if int64(timeDuration) > 5*int64(time.Second)/int64(fps) {
|
if t > 5*int64(time.Second)/int64(fps) {
|
||||||
// The previous time is too old.
|
// The previous time is too old.
|
||||||
// Let's force to sync the logical frame with the OS clock (or tick).
|
// Let's force to sync the logical time with the OS clock.
|
||||||
return 0, true
|
sync = true
|
||||||
|
} else {
|
||||||
|
count = int(t * int64(fps) / int64(time.Second))
|
||||||
}
|
}
|
||||||
count = int(int64(timeDuration) * int64(fps) / int64(time.Second))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Stabilize FPS.
|
// Stabilize FPS.
|
||||||
if count == 0 && (int64(time.Second)/int64(fps)/2) < int64(timeDuration) {
|
if count == 0 && (int64(time.Second)/int64(fps)/2) < t {
|
||||||
count = 1
|
count = 1
|
||||||
}
|
}
|
||||||
if count == 2 && (int64(time.Second)/int64(fps)*3/2) > int64(timeDuration) {
|
if count == 2 && (int64(time.Second)/int64(fps)*3/2) > t {
|
||||||
count = 1
|
count = 1
|
||||||
}
|
}
|
||||||
if count > 3 {
|
if count > 3 {
|
||||||
@ -72,5 +95,10 @@ func Frames(timeDuration time.Duration, fps int) (int, bool) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
frames += int64(count)
|
frames += int64(count)
|
||||||
return count, sync
|
if sync {
|
||||||
|
logicalTime = now
|
||||||
|
} else {
|
||||||
|
logicalTime += int64(count) * int64(time.Second) / int64(fps)
|
||||||
|
}
|
||||||
|
return count
|
||||||
}
|
}
|
||||||
|
@ -35,7 +35,6 @@ type runContext struct {
|
|||||||
currentFPS float64
|
currentFPS float64
|
||||||
runningSlowly bool
|
runningSlowly bool
|
||||||
framesForFPS int64
|
framesForFPS int64
|
||||||
lastUpdated int64
|
|
||||||
lastFPSUpdated int64
|
lastFPSUpdated int64
|
||||||
ping func()
|
ping func()
|
||||||
m sync.RWMutex
|
m sync.RWMutex
|
||||||
@ -67,7 +66,6 @@ func Start() error {
|
|||||||
theRunContext = &runContext{}
|
theRunContext = &runContext{}
|
||||||
|
|
||||||
n := now()
|
n := now()
|
||||||
theRunContext.lastUpdated = n
|
|
||||||
theRunContext.lastFPSUpdated = n
|
theRunContext.lastFPSUpdated = n
|
||||||
|
|
||||||
close(contextInitCh)
|
close(contextInitCh)
|
||||||
@ -78,23 +76,6 @@ func End() {
|
|||||||
theRunContext = nil
|
theRunContext = nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *runContext) updateCount(now int64) int {
|
|
||||||
t := now - c.lastUpdated
|
|
||||||
if t < 0 {
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
count, sync := clock.Frames(time.Duration(t), FPS)
|
|
||||||
|
|
||||||
if sync {
|
|
||||||
c.lastUpdated = now
|
|
||||||
} else {
|
|
||||||
c.lastUpdated += int64(count) * int64(time.Second) / int64(FPS)
|
|
||||||
}
|
|
||||||
|
|
||||||
return count
|
|
||||||
}
|
|
||||||
|
|
||||||
func RegisterPing(ping func()) {
|
func RegisterPing(ping func()) {
|
||||||
<-contextInitCh
|
<-contextInitCh
|
||||||
theRunContext.registerPing(ping)
|
theRunContext.registerPing(ping)
|
||||||
@ -124,7 +105,7 @@ func (c *runContext) update(u Updater) error {
|
|||||||
}
|
}
|
||||||
c.m.Unlock()
|
c.m.Unlock()
|
||||||
|
|
||||||
count := c.updateCount(n)
|
count := clock.Frames(n, FPS)
|
||||||
if err := u.Update(count); err != nil {
|
if err := u.Update(count); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user