diff --git a/audio/audio.go b/audio/audio.go index 00657e11c..3e23454cc 100644 --- a/audio/audio.go +++ b/audio/audio.go @@ -40,7 +40,6 @@ import ( "sync" "time" - "github.com/hajimehoshi/ebiten/internal/hooks" "github.com/hajimehoshi/ebiten/internal/web" ) @@ -112,15 +111,16 @@ func CurrentContext() *Context { func (c *Context) loop() { suspendCh := make(chan struct{}, 1) resumeCh := make(chan struct{}, 1) - hooks.OnSuspendAudio(func() { + h := getHook() + h.OnSuspendAudio(func() { suspendCh <- struct{}{} }) - hooks.OnResumeAudio(func() { + h.OnResumeAudio(func() { resumeCh <- struct{}{} }) var once sync.Once - hooks.AppendHookOnBeforeUpdate(func() error { + h.AppendHookOnBeforeUpdate(func() error { once.Do(func() { close(c.initCh) }) diff --git a/audio/audio_test.go b/audio/audio_test.go index 51df4777b..e8b021e64 100644 --- a/audio/audio_test.go +++ b/audio/audio_test.go @@ -15,34 +15,13 @@ package audio_test import ( - "errors" - "os" "runtime" "testing" "time" - "github.com/hajimehoshi/ebiten" . "github.com/hajimehoshi/ebiten/audio" - "github.com/hajimehoshi/ebiten/internal/testflock" ) -func TestMain(m *testing.M) { - testflock.Lock() - defer testflock.Unlock() - - code := 0 - // Run an Ebiten process so that audio is available. - regularTermination := errors.New("regular termination") - f := func(screen *ebiten.Image) error { - code = m.Run() - return regularTermination - } - if err := ebiten.Run(f, 320, 240, 1, "Test"); err != nil && err != regularTermination { - panic(err) - } - os.Exit(code) -} - var context *Context func init() { @@ -76,6 +55,9 @@ func TestGC(t *testing.T) { if want := 0; got == want { return } + if err := UpdateForTesting(); err != nil { + t.Error(err) + } // 200[ms] should be enough all the bytes are consumed. // TODO: This is a darty hack. Would it be possible to use virtual time? time.Sleep(200 * time.Millisecond) diff --git a/audio/context.go b/audio/context.go index d89cbe68e..69d9dd899 100644 --- a/audio/context.go +++ b/audio/context.go @@ -19,6 +19,8 @@ import ( "sync" "github.com/hajimehoshi/oto" + + "github.com/hajimehoshi/ebiten/internal/hooks" ) type context interface { @@ -100,3 +102,32 @@ func newContext(sampleRate int, initCh <-chan struct{}) context { initCh: initCh, } } + +type hook interface { + OnSuspendAudio(f func()) + OnResumeAudio(f func()) + AppendHookOnBeforeUpdate(f func() error) +} + +var hookForTesting hook + +func getHook() hook { + if hookForTesting != nil { + return hookForTesting + } + return &hookImpl{} +} + +type hookImpl struct{} + +func (h *hookImpl) OnSuspendAudio(f func()) { + hooks.OnSuspendAudio(f) +} + +func (h *hookImpl) OnResumeAudio(f func()) { + hooks.OnResumeAudio(f) +} + +func (h *hookImpl) AppendHookOnBeforeUpdate(f func() error) { + hooks.AppendHookOnBeforeUpdate(f) +} diff --git a/audio/context_test.go b/audio/context_test.go index c302433dd..9503f04bf 100644 --- a/audio/context_test.go +++ b/audio/context_test.go @@ -42,3 +42,25 @@ func (p *dummyPlayer) Close() error { func init() { contextForTesting = &dummyContext{} } + +type dummyHook struct { + update func() error +} + +func (h *dummyHook) OnSuspendAudio(f func()) { +} + +func (h *dummyHook) OnResumeAudio(f func()) { +} + +func (h *dummyHook) AppendHookOnBeforeUpdate(f func() error) { + h.update = f +} + +func init() { + hookForTesting = &dummyHook{} +} + +func UpdateForTesting() error { + return hookForTesting.(*dummyHook).update() +}