mirror of
https://github.com/hajimehoshi/ebiten.git
synced 2024-12-24 02:38:53 +01:00
loop: Refactoring
This commit is contained in:
parent
6640f60c88
commit
218df19ead
@ -23,7 +23,7 @@ import (
|
||||
)
|
||||
|
||||
func CurrentFPS() float64 {
|
||||
return currentRunContext.currentFPS()
|
||||
return currentRunContext.getCurrentFPS()
|
||||
}
|
||||
|
||||
func IsRunning() bool {
|
||||
@ -35,10 +35,14 @@ func IsRunningSlowly() bool {
|
||||
}
|
||||
|
||||
type runContext struct {
|
||||
running bool
|
||||
fps float64
|
||||
runningSlowly bool
|
||||
m sync.RWMutex
|
||||
running bool
|
||||
fps int
|
||||
currentFPS float64
|
||||
runningSlowly bool
|
||||
frames int
|
||||
beforeForUpdate int64
|
||||
beforeForFPS int64
|
||||
m sync.RWMutex
|
||||
}
|
||||
|
||||
var currentRunContext *runContext
|
||||
@ -61,20 +65,20 @@ func (c *runContext) endRunning() {
|
||||
c.running = false
|
||||
}
|
||||
|
||||
func (c *runContext) currentFPS() float64 {
|
||||
func (c *runContext) getCurrentFPS() float64 {
|
||||
c.m.RLock()
|
||||
defer c.m.RUnlock()
|
||||
if !c.running {
|
||||
// TODO: Should panic here?
|
||||
return 0
|
||||
}
|
||||
return c.fps
|
||||
return c.currentFPS
|
||||
}
|
||||
|
||||
func (c *runContext) updateFPS(fps float64) {
|
||||
c.m.Lock()
|
||||
defer c.m.Unlock()
|
||||
c.fps = fps
|
||||
c.currentFPS = fps
|
||||
}
|
||||
|
||||
func (c *runContext) isRunningSlowly() bool {
|
||||
@ -103,7 +107,9 @@ func Run(g GraphicsContext, width, height, scale int, title string, fps int) err
|
||||
if currentRunContext != nil {
|
||||
return errors.New("loop: The game is already running")
|
||||
}
|
||||
currentRunContext = &runContext{}
|
||||
currentRunContext = &runContext{
|
||||
fps: fps,
|
||||
}
|
||||
currentRunContext.startRunning()
|
||||
defer currentRunContext.endRunning()
|
||||
|
||||
@ -113,10 +119,9 @@ func Run(g GraphicsContext, width, height, scale int, title string, fps int) err
|
||||
// TODO: Use the error value
|
||||
defer ui.CurrentUI().Terminate()
|
||||
|
||||
frames := 0
|
||||
n := now()
|
||||
beforeForUpdate := n
|
||||
beforeForFPS := n
|
||||
currentRunContext.beforeForUpdate = n
|
||||
currentRunContext.beforeForFPS = n
|
||||
for {
|
||||
e, err := ui.CurrentUI().Update()
|
||||
if err != nil {
|
||||
@ -130,45 +135,8 @@ func Run(g GraphicsContext, width, height, scale int, title string, fps int) err
|
||||
case ui.CloseEvent:
|
||||
return nil
|
||||
case ui.RenderEvent:
|
||||
n2 := now()
|
||||
// If beforeForUpdate is too old, we assume that screen is not shown.
|
||||
if 5*int64(time.Second)/int64(fps) < n2-beforeForUpdate {
|
||||
currentRunContext.setRunningSlowly(false)
|
||||
beforeForUpdate = n2
|
||||
} else {
|
||||
// Note that generally t is a little different from 1/60[sec].
|
||||
t := n2 - beforeForUpdate
|
||||
tt := int(t * int64(fps) / int64(time.Second))
|
||||
// As t is not accurate 1/60[sec], errors are accumulated.
|
||||
// To make the FPS stable, set tt 1 if t is a little less than 1/60[sec].
|
||||
if tt == 0 && (int64(time.Second)/int64(fps)-int64(5*time.Millisecond)) < t {
|
||||
tt = 1
|
||||
}
|
||||
if 1 <= tt {
|
||||
for i := 0; i < tt; i++ {
|
||||
slow := i < tt-1
|
||||
currentRunContext.setRunningSlowly(slow)
|
||||
if err := g.UpdateAndDraw(); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if err := g.Draw(); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if err := ui.CurrentUI().SwapBuffers(); err != nil {
|
||||
return err
|
||||
}
|
||||
beforeForUpdate += int64(tt) * int64(time.Second) / int64(fps)
|
||||
frames++
|
||||
}
|
||||
// Calc the current FPS.
|
||||
if time.Second <= time.Duration(n2-beforeForFPS) {
|
||||
fps := float64(frames) * float64(time.Second) / float64(n2-beforeForFPS)
|
||||
currentRunContext.updateFPS(fps)
|
||||
beforeForFPS = n2
|
||||
frames = 0
|
||||
if err := currentRunContext.render(g); err != nil {
|
||||
return err
|
||||
}
|
||||
e.Done <- struct{}{}
|
||||
default:
|
||||
@ -176,3 +144,48 @@ func Run(g GraphicsContext, width, height, scale int, title string, fps int) err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (c *runContext) render(g GraphicsContext) error {
|
||||
fps := c.fps
|
||||
n := now()
|
||||
// If beforeForUpdate is too old, we assume that screen is not shown.
|
||||
if 5*int64(time.Second)/int64(fps) < n-c.beforeForUpdate {
|
||||
c.setRunningSlowly(false)
|
||||
c.beforeForUpdate = n
|
||||
} else {
|
||||
// Note that generally t is a little different from 1/60[sec].
|
||||
t := n - c.beforeForUpdate
|
||||
tt := int(t * int64(fps) / int64(time.Second))
|
||||
// As t is not accurate 1/60[sec], errors are accumulated.
|
||||
// To make the FPS stable, set tt 1 if t is a little less than 1/60[sec].
|
||||
if tt == 0 && (int64(time.Second)/int64(fps)-int64(5*time.Millisecond)) < t {
|
||||
tt = 1
|
||||
}
|
||||
if 1 <= tt {
|
||||
for i := 0; i < tt; i++ {
|
||||
slow := i < tt-1
|
||||
c.setRunningSlowly(slow)
|
||||
if err := g.UpdateAndDraw(); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if err := g.Draw(); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if err := ui.CurrentUI().SwapBuffers(); err != nil {
|
||||
return err
|
||||
}
|
||||
c.beforeForUpdate += int64(tt) * int64(time.Second) / int64(fps)
|
||||
c.frames++
|
||||
}
|
||||
// Calc the current FPS.
|
||||
if time.Second <= time.Duration(n-c.beforeForFPS) {
|
||||
fps := float64(c.frames) * float64(time.Second) / float64(n-c.beforeForFPS)
|
||||
c.updateFPS(fps)
|
||||
c.beforeForFPS = n
|
||||
c.frames = 0
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user