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