ui: Run returns immediately on GopherJS

Fixes #778
This commit is contained in:
Hajime Hoshi 2019-01-13 21:46:53 +09:00
parent 690dae0488
commit 607186859d
2 changed files with 23 additions and 5 deletions

View File

@ -18,6 +18,8 @@ package ui
import ( import (
"image" "image"
"log"
"runtime"
"strconv" "strconv"
"github.com/gopherjs/gopherwasm/js" "github.com/gopherjs/gopherwasm/js"
@ -235,7 +237,7 @@ func (u *userInterface) update(g GraphicsContext) error {
return nil return nil
} }
func (u *userInterface) loop(g GraphicsContext) error { func (u *userInterface) loop(g GraphicsContext) <-chan error {
ch := make(chan error) ch := make(chan error)
var cf js.Callback var cf js.Callback
f := func([]js.Value) { f := func([]js.Value) {
@ -255,7 +257,7 @@ func (u *userInterface) loop(g GraphicsContext) error {
go func() { go func() {
f(nil) f(nil)
}() }()
return <-ch return ch
} }
func init() { func init() {
@ -264,6 +266,7 @@ func init() {
window.Call("addEventListener", "load", js.NewCallback(func([]js.Value) { window.Call("addEventListener", "load", js.NewCallback(func([]js.Value) {
close(ch) close(ch)
})) }))
// TODO: This blocks the main goroutine, but should not.
<-ch <-ch
} }
@ -374,7 +377,18 @@ func Run(width, height int, scale float64, title string, g GraphicsContext, main
document.Set("title", title) document.Set("title", title)
u.setScreenSize(width, height, scale, u.fullscreen) u.setScreenSize(width, height, scale, u.fullscreen)
canvas.Call("focus") 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 { func (u *userInterface) setScreenSize(width, height int, scale float64, fullscreen bool) bool {

8
run.go
View File

@ -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. // 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. // On non-GopherJS environments, Run returns error when 1) OpenGL error happens, 2) audio error happens or
// In the case of 3), Run returns the same error. // 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. // The size unit is device-independent pixel.
// //