mirror of
https://github.com/hajimehoshi/ebiten.git
synced 2024-12-25 03:08:54 +01:00
mobile: Implement Pause and Resume to work correctly
This commit is contained in:
parent
f03a99e89a
commit
8121b2102f
@ -173,10 +173,12 @@ func Run(g GraphicsContext, width, height, scale int, title string, fps int) err
|
|||||||
if err := g.Pause(); err != nil {
|
if err := g.Pause(); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
e.Done <- struct{}{}
|
||||||
case ui.ResumeEvent:
|
case ui.ResumeEvent:
|
||||||
if err := g.Resume(); err != nil {
|
if err := g.Resume(); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
e.Done <- struct{}{}
|
||||||
default:
|
default:
|
||||||
panic("not reach")
|
panic("not reach")
|
||||||
}
|
}
|
||||||
|
@ -28,7 +28,9 @@ type RenderEvent struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type PauseEvent struct {
|
type PauseEvent struct {
|
||||||
|
Done chan struct{}
|
||||||
}
|
}
|
||||||
|
|
||||||
type ResumeEvent struct {
|
type ResumeEvent struct {
|
||||||
|
Done chan struct{}
|
||||||
}
|
}
|
||||||
|
@ -18,6 +18,7 @@ package ui
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/hajimehoshi/ebiten/internal/graphics/opengl"
|
"github.com/hajimehoshi/ebiten/internal/graphics/opengl"
|
||||||
)
|
)
|
||||||
@ -35,7 +36,28 @@ func Render(chError <-chan error) error {
|
|||||||
return errors.New("ui: chError must not be nil")
|
return errors.New("ui: chError must not be nil")
|
||||||
}
|
}
|
||||||
// TODO: Check this is called on the rendering thread
|
// TODO: Check this is called on the rendering thread
|
||||||
chRender <- struct{}{}
|
select {
|
||||||
|
case <-chPauseStart:
|
||||||
|
if err := doGLWorks(chError, chPauseEnd); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
chPauseEnd2 <- struct{}{}
|
||||||
|
return nil
|
||||||
|
case <-chResumeStart:
|
||||||
|
if err := doGLWorks(chError, chResumeEnd); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
case chRender <- struct{}{}:
|
||||||
|
return doGLWorks(chError, chRenderEnd)
|
||||||
|
case <-time.After(500 * time.Millisecond):
|
||||||
|
// This function must not be blocked so we need to break after a while.
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func doGLWorks(chError <-chan error, chDone <-chan struct{}) error {
|
||||||
|
// TODO: Check this is called on the rendering thread
|
||||||
worker := glContext.Worker()
|
worker := glContext.Worker()
|
||||||
loop:
|
loop:
|
||||||
for {
|
for {
|
||||||
@ -46,7 +68,7 @@ loop:
|
|||||||
worker.DoWork()
|
worker.DoWork()
|
||||||
default:
|
default:
|
||||||
select {
|
select {
|
||||||
case <-chRenderEnd:
|
case <-chDone:
|
||||||
break loop
|
break loop
|
||||||
default:
|
default:
|
||||||
}
|
}
|
||||||
@ -60,19 +82,23 @@ type userInterface struct {
|
|||||||
height int
|
height int
|
||||||
scale int
|
scale int
|
||||||
sizeChanged bool
|
sizeChanged bool
|
||||||
chRender chan struct{}
|
paused bool
|
||||||
chRenderEnd chan struct{}
|
|
||||||
chPause chan struct{}
|
|
||||||
chResume chan struct{}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
// TODO: Rename these channels
|
||||||
chRender = make(chan struct{})
|
chRender = make(chan struct{})
|
||||||
chRenderEnd = make(chan struct{})
|
chRenderEnd = make(chan struct{})
|
||||||
|
chPause = make(chan struct{})
|
||||||
|
chPauseStart = make(chan struct{})
|
||||||
|
chPauseEnd = make(chan struct{})
|
||||||
|
chPauseEnd2 = make(chan struct{})
|
||||||
|
chResume = make(chan struct{})
|
||||||
|
chResumeStart = make(chan struct{})
|
||||||
|
chResumeEnd = make(chan struct{})
|
||||||
currentUI = &userInterface{
|
currentUI = &userInterface{
|
||||||
sizeChanged: true,
|
sizeChanged: true,
|
||||||
chRender: chRender,
|
paused: false,
|
||||||
chRenderEnd: chRenderEnd,
|
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -104,12 +130,20 @@ func (u *userInterface) Update() (interface{}, error) {
|
|||||||
}
|
}
|
||||||
return e, nil
|
return e, nil
|
||||||
}
|
}
|
||||||
|
if u.paused {
|
||||||
select {
|
select {
|
||||||
case <-u.chPause:
|
case <-chResume:
|
||||||
return PauseEvent{}, nil
|
u.paused = false
|
||||||
case <-u.chResume:
|
chResumeStart <- struct{}{}
|
||||||
return ResumeEvent{}, nil
|
return ResumeEvent{chResumeEnd}, nil
|
||||||
case <-u.chRender:
|
}
|
||||||
|
}
|
||||||
|
select {
|
||||||
|
case <-chPause:
|
||||||
|
u.paused = true
|
||||||
|
chPauseStart <- struct{}{}
|
||||||
|
return PauseEvent{chPauseEnd}, nil
|
||||||
|
case <-chRender:
|
||||||
return RenderEvent{}, nil
|
return RenderEvent{}, nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -119,7 +153,7 @@ func (u *userInterface) SwapBuffers() error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (u *userInterface) FinishRendering() error {
|
func (u *userInterface) FinishRendering() error {
|
||||||
u.chRenderEnd <- struct{}{}
|
chRenderEnd <- struct{}{}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -141,16 +175,17 @@ func (u *userInterface) actualScreenScale() int {
|
|||||||
return u.scale
|
return u.scale
|
||||||
}
|
}
|
||||||
|
|
||||||
func Pause() {
|
func Pause() error {
|
||||||
go func() {
|
// Pause must be done in the current GL context.
|
||||||
currentUI.chPause <- struct{}{}
|
chPause <- struct{}{}
|
||||||
}()
|
<-chPauseEnd2
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func Resume() {
|
func Resume() error {
|
||||||
go func() {
|
chResume <- struct{}{}
|
||||||
currentUI.chResume <- struct{}{}
|
// Don't have to wait for resumeing done.
|
||||||
}()
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func UpdateTouches(touches []Touch) {
|
func UpdateTouches(touches []Touch) {
|
||||||
|
Loading…
Reference in New Issue
Block a user