diff --git a/image_test.go b/image_test.go index cd196d9b6..e3811a6d1 100644 --- a/image_test.go +++ b/image_test.go @@ -30,11 +30,14 @@ import ( func TestMain(m *testing.M) { code := 0 // Run an Ebiten process so that (*Image).At is available. + regularTermination := errors.New("regular termination") f := func(screen *Image) error { code = m.Run() - return errors.New("regular termination") + return regularTermination + } + if err := Run(f, 320, 240, 1, "Test"); err != nil && err != regularTermination { + panic(err) } - Run(f, 320, 240, 1, "Test") os.Exit(code) } diff --git a/internal/loop/run.go b/internal/loop/run.go index 7e661f881..09bdaafb7 100644 --- a/internal/loop/run.go +++ b/internal/loop/run.go @@ -86,7 +86,7 @@ type GraphicsContext interface { UpdateAndDraw(context *opengl.Context, updateCount int) error } -func Run(g GraphicsContext, width, height int, scale float64, title string, fps int) error { +func Run(g GraphicsContext, width, height int, scale float64, title string, fps int) (err error) { if currentRunContext != nil { return errors.New("loop: The game is already running") } @@ -100,7 +100,12 @@ func Run(g GraphicsContext, width, height int, scale float64, title string, fps return err } // TODO: Use the error value - defer ui.CurrentUI().Terminate() + defer func() { + if err != nil { + return + } + err = ui.CurrentUI().Terminate() + }() n := now() currentRunContext.lastUpdated = n diff --git a/internal/ui/ui_glfw.go b/internal/ui/ui_glfw.go index fea83819b..9c02ef859 100644 --- a/internal/ui/ui_glfw.go +++ b/internal/ui/ui_glfw.go @@ -76,14 +76,19 @@ func initialize() error { return nil } -func Main() error { - return currentUI.main() +func Main(ch <-chan error) error { + return currentUI.main(ch) } -func (u *userInterface) main() error { +func (u *userInterface) main(ch <-chan error) error { // TODO: Check this is done on the main thread. - for f := range u.funcs { - f() + for { + select { + case f := <-u.funcs: + f() + case err := <-ch: + return err + } } return nil } diff --git a/internal/ui/ui_js.go b/internal/ui/ui_js.go index 218a2d4e9..944e43719 100644 --- a/internal/ui/ui_js.go +++ b/internal/ui/ui_js.go @@ -278,9 +278,8 @@ func devicePixelRatio() float64 { return ratio } -func Main() error { - // Do nothing - return nil +func Main(ch <-chan error) error { + return <-ch } func (u *userInterface) Start(width, height int, scale float64, title string) error { diff --git a/internal/ui/ui_mobile.go b/internal/ui/ui_mobile.go index cec39ec31..035f7518b 100644 --- a/internal/ui/ui_mobile.go +++ b/internal/ui/ui_mobile.go @@ -24,7 +24,7 @@ import ( "github.com/hajimehoshi/ebiten/internal/graphics/opengl" ) -func Main() error { +func Main(ch <-chan error) error { return errors.New("ui: don't call this: use RunWithoutMainLoop instead of Run") } diff --git a/run.go b/run.go index 18c87ed73..498ee3764 100644 --- a/run.go +++ b/run.go @@ -81,10 +81,11 @@ func Run(f func(*Image) error, width, height int, scale float64, title string) e } close(ch) }() - if err := ui.Main(); err != nil { + // TODO: Use context in Go 1.7? + if err := ui.Main(ch); err != nil { return err } - return <-ch + return nil } // RunWithoutMainLoop runs the game, but don't call the loop on the main (UI) thread.