mirror of
https://github.com/hajimehoshi/ebiten.git
synced 2024-12-25 03:08:54 +01:00
internal/hooks: Enable to return error at suspend/resume audio
This commit is contained in:
parent
bcf8ef85b6
commit
58843b68f9
@ -125,17 +125,19 @@ func NewContext(sampleRate int) *Context {
|
||||
theContext = c
|
||||
|
||||
h := getHook()
|
||||
h.OnSuspendAudio(func() {
|
||||
h.OnSuspendAudio(func() error {
|
||||
c.semaphore <- struct{}{}
|
||||
if s, ok := np.(interface{ suspend() }); ok {
|
||||
s.suspend()
|
||||
}
|
||||
return nil
|
||||
})
|
||||
h.OnResumeAudio(func() {
|
||||
h.OnResumeAudio(func() error {
|
||||
<-c.semaphore
|
||||
if s, ok := np.(interface{ resume() }); ok {
|
||||
s.resume()
|
||||
}
|
||||
return nil
|
||||
})
|
||||
|
||||
h.AppendHookOnBeforeUpdate(func() error {
|
||||
@ -423,8 +425,8 @@ func (p *Player) SetVolume(volume float64) {
|
||||
}
|
||||
|
||||
type hook interface {
|
||||
OnSuspendAudio(f func())
|
||||
OnResumeAudio(f func())
|
||||
OnSuspendAudio(f func() error)
|
||||
OnResumeAudio(f func() error)
|
||||
AppendHookOnBeforeUpdate(f func() error)
|
||||
}
|
||||
|
||||
@ -439,11 +441,11 @@ func getHook() hook {
|
||||
|
||||
type hookImpl struct{}
|
||||
|
||||
func (h *hookImpl) OnSuspendAudio(f func()) {
|
||||
func (h *hookImpl) OnSuspendAudio(f func() error) {
|
||||
hooks.OnSuspendAudio(f)
|
||||
}
|
||||
|
||||
func (h *hookImpl) OnResumeAudio(f func()) {
|
||||
func (h *hookImpl) OnResumeAudio(f func() error) {
|
||||
hooks.OnResumeAudio(f)
|
||||
}
|
||||
|
||||
|
@ -141,10 +141,10 @@ type dummyHook struct {
|
||||
updates []func() error
|
||||
}
|
||||
|
||||
func (h *dummyHook) OnSuspendAudio(f func()) {
|
||||
func (h *dummyHook) OnSuspendAudio(f func() error) {
|
||||
}
|
||||
|
||||
func (h *dummyHook) OnResumeAudio(f func()) {
|
||||
func (h *dummyHook) OnResumeAudio(f func() error) {
|
||||
}
|
||||
|
||||
func (h *dummyHook) AppendHookOnBeforeUpdate(f func() error) {
|
||||
|
@ -313,7 +313,11 @@ const objcM = `// Code generated by ebitenmobile. DO NOT EDIT.
|
||||
|
||||
@synchronized(self) {
|
||||
active_ = false;
|
||||
EbitenmobileviewSuspend();
|
||||
NSError* err = nil;
|
||||
EbitenmobileviewSuspend(&err);
|
||||
if (err != nil) {
|
||||
[self onErrorOnGameUpdate:err];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -322,7 +326,11 @@ const objcM = `// Code generated by ebitenmobile. DO NOT EDIT.
|
||||
|
||||
@synchronized(self) {
|
||||
active_ = true;
|
||||
EbitenmobileviewResume();
|
||||
NSError* err = nil;
|
||||
EbitenmobileviewResume(&err);
|
||||
if (err != nil) {
|
||||
[self onErrorOnGameUpdate:err];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -689,7 +697,11 @@ public class EbitenView extends ViewGroup implements InputManager.InputDeviceLis
|
||||
public void suspendGame() {
|
||||
this.inputManager.unregisterInputDeviceListener(this);
|
||||
this.ebitenSurfaceView.onPause();
|
||||
try {
|
||||
Ebitenmobileview.suspend();
|
||||
} catch (final Exception e) {
|
||||
onErrorOnGameUpdate(e);
|
||||
}
|
||||
}
|
||||
|
||||
// resumeGame resumes the game.
|
||||
@ -698,7 +710,11 @@ public class EbitenView extends ViewGroup implements InputManager.InputDeviceLis
|
||||
public void resumeGame() {
|
||||
this.inputManager.registerInputDeviceListener(this, null);
|
||||
this.ebitenSurfaceView.onResume();
|
||||
try {
|
||||
Ebitenmobileview.resume();
|
||||
} catch (final Exception e) {
|
||||
onErrorOnGameUpdate(e);
|
||||
}
|
||||
}
|
||||
|
||||
// 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
@ -44,42 +44,44 @@ func RunBeforeUpdateHooks() error {
|
||||
|
||||
var (
|
||||
audioSuspended bool
|
||||
onSuspendAudio func()
|
||||
onResumeAudio func()
|
||||
onSuspendAudio func() error
|
||||
onResumeAudio func() error
|
||||
)
|
||||
|
||||
func OnSuspendAudio(f func()) {
|
||||
func OnSuspendAudio(f func() error) {
|
||||
m.Lock()
|
||||
onSuspendAudio = f
|
||||
m.Unlock()
|
||||
}
|
||||
|
||||
func OnResumeAudio(f func()) {
|
||||
func OnResumeAudio(f func() error) {
|
||||
m.Lock()
|
||||
onResumeAudio = f
|
||||
m.Unlock()
|
||||
}
|
||||
|
||||
func SuspendAudio() {
|
||||
func SuspendAudio() error {
|
||||
m.Lock()
|
||||
defer m.Unlock()
|
||||
if audioSuspended {
|
||||
return
|
||||
return nil
|
||||
}
|
||||
audioSuspended = true
|
||||
if onSuspendAudio != nil {
|
||||
onSuspendAudio()
|
||||
return onSuspendAudio()
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func ResumeAudio() {
|
||||
func ResumeAudio() error {
|
||||
m.Lock()
|
||||
defer m.Unlock()
|
||||
if !audioSuspended {
|
||||
return
|
||||
return nil
|
||||
}
|
||||
audioSuspended = false
|
||||
if onResumeAudio != nil {
|
||||
onResumeAudio()
|
||||
return onResumeAudio()
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
@ -916,12 +916,16 @@ func (u *UserInterface) update() (float64, float64, bool, error) {
|
||||
u.input.update(u.window, u.context)
|
||||
|
||||
for !u.isRunnableOnUnfocused() && u.window.GetAttrib(glfw.Focused) == 0 && !u.window.ShouldClose() {
|
||||
hooks.SuspendAudio()
|
||||
if err := hooks.SuspendAudio(); err != nil {
|
||||
return 0, 0, false, err
|
||||
}
|
||||
// Wait for an arbitrary period to avoid busy loop.
|
||||
time.Sleep(time.Second / 60)
|
||||
glfw.PollEvents()
|
||||
}
|
||||
hooks.ResumeAudio()
|
||||
if err := hooks.ResumeAudio(); err != nil {
|
||||
return 0, 0, false, err
|
||||
}
|
||||
|
||||
return outsideWidth, outsideHeight, outsideSizeChanged, nil
|
||||
}
|
||||
|
@ -258,10 +258,11 @@ func (u *UserInterface) isFocused() bool {
|
||||
|
||||
func (u *UserInterface) update() error {
|
||||
if u.suspended() {
|
||||
hooks.SuspendAudio()
|
||||
return nil
|
||||
return hooks.SuspendAudio()
|
||||
}
|
||||
if err := hooks.ResumeAudio(); err != nil {
|
||||
return err
|
||||
}
|
||||
hooks.ResumeAudio()
|
||||
return u.updateImpl(false)
|
||||
}
|
||||
|
||||
@ -284,7 +285,7 @@ func (u *UserInterface) updateImpl(force bool) error {
|
||||
func (u *UserInterface) loop(context driver.UIContext) <-chan error {
|
||||
u.context = context
|
||||
|
||||
errCh := make(chan error)
|
||||
errCh := make(chan error, 1)
|
||||
reqStopAudioCh := make(chan struct{})
|
||||
resStopAudioCh := make(chan struct{})
|
||||
|
||||
@ -300,7 +301,6 @@ func (u *UserInterface) loop(context driver.UIContext) <-chan error {
|
||||
<-resStopAudioCh
|
||||
|
||||
errCh <- err
|
||||
close(errCh)
|
||||
return
|
||||
}
|
||||
if u.vsync {
|
||||
@ -344,9 +344,15 @@ func (u *UserInterface) loop(context driver.UIContext) <-chan error {
|
||||
select {
|
||||
case <-t.C:
|
||||
if u.suspended() {
|
||||
hooks.SuspendAudio()
|
||||
if err := hooks.SuspendAudio(); err != nil {
|
||||
errCh <- err
|
||||
return
|
||||
}
|
||||
} else {
|
||||
hooks.ResumeAudio()
|
||||
if err := hooks.ResumeAudio(); err != nil {
|
||||
errCh <- err
|
||||
return
|
||||
}
|
||||
}
|
||||
case <-reqStopAudioCh:
|
||||
return
|
||||
|
@ -136,7 +136,10 @@ func (u *UserInterface) appMain(a app.App) {
|
||||
case lifecycle.Event:
|
||||
switch e.Crosses(lifecycle.StageVisible) {
|
||||
case lifecycle.CrossOn:
|
||||
u.SetForeground(true)
|
||||
if err := u.SetForeground(true); err != nil {
|
||||
// There are no other ways than panicking here.
|
||||
panic(err)
|
||||
}
|
||||
restorable.OnContextLost()
|
||||
glctx, _ = e.DrawContext.(gl.Context)
|
||||
// Assume that glctx is always a same instance.
|
||||
@ -147,7 +150,10 @@ func (u *UserInterface) appMain(a app.App) {
|
||||
}
|
||||
a.Send(paint.Event{})
|
||||
case lifecycle.CrossOff:
|
||||
u.SetForeground(false)
|
||||
if err := u.SetForeground(false); err != nil {
|
||||
// There are no other ways than panicking here.
|
||||
panic(err)
|
||||
}
|
||||
glctx = nil
|
||||
}
|
||||
case size.Event:
|
||||
@ -213,7 +219,7 @@ func (u *UserInterface) appMain(a app.App) {
|
||||
}
|
||||
}
|
||||
|
||||
func (u *UserInterface) SetForeground(foreground bool) {
|
||||
func (u *UserInterface) SetForeground(foreground bool) error {
|
||||
var v int32
|
||||
if foreground {
|
||||
v = 1
|
||||
@ -221,9 +227,9 @@ func (u *UserInterface) SetForeground(foreground bool) {
|
||||
atomic.StoreInt32(&u.foreground, v)
|
||||
|
||||
if foreground {
|
||||
hooks.ResumeAudio()
|
||||
return hooks.ResumeAudio()
|
||||
} else {
|
||||
hooks.SuspendAudio()
|
||||
return hooks.SuspendAudio()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -75,12 +75,12 @@ func Update() error {
|
||||
return mobile.Get().Update()
|
||||
}
|
||||
|
||||
func Suspend() {
|
||||
mobile.Get().SetForeground(false)
|
||||
func Suspend() error {
|
||||
return mobile.Get().SetForeground(false)
|
||||
}
|
||||
|
||||
func Resume() {
|
||||
mobile.Get().SetForeground(true)
|
||||
func Resume() error {
|
||||
return mobile.Get().SetForeground(true)
|
||||
}
|
||||
|
||||
func OnContextLost() {
|
||||
|
Loading…
Reference in New Issue
Block a user