From 27fd10595bcb1f69db8b6875ab1aa4cfe27350ad Mon Sep 17 00:00:00 2001 From: Hajime Hoshi Date: Sun, 15 Oct 2023 00:06:07 +0900 Subject: [PATCH] internal/ui: refactoring: reduce global functions and prefer Get() --- exp/textinput/textinput.go | 2 +- exp/textinput/textinput_darwin.go | 2 +- image.go | 2 +- imagedumper.go | 2 +- input.go | 2 +- internal/atlas/image_test.go | 48 +++++++------- internal/atlas/shader_test.go | 4 +- internal/graphicscommand/image_test.go | 4 +- internal/restorable/images_test.go | 88 +++++++++++++------------- internal/restorable/shader_test.go | 20 +++--- internal/ui/context.go | 4 +- internal/ui/globalstate.go | 5 +- internal/ui/graphics.go | 4 +- internal/ui/hideconsole_notwindows.go | 20 ------ internal/ui/hideconsole_windows.go | 4 +- internal/ui/image.go | 41 +++++------- internal/ui/input_glfw.go | 6 +- internal/ui/input_js.go | 6 +- internal/ui/input_mobile.go | 2 +- internal/ui/input_nintendosdk.go | 2 +- internal/ui/ui.go | 35 +++++++++- internal/ui/ui_darwin.go | 14 ++-- internal/ui/ui_glfw.go | 37 ++++++----- internal/ui/ui_js.go | 54 ++++++++-------- internal/ui/ui_linbsd.go | 4 ++ internal/ui/ui_mobile.go | 13 ++-- internal/ui/ui_nintendosdk.go | 2 +- internal/ui/ui_windows.go | 5 ++ run.go | 6 +- run_mobile.go | 2 +- 30 files changed, 226 insertions(+), 214 deletions(-) delete mode 100644 internal/ui/hideconsole_notwindows.go diff --git a/exp/textinput/textinput.go b/exp/textinput/textinput.go index 3c7286e52..c2ddd49bc 100644 --- a/exp/textinput/textinput.go +++ b/exp/textinput/textinput.go @@ -44,7 +44,7 @@ type State struct { // // Start returns nil and nil if the current environment doesn't support this package. func Start(x, y int) (states chan State, close func()) { - cx, cy := ui.LogicalPositionToClientPosition(float64(x), float64(y)) + cx, cy := ui.Get().LogicalPositionToClientPosition(float64(x), float64(y)) return theTextInput.Start(int(cx), int(cy)) } diff --git a/exp/textinput/textinput_darwin.go b/exp/textinput/textinput_darwin.go index a1096aef6..2ce6949a2 100644 --- a/exp/textinput/textinput_darwin.go +++ b/exp/textinput/textinput_darwin.go @@ -58,7 +58,7 @@ var theTextInput textInput func (t *textInput) Start(x, y int) (chan State, func()) { var session *session - ui.RunOnMainThread(func() { + ui.Get().RunOnMainThread(func() { if t.session != nil { t.session.end() t.session = nil diff --git a/image.go b/image.go index 279c33da2..b97433ee0 100644 --- a/image.go +++ b/image.go @@ -1068,7 +1068,7 @@ func newImage(bounds image.Rectangle, imageType atlas.ImageType) *Image { } i := &Image{ - image: ui.NewImage(width, height, imageType), + image: ui.Get().NewImage(width, height, imageType), bounds: bounds, } i.addr = i diff --git a/imagedumper.go b/imagedumper.go index b081471bf..327e4854c 100644 --- a/imagedumper.go +++ b/imagedumper.go @@ -52,7 +52,7 @@ func takeScreenshot(screen *Image, transparent bool) error { } func dumpInternalImages() error { - dumpedDir, err := ui.DumpImages("internalimages_" + datetimeForFilename()) + dumpedDir, err := ui.Get().DumpImages("internalimages_" + datetimeForFilename()) if err != nil { return err } diff --git a/input.go b/input.go index eca33733b..315a48033 100644 --- a/input.go +++ b/input.go @@ -76,7 +76,7 @@ func IsKeyPressed(key Key) bool { // // KeyName is concurrent-safe. func KeyName(key Key) string { - return ui.KeyName(ui.Key(key)) + return ui.Get().KeyName(ui.Key(key)) } // CursorPosition returns a position of a mouse cursor relative to the game screen (window). The cursor position is diff --git a/internal/atlas/image_test.go b/internal/atlas/image_test.go index 2b54748dd..f0efd545d 100644 --- a/internal/atlas/image_test.go +++ b/internal/atlas/image_test.go @@ -117,7 +117,7 @@ func TestEnsureIsolatedFromSourceBackend(t *testing.T) { } pix = make([]byte, 4*size*size) - if err := img4.ReadPixels(ui.GraphicsDriverForTesting(), pix, image.Rect(0, 0, size, size)); err != nil { + if err := img4.ReadPixels(ui.Get().GraphicsDriverForTesting(), pix, image.Rect(0, 0, size, size)); err != nil { t.Fatal(err) } for j := 0; j < size; j++ { @@ -195,7 +195,7 @@ func TestReputOnSourceBackend(t *testing.T) { // Use the doubled count since img1 was on a texture atlas and became an isolated image once. // Then, img1 requires longer time to recover to be on a texture atlas again. for i := 0; i < atlas.BaseCountToPutOnSourceBackend*2; i++ { - atlas.PutImagesOnSourceBackendForTesting(ui.GraphicsDriverForTesting()) + atlas.PutImagesOnSourceBackendForTesting(ui.Get().GraphicsDriverForTesting()) vs := quadVertices(size, size, 0, 0, 1) img0.DrawTriangles([graphics.ShaderImageCount]*atlas.Image{img1}, vs, is, graphicsdriver.BlendCopy, dr, [graphics.ShaderImageCount]image.Rectangle{}, atlas.NearestFilterShader, nil, false) if got, want := img1.IsOnSourceBackendForTesting(), false; got != want { @@ -203,16 +203,16 @@ func TestReputOnSourceBackend(t *testing.T) { } } // Finally, img1 is on a source backend. - atlas.PutImagesOnSourceBackendForTesting(ui.GraphicsDriverForTesting()) + atlas.PutImagesOnSourceBackendForTesting(ui.Get().GraphicsDriverForTesting()) vs := quadVertices(size, size, 0, 0, 1) img0.DrawTriangles([graphics.ShaderImageCount]*atlas.Image{img1}, vs, is, graphicsdriver.BlendCopy, dr, [graphics.ShaderImageCount]image.Rectangle{}, atlas.NearestFilterShader, nil, false) if got, want := img1.IsOnSourceBackendForTesting(), true; got != want { t.Errorf("got: %v, want: %v", got, want) } - atlas.PutImagesOnSourceBackendForTesting(ui.GraphicsDriverForTesting()) + atlas.PutImagesOnSourceBackendForTesting(ui.Get().GraphicsDriverForTesting()) pix = make([]byte, 4*size*size) - if err := img1.ReadPixels(ui.GraphicsDriverForTesting(), pix, image.Rect(0, 0, size, size)); err != nil { + if err := img1.ReadPixels(ui.Get().GraphicsDriverForTesting(), pix, image.Rect(0, 0, size, size)); err != nil { t.Fatal(err) } for j := 0; j < size; j++ { @@ -236,7 +236,7 @@ func TestReputOnSourceBackend(t *testing.T) { } pix = make([]byte, 4*size*size) - if err := img1.ReadPixels(ui.GraphicsDriverForTesting(), pix, image.Rect(0, 0, size, size)); err != nil { + if err := img1.ReadPixels(ui.Get().GraphicsDriverForTesting(), pix, image.Rect(0, 0, size, size)); err != nil { t.Fatal(err) } for j := 0; j < size; j++ { @@ -265,7 +265,7 @@ func TestReputOnSourceBackend(t *testing.T) { // Use img1 as a render source, but call WritePixels. // Now use 4x count as img1 became an isolated image again. for i := 0; i < atlas.BaseCountToPutOnSourceBackend*4; i++ { - atlas.PutImagesOnSourceBackendForTesting(ui.GraphicsDriverForTesting()) + atlas.PutImagesOnSourceBackendForTesting(ui.Get().GraphicsDriverForTesting()) img1.WritePixels(make([]byte, 4*size*size), image.Rect(0, 0, size, size)) vs := quadVertices(size, size, 0, 0, 1) img0.DrawTriangles([graphics.ShaderImageCount]*atlas.Image{img1}, vs, is, graphicsdriver.BlendCopy, dr, [graphics.ShaderImageCount]image.Rectangle{}, atlas.NearestFilterShader, nil, false) @@ -273,7 +273,7 @@ func TestReputOnSourceBackend(t *testing.T) { t.Errorf("got: %v, want: %v", got, want) } } - atlas.PutImagesOnSourceBackendForTesting(ui.GraphicsDriverForTesting()) + atlas.PutImagesOnSourceBackendForTesting(ui.Get().GraphicsDriverForTesting()) // img1 is not on an atlas due to WritePixels. vs = quadVertices(size, size, 0, 0, 1) @@ -284,7 +284,7 @@ func TestReputOnSourceBackend(t *testing.T) { // Use img3 as a render source. As img3 is volatile, img3 is never on an atlas. for i := 0; i < atlas.BaseCountToPutOnSourceBackend*2; i++ { - atlas.PutImagesOnSourceBackendForTesting(ui.GraphicsDriverForTesting()) + atlas.PutImagesOnSourceBackendForTesting(ui.Get().GraphicsDriverForTesting()) vs := quadVertices(size, size, 0, 0, 1) img0.DrawTriangles([graphics.ShaderImageCount]*atlas.Image{img3}, vs, is, graphicsdriver.BlendCopy, dr, [graphics.ShaderImageCount]image.Rectangle{}, atlas.NearestFilterShader, nil, false) if got, want := img3.IsOnSourceBackendForTesting(), false; got != want { @@ -324,7 +324,7 @@ func TestExtend(t *testing.T) { img1.WritePixels(p1, image.Rect(0, 0, w1, h1)) pix0 := make([]byte, 4*w0*h0) - if err := img0.ReadPixels(ui.GraphicsDriverForTesting(), pix0, image.Rect(0, 0, w0, h0)); err != nil { + if err := img0.ReadPixels(ui.Get().GraphicsDriverForTesting(), pix0, image.Rect(0, 0, w0, h0)); err != nil { t.Fatal(err) } for j := 0; j < h0; j++ { @@ -343,7 +343,7 @@ func TestExtend(t *testing.T) { } pix1 := make([]byte, 4*w1*h1) - if err := img1.ReadPixels(ui.GraphicsDriverForTesting(), pix1, image.Rect(0, 0, w1, h1)); err != nil { + if err := img1.ReadPixels(ui.Get().GraphicsDriverForTesting(), pix1, image.Rect(0, 0, w1, h1)); err != nil { t.Fatal(err) } for j := 0; j < h1; j++ { @@ -385,7 +385,7 @@ func TestWritePixelsAfterDrawTriangles(t *testing.T) { dst.WritePixels(pix, image.Rect(0, 0, w, h)) pix = make([]byte, 4*w*h) - if err := dst.ReadPixels(ui.GraphicsDriverForTesting(), pix, image.Rect(0, 0, w, h)); err != nil { + if err := dst.ReadPixels(ui.Get().GraphicsDriverForTesting(), pix, image.Rect(0, 0, w, h)); err != nil { t.Fatal(err) } for j := 0; j < h; j++ { @@ -427,7 +427,7 @@ func TestSmallImages(t *testing.T) { dst.DrawTriangles([graphics.ShaderImageCount]*atlas.Image{src}, vs, is, graphicsdriver.BlendSourceOver, dr, [graphics.ShaderImageCount]image.Rectangle{}, atlas.NearestFilterShader, nil, false) pix = make([]byte, 4*w*h) - if err := dst.ReadPixels(ui.GraphicsDriverForTesting(), pix, image.Rect(0, 0, w, h)); err != nil { + if err := dst.ReadPixels(ui.Get().GraphicsDriverForTesting(), pix, image.Rect(0, 0, w, h)); err != nil { t.Fatal(err) } for j := 0; j < h; j++ { @@ -470,7 +470,7 @@ func TestLongImages(t *testing.T) { dst.DrawTriangles([graphics.ShaderImageCount]*atlas.Image{src}, vs, is, graphicsdriver.BlendSourceOver, dr, [graphics.ShaderImageCount]image.Rectangle{}, atlas.NearestFilterShader, nil, false) pix = make([]byte, 4*dstW*dstH) - if err := dst.ReadPixels(ui.GraphicsDriverForTesting(), pix, image.Rect(0, 0, dstW, dstH)); err != nil { + if err := dst.ReadPixels(ui.Get().GraphicsDriverForTesting(), pix, image.Rect(0, 0, dstW, dstH)); err != nil { t.Fatal(err) } for j := 0; j < h; j++ { @@ -586,7 +586,7 @@ func TestDisposedAndReputOnSourceBackend(t *testing.T) { // Use src as a render source. for i := 0; i < atlas.BaseCountToPutOnSourceBackend/2; i++ { - atlas.PutImagesOnSourceBackendForTesting(ui.GraphicsDriverForTesting()) + atlas.PutImagesOnSourceBackendForTesting(ui.Get().GraphicsDriverForTesting()) vs := quadVertices(size, size, 0, 0, 1) dst.DrawTriangles([graphics.ShaderImageCount]*atlas.Image{src}, vs, is, graphicsdriver.BlendCopy, dr, [graphics.ShaderImageCount]image.Rectangle{}, atlas.NearestFilterShader, nil, false) if got, want := src.IsOnSourceBackendForTesting(), false; got != want { @@ -601,7 +601,7 @@ func TestDisposedAndReputOnSourceBackend(t *testing.T) { atlas.FlushDeferredForTesting() // Confirm that PutImagesOnSourceBackendForTesting doesn't panic. - atlas.PutImagesOnSourceBackendForTesting(ui.GraphicsDriverForTesting()) + atlas.PutImagesOnSourceBackendForTesting(ui.Get().GraphicsDriverForTesting()) } // Issue #1456 @@ -634,7 +634,7 @@ func TestImageIsNotReputOnSourceBackendWithoutUsingAsSource(t *testing.T) { // Update the count without using src2 as a rendering source. // This should not affect whether src2 is on an atlas or not. for i := 0; i < atlas.BaseCountToPutOnSourceBackend; i++ { - atlas.PutImagesOnSourceBackendForTesting(ui.GraphicsDriverForTesting()) + atlas.PutImagesOnSourceBackendForTesting(ui.Get().GraphicsDriverForTesting()) if got, want := src2.IsOnSourceBackendForTesting(), false; got != want { t.Errorf("got: %v, want: %v", got, want) } @@ -642,7 +642,7 @@ func TestImageIsNotReputOnSourceBackendWithoutUsingAsSource(t *testing.T) { // Update the count with using src2 as a rendering source. for i := 0; i < atlas.BaseCountToPutOnSourceBackend; i++ { - atlas.PutImagesOnSourceBackendForTesting(ui.GraphicsDriverForTesting()) + atlas.PutImagesOnSourceBackendForTesting(ui.Get().GraphicsDriverForTesting()) vs := quadVertices(size, size, 0, 0, 1) dst.DrawTriangles([graphics.ShaderImageCount]*atlas.Image{src2}, vs, is, graphicsdriver.BlendCopy, dr, [graphics.ShaderImageCount]image.Rectangle{}, atlas.NearestFilterShader, nil, false) if got, want := src2.IsOnSourceBackendForTesting(), false; got != want { @@ -650,7 +650,7 @@ func TestImageIsNotReputOnSourceBackendWithoutUsingAsSource(t *testing.T) { } } - atlas.PutImagesOnSourceBackendForTesting(ui.GraphicsDriverForTesting()) + atlas.PutImagesOnSourceBackendForTesting(ui.Get().GraphicsDriverForTesting()) if got, want := src2.IsOnSourceBackendForTesting(), true; got != want { t.Errorf("got: %v, want: %v", got, want) } @@ -684,7 +684,7 @@ func TestImageWritePixelsModify(t *testing.T) { // Check the pixels are the original ones. pix = make([]byte, 4*size*size) - if err := img.ReadPixels(ui.GraphicsDriverForTesting(), pix, image.Rect(0, 0, size, size)); err != nil { + if err := img.ReadPixels(ui.Get().GraphicsDriverForTesting(), pix, image.Rect(0, 0, size, size)); err != nil { t.Fatal(err) } for j := 0; j < size; j++ { @@ -767,14 +767,14 @@ func TestDestinationCountOverflow(t *testing.T) { // Use dst0 as a destination for a while. for i := 0; i < 31; i++ { dst0.DrawTriangles([graphics.ShaderImageCount]*atlas.Image{src}, vs, is, graphicsdriver.BlendCopy, dr, [graphics.ShaderImageCount]image.Rectangle{}, atlas.NearestFilterShader, nil, false) - atlas.PutImagesOnSourceBackendForTesting(ui.GraphicsDriverForTesting()) + atlas.PutImagesOnSourceBackendForTesting(ui.Get().GraphicsDriverForTesting()) } // Use dst0 as a source for a while. // As dst0 is used as a destination too many times (31 is a maximum), dst0's backend should never be a source backend. for i := 0; i < 100; i++ { dst1.DrawTriangles([graphics.ShaderImageCount]*atlas.Image{dst0}, vs, is, graphicsdriver.BlendCopy, dr, [graphics.ShaderImageCount]image.Rectangle{}, atlas.NearestFilterShader, nil, false) - atlas.PutImagesOnSourceBackendForTesting(ui.GraphicsDriverForTesting()) + atlas.PutImagesOnSourceBackendForTesting(ui.Get().GraphicsDriverForTesting()) if dst0.IsOnSourceBackendForTesting() { t.Errorf("dst0 cannot be on a source backend: %d", i) } @@ -801,7 +801,7 @@ func TestIteratingImagesToPutOnSourceBackend(t *testing.T) { for _, img := range srcs { img.DrawTriangles([graphics.ShaderImageCount]*atlas.Image{src}, vs, is, graphicsdriver.BlendCopy, dr, [graphics.ShaderImageCount]image.Rectangle{}, atlas.NearestFilterShader, nil, false) } - atlas.PutImagesOnSourceBackendForTesting(ui.GraphicsDriverForTesting()) + atlas.PutImagesOnSourceBackendForTesting(ui.Get().GraphicsDriverForTesting()) // Use srcs as sources. This will register an image to imagesToPutOnSourceBackend. // Check iterating the registered image works correctly. @@ -809,7 +809,7 @@ func TestIteratingImagesToPutOnSourceBackend(t *testing.T) { for _, src := range srcs { dst.DrawTriangles([graphics.ShaderImageCount]*atlas.Image{src}, vs, is, graphicsdriver.BlendCopy, dr, [graphics.ShaderImageCount]image.Rectangle{}, atlas.NearestFilterShader, nil, false) } - atlas.PutImagesOnSourceBackendForTesting(ui.GraphicsDriverForTesting()) + atlas.PutImagesOnSourceBackendForTesting(ui.Get().GraphicsDriverForTesting()) } } diff --git a/internal/atlas/shader_test.go b/internal/atlas/shader_test.go index 18e269cbd..dd3966d12 100644 --- a/internal/atlas/shader_test.go +++ b/internal/atlas/shader_test.go @@ -34,7 +34,7 @@ func TestShaderFillTwice(t *testing.T) { vs := quadVertices(w, h, 0, 0, 1) is := graphics.QuadIndices() dr := image.Rect(0, 0, w, h) - g := ui.GraphicsDriverForTesting() + g := ui.Get().GraphicsDriverForTesting() s0 := atlas.NewShader(etesting.ShaderProgramFill(0xff, 0xff, 0xff, 0xff)) dst.DrawTriangles([graphics.ShaderImageCount]*atlas.Image{}, vs, is, graphicsdriver.BlendCopy, dr, [graphics.ShaderImageCount]image.Rectangle{}, s0, nil, false) @@ -71,7 +71,7 @@ func TestImageDrawTwice(t *testing.T) { dst.DrawTriangles([graphics.ShaderImageCount]*atlas.Image{src1}, vs, is, graphicsdriver.BlendCopy, dr, [graphics.ShaderImageCount]image.Rectangle{}, atlas.NearestFilterShader, nil, false) pix := make([]byte, 4*w*h) - if err := dst.ReadPixels(ui.GraphicsDriverForTesting(), pix, image.Rect(0, 0, w, h)); err != nil { + if err := dst.ReadPixels(ui.Get().GraphicsDriverForTesting(), pix, image.Rect(0, 0, w, h)); err != nil { t.Error(err) } if got, want := (color.RGBA{R: pix[0], G: pix[1], B: pix[2], A: pix[3]}), (color.RGBA{R: 0x80, G: 0x80, B: 0x80, A: 0xff}); got != want { diff --git a/internal/graphicscommand/image_test.go b/internal/graphicscommand/image_test.go index ae55efc9a..0991cb526 100644 --- a/internal/graphicscommand/image_test.go +++ b/internal/graphicscommand/image_test.go @@ -62,7 +62,7 @@ func TestClear(t *testing.T) { dst.DrawTriangles([graphics.ShaderImageCount]*graphicscommand.Image{src}, vs, is, graphicsdriver.BlendClear, dr, [graphics.ShaderImageCount]image.Rectangle{}, nearestFilterShader, nil, false) pix := make([]byte, 4*w*h) - if err := dst.ReadPixels(ui.GraphicsDriverForTesting(), []graphicsdriver.PixelsArgs{ + if err := dst.ReadPixels(ui.Get().GraphicsDriverForTesting(), []graphicsdriver.PixelsArgs{ { Pixels: pix, Region: image.Rect(0, 0, w, h), @@ -111,7 +111,7 @@ func TestShader(t *testing.T) { dr := image.Rect(0, 0, w, h) dst.DrawTriangles([graphics.ShaderImageCount]*graphicscommand.Image{clr}, vs, is, graphicsdriver.BlendClear, dr, [graphics.ShaderImageCount]image.Rectangle{}, nearestFilterShader, nil, false) - g := ui.GraphicsDriverForTesting() + g := ui.Get().GraphicsDriverForTesting() s := graphicscommand.NewShader(etesting.ShaderProgramFill(0xff, 0, 0, 0xff)) dst.DrawTriangles([graphics.ShaderImageCount]*graphicscommand.Image{}, vs, is, graphicsdriver.BlendSourceOver, dr, [graphics.ShaderImageCount]image.Rectangle{}, s, nil, false) diff --git a/internal/restorable/images_test.go b/internal/restorable/images_test.go index 4c02e7fe9..a9fdfa720 100644 --- a/internal/restorable/images_test.go +++ b/internal/restorable/images_test.go @@ -71,10 +71,10 @@ func TestRestore(t *testing.T) { clr0 := color.RGBA{A: 0xff} img0.WritePixels(bytesToManagedBytes([]byte{clr0.R, clr0.G, clr0.B, clr0.A}), image.Rect(0, 0, 1, 1)) - if err := restorable.ResolveStaleImages(ui.GraphicsDriverForTesting()); err != nil { + if err := restorable.ResolveStaleImages(ui.Get().GraphicsDriverForTesting()); err != nil { t.Fatal(err) } - if err := restorable.RestoreIfNeeded(ui.GraphicsDriverForTesting()); err != nil { + if err := restorable.RestoreIfNeeded(ui.Get().GraphicsDriverForTesting()); err != nil { t.Fatal(err) } want := clr0 @@ -90,10 +90,10 @@ func TestRestoreWithoutDraw(t *testing.T) { // If there is no drawing command on img0, img0 is cleared when restored. - if err := restorable.ResolveStaleImages(ui.GraphicsDriverForTesting()); err != nil { + if err := restorable.ResolveStaleImages(ui.Get().GraphicsDriverForTesting()); err != nil { t.Fatal(err) } - if err := restorable.RestoreIfNeeded(ui.GraphicsDriverForTesting()); err != nil { + if err := restorable.RestoreIfNeeded(ui.Get().GraphicsDriverForTesting()); err != nil { t.Fatal(err) } @@ -145,10 +145,10 @@ func TestRestoreChain(t *testing.T) { dr := image.Rect(0, 0, 1, 1) imgs[i+1].DrawTriangles([graphics.ShaderImageCount]*restorable.Image{imgs[i]}, vs, is, graphicsdriver.BlendCopy, dr, [graphics.ShaderImageCount]image.Rectangle{}, restorable.NearestFilterShader, nil, false) } - if err := restorable.ResolveStaleImages(ui.GraphicsDriverForTesting()); err != nil { + if err := restorable.ResolveStaleImages(ui.Get().GraphicsDriverForTesting()); err != nil { t.Fatal(err) } - if err := restorable.RestoreIfNeeded(ui.GraphicsDriverForTesting()); err != nil { + if err := restorable.RestoreIfNeeded(ui.Get().GraphicsDriverForTesting()); err != nil { t.Fatal(err) } want := clr @@ -192,10 +192,10 @@ func TestRestoreChain2(t *testing.T) { imgs[i+1].DrawTriangles([graphics.ShaderImageCount]*restorable.Image{imgs[i]}, quadVertices(w, h, 0, 0), is, graphicsdriver.BlendCopy, dr, [graphics.ShaderImageCount]image.Rectangle{}, restorable.NearestFilterShader, nil, false) } - if err := restorable.ResolveStaleImages(ui.GraphicsDriverForTesting()); err != nil { + if err := restorable.ResolveStaleImages(ui.Get().GraphicsDriverForTesting()); err != nil { t.Fatal(err) } - if err := restorable.RestoreIfNeeded(ui.GraphicsDriverForTesting()); err != nil { + if err := restorable.RestoreIfNeeded(ui.Get().GraphicsDriverForTesting()); err != nil { t.Fatal(err) } for i, img := range imgs { @@ -234,10 +234,10 @@ func TestRestoreOverrideSource(t *testing.T) { img3.DrawTriangles([graphics.ShaderImageCount]*restorable.Image{img2}, quadVertices(w, h, 0, 0), is, graphicsdriver.BlendSourceOver, dr, [graphics.ShaderImageCount]image.Rectangle{}, restorable.NearestFilterShader, nil, false) img0.WritePixels(bytesToManagedBytes([]byte{clr1.R, clr1.G, clr1.B, clr1.A}), image.Rect(0, 0, w, h)) img1.DrawTriangles([graphics.ShaderImageCount]*restorable.Image{img0}, quadVertices(w, h, 0, 0), is, graphicsdriver.BlendSourceOver, dr, [graphics.ShaderImageCount]image.Rectangle{}, restorable.NearestFilterShader, nil, false) - if err := restorable.ResolveStaleImages(ui.GraphicsDriverForTesting()); err != nil { + if err := restorable.ResolveStaleImages(ui.Get().GraphicsDriverForTesting()); err != nil { t.Fatal(err) } - if err := restorable.RestoreIfNeeded(ui.GraphicsDriverForTesting()); err != nil { + if err := restorable.RestoreIfNeeded(ui.Get().GraphicsDriverForTesting()); err != nil { t.Fatal(err) } testCases := []struct { @@ -330,10 +330,10 @@ func TestRestoreComplexGraph(t *testing.T) { img7.DrawTriangles([graphics.ShaderImageCount]*restorable.Image{img2}, vs, is, graphicsdriver.BlendSourceOver, dr, [graphics.ShaderImageCount]image.Rectangle{}, restorable.NearestFilterShader, nil, false) vs = quadVertices(w, h, 2, 0) img7.DrawTriangles([graphics.ShaderImageCount]*restorable.Image{img3}, vs, is, graphicsdriver.BlendSourceOver, dr, [graphics.ShaderImageCount]image.Rectangle{}, restorable.NearestFilterShader, nil, false) - if err := restorable.ResolveStaleImages(ui.GraphicsDriverForTesting()); err != nil { + if err := restorable.ResolveStaleImages(ui.Get().GraphicsDriverForTesting()); err != nil { t.Fatal(err) } - if err := restorable.RestoreIfNeeded(ui.GraphicsDriverForTesting()); err != nil { + if err := restorable.RestoreIfNeeded(ui.Get().GraphicsDriverForTesting()); err != nil { t.Fatal(err) } testCases := []struct { @@ -424,10 +424,10 @@ func TestRestoreRecursive(t *testing.T) { dr := image.Rect(0, 0, w, h) img1.DrawTriangles([graphics.ShaderImageCount]*restorable.Image{img0}, quadVertices(w, h, 1, 0), is, graphicsdriver.BlendSourceOver, dr, [graphics.ShaderImageCount]image.Rectangle{}, restorable.NearestFilterShader, nil, false) img0.DrawTriangles([graphics.ShaderImageCount]*restorable.Image{img1}, quadVertices(w, h, 1, 0), is, graphicsdriver.BlendSourceOver, dr, [graphics.ShaderImageCount]image.Rectangle{}, restorable.NearestFilterShader, nil, false) - if err := restorable.ResolveStaleImages(ui.GraphicsDriverForTesting()); err != nil { + if err := restorable.ResolveStaleImages(ui.Get().GraphicsDriverForTesting()); err != nil { t.Fatal(err) } - if err := restorable.RestoreIfNeeded(ui.GraphicsDriverForTesting()); err != nil { + if err := restorable.RestoreIfNeeded(ui.Get().GraphicsDriverForTesting()); err != nil { t.Fatal(err) } testCases := []struct { @@ -474,7 +474,7 @@ func TestWritePixels(t *testing.T) { for i := range pix { pix[i] = 0 } - if err := img.ReadPixels(ui.GraphicsDriverForTesting(), pix, image.Rect(5, 7, 9, 11)); err != nil { + if err := img.ReadPixels(ui.Get().GraphicsDriverForTesting(), pix, image.Rect(5, 7, 9, 11)); err != nil { t.Fatal(err) } for j := 7; j < 11; j++ { @@ -487,13 +487,13 @@ func TestWritePixels(t *testing.T) { } } } - if err := restorable.ResolveStaleImages(ui.GraphicsDriverForTesting()); err != nil { + if err := restorable.ResolveStaleImages(ui.Get().GraphicsDriverForTesting()); err != nil { t.Fatal(err) } - if err := restorable.RestoreIfNeeded(ui.GraphicsDriverForTesting()); err != nil { + if err := restorable.RestoreIfNeeded(ui.Get().GraphicsDriverForTesting()); err != nil { t.Fatal(err) } - if err := img.ReadPixels(ui.GraphicsDriverForTesting(), pix, image.Rect(5, 7, 9, 11)); err != nil { + if err := img.ReadPixels(ui.Get().GraphicsDriverForTesting(), pix, image.Rect(5, 7, 9, 11)); err != nil { t.Fatal(err) } for j := 7; j < 11; j++ { @@ -525,14 +525,14 @@ func TestDrawTrianglesAndWritePixels(t *testing.T) { img1.DrawTriangles([graphics.ShaderImageCount]*restorable.Image{img0}, vs, is, graphicsdriver.BlendCopy, dr, [graphics.ShaderImageCount]image.Rectangle{}, restorable.NearestFilterShader, nil, false) img1.WritePixels(bytesToManagedBytes([]byte{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}), image.Rect(0, 0, 2, 1)) - if err := restorable.ResolveStaleImages(ui.GraphicsDriverForTesting()); err != nil { + if err := restorable.ResolveStaleImages(ui.Get().GraphicsDriverForTesting()); err != nil { t.Fatal(err) } - if err := restorable.RestoreIfNeeded(ui.GraphicsDriverForTesting()); err != nil { + if err := restorable.RestoreIfNeeded(ui.Get().GraphicsDriverForTesting()); err != nil { t.Fatal(err) } var pix [4]byte - if err := img1.ReadPixels(ui.GraphicsDriverForTesting(), pix[:], image.Rect(0, 0, 1, 1)); err != nil { + if err := img1.ReadPixels(ui.Get().GraphicsDriverForTesting(), pix[:], image.Rect(0, 0, 1, 1)); err != nil { t.Fatal(err) } got := color.RGBA{R: pix[0], G: pix[1], B: pix[2], A: pix[3]} @@ -564,14 +564,14 @@ func TestDispose(t *testing.T) { img0.DrawTriangles([graphics.ShaderImageCount]*restorable.Image{img1}, quadVertices(1, 1, 0, 0), is, graphicsdriver.BlendCopy, dr, [graphics.ShaderImageCount]image.Rectangle{}, restorable.NearestFilterShader, nil, false) img1.Dispose() - if err := restorable.ResolveStaleImages(ui.GraphicsDriverForTesting()); err != nil { + if err := restorable.ResolveStaleImages(ui.Get().GraphicsDriverForTesting()); err != nil { t.Fatal(err) } - if err := restorable.RestoreIfNeeded(ui.GraphicsDriverForTesting()); err != nil { + if err := restorable.RestoreIfNeeded(ui.Get().GraphicsDriverForTesting()); err != nil { t.Fatal(err) } var pix [4]byte - if err := img0.ReadPixels(ui.GraphicsDriverForTesting(), pix[:], image.Rect(0, 0, 1, 1)); err != nil { + if err := img0.ReadPixels(ui.Get().GraphicsDriverForTesting(), pix[:], image.Rect(0, 0, 1, 1)); err != nil { t.Fatal(err) } got := color.RGBA{R: pix[0], G: pix[1], B: pix[2], A: pix[3]} @@ -691,10 +691,10 @@ func TestWritePixelsOnly(t *testing.T) { } } - if err := restorable.ResolveStaleImages(ui.GraphicsDriverForTesting()); err != nil { + if err := restorable.ResolveStaleImages(ui.Get().GraphicsDriverForTesting()); err != nil { t.Fatal(err) } - if err := restorable.RestoreIfNeeded(ui.GraphicsDriverForTesting()); err != nil { + if err := restorable.RestoreIfNeeded(ui.Get().GraphicsDriverForTesting()); err != nil { t.Fatal(err) } want := color.RGBA{R: 1, G: 2, B: 3, A: 4} @@ -731,7 +731,7 @@ func TestReadPixelsFromVolatileImage(t *testing.T) { want := byte(0xff) var result [4]byte - if err := dst.ReadPixels(ui.GraphicsDriverForTesting(), result[:], image.Rect(0, 0, 1, 1)); err != nil { + if err := dst.ReadPixels(ui.Get().GraphicsDriverForTesting(), result[:], image.Rect(0, 0, 1, 1)); err != nil { t.Fatal(err) } got := result[0] @@ -771,15 +771,15 @@ func TestAllowWritePixelsForPartAfterDrawTriangles(t *testing.T) { dst.WritePixels(bytesToManagedBytes(make([]byte, 4*2*2)), image.Rect(0, 0, 2, 2)) // WritePixels for a part of image doesn't panic. - if err := restorable.ResolveStaleImages(ui.GraphicsDriverForTesting()); err != nil { + if err := restorable.ResolveStaleImages(ui.Get().GraphicsDriverForTesting()); err != nil { t.Fatal(err) } - if err := restorable.RestoreIfNeeded(ui.GraphicsDriverForTesting()); err != nil { + if err := restorable.RestoreIfNeeded(ui.Get().GraphicsDriverForTesting()); err != nil { t.Fatal(err) } result := make([]byte, 4*w*h) - if err := dst.ReadPixels(ui.GraphicsDriverForTesting(), result, image.Rect(0, 0, w, h)); err != nil { + if err := dst.ReadPixels(ui.Get().GraphicsDriverForTesting(), result, image.Rect(0, 0, w, h)); err != nil { t.Fatal(err) } for j := 0; j < h; j++ { @@ -819,7 +819,7 @@ func TestExtend(t *testing.T) { extended := orig.Extend(w*2, h*2) // After this, orig is already disposed. result := make([]byte, 4*(w*2)*(h*2)) - if err := extended.ReadPixels(ui.GraphicsDriverForTesting(), result, image.Rect(0, 0, w*2, h*2)); err != nil { + if err := extended.ReadPixels(ui.Get().GraphicsDriverForTesting(), result, image.Rect(0, 0, w*2, h*2)); err != nil { t.Fatal(err) } for j := 0; j < h*2; j++ { @@ -865,7 +865,7 @@ func TestDrawTrianglesAndExtend(t *testing.T) { extended := orig.Extend(w*2, h*2) // After this, orig is already disposed. result := make([]byte, 4*(w*2)*(h*2)) - if err := extended.ReadPixels(ui.GraphicsDriverForTesting(), result, image.Rect(0, 0, w*2, h*2)); err != nil { + if err := extended.ReadPixels(ui.Get().GraphicsDriverForTesting(), result, image.Rect(0, 0, w*2, h*2)); err != nil { t.Fatal(err) } for j := 0; j < h*2; j++ { @@ -918,19 +918,19 @@ func TestMutateSlices(t *testing.T) { for i := range is { is[i] = 0 } - if err := restorable.ResolveStaleImages(ui.GraphicsDriverForTesting()); err != nil { + if err := restorable.ResolveStaleImages(ui.Get().GraphicsDriverForTesting()); err != nil { t.Fatal(err) } - if err := restorable.RestoreIfNeeded(ui.GraphicsDriverForTesting()); err != nil { + if err := restorable.RestoreIfNeeded(ui.Get().GraphicsDriverForTesting()); err != nil { t.Fatal(err) } srcPix := make([]byte, 4*w*h) - if err := src.ReadPixels(ui.GraphicsDriverForTesting(), srcPix, image.Rect(0, 0, w, h)); err != nil { + if err := src.ReadPixels(ui.Get().GraphicsDriverForTesting(), srcPix, image.Rect(0, 0, w, h)); err != nil { t.Fatal(err) } dstPix := make([]byte, 4*w*h) - if err := dst.ReadPixels(ui.GraphicsDriverForTesting(), dstPix, image.Rect(0, 0, w, h)); err != nil { + if err := dst.ReadPixels(ui.Get().GraphicsDriverForTesting(), dstPix, image.Rect(0, 0, w, h)); err != nil { t.Fatal(err) } @@ -988,7 +988,7 @@ func TestOverlappedPixels(t *testing.T) { } result := make([]byte, 4*3*3) - if err := dst.ReadPixels(ui.GraphicsDriverForTesting(), result, image.Rect(0, 0, 3, 3)); err != nil { + if err := dst.ReadPixels(ui.Get().GraphicsDriverForTesting(), result, image.Rect(0, 0, 3, 3)); err != nil { t.Fatal(err) } for j := 0; j < 3; j++ { @@ -1017,7 +1017,7 @@ func TestOverlappedPixels(t *testing.T) { {0, 0xff, 0, 0xff}, {0, 0xff, 0, 0xff}, } - if err := dst.ReadPixels(ui.GraphicsDriverForTesting(), result, image.Rect(0, 0, 3, 3)); err != nil { + if err := dst.ReadPixels(ui.Get().GraphicsDriverForTesting(), result, image.Rect(0, 0, 3, 3)); err != nil { t.Fatal(err) } for j := 0; j < 3; j++ { @@ -1056,7 +1056,7 @@ func TestOverlappedPixels(t *testing.T) { {0, 0, 0xff, 0xff}, {0, 0, 0xff, 0xff}, } - if err := dst.ReadPixels(ui.GraphicsDriverForTesting(), result, image.Rect(0, 0, 3, 3)); err != nil { + if err := dst.ReadPixels(ui.Get().GraphicsDriverForTesting(), result, image.Rect(0, 0, 3, 3)); err != nil { t.Fatal(err) } for j := 0; j < 3; j++ { @@ -1070,14 +1070,14 @@ func TestOverlappedPixels(t *testing.T) { } } - if err := restorable.ResolveStaleImages(ui.GraphicsDriverForTesting()); err != nil { + if err := restorable.ResolveStaleImages(ui.Get().GraphicsDriverForTesting()); err != nil { t.Fatal(err) } - if err := restorable.RestoreIfNeeded(ui.GraphicsDriverForTesting()); err != nil { + if err := restorable.RestoreIfNeeded(ui.Get().GraphicsDriverForTesting()); err != nil { t.Fatal(err) } - if err := dst.ReadPixels(ui.GraphicsDriverForTesting(), result, image.Rect(0, 0, 3, 3)); err != nil { + if err := dst.ReadPixels(ui.Get().GraphicsDriverForTesting(), result, image.Rect(0, 0, 3, 3)); err != nil { t.Fatal(err) } for j := 0; j < 3; j++ { @@ -1106,7 +1106,7 @@ func TestDrawTrianglesAndReadPixels(t *testing.T) { dst.DrawTriangles([graphics.ShaderImageCount]*restorable.Image{src}, vs, is, graphicsdriver.BlendSourceOver, dr, [graphics.ShaderImageCount]image.Rectangle{}, restorable.NearestFilterShader, nil, false) pix := make([]byte, 4*w*h) - if err := dst.ReadPixels(ui.GraphicsDriverForTesting(), pix, image.Rect(0, 0, w, h)); err != nil { + if err := dst.ReadPixels(ui.Get().GraphicsDriverForTesting(), pix, image.Rect(0, 0, w, h)); err != nil { t.Fatal(err) } if got, want := (color.RGBA{R: pix[0], G: pix[1], B: pix[2], A: pix[3]}), (color.RGBA{R: 0x80, G: 0x80, B: 0x80, A: 0x80}); !sameColors(got, want, 1) { @@ -1131,7 +1131,7 @@ func TestWritePixelsAndDrawTriangles(t *testing.T) { // Get the pixels. pix := make([]byte, 4*2*1) - if err := dst.ReadPixels(ui.GraphicsDriverForTesting(), pix, image.Rect(0, 0, 2, 1)); err != nil { + if err := dst.ReadPixels(ui.Get().GraphicsDriverForTesting(), pix, image.Rect(0, 0, 2, 1)); err != nil { t.Fatal(err) } if got, want := (color.RGBA{R: pix[0], G: pix[1], B: pix[2], A: pix[3]}), (color.RGBA{R: 0x40, G: 0x40, B: 0x40, A: 0x40}); !sameColors(got, want, 1) { diff --git a/internal/restorable/shader_test.go b/internal/restorable/shader_test.go index 0c3c9442f..6fd150f1a 100644 --- a/internal/restorable/shader_test.go +++ b/internal/restorable/shader_test.go @@ -57,10 +57,10 @@ func TestShader(t *testing.T) { dr := image.Rect(0, 0, 1, 1) img.DrawTriangles([graphics.ShaderImageCount]*restorable.Image{}, quadVertices(1, 1, 0, 0), graphics.QuadIndices(), graphicsdriver.BlendCopy, dr, [graphics.ShaderImageCount]image.Rectangle{}, s, nil, false) - if err := restorable.ResolveStaleImages(ui.GraphicsDriverForTesting()); err != nil { + if err := restorable.ResolveStaleImages(ui.Get().GraphicsDriverForTesting()); err != nil { t.Fatal(err) } - if err := restorable.RestoreIfNeeded(ui.GraphicsDriverForTesting()); err != nil { + if err := restorable.RestoreIfNeeded(ui.Get().GraphicsDriverForTesting()); err != nil { t.Fatal(err) } @@ -88,10 +88,10 @@ func TestShaderChain(t *testing.T) { imgs[i+1].DrawTriangles([graphics.ShaderImageCount]*restorable.Image{imgs[i]}, quadVertices(1, 1, 0, 0), graphics.QuadIndices(), graphicsdriver.BlendCopy, dr, [graphics.ShaderImageCount]image.Rectangle{}, s, nil, false) } - if err := restorable.ResolveStaleImages(ui.GraphicsDriverForTesting()); err != nil { + if err := restorable.ResolveStaleImages(ui.Get().GraphicsDriverForTesting()); err != nil { t.Fatal(err) } - if err := restorable.RestoreIfNeeded(ui.GraphicsDriverForTesting()); err != nil { + if err := restorable.RestoreIfNeeded(ui.Get().GraphicsDriverForTesting()); err != nil { t.Fatal(err) } @@ -122,10 +122,10 @@ func TestShaderMultipleSources(t *testing.T) { // Clear one of the sources after DrawTriangles. dst should not be affected. clearImage(srcs[0], 1, 1) - if err := restorable.ResolveStaleImages(ui.GraphicsDriverForTesting()); err != nil { + if err := restorable.ResolveStaleImages(ui.Get().GraphicsDriverForTesting()); err != nil { t.Fatal(err) } - if err := restorable.RestoreIfNeeded(ui.GraphicsDriverForTesting()); err != nil { + if err := restorable.RestoreIfNeeded(ui.Get().GraphicsDriverForTesting()); err != nil { t.Fatal(err) } @@ -159,10 +159,10 @@ func TestShaderMultipleSourcesOnOneTexture(t *testing.T) { // Clear one of the sources after DrawTriangles. dst should not be affected. clearImage(srcs[0], 3, 1) - if err := restorable.ResolveStaleImages(ui.GraphicsDriverForTesting()); err != nil { + if err := restorable.ResolveStaleImages(ui.Get().GraphicsDriverForTesting()); err != nil { t.Fatal(err) } - if err := restorable.RestoreIfNeeded(ui.GraphicsDriverForTesting()); err != nil { + if err := restorable.RestoreIfNeeded(ui.Get().GraphicsDriverForTesting()); err != nil { t.Fatal(err) } @@ -185,10 +185,10 @@ func TestShaderDispose(t *testing.T) { // stale. s.Dispose() - if err := restorable.ResolveStaleImages(ui.GraphicsDriverForTesting()); err != nil { + if err := restorable.ResolveStaleImages(ui.Get().GraphicsDriverForTesting()); err != nil { t.Fatal(err) } - if err := restorable.RestoreIfNeeded(ui.GraphicsDriverForTesting()); err != nil { + if err := restorable.RestoreIfNeeded(ui.Get().GraphicsDriverForTesting()); err != nil { t.Fatal(err) } diff --git a/internal/ui/context.go b/internal/ui/context.go index 91ad6b8f7..b2abe987b 100644 --- a/internal/ui/context.go +++ b/internal/ui/context.go @@ -280,6 +280,6 @@ func (c *context) screenScaleAndOffsets() (scale, offsetX, offsetY float64) { return } -func LogicalPositionToClientPosition(x, y float64) (float64, float64) { - return theUI.context.logicalPositionToClientPosition(x, y, theUI.DeviceScaleFactor()) +func (u *UserInterface) LogicalPositionToClientPosition(x, y float64) (float64, float64) { + return u.context.logicalPositionToClientPosition(x, y, u.DeviceScaleFactor()) } diff --git a/internal/ui/globalstate.go b/internal/ui/globalstate.go index bb0a2a32d..ec3f7f91c 100644 --- a/internal/ui/globalstate.go +++ b/internal/ui/globalstate.go @@ -19,6 +19,7 @@ import ( "sync/atomic" ) +// TODO: Move theGlobalState to UserInterface's member var theGlobalState = globalState{ isScreenClearedEveryFrame_: 1, graphicsLibrary_: int32(GraphicsLibraryUnknown), @@ -81,9 +82,9 @@ func FPSMode() FPSModeType { return theGlobalState.fpsMode() } -func SetFPSMode(fpsMode FPSModeType) { +func (u *UserInterface) SetFPSMode(fpsMode FPSModeType) { theGlobalState.setFPSMode(fpsMode) - theUI.SetFPSMode(fpsMode) + u.setFPSMode(fpsMode) } func IsScreenClearedEveryFrame() bool { diff --git a/internal/ui/graphics.go b/internal/ui/graphics.go index 932e25a7b..0747d920a 100644 --- a/internal/ui/graphics.go +++ b/internal/ui/graphics.go @@ -98,8 +98,8 @@ func newGraphicsDriver(creator graphicsDriverCreator, graphicsLibrary GraphicsLi } } -func GraphicsDriverForTesting() graphicsdriver.Graphics { - return theUI.graphicsDriver +func (u *UserInterface) GraphicsDriverForTesting() graphicsdriver.Graphics { + return u.graphicsDriver } type GraphicsLibrary int diff --git a/internal/ui/hideconsole_notwindows.go b/internal/ui/hideconsole_notwindows.go deleted file mode 100644 index 9d56e8153..000000000 --- a/internal/ui/hideconsole_notwindows.go +++ /dev/null @@ -1,20 +0,0 @@ -// Copyright 2017 The Ebiten Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -//go:build !windows - -package ui - -// hideConsoleWindowOnWindows does nothing on non-Windows systems. -func hideConsoleWindowOnWindows() {} diff --git a/internal/ui/hideconsole_windows.go b/internal/ui/hideconsole_windows.go index 8f10b9e4c..42dfc1cf4 100644 --- a/internal/ui/hideconsole_windows.go +++ b/internal/ui/hideconsole_windows.go @@ -43,9 +43,9 @@ func getConsoleWindow() windows.HWND { return windows.HWND(r) } -// hideConsoleWindowOnWindows will hide the console window that is showing when +// hideConsoleWindow will hide the console window that is showing when // compiling on Windows without specifying the '-ldflags "-Hwindowsgui"' flag. -func hideConsoleWindowOnWindows() { +func hideConsoleWindow() { // In Xbox, GetWindowThreadProcessId might not exist. if user32.NewProc("GetWindowThreadProcessId").Find() != nil { return diff --git a/internal/ui/image.go b/internal/ui/image.go index 30cb4a48a..4555deecc 100644 --- a/internal/ui/image.go +++ b/internal/ui/image.go @@ -36,6 +36,8 @@ func SetPanicOnErrorOnReadingPixelsForTesting(value bool) { const bigOffscreenScale = 2 type Image struct { + ui *UserInterface + mipmap *mipmap.Mipmap width int height int @@ -53,8 +55,9 @@ type Image struct { tmpVerticesForFill []float32 } -func NewImage(width, height int, imageType atlas.ImageType) *Image { +func (u *UserInterface) NewImage(width, height int, imageType atlas.ImageType) *Image { return &Image{ + ui: u, mipmap: mipmap.New(width, height, imageType), width: width, height: height, @@ -95,7 +98,7 @@ func (i *Image) DrawTriangles(srcs [graphics.ShaderImageCount]*Image, vertices [ default: panic(fmt.Sprintf("ui: unexpected image type: %d", imageType)) } - i.bigOffscreenBuffer = newBigOffscreenImage(i, imageType) + i.bigOffscreenBuffer = i.ui.newBigOffscreenImage(i, imageType) } i.bigOffscreenBuffer.drawTriangles(srcs, vertices, indices, blend, dstRegion, srcRegions, shader, uniforms, evenOdd, canSkipMipmap, false) @@ -163,7 +166,7 @@ func (i *Image) ReadPixels(pixels []byte, region image.Rectangle) { i.flushDotsBufferIfNeeded() } - if err := theUI.readPixels(i.mipmap, pixels, region); err != nil { + if err := i.ui.readPixels(i.mipmap, pixels, region); err != nil { if panicOnErrorOnReadingPixels { panic(err) } @@ -173,7 +176,7 @@ func (i *Image) ReadPixels(pixels []byte, region image.Rectangle) { func (i *Image) DumpScreenshot(name string, blackbg bool) (string, error) { i.flushBufferIfNeeded() - return theUI.dumpScreenshot(i.mipmap, name, blackbg) + return i.ui.dumpScreenshot(i.mipmap, name, blackbg) } func (i *Image) flushBufferIfNeeded() { @@ -244,7 +247,7 @@ func (i *Image) flushDotsBufferIfNeeded() { } i.dotsBuffer = nil - srcs := [graphics.ShaderImageCount]*mipmap.Mipmap{whiteImage.mipmap} + srcs := [graphics.ShaderImageCount]*mipmap.Mipmap{i.ui.whiteImage.mipmap} dr := image.Rect(0, 0, i.width, i.height) i.mipmap.DrawTriangles(srcs, vs, is, graphicsdriver.BlendCopy, dr, [graphics.ShaderImageCount]image.Rectangle{}, NearestFilterShader.shader, nil, false, true) } @@ -255,21 +258,8 @@ func (i *Image) flushBigOffscreenBufferIfNeeded() { } } -func DumpImages(dir string) (string, error) { - return theUI.dumpImages(dir) -} - -var ( - whiteImage = NewImage(3, 3, atlas.ImageTypeRegular) -) - -func init() { - pix := make([]byte, 4*whiteImage.width*whiteImage.height) - for i := range pix { - pix[i] = 0xff - } - // As whiteImage is used at Fill, use WritePixels instead. - whiteImage.WritePixels(pix, image.Rect(0, 0, whiteImage.width, whiteImage.height)) +func (u *UserInterface) DumpImages(dir string) (string, error) { + return u.dumpImages(dir) } func (i *Image) clear() { @@ -283,17 +273,19 @@ func (i *Image) Fill(r, g, b, a float32, region image.Rectangle) { // i.tmpVerticesForFill can be reused as this is sent to DrawTriangles immediately. graphics.QuadVertices( i.tmpVerticesForFill, - 1, 1, float32(whiteImage.width-1), float32(whiteImage.height-1), + 1, 1, float32(i.ui.whiteImage.width-1), float32(i.ui.whiteImage.height-1), float32(i.width), 0, 0, float32(i.height), 0, 0, r, g, b, a) is := graphics.QuadIndices() - srcs := [graphics.ShaderImageCount]*Image{whiteImage} + srcs := [graphics.ShaderImageCount]*Image{i.ui.whiteImage} i.DrawTriangles(srcs, i.tmpVerticesForFill, is, graphicsdriver.BlendCopy, region, [graphics.ShaderImageCount]image.Rectangle{}, NearestFilterShader, nil, false, true, false) } type bigOffscreenImage struct { + ui *UserInterface + orig *Image imageType atlas.ImageType @@ -307,8 +299,9 @@ type bigOffscreenImage struct { tmpVerticesForCopying []float32 } -func newBigOffscreenImage(orig *Image, imageType atlas.ImageType) *bigOffscreenImage { +func (u *UserInterface) newBigOffscreenImage(orig *Image, imageType atlas.ImageType) *bigOffscreenImage { return &bigOffscreenImage{ + ui: u, orig: orig, imageType: imageType, } @@ -340,7 +333,7 @@ func (i *bigOffscreenImage) drawTriangles(srcs [graphics.ShaderImageCount]*Image } if i.image == nil { - i.image = NewImage(i.region.Dx()*bigOffscreenScale, i.region.Dy()*bigOffscreenScale, i.imageType) + i.image = i.ui.NewImage(i.region.Dx()*bigOffscreenScale, i.region.Dy()*bigOffscreenScale, i.imageType) } // Copy the current rendering result to get the correct blending result. diff --git a/internal/ui/input_glfw.go b/internal/ui/input_glfw.go index 22b3cf8da..700b9f80b 100644 --- a/internal/ui/input_glfw.go +++ b/internal/ui/input_glfw.go @@ -122,11 +122,7 @@ func (u *UserInterface) updateInputStateImpl() error { return nil } -func KeyName(key Key) string { - return theUI.keyName(key) -} - -func (u *UserInterface) keyName(key Key) string { +func (u *UserInterface) KeyName(key Key) string { if !u.isRunning() { return "" } diff --git a/internal/ui/input_js.go b/internal/ui/input_js.go index 3363e9a76..e76d5594c 100644 --- a/internal/ui/input_js.go +++ b/internal/ui/input_js.go @@ -199,11 +199,7 @@ func init() { }) } -func KeyName(key Key) string { - return theUI.keyName(key) -} - -func (u *UserInterface) keyName(key Key) string { +func (u *UserInterface) KeyName(key Key) string { if !u.running { return "" } diff --git a/internal/ui/input_mobile.go b/internal/ui/input_mobile.go index 38f6c5e7d..582cd3a18 100644 --- a/internal/ui/input_mobile.go +++ b/internal/ui/input_mobile.go @@ -61,7 +61,7 @@ func (u *UserInterface) updateInputState() error { return nil } -func KeyName(key Key) string { +func (u *UserInterface) KeyName(key Key) string { // TODO: Implement this. return "" } diff --git a/internal/ui/input_nintendosdk.go b/internal/ui/input_nintendosdk.go index 75e4bf4d7..281bf2cb0 100644 --- a/internal/ui/input_nintendosdk.go +++ b/internal/ui/input_nintendosdk.go @@ -71,6 +71,6 @@ func (u *UserInterface) updateInputStateImpl() error { return nil } -func KeyName(key Key) string { +func (u *UserInterface) KeyName(key Key) string { return "" } diff --git a/internal/ui/ui.go b/internal/ui/ui.go index 884051e39..73225dd95 100644 --- a/internal/ui/ui.go +++ b/internal/ui/ui.go @@ -67,16 +67,47 @@ const ( ) type UserInterface struct { + whiteImage *Image + userInterfaceImpl } -var theUI = &UserInterface{} +var ( + theUI *UserInterface +) + +func init() { + // newUserInterface() must be called in the main goroutine. + u, err := newUserInterface() + if err != nil { + panic(err) + } + theUI = u +} func Get() *UserInterface { - // TODO: Get is a legacy API to access this package. Remove this. return theUI } +// newUserInterface must be called from the main thread. +func newUserInterface() (*UserInterface, error) { + u := &UserInterface{} + + u.whiteImage = u.NewImage(3, 3, atlas.ImageTypeRegular) + pix := make([]byte, 4*u.whiteImage.width*u.whiteImage.height) + for i := range pix { + pix[i] = 0xff + } + // As a white image is used at Fill, use WritePixels instead. + u.whiteImage.WritePixels(pix, image.Rect(0, 0, u.whiteImage.width, u.whiteImage.height)) + + if err := u.init(); err != nil { + return nil, err + } + + return u, nil +} + func (u *UserInterface) readPixels(mipmap *mipmap.Mipmap, pixels []byte, region image.Rectangle) error { return mipmap.ReadPixels(u.graphicsDriver, pixels, region) } diff --git a/internal/ui/ui_darwin.go b/internal/ui/ui_darwin.go index 8c27a01c5..60797728c 100644 --- a/internal/ui/ui_darwin.go +++ b/internal/ui/ui_darwin.go @@ -32,8 +32,7 @@ import ( var class_EbitengineWindowDelegate objc.Class -func init() { - var err error +func (u *UserInterface) initializePlatform() error { pushResizableState := func(id, win objc.ID) { window := cocoa.NSWindow{ID: win} id.Send(sel_setOrigResizable, window.StyleMask()&cocoa.NSWindowStyleMaskResizable != 0) @@ -48,7 +47,7 @@ func init() { } id.Send(sel_setOrigResizable, false) } - class_EbitengineWindowDelegate, err = objc.RegisterClass( + d, err := objc.RegisterClass( "EbitengineWindowDelegate", objc.GetClass("NSObject"), []*objc.Protocol{objc.GetProtocol("NSWindowDelegate")}, @@ -122,7 +121,7 @@ func init() { { Cmd: sel_windowWillEnterFullScreen, Fn: func(id objc.ID, cmd objc.SEL, notification objc.ID) { - if err := theUI.setOrigWindowPosWithCurrentPos(); err != nil { + if err := u.setOrigWindowPosWithCurrentPos(); err != nil { theGlobalState.setError(err) return } @@ -142,7 +141,7 @@ func init() { // Even a window has a size limitation, a window can be fullscreen by calling SetFullscreen(true). // In this case, the window size limitation is disabled temporarily. // When exiting from fullscreen, reset the window size limitation. - if err := theUI.updateWindowSizeLimits(); err != nil { + if err := u.updateWindowSizeLimits(); err != nil { theGlobalState.setError(err) return } @@ -158,8 +157,11 @@ func init() { }, ) if err != nil { - panic(err) + return err } + class_EbitengineWindowDelegate = d + + return nil } type graphicsDriverCreatorImpl struct { diff --git a/internal/ui/ui_glfw.go b/internal/ui/ui_glfw.go index 1864c6c54..4ad848b01 100644 --- a/internal/ui/ui_glfw.go +++ b/internal/ui/ui_glfw.go @@ -123,8 +123,10 @@ const ( func init() { // Lock the main thread. runtime.LockOSThread() +} - theUI.userInterfaceImpl = userInterfaceImpl{ +func (u *UserInterface) init() error { + u.userInterfaceImpl = userInterfaceImpl{ runnableOnUnfocused: true, minWindowWidthInDIP: glfw.DontCare, minWindowHeightInDIP: glfw.DontCare, @@ -142,25 +144,28 @@ func init() { savedCursorX: math.NaN(), savedCursorY: math.NaN(), } - theUI.iwindow.ui = theUI + u.iwindow.ui = u - hideConsoleWindowOnWindows() - - if err := initialize(); err != nil { - panic(err) + if err := u.initializePlatform(); err != nil { + return err + } + if err := u.initializeGLFW(); err != nil { + return err } if _, err := glfw.SetMonitorCallback(func(monitor *glfw.Monitor, event glfw.PeripheralEvent) { if err := theMonitors.update(); err != nil { theGlobalState.setError(err) } }); err != nil { - panic(err) + return err } + + return nil } var glfwSystemCursors = map[CursorShape]*glfw.Cursor{} -func initialize() error { +func (u *UserInterface) initializeGLFW() error { if err := glfw.Init(); err != nil { return err } @@ -183,7 +188,7 @@ func initialize() error { return errors.New("ui: no monitor was found at initialize") } - theUI.setInitMonitor(m) + u.setInitMonitor(m) // Create system cursors. These cursors are destroyed at glfw.Terminate(). glfwSystemCursors[CursorShapeDefault] = nil @@ -722,7 +727,7 @@ func (u *UserInterface) IsRunnableOnUnfocused() bool { return u.isRunnableOnUnfocused() } -func (u *UserInterface) SetFPSMode(mode FPSModeType) { +func (u *UserInterface) setFPSMode(mode FPSModeType) { if u.isTerminated() { return } @@ -741,7 +746,7 @@ func (u *UserInterface) SetFPSMode(mode FPSModeType) { u.fpsMode = mode return } - if err := u.setFPSMode(mode); err != nil { + if err := u.setFPSModeImpl(mode); err != nil { theGlobalState.setError(err) return } @@ -1285,8 +1290,8 @@ func (u *UserInterface) outsideSize() (float64, float64, error) { return w, h, nil } -// setFPSMode must be called from the main thread. -func (u *UserInterface) setFPSMode(fpsMode FPSModeType) error { +// setFPSModeImpl must be called from the main thread. +func (u *UserInterface) setFPSModeImpl(fpsMode FPSModeType) error { needUpdate := u.fpsMode != fpsMode || !u.fpsModeInited u.fpsMode = fpsMode u.fpsModeInited = true @@ -1356,7 +1361,7 @@ func (u *UserInterface) update() (float64, float64, error) { // Initialize vsync after SetMonitor is called. See the comment in updateVsync. // Calling this inside setWindowSize didn't work (#1363). if !u.fpsModeInited { - if err := u.setFPSMode(u.fpsMode); err != nil { + if err := u.setFPSModeImpl(u.fpsMode); err != nil { return 0, 0, err } } @@ -2192,6 +2197,6 @@ func IsScreenTransparentAvailable() bool { return true } -func RunOnMainThread(f func()) { - theUI.mainThread.Call(f) +func (u *UserInterface) RunOnMainThread(f func()) { + u.mainThread.Call(f) } diff --git a/internal/ui/ui_js.go b/internal/ui/ui_js.go index bec394ec6..13a626c18 100644 --- a/internal/ui/ui_js.go +++ b/internal/ui/ui_js.go @@ -144,8 +144,8 @@ func (u *UserInterface) SetFullscreen(fullscreen bool) { return } - if theUI.cursorMode == CursorModeCaptured { - theUI.saveCursorPosition() + if u.cursorMode == CursorModeCaptured { + u.saveCursorPosition() } if fullscreen { @@ -186,7 +186,7 @@ func (u *UserInterface) IsRunnableOnUnfocused() bool { return u.runnableOnUnfocused } -func (u *UserInterface) SetFPSMode(mode FPSModeType) { +func (u *UserInterface) setFPSMode(mode FPSModeType) { u.fpsMode = mode } @@ -236,7 +236,7 @@ func (u *UserInterface) setCursorMode(mode CursorMode) { } func (u *UserInterface) recoverCursorMode() { - if theUI.cursorPrevMode == CursorModeCaptured { + if u.cursorPrevMode == CursorModeCaptured { panic("ui: cursorPrevMode must not be CursorModeCaptured at recoverCursorMode") } u.SetCursorMode(u.cursorPrevMode) @@ -471,8 +471,8 @@ func (u *UserInterface) loop(game Game) <-chan error { return errCh } -func init() { - theUI.userInterfaceImpl = userInterfaceImpl{ +func (u *UserInterface) init() error { + u.userInterfaceImpl = userInterfaceImpl{ runnableOnUnfocused: true, savedCursorX: math.NaN(), savedCursorY: math.NaN(), @@ -480,7 +480,7 @@ func init() { // docuemnt is undefined on node.js if !document.Truthy() { - return + return nil } if !document.Get("body").Truthy() { @@ -492,7 +492,7 @@ func init() { <-ch } - setWindowEventHandlers(window) + u.setWindowEventHandlers(window) // Adjust the initial scale to 1. // https://developer.mozilla.org/en/docs/Mozilla/Mobile/Viewport_meta_tag @@ -528,7 +528,7 @@ func init() { canvas.Call("setAttribute", "tabindex", 1) canvas.Get("style").Set("outline", "none") - setCanvasEventHandlers(canvas) + u.setCanvasEventHandlers(canvas) // Pointer Lock document.Call("addEventListener", "pointerlockchange", js.FuncOf(func(this js.Value, args []js.Value) any { @@ -538,10 +538,10 @@ func init() { // Recover the state correctly when the pointer lock exits. // A user can exit the pointer lock by pressing ESC. In this case, sync the cursor mode state. - if theUI.cursorMode == CursorModeCaptured { - theUI.recoverCursorMode() + if u.cursorMode == CursorModeCaptured { + u.recoverCursorMode() } - theUI.recoverCursorPosition() + u.recoverCursorPosition() return nil })) document.Call("addEventListener", "pointerlockerror", js.FuncOf(func(this js.Value, args []js.Value) any { @@ -556,16 +556,18 @@ func init() { js.Global().Get("console").Call("error", "webkitfullscreenerror event is fired. 'allow=\"fullscreen\"' or 'allowfullscreen' might be required at an iframe. This function on browsers must be called as a result of a gestural interaction or orientation change.") return nil })) + + return nil } -func setWindowEventHandlers(v js.Value) { +func (u *UserInterface) setWindowEventHandlers(v js.Value) { v.Call("addEventListener", "resize", js.FuncOf(func(this js.Value, args []js.Value) any { - theUI.updateScreenSize() + u.updateScreenSize() // updateImpl can block. Use goroutine. // See https://pkg.go.dev/syscall/js#FuncOf. go func() { - if err := theUI.updateImpl(true); err != nil { + if err := u.updateImpl(true); err != nil { theGlobalState.setError(err) return } @@ -574,7 +576,7 @@ func setWindowEventHandlers(v js.Value) { })) } -func setCanvasEventHandlers(v js.Value) { +func (u *UserInterface) setCanvasEventHandlers(v js.Value) { // Keyboard v.Call("addEventListener", "keydown", js.FuncOf(func(this js.Value, args []js.Value) any { // Focus the canvas explicitly to activate tha game (#961). @@ -582,7 +584,7 @@ func setCanvasEventHandlers(v js.Value) { e := args[0] e.Call("preventDefault") - if err := theUI.updateInputFromEvent(e); err != nil { + if err := u.updateInputFromEvent(e); err != nil { theGlobalState.setError(err) return nil } @@ -591,7 +593,7 @@ func setCanvasEventHandlers(v js.Value) { v.Call("addEventListener", "keyup", js.FuncOf(func(this js.Value, args []js.Value) any { e := args[0] e.Call("preventDefault") - if err := theUI.updateInputFromEvent(e); err != nil { + if err := u.updateInputFromEvent(e); err != nil { theGlobalState.setError(err) return nil } @@ -605,7 +607,7 @@ func setCanvasEventHandlers(v js.Value) { e := args[0] e.Call("preventDefault") - if err := theUI.updateInputFromEvent(e); err != nil { + if err := u.updateInputFromEvent(e); err != nil { theGlobalState.setError(err) return nil } @@ -614,7 +616,7 @@ func setCanvasEventHandlers(v js.Value) { v.Call("addEventListener", "mouseup", js.FuncOf(func(this js.Value, args []js.Value) any { e := args[0] e.Call("preventDefault") - if err := theUI.updateInputFromEvent(e); err != nil { + if err := u.updateInputFromEvent(e); err != nil { theGlobalState.setError(err) return nil } @@ -623,7 +625,7 @@ func setCanvasEventHandlers(v js.Value) { v.Call("addEventListener", "mousemove", js.FuncOf(func(this js.Value, args []js.Value) any { e := args[0] e.Call("preventDefault") - if err := theUI.updateInputFromEvent(e); err != nil { + if err := u.updateInputFromEvent(e); err != nil { theGlobalState.setError(err) return nil } @@ -632,7 +634,7 @@ func setCanvasEventHandlers(v js.Value) { v.Call("addEventListener", "wheel", js.FuncOf(func(this js.Value, args []js.Value) any { e := args[0] e.Call("preventDefault") - if err := theUI.updateInputFromEvent(e); err != nil { + if err := u.updateInputFromEvent(e); err != nil { theGlobalState.setError(err) return nil } @@ -646,7 +648,7 @@ func setCanvasEventHandlers(v js.Value) { e := args[0] e.Call("preventDefault") - if err := theUI.updateInputFromEvent(e); err != nil { + if err := u.updateInputFromEvent(e); err != nil { theGlobalState.setError(err) return nil } @@ -655,7 +657,7 @@ func setCanvasEventHandlers(v js.Value) { v.Call("addEventListener", "touchend", js.FuncOf(func(this js.Value, args []js.Value) any { e := args[0] e.Call("preventDefault") - if err := theUI.updateInputFromEvent(e); err != nil { + if err := u.updateInputFromEvent(e); err != nil { theGlobalState.setError(err) return nil } @@ -664,7 +666,7 @@ func setCanvasEventHandlers(v js.Value) { v.Call("addEventListener", "touchmove", js.FuncOf(func(this js.Value, args []js.Value) any { e := args[0] e.Call("preventDefault") - if err := theUI.updateInputFromEvent(e); err != nil { + if err := u.updateInputFromEvent(e); err != nil { theGlobalState.setError(err) return nil } @@ -700,7 +702,7 @@ func setCanvasEventHandlers(v js.Value) { return nil } - go theUI.appendDroppedFiles(data) + go u.appendDroppedFiles(data) return nil })) } diff --git a/internal/ui/ui_linbsd.go b/internal/ui/ui_linbsd.go index 7315afb25..e0878df3a 100644 --- a/internal/ui/ui_linbsd.go +++ b/internal/ui/ui_linbsd.go @@ -29,6 +29,10 @@ import ( "github.com/hajimehoshi/ebiten/v2/internal/graphicsdriver/opengl" ) +func (u *UserInterface) initializePlatform() error { + return nil +} + type graphicsDriverCreatorImpl struct { transparent bool } diff --git a/internal/ui/ui_mobile.go b/internal/ui/ui_mobile.go index abed875e7..9b8ee6e98 100644 --- a/internal/ui/ui_mobile.go +++ b/internal/ui/ui_mobile.go @@ -51,8 +51,8 @@ var ( renderEndCh = make(chan struct{}) ) -func init() { - theUI.userInterfaceImpl = userInterfaceImpl{ +func (u *UserInterface) init() error { + u.userInterfaceImpl = userInterfaceImpl{ foreground: 1, graphicsDriverInitCh: make(chan struct{}), errCh: make(chan error), @@ -61,6 +61,7 @@ func init() { outsideWidth: 640, outsideHeight: 480, } + return nil } // Update is called from mobile/ebitenmobileview. @@ -249,11 +250,7 @@ func (u *UserInterface) Run(game Game, options *RunOptions) error { return nil } -func RunWithoutMainLoop(game Game, options *RunOptions) { - theUI.runWithoutMainLoop(game, options) -} - -func (u *UserInterface) runWithoutMainLoop(game Game, options *RunOptions) { +func (u *UserInterface) RunWithoutMainLoop(game Game, options *RunOptions) { go func() { if err := u.run(game, false, options); err != nil { u.errCh <- err @@ -402,7 +399,7 @@ func (u *UserInterface) SetRunnableOnUnfocused(runnableOnUnfocused bool) { // Do nothing } -func (u *UserInterface) SetFPSMode(mode FPSModeType) { +func (u *UserInterface) setFPSMode(mode FPSModeType) { u.fpsMode = mode u.updateExplicitRenderingModeIfNeeded() } diff --git a/internal/ui/ui_nintendosdk.go b/internal/ui/ui_nintendosdk.go index 158142ff0..8b6316604 100644 --- a/internal/ui/ui_nintendosdk.go +++ b/internal/ui/ui_nintendosdk.go @@ -178,7 +178,7 @@ func (*UserInterface) IsRunnableOnUnfocused() bool { func (*UserInterface) SetRunnableOnUnfocused(runnableOnUnfocused bool) { } -func (*UserInterface) SetFPSMode(mode FPSModeType) { +func (*UserInterface) setFPSMode(mode FPSModeType) { } func (*UserInterface) ScheduleFrame() { diff --git a/internal/ui/ui_windows.go b/internal/ui/ui_windows.go index 94f709cbf..9630c579b 100644 --- a/internal/ui/ui_windows.go +++ b/internal/ui/ui_windows.go @@ -30,6 +30,11 @@ import ( "github.com/hajimehoshi/ebiten/v2/internal/winver" ) +func (u *UserInterface) initializePlatform() error { + hideConsoleWindow() + return nil +} + type graphicsDriverCreatorImpl struct { transparent bool } diff --git a/run.go b/run.go index 181796525..c7afbe40b 100644 --- a/run.go +++ b/run.go @@ -477,9 +477,9 @@ func IsVsyncEnabled() bool { // the game uses the display's vsync. func SetVsyncEnabled(enabled bool) { if enabled { - ui.SetFPSMode(ui.FPSModeVsyncOn) + ui.Get().SetFPSMode(ui.FPSModeVsyncOn) } else { - ui.SetFPSMode(ui.FPSModeVsyncOffMaximum) + ui.Get().SetFPSMode(ui.FPSModeVsyncOffMaximum) } } @@ -536,7 +536,7 @@ func FPSMode() FPSModeType { // // Deprecated: as of v2.5. Use SetVsyncEnabled instead. func SetFPSMode(mode FPSModeType) { - ui.SetFPSMode(mode) + ui.Get().SetFPSMode(mode) } // ScheduleFrame schedules a next frame when the current FPS mode is FPSModeVsyncOffMinimum. diff --git a/run_mobile.go b/run_mobile.go index fd3e5745f..7f314f315 100644 --- a/run_mobile.go +++ b/run_mobile.go @@ -29,5 +29,5 @@ import ( // TODO: Remove this. In order to remove this, the gameForUI should be in another package. func RunGameWithoutMainLoop(game Game, options *RunGameOptions) { op := toUIRunOptions(options) - ui.RunWithoutMainLoop(newGameForUI(game, op.ScreenTransparent), op) + ui.Get().RunWithoutMainLoop(newGameForUI(game, op.ScreenTransparent), op) }