From 607186859ddce57a592fe75d616c6bbb3db9f2f1 Mon Sep 17 00:00:00 2001 From: Hajime Hoshi Date: Sun, 13 Jan 2019 21:46:53 +0900 Subject: [PATCH] ui: Run returns immediately on GopherJS Fixes #778 --- internal/ui/ui_js.go | 20 +++++++++++++++++--- run.go | 8 ++++++-- 2 files changed, 23 insertions(+), 5 deletions(-) diff --git a/internal/ui/ui_js.go b/internal/ui/ui_js.go index 3c02d5561..502706808 100644 --- a/internal/ui/ui_js.go +++ b/internal/ui/ui_js.go @@ -18,6 +18,8 @@ package ui import ( "image" + "log" + "runtime" "strconv" "github.com/gopherjs/gopherwasm/js" @@ -235,7 +237,7 @@ func (u *userInterface) update(g GraphicsContext) error { return nil } -func (u *userInterface) loop(g GraphicsContext) error { +func (u *userInterface) loop(g GraphicsContext) <-chan error { ch := make(chan error) var cf js.Callback f := func([]js.Value) { @@ -255,7 +257,7 @@ func (u *userInterface) loop(g GraphicsContext) error { go func() { f(nil) }() - return <-ch + return ch } func init() { @@ -264,6 +266,7 @@ func init() { window.Call("addEventListener", "load", js.NewCallback(func([]js.Value) { close(ch) })) + // TODO: This blocks the main goroutine, but should not. <-ch } @@ -374,7 +377,18 @@ func Run(width, height int, scale float64, title string, g GraphicsContext, main document.Set("title", title) u.setScreenSize(width, height, scale, u.fullscreen) canvas.Call("focus") - return u.loop(g) + ch := u.loop(g) + if runtime.GOARCH == "wasm" { + return <-ch + } + + // On GopherJS, the main goroutine must not be blocked. Return immediately. + go func() { + if err := <-ch; err != nil { + log.Fatal(err) + } + }() + return nil } func (u *userInterface) setScreenSize(width, height int, scale float64, fullscreen bool) bool { diff --git a/run.go b/run.go index fe4b8a4d8..ae39b3a50 100644 --- a/run.go +++ b/run.go @@ -123,8 +123,12 @@ func run(width, height int, scale float64, title string, g *graphicsContext, mai // // The given scale is ignored on fullscreen mode or gomobile-build mode. // -// Run returns error when 1) OpenGL error happens, 2) audio error happens or 3) f returns error. -// In the case of 3), Run returns the same error. +// On non-GopherJS environments, Run returns error when 1) OpenGL error happens, 2) audio error happens or +// 3) f returns error. In the case of 3), Run returns the same error. +// +// On GopherJS, Run returns immediately. +// It is because the 'main' goroutine cannot be blocked on GopherJS. +// When an error happens, this is shown as an error on the console. // // The size unit is device-independent pixel. //