mirror of
https://github.com/hajimehoshi/ebiten.git
synced 2025-01-13 04:22:05 +01:00
uidriver/mobile: Implement IsForeground
This adds hooks on resuming/suspending the application, and switches the foreground state there. This change also updates the logic to suspend the game loop to be clearer. Fixes #1037
This commit is contained in:
parent
38f49c3768
commit
802693fa20
@ -313,6 +313,7 @@ const objcM = `// Code generated by ebitenmobile. DO NOT EDIT.
|
|||||||
|
|
||||||
@synchronized(self) {
|
@synchronized(self) {
|
||||||
active_ = false;
|
active_ = false;
|
||||||
|
EbitenmobileviewSuspend();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -321,6 +322,7 @@ const objcM = `// Code generated by ebitenmobile. DO NOT EDIT.
|
|||||||
|
|
||||||
@synchronized(self) {
|
@synchronized(self) {
|
||||||
active_ = true;
|
active_ = true;
|
||||||
|
EbitenmobileviewResume();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -402,6 +404,7 @@ public class EbitenView extends ViewGroup {
|
|||||||
// Activity's onPause is called.
|
// Activity's onPause is called.
|
||||||
public void suspendGame() {
|
public void suspendGame() {
|
||||||
ebitenSurfaceView_.onPause();
|
ebitenSurfaceView_.onPause();
|
||||||
|
Ebitenmobileview.suspend();
|
||||||
}
|
}
|
||||||
|
|
||||||
// resumeGame resumes the game.
|
// resumeGame resumes the game.
|
||||||
@ -409,6 +412,7 @@ public class EbitenView extends ViewGroup {
|
|||||||
// Activity's onResume is called.
|
// Activity's onResume is called.
|
||||||
public void resumeGame() {
|
public void resumeGame() {
|
||||||
ebitenSurfaceView_.onResume();
|
ebitenSurfaceView_.onResume();
|
||||||
|
Ebitenmobileview.resume();
|
||||||
}
|
}
|
||||||
|
|
||||||
// onErrorOnGameUpdate is called on the main thread when an error happens when updating a game.
|
// onErrorOnGameUpdate is called on the main thread when an error happens when updating a game.
|
||||||
|
File diff suppressed because one or more lines are too long
@ -21,7 +21,6 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"runtime/debug"
|
"runtime/debug"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
|
||||||
|
|
||||||
"golang.org/x/mobile/app"
|
"golang.org/x/mobile/app"
|
||||||
"golang.org/x/mobile/event/lifecycle"
|
"golang.org/x/mobile/event/lifecycle"
|
||||||
@ -46,7 +45,9 @@ var (
|
|||||||
// renderEndCh receives when updating finishes.
|
// renderEndCh receives when updating finishes.
|
||||||
renderEndCh = make(chan struct{})
|
renderEndCh = make(chan struct{})
|
||||||
|
|
||||||
theUI = &UserInterface{}
|
theUI = &UserInterface{
|
||||||
|
foreground: true,
|
||||||
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
@ -58,6 +59,13 @@ func Get() *UserInterface {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (u *UserInterface) Update() {
|
func (u *UserInterface) Update() {
|
||||||
|
u.m.Lock()
|
||||||
|
fg := u.foreground
|
||||||
|
u.m.Unlock()
|
||||||
|
if !fg {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
renderCh <- struct{}{}
|
renderCh <- struct{}{}
|
||||||
ctx, cancel := context.WithCancel(context.Background())
|
ctx, cancel := context.WithCancel(context.Background())
|
||||||
go func() {
|
go func() {
|
||||||
@ -99,6 +107,7 @@ type UserInterface struct {
|
|||||||
scale float64
|
scale float64
|
||||||
|
|
||||||
sizeChanged bool
|
sizeChanged bool
|
||||||
|
foreground bool
|
||||||
|
|
||||||
// Used for gomobile-build
|
// Used for gomobile-build
|
||||||
gbuildWidthPx int
|
gbuildWidthPx int
|
||||||
@ -130,6 +139,7 @@ func (u *UserInterface) appMain(a app.App) {
|
|||||||
case lifecycle.Event:
|
case lifecycle.Event:
|
||||||
switch e.Crosses(lifecycle.StageVisible) {
|
switch e.Crosses(lifecycle.StageVisible) {
|
||||||
case lifecycle.CrossOn:
|
case lifecycle.CrossOn:
|
||||||
|
u.SetForeground(true)
|
||||||
glctx, _ = e.DrawContext.(gl.Context)
|
glctx, _ = e.DrawContext.(gl.Context)
|
||||||
// Assume that glctx is always a same instance.
|
// Assume that glctx is always a same instance.
|
||||||
// Then, only once initializing should be enough.
|
// Then, only once initializing should be enough.
|
||||||
@ -139,6 +149,7 @@ func (u *UserInterface) appMain(a app.App) {
|
|||||||
}
|
}
|
||||||
a.Send(paint.Event{})
|
a.Send(paint.Event{})
|
||||||
case lifecycle.CrossOff:
|
case lifecycle.CrossOff:
|
||||||
|
u.SetForeground(false)
|
||||||
glctx = nil
|
glctx = nil
|
||||||
}
|
}
|
||||||
case size.Event:
|
case size.Event:
|
||||||
@ -182,6 +193,18 @@ func (u *UserInterface) appMain(a app.App) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (u *UserInterface) SetForeground(foreground bool) {
|
||||||
|
u.m.Lock()
|
||||||
|
u.foreground = foreground
|
||||||
|
u.m.Unlock()
|
||||||
|
|
||||||
|
if foreground {
|
||||||
|
hooks.ResumeAudio()
|
||||||
|
} else {
|
||||||
|
hooks.SuspendAudio()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (u *UserInterface) Run(context driver.UIContext) error {
|
func (u *UserInterface) Run(context driver.UIContext) error {
|
||||||
// TODO: Remove width/height/scale arguments. They are not used from gomobile-build.
|
// TODO: Remove width/height/scale arguments. They are not used from gomobile-build.
|
||||||
|
|
||||||
@ -290,18 +313,7 @@ func (u *UserInterface) updateSize(context driver.UIContext) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (u *UserInterface) update(context driver.UIContext) error {
|
func (u *UserInterface) update(context driver.UIContext) error {
|
||||||
t := time.NewTimer(500 * time.Millisecond)
|
<-renderCh
|
||||||
defer t.Stop()
|
|
||||||
|
|
||||||
select {
|
|
||||||
case <-renderCh:
|
|
||||||
case <-t.C:
|
|
||||||
hooks.SuspendAudio()
|
|
||||||
<-renderCh
|
|
||||||
}
|
|
||||||
|
|
||||||
hooks.ResumeAudio()
|
|
||||||
|
|
||||||
defer func() {
|
defer func() {
|
||||||
renderEndCh <- struct{}{}
|
renderEndCh <- struct{}{}
|
||||||
}()
|
}()
|
||||||
@ -370,8 +382,10 @@ func (u *UserInterface) SetFullscreen(fullscreen bool) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (u *UserInterface) IsForeground() bool {
|
func (u *UserInterface) IsForeground() bool {
|
||||||
// TODO: implement this
|
u.m.Lock()
|
||||||
return true
|
fg := u.foreground
|
||||||
|
u.m.Unlock()
|
||||||
|
return fg
|
||||||
}
|
}
|
||||||
|
|
||||||
func (u *UserInterface) IsRunnableInBackground() bool {
|
func (u *UserInterface) IsRunnableInBackground() bool {
|
||||||
|
@ -80,3 +80,11 @@ func Update() error {
|
|||||||
|
|
||||||
return update()
|
return update()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func Suspend() {
|
||||||
|
mobile.Get().SetForeground(false)
|
||||||
|
}
|
||||||
|
|
||||||
|
func Resume() {
|
||||||
|
mobile.Get().SetForeground(true)
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user