driver: Remove the return value from RunWithoutMainLoop

This commit is contained in:
Hajime Hoshi 2020-02-11 23:19:43 +09:00
parent aef4b4ba53
commit d59aea1db1
6 changed files with 26 additions and 31 deletions

View File

@ -32,7 +32,7 @@ var RegularTermination = errors.New("regular termination")
type UI interface { type UI interface {
Run(context UIContext) error Run(context UIContext) error
RunWithoutMainLoop(context UIContext) <-chan error RunWithoutMainLoop(context UIContext)
DeviceScaleFactor() float64 DeviceScaleFactor() float64
CursorMode() CursorMode CursorMode() CursorMode

View File

@ -543,7 +543,7 @@ func (u *UserInterface) Run(uicontext driver.UIContext) error {
return <-ch return <-ch
} }
func (u *UserInterface) RunWithoutMainLoop(context driver.UIContext) <-chan error { func (u *UserInterface) RunWithoutMainLoop(context driver.UIContext) {
panic("glfw: RunWithoutMainLoop is not implemented") panic("glfw: RunWithoutMainLoop is not implemented")
} }

View File

@ -425,7 +425,7 @@ func (u *UserInterface) Run(context driver.UIContext) error {
return nil return nil
} }
func (u *UserInterface) RunWithoutMainLoop(context driver.UIContext) <-chan error { func (u *UserInterface) RunWithoutMainLoop(context driver.UIContext) {
panic("js: RunWithoutMainLoop is not implemented") panic("js: RunWithoutMainLoop is not implemented")
} }

View File

@ -47,6 +47,7 @@ var (
theUI = &UserInterface{ theUI = &UserInterface{
foreground: true, foreground: true,
errCh: make(chan error),
// Give a default outside size so that the game can start without initializing them. // Give a default outside size so that the game can start without initializing them.
outsideWidth: 640, outsideWidth: 640,
@ -64,12 +65,18 @@ func Get() *UserInterface {
} }
// Update is called from mobile/ebitenmobileview. // Update is called from mobile/ebitenmobileview.
func (u *UserInterface) Update() { func (u *UserInterface) Update() error {
select {
case err := <-u.errCh:
return err
default:
}
u.m.Lock() u.m.Lock()
fg := u.foreground fg := u.foreground
u.m.Unlock() u.m.Unlock()
if !fg { if !fg {
return return nil
} }
renderCh <- struct{}{} renderCh <- struct{}{}
@ -100,10 +107,11 @@ func (u *UserInterface) Update() {
break loop break loop
} }
} }
return return nil
} else { } else {
u.t.Loop(ctx) u.t.Loop(ctx)
} }
return nil
} }
type UserInterface struct { type UserInterface struct {
@ -112,6 +120,7 @@ type UserInterface struct {
sizeChanged bool sizeChanged bool
foreground bool foreground bool
errCh chan error
// Used for gomobile-build // Used for gomobile-build
gbuildWidthPx int gbuildWidthPx int
@ -221,17 +230,13 @@ func (u *UserInterface) Run(context driver.UIContext) error {
return nil return nil
} }
func (u *UserInterface) RunWithoutMainLoop(context driver.UIContext) <-chan error { func (u *UserInterface) RunWithoutMainLoop(context driver.UIContext) {
ch := make(chan error)
go func() { go func() {
defer close(ch)
// title is ignored? // title is ignored?
if err := u.run(context, false); err != nil { if err := u.run(context, false); err != nil {
ch <- err u.errCh <- err
} }
}() }()
return ch
} }
func (u *UserInterface) run(context driver.UIContext, mainloop bool) (err error) { func (u *UserInterface) run(context driver.UIContext, mainloop bool) (err error) {

View File

@ -36,9 +36,7 @@ import (
var theState state var theState state
type state struct { type state struct {
game ebiten.Game started bool
errorCh <-chan error
// m is a mutex required for each function. // m is a mutex required for each function.
// For example, on Android, Update can be called from a different thread: // For example, on Android, Update can be called from a different thread:
@ -47,18 +45,18 @@ type state struct {
} }
func (s *state) isRunning() bool { func (s *state) isRunning() bool {
return s.game != nil && s.errorCh != nil return s.started
} }
func SetGame(game ebiten.Game) { func SetGame(game ebiten.Game) {
theState.m.Lock() theState.m.Lock()
defer theState.m.Unlock() defer theState.m.Unlock()
if theState.game != nil { if theState.started {
panic("ebitenmobileview: SetGame cannot be called twice or more") panic("ebitenmobileview: SetGame cannot be called twice or more")
} }
theState.game = game ebiten.RunGameWithoutMainLoop(game)
theState.errorCh = ebiten.RunGameWithoutMainLoop(theState.game) theState.started = true
} }
func Layout(viewWidth, viewHeight float64) { func Layout(viewWidth, viewHeight float64) {
@ -75,21 +73,13 @@ func Update() error {
theState.m.Lock() theState.m.Lock()
defer theState.m.Unlock() defer theState.m.Unlock()
if !theState.started {
if !theState.isRunning() {
// start is not called yet, but as update can be called from another thread, it is OK. Just ignore // start is not called yet, but as update can be called from another thread, it is OK. Just ignore
// this. // this.
return nil return nil
} }
select { return mobile.Get().Update()
case err := <-theState.errorCh:
return err
default:
}
mobile.Get().Update()
return nil
} }
func Suspend() { func Suspend() {

4
run.go
View File

@ -243,11 +243,11 @@ func runGame(game Game, scale float64) error {
// //
// Ebiten users should NOT call RunGameWithoutMainLoop. // Ebiten users should NOT call RunGameWithoutMainLoop.
// Instead, functions in github.com/hajimehoshi/ebiten/mobile package calls this. // Instead, functions in github.com/hajimehoshi/ebiten/mobile package calls this.
func RunGameWithoutMainLoop(game Game) <-chan error { func RunGameWithoutMainLoop(game Game) {
game = &imageDumperGame{game: game} game = &imageDumperGame{game: game}
fixWindowPosition(WindowSize()) fixWindowPosition(WindowSize())
theUIContext.set(game, 0) theUIContext.set(game, 0)
return uiDriver().RunWithoutMainLoop(theUIContext) uiDriver().RunWithoutMainLoop(theUIContext)
} }
// ScreenSizeInFullscreen is deprecated as of 1.11.0-alpha. // ScreenSizeInFullscreen is deprecated as of 1.11.0-alpha.