mirror of
https://github.com/hajimehoshi/ebiten.git
synced 2024-11-10 04:57:26 +01:00
parent
f2a18ed6ba
commit
f34932151d
16
gameforui.go
16
gameforui.go
@ -25,18 +25,10 @@ import (
|
||||
"github.com/hajimehoshi/ebiten/v2/internal/ui"
|
||||
)
|
||||
|
||||
var screenFilterEnabled = int32(1)
|
||||
var screenFilterEnabled atomic.Bool
|
||||
|
||||
func isScreenFilterEnabled() bool {
|
||||
return atomic.LoadInt32(&screenFilterEnabled) != 0
|
||||
}
|
||||
|
||||
func setScreenFilterEnabled(enabled bool) {
|
||||
v := int32(0)
|
||||
if enabled {
|
||||
v = 1
|
||||
}
|
||||
atomic.StoreInt32(&screenFilterEnabled, v)
|
||||
func init() {
|
||||
screenFilterEnabled.Store(true)
|
||||
}
|
||||
|
||||
type gameForUI struct {
|
||||
@ -145,7 +137,7 @@ func (g *gameForUI) DrawFinalScreen(scale, offsetX, offsetY float64) {
|
||||
}
|
||||
|
||||
switch {
|
||||
case !isScreenFilterEnabled(), math.Floor(scale) == scale:
|
||||
case !screenFilterEnabled.Load(), math.Floor(scale) == scale:
|
||||
op := &DrawImageOptions{}
|
||||
op.GeoM = geoM
|
||||
g.screen.DrawImage(g.offscreen, op)
|
||||
|
@ -113,7 +113,7 @@ type nativeGamepadsDesktop struct {
|
||||
enumObjectsCallback uintptr
|
||||
|
||||
nativeWindow windows.HWND
|
||||
deviceChanged int32
|
||||
deviceChanged atomic.Bool
|
||||
err error
|
||||
}
|
||||
|
||||
@ -537,11 +537,11 @@ func (g *nativeGamepadsDesktop) update(gamepads *gamepads) error {
|
||||
g.origWndProc = h
|
||||
}
|
||||
|
||||
if atomic.LoadInt32(&g.deviceChanged) != 0 {
|
||||
if g.deviceChanged.Load() {
|
||||
if err := g.detectConnection(gamepads); err != nil {
|
||||
g.err = err
|
||||
}
|
||||
atomic.StoreInt32(&g.deviceChanged, 0)
|
||||
g.deviceChanged.Store(false)
|
||||
}
|
||||
|
||||
return nil
|
||||
@ -550,7 +550,7 @@ func (g *nativeGamepadsDesktop) update(gamepads *gamepads) error {
|
||||
func (g *nativeGamepadsDesktop) wndProc(hWnd uintptr, uMsg uint32, wParam, lParam uintptr) uintptr {
|
||||
switch uMsg {
|
||||
case _WM_DEVICECHANGE:
|
||||
atomic.StoreInt32(&g.deviceChanged, 1)
|
||||
g.deviceChanged.Store(true)
|
||||
}
|
||||
return _CallWindowProcW(g.origWndProc, hWnd, uMsg, wParam, lParam)
|
||||
}
|
||||
|
@ -43,14 +43,14 @@ const (
|
||||
maxVertexFloatCount = MaxVertexCount * graphics.VertexFloatCount
|
||||
)
|
||||
|
||||
var vsyncEnabled int32 = 1
|
||||
var vsyncEnabled atomic.Bool
|
||||
|
||||
func init() {
|
||||
vsyncEnabled.Store(true)
|
||||
}
|
||||
|
||||
func SetVsyncEnabled(enabled bool, graphicsDriver graphicsdriver.Graphics) {
|
||||
if enabled {
|
||||
atomic.StoreInt32(&vsyncEnabled, 1)
|
||||
} else {
|
||||
atomic.StoreInt32(&vsyncEnabled, 0)
|
||||
}
|
||||
vsyncEnabled.Store(enabled)
|
||||
|
||||
runOnRenderThread(func() {
|
||||
graphicsDriver.SetVsyncEnabled(enabled)
|
||||
@ -185,7 +185,7 @@ func (q *commandQueue) Flush(graphicsDriver graphicsdriver.Graphics, endFrame bo
|
||||
|
||||
var sync bool
|
||||
// Disable asynchronous rendering when vsync is on, as this causes a rendering delay (#2822).
|
||||
if endFrame && atomic.LoadInt32(&vsyncEnabled) != 0 {
|
||||
if endFrame && vsyncEnabled.Load() {
|
||||
sync = true
|
||||
}
|
||||
if !sync {
|
||||
|
@ -65,13 +65,13 @@ type monitors struct {
|
||||
|
||||
m sync.Mutex
|
||||
|
||||
updateCalled int32
|
||||
updateCalled atomic.Bool
|
||||
}
|
||||
|
||||
var theMonitors monitors
|
||||
|
||||
func (m *monitors) append(ms []*Monitor) []*Monitor {
|
||||
if atomic.LoadInt32(&m.updateCalled) == 0 {
|
||||
if !m.updateCalled.Load() {
|
||||
panic("ui: (*monitors).update must be called before (*monitors).append is called")
|
||||
}
|
||||
|
||||
@ -82,7 +82,7 @@ func (m *monitors) append(ms []*Monitor) []*Monitor {
|
||||
}
|
||||
|
||||
func (m *monitors) primaryMonitor() *Monitor {
|
||||
if atomic.LoadInt32(&m.updateCalled) == 0 {
|
||||
if !m.updateCalled.Load() {
|
||||
panic("ui: (*monitors).update must be called before (*monitors).primaryMonitor is called")
|
||||
}
|
||||
|
||||
@ -179,6 +179,6 @@ func (m *monitors) update() error {
|
||||
m.monitors = newMonitors
|
||||
m.m.Unlock()
|
||||
|
||||
atomic.StoreInt32(&m.updateCalled, 1)
|
||||
m.updateCalled.Store(true)
|
||||
return nil
|
||||
}
|
||||
|
@ -75,10 +75,10 @@ type UserInterface struct {
|
||||
err error
|
||||
errM sync.Mutex
|
||||
|
||||
isScreenClearedEveryFrame int32
|
||||
isScreenClearedEveryFrame atomic.Bool
|
||||
graphicsLibrary int32
|
||||
running int32
|
||||
terminated int32
|
||||
running atomic.Bool
|
||||
terminated atomic.Bool
|
||||
|
||||
whiteImage *Image
|
||||
|
||||
@ -107,9 +107,9 @@ func Get() *UserInterface {
|
||||
// newUserInterface must be called from the main thread.
|
||||
func newUserInterface() (*UserInterface, error) {
|
||||
u := &UserInterface{
|
||||
isScreenClearedEveryFrame: 1,
|
||||
graphicsLibrary: int32(GraphicsLibraryUnknown),
|
||||
}
|
||||
u.isScreenClearedEveryFrame.Store(true)
|
||||
|
||||
u.whiteImage = u.NewImage(3, 3, atlas.ImageTypeRegular)
|
||||
pix := make([]byte, 4*u.whiteImage.width*u.whiteImage.height)
|
||||
@ -196,15 +196,11 @@ func (u *UserInterface) setError(err error) {
|
||||
}
|
||||
|
||||
func (u *UserInterface) IsScreenClearedEveryFrame() bool {
|
||||
return atomic.LoadInt32(&u.isScreenClearedEveryFrame) != 0
|
||||
return u.isScreenClearedEveryFrame.Load()
|
||||
}
|
||||
|
||||
func (u *UserInterface) SetScreenClearedEveryFrame(cleared bool) {
|
||||
v := int32(0)
|
||||
if cleared {
|
||||
v = 1
|
||||
}
|
||||
atomic.StoreInt32(&u.isScreenClearedEveryFrame, v)
|
||||
u.isScreenClearedEveryFrame.Store(cleared)
|
||||
}
|
||||
|
||||
func (u *UserInterface) setGraphicsLibrary(library GraphicsLibrary) {
|
||||
@ -216,21 +212,17 @@ func (u *UserInterface) GraphicsLibrary() GraphicsLibrary {
|
||||
}
|
||||
|
||||
func (u *UserInterface) isRunning() bool {
|
||||
return atomic.LoadInt32(&u.running) != 0 && !u.isTerminated()
|
||||
return u.running.Load() && !u.isTerminated()
|
||||
}
|
||||
|
||||
func (u *UserInterface) setRunning(running bool) {
|
||||
if running {
|
||||
atomic.StoreInt32(&u.running, 1)
|
||||
} else {
|
||||
atomic.StoreInt32(&u.running, 0)
|
||||
}
|
||||
u.running.Store(running)
|
||||
}
|
||||
|
||||
func (u *UserInterface) isTerminated() bool {
|
||||
return atomic.LoadInt32(&u.terminated) != 0
|
||||
return u.terminated.Load()
|
||||
}
|
||||
|
||||
func (u *UserInterface) setTerminated() {
|
||||
atomic.StoreInt32(&u.terminated, 1)
|
||||
u.terminated.Store(true)
|
||||
}
|
||||
|
@ -40,7 +40,6 @@ var (
|
||||
|
||||
func (u *UserInterface) init() error {
|
||||
u.userInterfaceImpl = userInterfaceImpl{
|
||||
foreground: 1,
|
||||
graphicsLibraryInitCh: make(chan struct{}),
|
||||
errCh: make(chan error),
|
||||
|
||||
@ -48,6 +47,7 @@ func (u *UserInterface) init() error {
|
||||
outsideWidth: 640,
|
||||
outsideHeight: 480,
|
||||
}
|
||||
u.foreground.Store(true)
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -89,7 +89,7 @@ type userInterfaceImpl struct {
|
||||
outsideWidth float64
|
||||
outsideHeight float64
|
||||
|
||||
foreground int32
|
||||
foreground atomic.Bool
|
||||
errCh chan error
|
||||
|
||||
context *context
|
||||
@ -104,11 +104,7 @@ type userInterfaceImpl struct {
|
||||
}
|
||||
|
||||
func (u *UserInterface) SetForeground(foreground bool) error {
|
||||
var v int32
|
||||
if foreground {
|
||||
v = 1
|
||||
}
|
||||
atomic.StoreInt32(&u.foreground, v)
|
||||
u.foreground.Store(foreground)
|
||||
|
||||
if foreground {
|
||||
return hook.ResumeAudio()
|
||||
@ -220,7 +216,7 @@ func (u *UserInterface) SetFullscreen(fullscreen bool) {
|
||||
}
|
||||
|
||||
func (u *UserInterface) IsFocused() bool {
|
||||
return atomic.LoadInt32(&u.foreground) != 0
|
||||
return u.foreground.Load()
|
||||
}
|
||||
|
||||
func (u *UserInterface) IsRunnableOnUnfocused() bool {
|
||||
|
38
run.go
38
run.go
@ -149,7 +149,7 @@ func CurrentFPS() float64 {
|
||||
}
|
||||
|
||||
var (
|
||||
isRunGameEnded_ = int32(0)
|
||||
isRunGameEnded_ atomic.Bool
|
||||
)
|
||||
|
||||
// SetScreenClearedEveryFrame enables or disables the clearing of the screen at the beginning of each frame.
|
||||
@ -179,7 +179,7 @@ func IsScreenClearedEveryFrame() bool {
|
||||
//
|
||||
// Deprecated: as of v2.5. Use FinalScreenDrawer instead.
|
||||
func SetScreenFilterEnabled(enabled bool) {
|
||||
setScreenFilterEnabled(enabled)
|
||||
screenFilterEnabled.Store(enabled)
|
||||
}
|
||||
|
||||
// IsScreenFilterEnabled returns true if Ebitengine's "screen" filter is enabled.
|
||||
@ -188,7 +188,7 @@ func SetScreenFilterEnabled(enabled bool) {
|
||||
//
|
||||
// Deprecated: as of v2.5.
|
||||
func IsScreenFilterEnabled() bool {
|
||||
return isScreenFilterEnabled()
|
||||
return screenFilterEnabled.Load()
|
||||
}
|
||||
|
||||
// Termination is a special error which indicates Game termination without error.
|
||||
@ -309,17 +309,13 @@ type RunGameOptions struct {
|
||||
//
|
||||
// Don't call RunGame or RunGameWithOptions twice or more in one process.
|
||||
func RunGameWithOptions(game Game, options *RunGameOptions) error {
|
||||
defer atomic.StoreInt32(&isRunGameEnded_, 1)
|
||||
defer isRunGameEnded_.Store(true)
|
||||
|
||||
initializeWindowPositionIfNeeded(WindowSize())
|
||||
|
||||
op := toUIRunOptions(options)
|
||||
// This is necessary to change the result of IsScreenTransparent.
|
||||
if op.ScreenTransparent {
|
||||
atomic.StoreInt32(&screenTransparent, 1)
|
||||
} else {
|
||||
atomic.StoreInt32(&screenTransparent, 0)
|
||||
}
|
||||
screenTransparent.Store(op.ScreenTransparent)
|
||||
g := newGameForUI(game, op.ScreenTransparent)
|
||||
|
||||
if err := ui.Get().Run(g, op); err != nil {
|
||||
@ -333,7 +329,7 @@ func RunGameWithOptions(game Game, options *RunGameOptions) error {
|
||||
}
|
||||
|
||||
func isRunGameEnded() bool {
|
||||
return atomic.LoadInt32(&isRunGameEnded_) != 0
|
||||
return isRunGameEnded_.Load()
|
||||
}
|
||||
|
||||
// ScreenSizeInFullscreen returns the size in device-independent pixels when the game is fullscreen.
|
||||
@ -640,7 +636,7 @@ func IsScreenTransparent() bool {
|
||||
if !ui.IsScreenTransparentAvailable() {
|
||||
return false
|
||||
}
|
||||
return atomic.LoadInt32(&screenTransparent) != 0
|
||||
return screenTransparent.Load()
|
||||
}
|
||||
|
||||
// SetScreenTransparent sets the state if the window is transparent.
|
||||
@ -653,14 +649,10 @@ func IsScreenTransparent() bool {
|
||||
//
|
||||
// Deprecated: as of v2.5. Use RunGameWithOptions instead.
|
||||
func SetScreenTransparent(transparent bool) {
|
||||
if transparent {
|
||||
atomic.StoreInt32(&screenTransparent, 1)
|
||||
} else {
|
||||
atomic.StoreInt32(&screenTransparent, 0)
|
||||
}
|
||||
screenTransparent.Store(transparent)
|
||||
}
|
||||
|
||||
var screenTransparent int32 = 0
|
||||
var screenTransparent atomic.Bool
|
||||
|
||||
// SetInitFocused sets whether the application is focused on show.
|
||||
// The default value is true, i.e., the application is focused.
|
||||
@ -673,14 +665,10 @@ var screenTransparent int32 = 0
|
||||
//
|
||||
// Deprecated: as of v2.5. Use RunGameWithOptions instead.
|
||||
func SetInitFocused(focused bool) {
|
||||
if focused {
|
||||
atomic.StoreInt32(&initUnfocused, 0)
|
||||
} else {
|
||||
atomic.StoreInt32(&initUnfocused, 1)
|
||||
}
|
||||
initUnfocused.Store(!focused)
|
||||
}
|
||||
|
||||
var initUnfocused int32 = 0
|
||||
var initUnfocused atomic.Bool
|
||||
|
||||
func toUIRunOptions(options *RunGameOptions) *ui.RunOptions {
|
||||
const (
|
||||
@ -690,8 +678,8 @@ func toUIRunOptions(options *RunGameOptions) *ui.RunOptions {
|
||||
|
||||
if options == nil {
|
||||
return &ui.RunOptions{
|
||||
InitUnfocused: atomic.LoadInt32(&initUnfocused) != 0,
|
||||
ScreenTransparent: atomic.LoadInt32(&screenTransparent) != 0,
|
||||
InitUnfocused: initUnfocused.Load(),
|
||||
ScreenTransparent: screenTransparent.Load(),
|
||||
X11ClassName: defaultX11ClassName,
|
||||
X11InstanceName: defaultX11InstanceName,
|
||||
}
|
||||
|
@ -155,16 +155,16 @@ func WindowPosition() (x, y int) {
|
||||
//
|
||||
// SetWindowPosition is concurrent-safe.
|
||||
func SetWindowPosition(x, y int) {
|
||||
atomic.StoreUint32(&windowPositionSetExplicitly, 1)
|
||||
windowPositionSetExplicitly.Store(true)
|
||||
ui.Get().Window().SetPosition(x, y)
|
||||
}
|
||||
|
||||
var (
|
||||
windowPositionSetExplicitly uint32
|
||||
windowPositionSetExplicitly atomic.Bool
|
||||
)
|
||||
|
||||
func initializeWindowPositionIfNeeded(width, height int) {
|
||||
if atomic.LoadUint32(&windowPositionSetExplicitly) == 0 {
|
||||
if !windowPositionSetExplicitly.Load() {
|
||||
sw, sh := ui.Get().Monitor().Size()
|
||||
x, y := ui.InitialWindowPosition(sw, sh, width, height)
|
||||
ui.Get().Window().SetPosition(x, y)
|
||||
|
Loading…
Reference in New Issue
Block a user