mirror of
https://github.com/hajimehoshi/ebiten.git
synced 2025-01-12 20:18:59 +01:00
internal/ui: refactoring: integrate (*UserInterface).run
This commit is contained in:
parent
ea842495cf
commit
5fe8c29b4c
@ -12,7 +12,7 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
//go:build !android && !ios && !js && !nintendosdk && !playstation5 && !ebitenginesinglethread && !ebitensinglethread
|
||||
//go:build !android && !ios && !js && !ebitenginesinglethread && !ebitensinglethread
|
||||
|
||||
package ui
|
||||
|
||||
@ -25,7 +25,7 @@ import (
|
||||
"github.com/hajimehoshi/ebiten/v2/internal/thread"
|
||||
)
|
||||
|
||||
func (u *UserInterface) Run(game Game, options *RunOptions) error {
|
||||
func (u *UserInterface) run(game Game, options *RunOptions) error {
|
||||
u.mainThread = thread.NewOSThread()
|
||||
u.renderThread = thread.NewOSThread()
|
||||
graphicscommand.SetRenderThread(u.renderThread)
|
@ -12,7 +12,7 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
//go:build !android && !ios && !js && !nintendosdk && !playstation5 && (ebitenginesinglethread || ebitensinglethread)
|
||||
//go:build js || (!android && !ios && (ebitenginesinglethread || ebitensinglethread))
|
||||
|
||||
package ui
|
||||
|
||||
@ -21,7 +21,7 @@ import (
|
||||
"github.com/hajimehoshi/ebiten/v2/internal/thread"
|
||||
)
|
||||
|
||||
func (u *UserInterface) Run(game Game, options *RunOptions) error {
|
||||
func (u *UserInterface) run(game Game, options *RunOptions) error {
|
||||
// Initialize the main thread first so the thread is available at u.run (#809).
|
||||
u.mainThread = thread.NewNoopThread()
|
||||
u.renderThread = thread.NewNoopThread()
|
@ -22,6 +22,7 @@ import (
|
||||
|
||||
"github.com/hajimehoshi/ebiten/v2/internal/atlas"
|
||||
"github.com/hajimehoshi/ebiten/v2/internal/mipmap"
|
||||
"github.com/hajimehoshi/ebiten/v2/internal/thread"
|
||||
)
|
||||
|
||||
// RegularTermination represents a regular termination.
|
||||
@ -79,6 +80,9 @@ type UserInterface struct {
|
||||
|
||||
whiteImage *Image
|
||||
|
||||
mainThread thread.Thread
|
||||
renderThread thread.Thread
|
||||
|
||||
userInterfaceImpl
|
||||
}
|
||||
|
||||
|
@ -107,9 +107,7 @@ type userInterfaceImpl struct {
|
||||
darwinInitOnce sync.Once
|
||||
bufferOnceSwappedOnce sync.Once
|
||||
|
||||
mainThread thread.Thread
|
||||
renderThread thread.Thread
|
||||
m sync.RWMutex
|
||||
m sync.RWMutex
|
||||
}
|
||||
|
||||
const (
|
||||
@ -123,6 +121,10 @@ func init() {
|
||||
runtime.LockOSThread()
|
||||
}
|
||||
|
||||
func (u *UserInterface) Run(game Game, options *RunOptions) error {
|
||||
return u.run(game, options)
|
||||
}
|
||||
|
||||
func (u *UserInterface) init() error {
|
||||
u.userInterfaceImpl = userInterfaceImpl{
|
||||
runnableOnUnfocused: true,
|
||||
|
@ -390,9 +390,7 @@ func (u *UserInterface) needsUpdate() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (u *UserInterface) loop(game Game) <-chan error {
|
||||
u.context = newContext(game)
|
||||
|
||||
func (u *UserInterface) loopGame() error {
|
||||
errCh := make(chan error, 1)
|
||||
reqStopAudioCh := make(chan struct{})
|
||||
resStopAudioCh := make(chan struct{})
|
||||
@ -476,7 +474,7 @@ func (u *UserInterface) loop(game Game) <-chan error {
|
||||
}
|
||||
}()
|
||||
|
||||
return errCh
|
||||
return <-errCh
|
||||
}
|
||||
|
||||
func (u *UserInterface) init() error {
|
||||
@ -743,9 +741,10 @@ func (u *UserInterface) forceUpdateOnMinimumFPSMode() {
|
||||
}
|
||||
|
||||
func (u *UserInterface) Run(game Game, options *RunOptions) error {
|
||||
u.setRunning(true)
|
||||
defer u.setRunning(false)
|
||||
return u.run(game, options)
|
||||
}
|
||||
|
||||
func (u *UserInterface) initOnMainThread(options *RunOptions) error {
|
||||
if !options.InitUnfocused && window.Truthy() {
|
||||
// Do not focus the canvas when the current document is in an iframe.
|
||||
// Otherwise, the parent page tries to focus the iframe on every loading, which is annoying (#1373).
|
||||
@ -770,7 +769,7 @@ func (u *UserInterface) Run(game Game, options *RunOptions) error {
|
||||
bodyStyle.Set("backgroundColor", "#000")
|
||||
}
|
||||
|
||||
return <-u.loop(game)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (u *UserInterface) updateScreenSize() {
|
||||
|
@ -241,7 +241,7 @@ func (u *UserInterface) SetForeground(foreground bool) error {
|
||||
func (u *UserInterface) Run(game Game, options *RunOptions) error {
|
||||
u.setGBuildSizeCh = make(chan struct{})
|
||||
go func() {
|
||||
if err := u.run(game, true, options); err != nil {
|
||||
if err := u.runMobile(game, true, options); err != nil {
|
||||
// As mobile apps never ends, Loop can't return. Just panic here.
|
||||
panic(err)
|
||||
}
|
||||
@ -252,13 +252,13 @@ func (u *UserInterface) Run(game Game, options *RunOptions) error {
|
||||
|
||||
func (u *UserInterface) RunWithoutMainLoop(game Game, options *RunOptions) {
|
||||
go func() {
|
||||
if err := u.run(game, false, options); err != nil {
|
||||
if err := u.runMobile(game, false, options); err != nil {
|
||||
u.errCh <- err
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
||||
func (u *UserInterface) run(game Game, mainloop bool, options *RunOptions) (err error) {
|
||||
func (u *UserInterface) runMobile(game Game, mainloop bool, options *RunOptions) (err error) {
|
||||
// Convert the panic to a regular error so that Java/Objective-C layer can treat this easily e.g., for
|
||||
// Crashlytics. A panic is treated as SIGABRT, and there is no way to handle this on Java/Objective-C layer
|
||||
// unfortunately.
|
||||
|
@ -21,15 +21,11 @@ package ui
|
||||
import "C"
|
||||
|
||||
import (
|
||||
stdcontext "context"
|
||||
"errors"
|
||||
"image"
|
||||
"runtime"
|
||||
"sync"
|
||||
|
||||
"golang.org/x/sync/errgroup"
|
||||
|
||||
"github.com/hajimehoshi/ebiten/v2/internal/graphicscommand"
|
||||
"github.com/hajimehoshi/ebiten/v2/internal/graphicsdriver"
|
||||
"github.com/hajimehoshi/ebiten/v2/internal/graphicsdriver/opengl"
|
||||
"github.com/hajimehoshi/ebiten/v2/internal/thread"
|
||||
@ -84,15 +80,10 @@ func (u *UserInterface) init() error {
|
||||
}
|
||||
|
||||
func (u *UserInterface) Run(game Game, options *RunOptions) error {
|
||||
u.mainThread = thread.NewOSThread()
|
||||
u.renderThread = thread.NewOSThread()
|
||||
graphicscommand.SetRenderThread(u.renderThread)
|
||||
|
||||
u.setRunning(true)
|
||||
defer u.setRunning(false)
|
||||
|
||||
u.context = newContext(game)
|
||||
return u.run(game, options)
|
||||
}
|
||||
|
||||
func (u *UserInterface) initOnMainThread(options *RunOptions) error {
|
||||
g, lib, err := newGraphicsDriver(&graphicsDriverCreatorImpl{}, options.GraphicsLibrary)
|
||||
if err != nil {
|
||||
return err
|
||||
@ -107,45 +98,25 @@ func (u *UserInterface) Run(game Game, options *RunOptions) error {
|
||||
|
||||
initializeProfiler()
|
||||
|
||||
ctx, cancel := stdcontext.WithCancel(stdcontext.Background())
|
||||
defer cancel()
|
||||
|
||||
var wg errgroup.Group
|
||||
|
||||
// Run the render thread.
|
||||
wg.Go(func() error {
|
||||
defer cancel()
|
||||
_ = u.renderThread.Loop(ctx)
|
||||
return nil
|
||||
})
|
||||
|
||||
// Run the game thread.
|
||||
wg.Go(func() error {
|
||||
defer cancel()
|
||||
|
||||
u.renderThread.Call(func() {
|
||||
u.egl.makeContextCurrent()
|
||||
})
|
||||
|
||||
for {
|
||||
recordProfilerHeartbeat()
|
||||
|
||||
if err := u.context.updateFrame(u.graphicsDriver, float64(C.kScreenWidth), float64(C.kScreenHeight), deviceScaleFactor, u, func() {
|
||||
u.egl.swapBuffers()
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
// Run the main thread.
|
||||
_ = u.mainThread.Loop(ctx)
|
||||
if err := wg.Wait(); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (u *UserInterface) loopGame() error {
|
||||
u.renderThread.Call(func() {
|
||||
u.egl.makeContextCurrent()
|
||||
})
|
||||
|
||||
for {
|
||||
recordProfilerHeartbeat()
|
||||
|
||||
if err := u.context.updateFrame(u.graphicsDriver, float64(C.kScreenWidth), float64(C.kScreenHeight), deviceScaleFactor, u, func() {
|
||||
u.egl.swapBuffers()
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (*UserInterface) DeviceScaleFactor() float64 {
|
||||
return deviceScaleFactor
|
||||
}
|
||||
|
@ -64,10 +64,15 @@ func (u *UserInterface) init() error {
|
||||
}
|
||||
|
||||
func (u *UserInterface) Run(game Game, options *RunOptions) error {
|
||||
u.setRunning(true)
|
||||
defer u.setRunning(false)
|
||||
return u.run(game, options)
|
||||
}
|
||||
|
||||
// TODO: Implement this.
|
||||
func (u *UserInterface) initOnMainThread(options *RunOptions) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (u *UserInterface) loopGame() error {
|
||||
// TODO: Implement this
|
||||
return nil
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user