mirror of
https://github.com/hajimehoshi/ebiten.git
synced 2024-11-10 04:57:26 +01:00
internal/thread: remove Stop and use context.Context instead
This commit is contained in:
parent
01eb1a0bca
commit
c638727759
@ -14,26 +14,27 @@
|
||||
|
||||
package thread
|
||||
|
||||
import (
|
||||
"context"
|
||||
)
|
||||
|
||||
// Thread defines threading behavior in Ebitengine.
|
||||
type Thread interface {
|
||||
Call(func())
|
||||
Loop()
|
||||
Stop()
|
||||
Loop(context.Context) error
|
||||
}
|
||||
|
||||
// OSThread represents an OS thread.
|
||||
type OSThread struct {
|
||||
funcs chan func()
|
||||
done chan struct{}
|
||||
terminate chan struct{}
|
||||
funcs chan func()
|
||||
done chan struct{}
|
||||
}
|
||||
|
||||
// NewOSThread creates a new thread.
|
||||
func NewOSThread() *OSThread {
|
||||
return &OSThread{
|
||||
funcs: make(chan func()),
|
||||
done: make(chan struct{}),
|
||||
terminate: make(chan struct{}),
|
||||
funcs: make(chan func()),
|
||||
done: make(chan struct{}),
|
||||
}
|
||||
}
|
||||
|
||||
@ -42,7 +43,7 @@ func NewOSThread() *OSThread {
|
||||
// It is assumed that an OS thread is fixed by runtime.LockOSThread when Loop is called.
|
||||
//
|
||||
// Loop must be called on the thread.
|
||||
func (t *OSThread) Loop() {
|
||||
func (t *OSThread) Loop(ctx context.Context) error {
|
||||
for {
|
||||
select {
|
||||
case fn := <-t.funcs:
|
||||
@ -53,17 +54,12 @@ func (t *OSThread) Loop() {
|
||||
|
||||
fn()
|
||||
}()
|
||||
case <-t.terminate:
|
||||
return
|
||||
case <-ctx.Done():
|
||||
return ctx.Err()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Stop stops the thread loop.
|
||||
func (t *OSThread) Stop() {
|
||||
t.terminate <- struct{}{}
|
||||
}
|
||||
|
||||
// Call calls f on the thread.
|
||||
//
|
||||
// Do not call this from the same thread. This would block forever.
|
||||
@ -83,10 +79,9 @@ func NewNoopThread() *NoopThread {
|
||||
}
|
||||
|
||||
// Loop does nothing
|
||||
func (t *NoopThread) Loop() {}
|
||||
func (t *NoopThread) Loop(ctx context.Context) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Call executes the func immediately
|
||||
func (t *NoopThread) Call(f func()) { f() }
|
||||
|
||||
// Stop does nothing
|
||||
func (t *NoopThread) Stop() {}
|
||||
|
@ -17,6 +17,9 @@
|
||||
package ui
|
||||
|
||||
import (
|
||||
stdcontext "context"
|
||||
"errors"
|
||||
|
||||
"github.com/hajimehoshi/ebiten/v2/internal/graphicscommand"
|
||||
"github.com/hajimehoshi/ebiten/v2/internal/thread"
|
||||
)
|
||||
@ -36,20 +39,25 @@ func (u *userInterfaceImpl) Run(game Game, options *RunOptions) error {
|
||||
return err
|
||||
}
|
||||
|
||||
ctx, cancel := stdcontext.WithCancel(stdcontext.Background())
|
||||
defer cancel()
|
||||
|
||||
ch := make(chan error, 1)
|
||||
go func() {
|
||||
defer close(ch)
|
||||
|
||||
if err := u.loopGame(); err != nil {
|
||||
ch <- err
|
||||
cancel()
|
||||
return
|
||||
}
|
||||
}()
|
||||
|
||||
defer u.mainThread.Stop()
|
||||
u.mainThread.Loop()
|
||||
|
||||
return <-ch
|
||||
err := u.mainThread.Loop(ctx)
|
||||
if errors.Is(err, stdcontext.Canceled) {
|
||||
return <-ch
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
// runOnAnotherThreadFromMainThread is called from the main thread, and calls f on a new goroutine (thread).
|
||||
@ -68,9 +76,11 @@ func (u *userInterfaceImpl) runOnAnotherThreadFromMainThread(f func()) {
|
||||
u.mainThread = thread.NewOSThread()
|
||||
graphicscommand.SetRenderingThread(u.mainThread)
|
||||
|
||||
ctx, cancel := stdcontext.WithCancel(stdcontext.Background())
|
||||
defer cancel()
|
||||
go func() {
|
||||
defer u.mainThread.Stop()
|
||||
defer cancel()
|
||||
f()
|
||||
}()
|
||||
u.mainThread.Loop()
|
||||
_ = u.mainThread.Loop(ctx)
|
||||
}
|
||||
|
@ -17,6 +17,7 @@
|
||||
package ui
|
||||
|
||||
import (
|
||||
stdcontext "context"
|
||||
"fmt"
|
||||
"runtime/debug"
|
||||
"sync"
|
||||
@ -80,12 +81,16 @@ func (u *userInterfaceImpl) Update() error {
|
||||
return err
|
||||
}
|
||||
|
||||
ctx, cancel := stdcontext.WithCancel(stdcontext.Background())
|
||||
defer cancel()
|
||||
|
||||
renderCh <- struct{}{}
|
||||
go func() {
|
||||
<-renderEndCh
|
||||
u.t.Stop()
|
||||
cancel()
|
||||
}()
|
||||
u.t.Loop()
|
||||
|
||||
_ = u.t.Loop(ctx)
|
||||
return nil
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user