internal/uidriver/*: integrate the packages into internal/ui

Updates #1983
This commit is contained in:
Hajime Hoshi 2022-02-06 16:08:22 +09:00
parent 67bb58849e
commit 149736c3cf
39 changed files with 184 additions and 308 deletions

View File

@ -570,13 +570,13 @@ const (
) )
` `
const uidriverGlfwKeysTmpl = `{{.License}} const uiGLFWKeysTmpl = `{{.License}}
{{.DoNotEdit}} {{.DoNotEdit}}
{{.BuildTag}} {{.BuildTag}}
package glfw package ui
import ( import (
"github.com/hajimehoshi/ebiten/v2/internal/driver" "github.com/hajimehoshi/ebiten/v2/internal/driver"
@ -594,13 +594,13 @@ var driverKeyToGLFWKey = map[driver.Key]glfw.Key{
} }
` `
const uidriverJsKeysTmpl = `{{.License}} const uiJSKeysTmpl = `{{.License}}
{{.DoNotEdit}} {{.DoNotEdit}}
{{.BuildTag}} {{.BuildTag}}
package js package ui
import ( import (
"syscall/js" "syscall/js"
@ -651,13 +651,13 @@ var androidKeyToDriverKey = map[int]driver.Key{
} }
` `
const uidriverMobileKeysTmpl = `{{.License}} const uiMobileKeysTmpl = `{{.License}}
{{.DoNotEdit}} {{.DoNotEdit}}
{{.BuildTag}} {{.BuildTag}}
package mobile package ui
import ( import (
"golang.org/x/mobile/event/key" "golang.org/x/mobile/event/key"
@ -790,9 +790,9 @@ func main() {
for path, tmpl := range map[string]string{ for path, tmpl := range map[string]string{
filepath.Join("internal", "driver", "keys.go"): driverKeysTmpl, filepath.Join("internal", "driver", "keys.go"): driverKeysTmpl,
filepath.Join("internal", "glfw", "keys.go"): glfwKeysTmpl, filepath.Join("internal", "glfw", "keys.go"): glfwKeysTmpl,
filepath.Join("internal", "uidriver", "glfw", "keys.go"): uidriverGlfwKeysTmpl, filepath.Join("internal", "ui", "keys_glfw.go"): uiGLFWKeysTmpl,
filepath.Join("internal", "uidriver", "mobile", "keys.go"): uidriverMobileKeysTmpl, filepath.Join("internal", "ui", "keys_mobile.go"): uiMobileKeysTmpl,
filepath.Join("internal", "uidriver", "js", "keys_js.go"): uidriverJsKeysTmpl, filepath.Join("internal", "ui", "keys_js.go"): uiJSKeysTmpl,
filepath.Join("keys.go"): ebitenKeysTmpl, filepath.Join("keys.go"): ebitenKeysTmpl,
filepath.Join("mobile", "ebitenmobileview", "keys_android.go"): mobileAndroidKeysTmpl, filepath.Join("mobile", "ebitenmobileview", "keys_android.go"): mobileAndroidKeysTmpl,
} { } {
@ -817,12 +817,13 @@ func main() {
case filepath.Join("internal", "glfw", "keys.go"): case filepath.Join("internal", "glfw", "keys.go"):
buildTag = "//go:build !js" + buildTag = "//go:build !js" +
"\n// +build !js" "\n// +build !js"
case filepath.Join("internal", "uidriver", "mobile", "keys.go"): case filepath.Join("internal", "ui", "keys_mobile.go"):
buildTag = "//go:build android || ios" + buildTag = "//go:build (android || ios) && !ebitencbackend" +
"\n// +build android ios" "\n// +build android ios" +
case filepath.Join("internal", "uidriver", "glfw", "keys.go"): "\n// +build !ebitencbackend"
buildTag = "//go:build !android && !js && !ios" + case filepath.Join("internal", "ui", "keys_glfw.go"):
"\n// +build !android,!js,!ios" buildTag = "//go:build !android && !js && !ios && !ebitencbackend" +
"\n// +build !android,!js,!ios,!ebitencbackend"
} }
// NOTE: According to godoc, maps are automatically sorted by key. // NOTE: According to godoc, maps are automatically sorted by key.
if err := tmpl.Execute(f, struct { if err := tmpl.Execute(f, struct {

View File

@ -16,8 +16,9 @@ package ebiten
import ( import (
"github.com/hajimehoshi/ebiten/v2/internal/graphicscommand" "github.com/hajimehoshi/ebiten/v2/internal/graphicscommand"
"github.com/hajimehoshi/ebiten/v2/internal/ui"
) )
func init() { func init() {
graphicscommand.SetGraphicsDriver(uiDriver().Graphics()) graphicscommand.SetGraphicsDriver(ui.Get().Graphics())
} }

View File

@ -18,6 +18,7 @@ import (
"github.com/hajimehoshi/ebiten/v2/internal/driver" "github.com/hajimehoshi/ebiten/v2/internal/driver"
"github.com/hajimehoshi/ebiten/v2/internal/gamepad" "github.com/hajimehoshi/ebiten/v2/internal/gamepad"
"github.com/hajimehoshi/ebiten/v2/internal/gamepaddb" "github.com/hajimehoshi/ebiten/v2/internal/gamepaddb"
"github.com/hajimehoshi/ebiten/v2/internal/ui"
) )
// AppendInputChars appends "printable" runes, read from the keyboard at the time update is called, to runes, // AppendInputChars appends "printable" runes, read from the keyboard at the time update is called, to runes,
@ -35,7 +36,7 @@ import (
// //
// Keyboards don't work on iOS yet (#1090). // Keyboards don't work on iOS yet (#1090).
func AppendInputChars(runes []rune) []rune { func AppendInputChars(runes []rune) []rune {
return uiDriver().Input().AppendInputChars(runes) return ui.Get().Input().AppendInputChars(runes)
} }
// InputChars return "printable" runes read from the keyboard at the time update is called. // InputChars return "printable" runes read from the keyboard at the time update is called.
@ -82,7 +83,7 @@ func IsKeyPressed(key Key) bool {
keys = []driver.Key{driver.Key(key)} keys = []driver.Key{driver.Key(key)}
} }
for _, k := range keys { for _, k := range keys {
if uiDriver().Input().IsKeyPressed(k) { if ui.Get().Input().IsKeyPressed(k) {
return true return true
} }
} }
@ -98,7 +99,7 @@ func IsKeyPressed(key Key) bool {
// //
// CursorPosition is concurrent-safe. // CursorPosition is concurrent-safe.
func CursorPosition() (x, y int) { func CursorPosition() (x, y int) {
return uiDriver().Input().CursorPosition() return ui.Get().Input().CursorPosition()
} }
// Wheel returns x and y offsets of the mouse wheel or touchpad scroll. // Wheel returns x and y offsets of the mouse wheel or touchpad scroll.
@ -106,7 +107,7 @@ func CursorPosition() (x, y int) {
// //
// Wheel is concurrent-safe. // Wheel is concurrent-safe.
func Wheel() (xoff, yoff float64) { func Wheel() (xoff, yoff float64) {
return uiDriver().Input().Wheel() return ui.Get().Input().Wheel()
} }
// IsMouseButtonPressed returns a boolean indicating whether mouseButton is pressed. // IsMouseButtonPressed returns a boolean indicating whether mouseButton is pressed.
@ -116,7 +117,7 @@ func Wheel() (xoff, yoff float64) {
// //
// IsMouseButtonPressed is concurrent-safe. // IsMouseButtonPressed is concurrent-safe.
func IsMouseButtonPressed(mouseButton MouseButton) bool { func IsMouseButtonPressed(mouseButton MouseButton) bool {
return uiDriver().Input().IsMouseButtonPressed(mouseButton) return ui.Get().Input().IsMouseButtonPressed(mouseButton)
} }
// GamepadID represents a gamepad's identifier. // GamepadID represents a gamepad's identifier.
@ -336,7 +337,7 @@ type TouchID = driver.TouchID
// //
// AppendTouchIDs is concurrent-safe. // AppendTouchIDs is concurrent-safe.
func AppendTouchIDs(touches []TouchID) []TouchID { func AppendTouchIDs(touches []TouchID) []TouchID {
return uiDriver().Input().AppendTouchIDs(touches) return ui.Get().Input().AppendTouchIDs(touches)
} }
// TouchIDs returns the current touch states. // TouchIDs returns the current touch states.
@ -352,5 +353,5 @@ func TouchIDs() []TouchID {
// //
// TouchPosition is cuncurrent-safe. // TouchPosition is cuncurrent-safe.
func TouchPosition(id TouchID) (int, int) { func TouchPosition(id TouchID) (int, int) {
return uiDriver().Input().TouchPosition(id) return ui.Get().Input().TouchPosition(id)
} }

View File

@ -12,10 +12,10 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
//go:build !ebitengl && !ios //go:build !ios && !ebitengl && !ebitencbackend
// +build !ebitengl,!ios // +build !ios,!ebitengl,!ebitencbackend
package glfw package ui
// #cgo CFLAGS: -x objective-c // #cgo CFLAGS: -x objective-c
// #cgo LDFLAGS: -framework Foundation // #cgo LDFLAGS: -framework Foundation

View File

@ -12,11 +12,12 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
//go:build ((ios && arm) || (ios && arm64)) && !ebitengl //go:build ((ios && arm) || (ios && arm64)) && !ebitengl && !ebitencbackend
// +build ios,arm ios,arm64 // +build ios,arm ios,arm64
// +build !ebitengl // +build !ebitengl
// +build !ebitencbackend
package mobile package ui
import ( import (
"fmt" "fmt"

View File

@ -12,10 +12,10 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
//go:build android || (ios && 386) || (ios && amd64) || (ios && ebitengl) //go:build !darwin || (ios && 386) || (ios && amd64) || ebitengl
// +build android ios,386 ios,amd64 ios,ebitengl // +build !darwin ios,386 ios,amd64 ebitengl
package mobile package ui
import ( import (
"github.com/hajimehoshi/ebiten/v2/internal/driver" "github.com/hajimehoshi/ebiten/v2/internal/driver"

View File

@ -12,10 +12,10 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
//go:build !windows || js //go:build !windows || ebitencbackend
// +build !windows js // +build !windows ebitencbackend
package glfw package ui
// hideConsoleWindowOnWindows does nothing on non-Windows systems. // hideConsoleWindowOnWindows does nothing on non-Windows systems.
func hideConsoleWindowOnWindows() {} func hideConsoleWindowOnWindows() {}

View File

@ -12,7 +12,10 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
package glfw //go:build !ebitencbackend
// +build !ebitencbackend
package ui
import ( import (
"fmt" "fmt"
@ -39,9 +42,9 @@ func freeConsole() error {
r, _, e := procFreeConsoleWindow.Call() r, _, e := procFreeConsoleWindow.Call()
if r == 0 { if r == 0 {
if e != nil && e != windows.ERROR_SUCCESS { if e != nil && e != windows.ERROR_SUCCESS {
return fmt.Errorf("glfw: FreeConsole failed: %w", e) return fmt.Errorf("ui: FreeConsole failed: %w", e)
} }
return fmt.Errorf("glfw: FreeConsole returned 0") return fmt.Errorf("ui: FreeConsole returned 0")
} }
return nil return nil
} }

View File

@ -15,7 +15,7 @@
//go:build ebitencbackend //go:build ebitencbackend
// +build ebitencbackend // +build ebitencbackend
package cbackend package ui
import ( import (
"sync" "sync"

View File

@ -12,10 +12,10 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
//go:build !android && !js && !ios //go:build !android && !js && !ios && !ebitencbackend
// +build !android,!js,!ios // +build !android,!js,!ios,!ebitencbackend
package glfw package ui
import ( import (
"math" "math"

View File

@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
package js package ui
import ( import (
"syscall/js" "syscall/js"

View File

@ -12,10 +12,11 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
//go:build android || ios //go:build (android || ios) && !ebitencbackend
// +build android ios // +build android ios
// +build !ebitencbackend
package mobile package ui
import ( import (
"github.com/hajimehoshi/ebiten/v2/internal/driver" "github.com/hajimehoshi/ebiten/v2/internal/driver"

View File

@ -14,10 +14,10 @@
// Code generated by genkeys.go using 'go generate'. DO NOT EDIT. // Code generated by genkeys.go using 'go generate'. DO NOT EDIT.
//go:build !android && !js && !ios //go:build !android && !js && !ios && !ebitencbackend
// +build !android,!js,!ios // +build !android,!js,!ios,!ebitencbackend
package glfw package ui
import ( import (
"github.com/hajimehoshi/ebiten/v2/internal/driver" "github.com/hajimehoshi/ebiten/v2/internal/driver"

View File

@ -14,7 +14,7 @@
// Code generated by genkeys.go using 'go generate'. DO NOT EDIT. // Code generated by genkeys.go using 'go generate'. DO NOT EDIT.
package js package ui
import ( import (
"syscall/js" "syscall/js"

View File

@ -14,10 +14,11 @@
// Code generated by genkeys.go using 'go generate'. DO NOT EDIT. // Code generated by genkeys.go using 'go generate'. DO NOT EDIT.
//go:build android || ios //go:build (android || ios) && !ebitencbackend
// +build android ios // +build android ios
// +build !ebitencbackend
package mobile package ui
import ( import (
"golang.org/x/mobile/event/key" "golang.org/x/mobile/event/key"

View File

@ -12,10 +12,10 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
//go:build !ebitensinglethread && !android && !js && !ios //go:build !android && !js && !ios && !ebitencbackend && !ebitensinglethread
// +build !ebitensinglethread,!android,!js,!ios // +build !android,!js,!ios,!ebitencbackend,!ebitensinglethread
package glfw package ui
import ( import (
"github.com/hajimehoshi/ebiten/v2/internal/driver" "github.com/hajimehoshi/ebiten/v2/internal/driver"

View File

@ -12,10 +12,10 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
//go:build ebitensinglethread && !android && !js && !ios //go:build !android && !js && !ios && !ebitencbackend && ebitensinglethread
// +build ebitensinglethread,!android,!js,!ios // +build !android,!js,!ios,!ebitencbackend,ebitensinglethread
package glfw package ui
import ( import (
"github.com/hajimehoshi/ebiten/v2/internal/driver" "github.com/hajimehoshi/ebiten/v2/internal/driver"

View File

@ -15,7 +15,7 @@
//go:build ebitencbackend //go:build ebitencbackend
// +build ebitencbackend // +build ebitencbackend
package cbackend package ui
import ( import (
"runtime" "runtime"
@ -23,7 +23,6 @@ import (
"github.com/hajimehoshi/ebiten/v2/internal/cbackend" "github.com/hajimehoshi/ebiten/v2/internal/cbackend"
"github.com/hajimehoshi/ebiten/v2/internal/driver" "github.com/hajimehoshi/ebiten/v2/internal/driver"
"github.com/hajimehoshi/ebiten/v2/internal/graphicsdriver/opengl"
) )
const deviceScaleFactor = 1 const deviceScaleFactor = 1
@ -60,7 +59,7 @@ func (u *UserInterface) Run(context driver.UIContext) error {
} }
func (*UserInterface) RunWithoutMainLoop(context driver.UIContext) { func (*UserInterface) RunWithoutMainLoop(context driver.UIContext) {
panic("cbackend: RunWithoutMainLoop is not implemented") panic("ui: RunWithoutMainLoop is not implemented")
} }
func (*UserInterface) DeviceScaleFactor() float64 { func (*UserInterface) DeviceScaleFactor() float64 {
@ -136,7 +135,3 @@ func (*UserInterface) Input() driver.Input {
func (*UserInterface) Window() driver.Window { func (*UserInterface) Window() driver.Window {
return nil return nil
} }
func (*UserInterface) Graphics() driver.Graphics {
return opengl.Get()
}

View File

@ -12,10 +12,10 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
//go:build !ios //go:build !ios && !ebitencbackend
// +build !ios // +build !ios,!ebitencbackend
package glfw package ui
// #cgo CFLAGS: -x objective-c // #cgo CFLAGS: -x objective-c
// #cgo LDFLAGS: -framework AppKit // #cgo LDFLAGS: -framework AppKit

View File

@ -12,10 +12,10 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
//go:build !android && !js && !ios //go:build !android && !js && !ios && !ebitencbackend
// +build !android,!js,!ios // +build !android,!js,!ios,!ebitencbackend
package glfw package ui
import ( import (
"fmt" "fmt"
@ -42,7 +42,7 @@ func driverCursorModeToGLFWCursorMode(mode driver.CursorMode) int {
case driver.CursorModeCaptured: case driver.CursorModeCaptured:
return glfw.CursorDisabled return glfw.CursorDisabled
default: default:
panic(fmt.Sprintf("glfw: invalid driver.CursorMode: %d", mode)) panic(fmt.Sprintf("ui: invalid driver.CursorMode: %d", mode))
} }
} }
@ -178,7 +178,7 @@ func initialize() error {
} }
if w == nil { if w == nil {
// This can happen on Windows Remote Desktop (#903). // This can happen on Windows Remote Desktop (#903).
panic("glfw: glfw.CreateWindow must not return nil") panic("ui: glfw.CreateWindow must not return nil")
} }
defer w.Destroy() defer w.Destroy()
initializeWindowAfterCreation(w) initializeWindowAfterCreation(w)
@ -498,7 +498,7 @@ func (u *UserInterface) ScreenSizeInFullscreen() (int, int) {
// isFullscreen must be called from the main thread. // isFullscreen must be called from the main thread.
func (u *UserInterface) isFullscreen() bool { func (u *UserInterface) isFullscreen() bool {
if !u.isRunning() { if !u.isRunning() {
panic("glfw: isFullscreen can't be called before the main loop starts") panic("ui: isFullscreen can't be called before the main loop starts")
} }
return u.window.GetMonitor() != nil || u.isNativeFullscreen() return u.window.GetMonitor() != nil || u.isNativeFullscreen()
} }
@ -613,7 +613,7 @@ func (u *UserInterface) CursorMode() driver.CursorMode {
case glfw.CursorDisabled: case glfw.CursorDisabled:
v = driver.CursorModeCaptured v = driver.CursorModeCaptured
default: default:
panic(fmt.Sprintf("glfw: invalid GLFW cursor mode: %d", mode)) panic(fmt.Sprintf("ui: invalid GLFW cursor mode: %d", mode))
} }
return v return v
} }
@ -676,7 +676,7 @@ func init() {
} }
func (u *UserInterface) RunWithoutMainLoop(context driver.UIContext) { func (u *UserInterface) RunWithoutMainLoop(context driver.UIContext) {
panic("glfw: RunWithoutMainLoop is not implemented") panic("ui: RunWithoutMainLoop is not implemented")
} }
// createWindow creates a GLFW window. // createWindow creates a GLFW window.
@ -686,7 +686,7 @@ func (u *UserInterface) RunWithoutMainLoop(context driver.UIContext) {
// createWindow does not set the position or size so far. // createWindow does not set the position or size so far.
func (u *UserInterface) createWindow() error { func (u *UserInterface) createWindow() error {
if u.window != nil { if u.window != nil {
panic("glfw: u.window must not exist at createWindow") panic("ui: u.window must not exist at createWindow")
} }
// As a start, create a window with temporary size to create OpenGL context thread. // As a start, create a window with temporary size to create OpenGL context thread.
@ -1288,7 +1288,7 @@ func (u *UserInterface) setWindowSizeInDIPImpl(width, height int, fullscreen boo
} }
if err := u.createWindow(); err != nil { if err := u.createWindow(); err != nil {
// TODO: This should return an error. // TODO: This should return an error.
panic(fmt.Sprintf("glfw: failed to recreate window: %v", err)) panic(fmt.Sprintf("ui: failed to recreate window: %v", err))
} }
// Reset the size limits explicitly. // Reset the size limits explicitly.
u.updateWindowSizeLimits() u.updateWindowSizeLimits()
@ -1396,7 +1396,7 @@ func (u *UserInterface) SetScreenTransparent(transparent bool) {
u.setInitScreenTransparent(transparent) u.setInitScreenTransparent(transparent)
return return
} }
panic("glfw: SetScreenTransparent can't be called after the main loop starts") panic("ui: SetScreenTransparent can't be called after the main loop starts")
} }
func (u *UserInterface) IsScreenTransparent() bool { func (u *UserInterface) IsScreenTransparent() bool {

View File

@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
package js package ui
import ( import (
"syscall/js" "syscall/js"
@ -21,7 +21,6 @@ import (
"github.com/hajimehoshi/ebiten/v2/internal/devicescale" "github.com/hajimehoshi/ebiten/v2/internal/devicescale"
"github.com/hajimehoshi/ebiten/v2/internal/driver" "github.com/hajimehoshi/ebiten/v2/internal/driver"
"github.com/hajimehoshi/ebiten/v2/internal/gamepad" "github.com/hajimehoshi/ebiten/v2/internal/gamepad"
"github.com/hajimehoshi/ebiten/v2/internal/graphicsdriver/opengl"
"github.com/hajimehoshi/ebiten/v2/internal/hooks" "github.com/hajimehoshi/ebiten/v2/internal/hooks"
) )
@ -198,7 +197,7 @@ func (u *UserInterface) SetCursorMode(mode driver.CursorMode) {
func (u *UserInterface) recoverCursorMode() { func (u *UserInterface) recoverCursorMode() {
if theUI.cursorPrevMode == driver.CursorModeCaptured { if theUI.cursorPrevMode == driver.CursorModeCaptured {
panic("js: cursorPrevMode must not be driver.CursorModeCaptured at recoverCursorMode") panic("ui: cursorPrevMode must not be driver.CursorModeCaptured at recoverCursorMode")
} }
u.SetCursorMode(u.cursorPrevMode) u.SetCursorMode(u.cursorPrevMode)
} }
@ -607,7 +606,7 @@ func (u *UserInterface) Run(context driver.UIContext) error {
} }
func (u *UserInterface) RunWithoutMainLoop(context driver.UIContext) { func (u *UserInterface) RunWithoutMainLoop(context driver.UIContext) {
panic("js: RunWithoutMainLoop is not implemented") panic("ui: RunWithoutMainLoop is not implemented")
} }
func (u *UserInterface) updateScreenSize() { func (u *UserInterface) updateScreenSize() {
@ -626,7 +625,7 @@ func (u *UserInterface) updateScreenSize() {
func (u *UserInterface) SetScreenTransparent(transparent bool) { func (u *UserInterface) SetScreenTransparent(transparent bool) {
if u.running { if u.running {
panic("js: SetScreenTransparent can't be called after the main loop starts") panic("ui: SetScreenTransparent can't be called after the main loop starts")
} }
bodyStyle := document.Get("body").Get("style") bodyStyle := document.Get("body").Get("style")
@ -669,7 +668,3 @@ func (u *UserInterface) Input() driver.Input {
func (u *UserInterface) Window() driver.Window { func (u *UserInterface) Window() driver.Window {
return nil return nil
} }
func (*UserInterface) Graphics() driver.Graphics {
return opengl.Get()
}

View File

@ -12,10 +12,11 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
//go:build android || ios //go:build (android || ios) && !ebitencbackend
// +build android ios // +build android ios
// +build !ebitencbackend
package mobile package ui
import ( import (
"fmt" "fmt"

View File

@ -12,10 +12,10 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
//go:build !android && !darwin && !js && !windows //go:build !android && !darwin && !js && !windows && !ebitencbackend
// +build !android,!darwin,!js,!windows // +build !android,!darwin,!js,!windows,!ebitencbackend
package glfw package ui
import ( import (
"fmt" "fmt"
@ -162,7 +162,7 @@ func (u *UserInterface) isNativeFullscreenAvailable() bool {
} }
func (u *UserInterface) setNativeFullscreen(fullscreen bool) { func (u *UserInterface) setNativeFullscreen(fullscreen bool) {
panic(fmt.Sprintf("glfw: setNativeFullscreen is not implemented in this environment: %s", runtime.GOOS)) panic(fmt.Sprintf("ui: setNativeFullscreen is not implemented in this environment: %s", runtime.GOOS))
} }
func (u *UserInterface) adjustViewSize() { func (u *UserInterface) adjustViewSize() {

View File

@ -12,7 +12,10 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
package glfw //go:build !ebitencbackend
// +build !ebitencbackend
package ui
import ( import (
"fmt" "fmt"
@ -57,7 +60,7 @@ func getSystemMetrics(nIndex int) (int32, error) {
if r == 0 { if r == 0 {
// GetLastError doesn't provide an extended information. // GetLastError doesn't provide an extended information.
// See https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-getsystemmetrics // See https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-getsystemmetrics
return 0, fmt.Errorf("glfw: GetSystemMetrics returned 0") return 0, fmt.Errorf("ui: GetSystemMetrics returned 0")
} }
return int32(r), nil return int32(r), nil
} }
@ -76,9 +79,9 @@ func getMonitorInfoW(hMonitor uintptr, lpmi *monitorInfo) error {
r, _, e := procGetMonitorInfoW.Call(hMonitor, uintptr(unsafe.Pointer(lpmi))) r, _, e := procGetMonitorInfoW.Call(hMonitor, uintptr(unsafe.Pointer(lpmi)))
if r == 0 { if r == 0 {
if e != nil && e != windows.ERROR_SUCCESS { if e != nil && e != windows.ERROR_SUCCESS {
return fmt.Errorf("glfw: GetMonitorInfoW failed: error code: %w", e) return fmt.Errorf("ui: GetMonitorInfoW failed: error code: %w", e)
} }
return fmt.Errorf("glfw: GetMonitorInfoW failed: returned 0") return fmt.Errorf("ui: GetMonitorInfoW failed: returned 0")
} }
return nil return nil
} }
@ -175,7 +178,7 @@ func (u *UserInterface) isNativeFullscreenAvailable() bool {
} }
func (u *UserInterface) setNativeFullscreen(fullscreen bool) { func (u *UserInterface) setNativeFullscreen(fullscreen bool) {
panic(fmt.Sprintf("glfw: setNativeFullscreen is not implemented in this environment: %s", runtime.GOOS)) panic(fmt.Sprintf("ui: setNativeFullscreen is not implemented in this environment: %s", runtime.GOOS))
} }
func (u *UserInterface) adjustViewSize() { func (u *UserInterface) adjustViewSize() {

View File

@ -12,7 +12,10 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
package mobile //go:build !ebitencbackend
// +build !ebitencbackend
package ui
import ( import (
"time" "time"

View File

@ -12,10 +12,10 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
//go:build ios //go:build ios && !ebitencbackend
// +build ios // +build ios,!ebitencbackend
package mobile package ui
// #cgo CFLAGS: -x objective-c // #cgo CFLAGS: -x objective-c
// #cgo LDFLAGS: -framework AVFoundation -framework CoreHaptics -framework Foundation // #cgo LDFLAGS: -framework AVFoundation -framework CoreHaptics -framework Foundation

View File

@ -12,10 +12,10 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
//go:build !android && !js && !ios //go:build !android && !js && !ios && !ebitencbackend
// +build !android,!js,!ios // +build !android,!js,!ios,!ebitencbackend
package glfw package ui
import ( import (
"image" "image"
@ -114,7 +114,7 @@ func (w *window) IsMaximized() bool {
func (w *window) Maximize() { func (w *window) Maximize() {
if !w.IsResizable() { if !w.IsResizable() {
panic("glfw: a window to maximize must be resizable") panic("ui: a window to maximize must be resizable")
} }
if !w.ui.isRunning() { if !w.ui.isRunning() {
w.ui.setInitWindowMaximized(true) w.ui.setInitWindowMaximized(true)
@ -152,7 +152,7 @@ func (w *window) Restore() {
func (w *window) Position() (int, int) { func (w *window) Position() (int, int) {
if !w.ui.isRunning() { if !w.ui.isRunning() {
panic("glfw: WindowPosition can't be called before the main loop starts") panic("ui: WindowPosition can't be called before the main loop starts")
} }
x, y := 0, 0 x, y := 0, 0
w.ui.t.Call(func() { w.ui.t.Call(func() {

View File

@ -1,30 +0,0 @@
// Copyright 2018 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 !android && (!darwin || ebitengl) && !ios && !js
// +build !android
// +build !darwin ebitengl
// +build !ios
// +build !js
package glfw
import (
"github.com/hajimehoshi/ebiten/v2/internal/driver"
"github.com/hajimehoshi/ebiten/v2/internal/graphicsdriver/opengl"
)
func (*UserInterface) Graphics() driver.Graphics {
return opengl.Get()
}

View File

@ -19,7 +19,7 @@ package ebitenmobileview
import ( import (
"github.com/hajimehoshi/ebiten/v2/internal/driver" "github.com/hajimehoshi/ebiten/v2/internal/driver"
"github.com/hajimehoshi/ebiten/v2/internal/uidriver/mobile" "github.com/hajimehoshi/ebiten/v2/internal/ui"
) )
type position struct { type position struct {
@ -34,18 +34,18 @@ var (
) )
var ( var (
touchSlice []mobile.Touch touchSlice []ui.Touch
) )
func updateInput() { func updateInput() {
touchSlice = touchSlice[:0] touchSlice = touchSlice[:0]
for id, position := range touches { for id, position := range touches {
touchSlice = append(touchSlice, mobile.Touch{ touchSlice = append(touchSlice, ui.Touch{
ID: id, ID: id,
X: position.x, X: position.x,
Y: position.y, Y: position.y,
}) })
} }
mobile.Get().UpdateInput(keys, runes, touchSlice) ui.Get().UpdateInput(keys, runes, touchSlice)
} }

View File

@ -33,7 +33,7 @@ import (
"github.com/hajimehoshi/ebiten/v2" "github.com/hajimehoshi/ebiten/v2"
"github.com/hajimehoshi/ebiten/v2/internal/devicescale" "github.com/hajimehoshi/ebiten/v2/internal/devicescale"
"github.com/hajimehoshi/ebiten/v2/internal/restorable" "github.com/hajimehoshi/ebiten/v2/internal/restorable"
"github.com/hajimehoshi/ebiten/v2/internal/uidriver/mobile" "github.com/hajimehoshi/ebiten/v2/internal/ui"
) )
var theState state var theState state
@ -59,7 +59,7 @@ func SetGame(game ebiten.Game) {
} }
func Layout(viewWidth, viewHeight float64) { func Layout(viewWidth, viewHeight float64) {
mobile.Get().SetOutsideSize(viewWidth, viewHeight) ui.Get().SetOutsideSize(viewWidth, viewHeight)
} }
func Update() error { func Update() error {
@ -73,15 +73,15 @@ func Update() error {
return nil return nil
} }
return mobile.Get().Update() return ui.Get().Update()
} }
func Suspend() error { func Suspend() error {
return mobile.Get().SetForeground(false) return ui.Get().SetForeground(false)
} }
func Resume() error { func Resume() error {
return mobile.Get().SetForeground(true) return ui.Get().SetForeground(true)
} }
func OnContextLost() { func OnContextLost() {
@ -98,5 +98,5 @@ type RenderRequester interface {
} }
func SetRenderRequester(renderRequester RenderRequester) { func SetRenderRequester(renderRequester RenderRequester) {
mobile.Get().SetRenderRequester(renderRequester) ui.Get().SetRenderRequester(renderRequester)
} }

43
run.go
View File

@ -20,6 +20,7 @@ import (
"github.com/hajimehoshi/ebiten/v2/internal/clock" "github.com/hajimehoshi/ebiten/v2/internal/clock"
"github.com/hajimehoshi/ebiten/v2/internal/driver" "github.com/hajimehoshi/ebiten/v2/internal/driver"
"github.com/hajimehoshi/ebiten/v2/internal/graphicscommand" "github.com/hajimehoshi/ebiten/v2/internal/graphicscommand"
"github.com/hajimehoshi/ebiten/v2/internal/ui"
) )
// Game defines necessary functions for a game. // Game defines necessary functions for a game.
@ -160,7 +161,7 @@ func RunGame(game Game) error {
theUIContext.set(&imageDumperGame{ theUIContext.set(&imageDumperGame{
game: game, game: game,
}) })
if err := uiDriver().Run(theUIContext); err != nil { if err := ui.Get().Run(theUIContext); err != nil {
if err == driver.RegularTermination { if err == driver.RegularTermination {
return nil return nil
} }
@ -194,7 +195,7 @@ func isRunGameEnded() bool {
// ScreenSizeInFullscreen must be called on the main thread before ebiten.Run, and is concurrent-safe after // ScreenSizeInFullscreen must be called on the main thread before ebiten.Run, and is concurrent-safe after
// ebiten.Run. // ebiten.Run.
func ScreenSizeInFullscreen() (int, int) { func ScreenSizeInFullscreen() (int, int) {
return uiDriver().ScreenSizeInFullscreen() return ui.Get().ScreenSizeInFullscreen()
} }
// CursorMode returns the current cursor mode. // CursorMode returns the current cursor mode.
@ -203,7 +204,7 @@ func ScreenSizeInFullscreen() (int, int) {
// //
// CursorMode is concurrent-safe. // CursorMode is concurrent-safe.
func CursorMode() CursorModeType { func CursorMode() CursorModeType {
return uiDriver().CursorMode() return ui.Get().CursorMode()
} }
// SetCursorMode sets the render and capture mode of the mouse cursor. // SetCursorMode sets the render and capture mode of the mouse cursor.
@ -219,7 +220,7 @@ func CursorMode() CursorModeType {
// //
// SetCursorMode is concurrent-safe. // SetCursorMode is concurrent-safe.
func SetCursorMode(mode CursorModeType) { func SetCursorMode(mode CursorModeType) {
uiDriver().SetCursorMode(mode) ui.Get().SetCursorMode(mode)
} }
// CursorShape returns the current cursor shape. // CursorShape returns the current cursor shape.
@ -228,14 +229,14 @@ func SetCursorMode(mode CursorModeType) {
// //
// CursorShape is concurrent-safe. // CursorShape is concurrent-safe.
func CursorShape() CursorShapeType { func CursorShape() CursorShapeType {
return uiDriver().CursorShape() return ui.Get().CursorShape()
} }
// SetCursorShape sets the cursor shape. // SetCursorShape sets the cursor shape.
// //
// SetCursorShape is concurrent-safe. // SetCursorShape is concurrent-safe.
func SetCursorShape(shape CursorShapeType) { func SetCursorShape(shape CursorShapeType) {
uiDriver().SetCursorShape(shape) ui.Get().SetCursorShape(shape)
} }
// IsFullscreen reports whether the current mode is fullscreen or not. // IsFullscreen reports whether the current mode is fullscreen or not.
@ -244,7 +245,7 @@ func SetCursorShape(shape CursorShapeType) {
// //
// IsFullscreen is concurrent-safe. // IsFullscreen is concurrent-safe.
func IsFullscreen() bool { func IsFullscreen() bool {
return uiDriver().IsFullscreen() return ui.Get().IsFullscreen()
} }
// SetFullscreen changes the current mode to fullscreen or not on desktops and browsers. // SetFullscreen changes the current mode to fullscreen or not on desktops and browsers.
@ -265,7 +266,7 @@ func IsFullscreen() bool {
// //
// SetFullscreen is concurrent-safe. // SetFullscreen is concurrent-safe.
func SetFullscreen(fullscreen bool) { func SetFullscreen(fullscreen bool) {
uiDriver().SetFullscreen(fullscreen) ui.Get().SetFullscreen(fullscreen)
} }
// IsFocused returns a boolean value indicating whether // IsFocused returns a boolean value indicating whether
@ -275,7 +276,7 @@ func SetFullscreen(fullscreen bool) {
// //
// IsFocused is concurrent-safe. // IsFocused is concurrent-safe.
func IsFocused() bool { func IsFocused() bool {
return uiDriver().IsFocused() return ui.Get().IsFocused()
} }
// IsRunnableOnUnfocused returns a boolean value indicating whether // IsRunnableOnUnfocused returns a boolean value indicating whether
@ -283,7 +284,7 @@ func IsFocused() bool {
// //
// IsRunnableOnUnfocused is concurrent-safe. // IsRunnableOnUnfocused is concurrent-safe.
func IsRunnableOnUnfocused() bool { func IsRunnableOnUnfocused() bool {
return uiDriver().IsRunnableOnUnfocused() return ui.Get().IsRunnableOnUnfocused()
} }
// SetRunnableOnUnfocused sets the state if the game runs even in background. // SetRunnableOnUnfocused sets the state if the game runs even in background.
@ -298,7 +299,7 @@ func IsRunnableOnUnfocused() bool {
// //
// SetRunnableOnUnfocused is concurrent-safe. // SetRunnableOnUnfocused is concurrent-safe.
func SetRunnableOnUnfocused(runnableOnUnfocused bool) { func SetRunnableOnUnfocused(runnableOnUnfocused bool) {
uiDriver().SetRunnableOnUnfocused(runnableOnUnfocused) ui.Get().SetRunnableOnUnfocused(runnableOnUnfocused)
} }
// DeviceScaleFactor returns a device scale factor value of the current monitor which the window belongs to. // DeviceScaleFactor returns a device scale factor value of the current monitor which the window belongs to.
@ -316,7 +317,7 @@ func SetRunnableOnUnfocused(runnableOnUnfocused bool) {
// //
// BUG: DeviceScaleFactor value is not affected by SetWindowPosition before RunGame (#1575). // BUG: DeviceScaleFactor value is not affected by SetWindowPosition before RunGame (#1575).
func DeviceScaleFactor() float64 { func DeviceScaleFactor() float64 {
return uiDriver().DeviceScaleFactor() return ui.Get().DeviceScaleFactor()
} }
// IsVsyncEnabled returns a boolean value indicating whether // IsVsyncEnabled returns a boolean value indicating whether
@ -324,7 +325,7 @@ func DeviceScaleFactor() float64 {
// //
// Deprecated: as of v2.2. Use FPSMode instead. // Deprecated: as of v2.2. Use FPSMode instead.
func IsVsyncEnabled() bool { func IsVsyncEnabled() bool {
return uiDriver().FPSMode() == driver.FPSModeVsyncOn return ui.Get().FPSMode() == driver.FPSModeVsyncOn
} }
// SetVsyncEnabled sets a boolean value indicating whether // SetVsyncEnabled sets a boolean value indicating whether
@ -333,9 +334,9 @@ func IsVsyncEnabled() bool {
// Deprecated: as of v2.2. Use SetFPSMode instead. // Deprecated: as of v2.2. Use SetFPSMode instead.
func SetVsyncEnabled(enabled bool) { func SetVsyncEnabled(enabled bool) {
if enabled { if enabled {
uiDriver().SetFPSMode(driver.FPSModeVsyncOn) ui.Get().SetFPSMode(driver.FPSModeVsyncOn)
} else { } else {
uiDriver().SetFPSMode(driver.FPSModeVsyncOffMaximum) ui.Get().SetFPSMode(driver.FPSModeVsyncOffMaximum)
} }
} }
@ -371,7 +372,7 @@ const (
// //
// FPSMode is concurrent-safe. // FPSMode is concurrent-safe.
func FPSMode() FPSModeType { func FPSMode() FPSModeType {
return uiDriver().FPSMode() return ui.Get().FPSMode()
} }
// SetFPSMode sets the FPS mode. // SetFPSMode sets the FPS mode.
@ -379,14 +380,14 @@ func FPSMode() FPSModeType {
// //
// SetFPSMode is concurrent-safe. // SetFPSMode is concurrent-safe.
func SetFPSMode(mode FPSModeType) { func SetFPSMode(mode FPSModeType) {
uiDriver().SetFPSMode(mode) ui.Get().SetFPSMode(mode)
} }
// ScheduleFrame schedules a next frame when the current FPS mode is FPSModeVsyncOffMinimum. // ScheduleFrame schedules a next frame when the current FPS mode is FPSModeVsyncOffMinimum.
// //
// ScheduleFrame is concurrent-safe. // ScheduleFrame is concurrent-safe.
func ScheduleFrame() { func ScheduleFrame() {
uiDriver().ScheduleFrame() ui.Get().ScheduleFrame()
} }
// MaxTPS returns the current maximum TPS. // MaxTPS returns the current maximum TPS.
@ -436,7 +437,7 @@ func SetMaxTPS(tps int) {
// //
// IsScreenTransparent is concurrent-safe. // IsScreenTransparent is concurrent-safe.
func IsScreenTransparent() bool { func IsScreenTransparent() bool {
return uiDriver().IsScreenTransparent() return ui.Get().IsScreenTransparent()
} }
// SetScreenTransparent sets the state if the window is transparent. // SetScreenTransparent sets the state if the window is transparent.
@ -447,7 +448,7 @@ func IsScreenTransparent() bool {
// //
// SetScreenTransparent is concurrent-safe. // SetScreenTransparent is concurrent-safe.
func SetScreenTransparent(transparent bool) { func SetScreenTransparent(transparent bool) {
uiDriver().SetScreenTransparent(transparent) ui.Get().SetScreenTransparent(transparent)
} }
// SetInitFocused sets whether the application is focused on show. // SetInitFocused sets whether the application is focused on show.
@ -461,5 +462,5 @@ func SetScreenTransparent(transparent bool) {
// //
// SetInitFocused is cuncurrent-safe. // SetInitFocused is cuncurrent-safe.
func SetInitFocused(focused bool) { func SetInitFocused(focused bool) {
uiDriver().SetInitFocused(focused) ui.Get().SetInitFocused(focused)
} }

View File

@ -17,6 +17,10 @@
package ebiten package ebiten
import (
"github.com/hajimehoshi/ebiten/v2/internal/ui"
)
// RunGameWithoutMainLoop runs the game, but doesn't call the loop on the main (UI) thread. // RunGameWithoutMainLoop runs the game, but doesn't call the loop on the main (UI) thread.
// RunGameWithoutMainLoop returns immediately unlike Run. // RunGameWithoutMainLoop returns immediately unlike Run.
// //
@ -26,5 +30,5 @@ package ebiten
// TODO: Remove this. In order to remove this, the uiContext should be in another package. // TODO: Remove this. In order to remove this, the uiContext should be in another package.
func RunGameWithoutMainLoop(game Game) { func RunGameWithoutMainLoop(game Game) {
theUIContext.set(game) theUIContext.set(game)
uiDriver().RunWithoutMainLoop(theUIContext) ui.Get().RunWithoutMainLoop(theUIContext)
} }

View File

@ -26,6 +26,7 @@ import (
"github.com/hajimehoshi/ebiten/v2/internal/driver" "github.com/hajimehoshi/ebiten/v2/internal/driver"
"github.com/hajimehoshi/ebiten/v2/internal/graphics" "github.com/hajimehoshi/ebiten/v2/internal/graphics"
"github.com/hajimehoshi/ebiten/v2/internal/hooks" "github.com/hajimehoshi/ebiten/v2/internal/hooks"
"github.com/hajimehoshi/ebiten/v2/internal/ui"
) )
type uiContext struct { type uiContext struct {
@ -66,7 +67,7 @@ func (c *uiContext) Layout(outsideWidth, outsideHeight float64) {
} }
func (c *uiContext) updateOffscreen() { func (c *uiContext) updateOffscreen() {
d := uiDriver().DeviceScaleFactor() d := ui.Get().DeviceScaleFactor()
sw, sh := int(c.outsideWidth*d), int(c.outsideHeight*d) sw, sh := int(c.outsideWidth*d), int(c.outsideHeight*d)
ow, oh := c.game.Layout(int(c.outsideWidth), int(c.outsideHeight)) ow, oh := c.game.Layout(int(c.outsideWidth), int(c.outsideHeight))
@ -188,7 +189,7 @@ func (c *uiContext) updateFrameImpl(updateCount int) error {
if err := c.game.Update(); err != nil { if err := c.game.Update(); err != nil {
return err return err
} }
uiDriver().ResetForFrame() ui.Get().ResetForFrame()
} }
// Even though updateCount == 0, the offscreen is cleared and Draw is called. // Even though updateCount == 0, the offscreen is cleared and Draw is called.
@ -199,15 +200,15 @@ func (c *uiContext) updateFrameImpl(updateCount int) error {
} }
c.game.Draw(c.offscreen) c.game.Draw(c.offscreen)
if uiDriver().Graphics().NeedsClearingScreen() { if ui.Get().Graphics().NeedsClearingScreen() {
// This clear is needed for fullscreen mode or some mobile platforms (#622). // This clear is needed for fullscreen mode or some mobile platforms (#622).
c.screen.Clear() c.screen.Clear()
} }
op := &DrawImageOptions{} op := &DrawImageOptions{}
s := c.screenScale(uiDriver().DeviceScaleFactor()) s := c.screenScale(ui.Get().DeviceScaleFactor())
switch vd := uiDriver().Graphics().FramebufferYDirection(); vd { switch vd := ui.Get().Graphics().FramebufferYDirection(); vd {
case driver.Upward: case driver.Upward:
op.GeoM.Scale(s, -s) op.GeoM.Scale(s, -s)
_, h := c.offscreen.Size() _, h := c.offscreen.Size()
@ -218,7 +219,7 @@ func (c *uiContext) updateFrameImpl(updateCount int) error {
panic(fmt.Sprintf("ebiten: invalid v-direction: %d", vd)) panic(fmt.Sprintf("ebiten: invalid v-direction: %d", vd))
} }
op.GeoM.Translate(c.offsets(uiDriver().DeviceScaleFactor())) op.GeoM.Translate(c.offsets(ui.Get().DeviceScaleFactor()))
op.CompositeMode = CompositeModeCopy op.CompositeMode = CompositeModeCopy
// filterScreen works with >=1 scale, but does not well with <1 scale. // filterScreen works with >=1 scale, but does not well with <1 scale.

View File

@ -1,27 +0,0 @@
// Copyright 2021 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 ebitencbackend
// +build ebitencbackend
package ebiten
import (
"github.com/hajimehoshi/ebiten/v2/internal/driver"
"github.com/hajimehoshi/ebiten/v2/internal/uidriver/cbackend"
)
func uiDriver() driver.UI {
return cbackend.Get()
}

View File

@ -1,27 +0,0 @@
// Copyright 2019 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 !android && !js && !ios && !ebitencbackend
// +build !android,!js,!ios,!ebitencbackend
package ebiten
import (
"github.com/hajimehoshi/ebiten/v2/internal/driver"
"github.com/hajimehoshi/ebiten/v2/internal/uidriver/glfw"
)
func uiDriver() driver.UI {
return glfw.Get()
}

View File

@ -1,27 +0,0 @@
// Copyright 2019 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 !ebitencbackend
// +build !ebitencbackend
package ebiten
import (
"github.com/hajimehoshi/ebiten/v2/internal/driver"
"github.com/hajimehoshi/ebiten/v2/internal/uidriver/js"
)
func uiDriver() driver.UI {
return js.Get()
}

View File

@ -1,28 +0,0 @@
// Copyright 2019 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 (android || ios) && !ebitencbackend
// +build android ios
// +build !ebitencbackend
package ebiten
import (
"github.com/hajimehoshi/ebiten/v2/internal/driver"
"github.com/hajimehoshi/ebiten/v2/internal/uidriver/mobile"
)
func uiDriver() driver.UI {
return mobile.Get()
}

View File

@ -18,6 +18,7 @@ import (
"time" "time"
"github.com/hajimehoshi/ebiten/v2/internal/gamepad" "github.com/hajimehoshi/ebiten/v2/internal/gamepad"
"github.com/hajimehoshi/ebiten/v2/internal/ui"
) )
// VibrateOptions represents the options for device vibration. // VibrateOptions represents the options for device vibration.
@ -50,7 +51,7 @@ type VibrateOptions struct {
// //
// Vibrate is concurrent-safe. // Vibrate is concurrent-safe.
func Vibrate(options *VibrateOptions) { func Vibrate(options *VibrateOptions) {
uiDriver().Vibrate(options.Duration, options.Magnitude) ui.Get().Vibrate(options.Duration, options.Magnitude)
} }
// VibrateGamepadOptions represents the options for gamepad vibration. // VibrateGamepadOptions represents the options for gamepad vibration.

View File

@ -17,6 +17,8 @@ package ebiten
import ( import (
"image" "image"
"sync/atomic" "sync/atomic"
"github.com/hajimehoshi/ebiten/v2/internal/ui"
) )
const ( const (
@ -29,7 +31,7 @@ const (
// //
// IsWindowDecorated is concurrent-safe. // IsWindowDecorated is concurrent-safe.
func IsWindowDecorated() bool { func IsWindowDecorated() bool {
if w := uiDriver().Window(); w != nil { if w := ui.Get().Window(); w != nil {
return w.IsDecorated() return w.IsDecorated()
} }
return false return false
@ -47,7 +49,7 @@ func IsWindowDecorated() bool {
// //
// SetWindowDecorated is concurrent-safe. // SetWindowDecorated is concurrent-safe.
func SetWindowDecorated(decorated bool) { func SetWindowDecorated(decorated bool) {
if w := uiDriver().Window(); w != nil { if w := ui.Get().Window(); w != nil {
w.SetDecorated(decorated) w.SetDecorated(decorated)
} }
} }
@ -57,7 +59,7 @@ func SetWindowDecorated(decorated bool) {
// //
// IsWindowResizable is concurrent-safe. // IsWindowResizable is concurrent-safe.
func IsWindowResizable() bool { func IsWindowResizable() bool {
if w := uiDriver().Window(); w != nil { if w := ui.Get().Window(); w != nil {
return w.IsResizable() return w.IsResizable()
} }
return false return false
@ -75,7 +77,7 @@ func IsWindowResizable() bool {
// //
// SetWindowResizable is concurrent-safe. // SetWindowResizable is concurrent-safe.
func SetWindowResizable(resizable bool) { func SetWindowResizable(resizable bool) {
if w := uiDriver().Window(); w != nil { if w := ui.Get().Window(); w != nil {
w.SetResizable(resizable) w.SetResizable(resizable)
} }
} }
@ -86,7 +88,7 @@ func SetWindowResizable(resizable bool) {
// //
// SetWindowTitle is concurrent-safe. // SetWindowTitle is concurrent-safe.
func SetWindowTitle(title string) { func SetWindowTitle(title string) {
if w := uiDriver().Window(); w != nil { if w := ui.Get().Window(); w != nil {
w.SetTitle(title) w.SetTitle(title)
} }
} }
@ -112,7 +114,7 @@ func SetWindowTitle(title string) {
// //
// SetWindowIcon is concurrent-safe. // SetWindowIcon is concurrent-safe.
func SetWindowIcon(iconImages []image.Image) { func SetWindowIcon(iconImages []image.Image) {
if w := uiDriver().Window(); w != nil { if w := ui.Get().Window(); w != nil {
w.SetIcon(iconImages) w.SetIcon(iconImages)
} }
} }
@ -129,7 +131,7 @@ func SetWindowIcon(iconImages []image.Image) {
// //
// WindowPosition is concurrent-safe. // WindowPosition is concurrent-safe.
func WindowPosition() (x, y int) { func WindowPosition() (x, y int) {
if w := uiDriver().Window(); w != nil { if w := ui.Get().Window(); w != nil {
return w.Position() return w.Position()
} }
return 0, 0 return 0, 0
@ -146,7 +148,7 @@ func WindowPosition() (x, y int) {
// SetWindowPosition is concurrent-safe. // SetWindowPosition is concurrent-safe.
func SetWindowPosition(x, y int) { func SetWindowPosition(x, y int) {
atomic.StoreUint32(&windowPositionSetExplicitly, 1) atomic.StoreUint32(&windowPositionSetExplicitly, 1)
if w := uiDriver().Window(); w != nil { if w := ui.Get().Window(); w != nil {
w.SetPosition(x, y) w.SetPosition(x, y)
} }
} }
@ -156,13 +158,13 @@ var (
) )
func initializeWindowPositionIfNeeded(width, height int) { func initializeWindowPositionIfNeeded(width, height int) {
w := uiDriver().Window() w := ui.Get().Window()
if w == nil { if w == nil {
return return
} }
if atomic.LoadUint32(&windowPositionSetExplicitly) == 0 { if atomic.LoadUint32(&windowPositionSetExplicitly) == 0 {
sw, sh := uiDriver().ScreenSizeInFullscreen() sw, sh := ui.Get().ScreenSizeInFullscreen()
x := (sw - width) / 2 x := (sw - width) / 2
y := (sh - height) / 3 y := (sh - height) / 3
w.SetPosition(x, y) w.SetPosition(x, y)
@ -176,7 +178,7 @@ func initializeWindowPositionIfNeeded(width, height int) {
// //
// WindowSize is concurrent-safe. // WindowSize is concurrent-safe.
func WindowSize() (int, int) { func WindowSize() (int, int) {
if w := uiDriver().Window(); w != nil { if w := ui.Get().Window(); w != nil {
return w.Size() return w.Size()
} }
return 0, 0 return 0, 0
@ -194,7 +196,7 @@ func SetWindowSize(width, height int) {
if width <= 0 || height <= 0 { if width <= 0 || height <= 0 {
panic("ebiten: width and height must be positive") panic("ebiten: width and height must be positive")
} }
if w := uiDriver().Window(); w != nil { if w := ui.Get().Window(); w != nil {
w.SetSize(width, height) w.SetSize(width, height)
} }
} }
@ -204,7 +206,7 @@ func SetWindowSize(width, height int) {
// //
// WindowSizeLimits is concurrent-safe. // WindowSizeLimits is concurrent-safe.
func WindowSizeLimits() (minw, minh, maxw, maxh int) { func WindowSizeLimits() (minw, minh, maxw, maxh int) {
if w := uiDriver().Window(); w != nil { if w := ui.Get().Window(); w != nil {
return w.SizeLimits() return w.SizeLimits()
} }
return -1, -1, -1, -1 return -1, -1, -1, -1
@ -215,7 +217,7 @@ func WindowSizeLimits() (minw, minh, maxw, maxh int) {
// //
// SetWindowSizeLimits is concurrent-safe. // SetWindowSizeLimits is concurrent-safe.
func SetWindowSizeLimits(minw, minh, maxw, maxh int) { func SetWindowSizeLimits(minw, minh, maxw, maxh int) {
if w := uiDriver().Window(); w != nil { if w := ui.Get().Window(); w != nil {
w.SetSizeLimits(minw, minh, maxw, maxh) w.SetSizeLimits(minw, minh, maxw, maxh)
} }
} }
@ -226,7 +228,7 @@ func SetWindowSizeLimits(minw, minh, maxw, maxh int) {
// //
// IsWindowFloating is concurrent-safe. // IsWindowFloating is concurrent-safe.
func IsWindowFloating() bool { func IsWindowFloating() bool {
if w := uiDriver().Window(); w != nil { if w := ui.Get().Window(); w != nil {
return w.IsFloating() return w.IsFloating()
} }
return false return false
@ -241,7 +243,7 @@ func IsWindowFloating() bool {
// //
// SetWindowFloating is concurrent-safe. // SetWindowFloating is concurrent-safe.
func SetWindowFloating(float bool) { func SetWindowFloating(float bool) {
if w := uiDriver().Window(); w != nil { if w := ui.Get().Window(); w != nil {
w.SetFloating(float) w.SetFloating(float)
} }
} }
@ -257,7 +259,7 @@ func MaximizeWindow() {
if !IsWindowResizable() { if !IsWindowResizable() {
panic("ebiten: a window to maximize must be resizable") panic("ebiten: a window to maximize must be resizable")
} }
if w := uiDriver().Window(); w != nil { if w := ui.Get().Window(); w != nil {
w.Maximize() w.Maximize()
} }
} }
@ -273,7 +275,7 @@ func IsWindowMaximized() bool {
if !IsWindowResizable() { if !IsWindowResizable() {
return false return false
} }
if w := uiDriver().Window(); w != nil { if w := ui.Get().Window(); w != nil {
return w.IsMaximized() return w.IsMaximized()
} }
return false return false
@ -287,7 +289,7 @@ func IsWindowMaximized() bool {
// //
// MinimizeWindow is concurrent-safe. // MinimizeWindow is concurrent-safe.
func MinimizeWindow() { func MinimizeWindow() {
if w := uiDriver().Window(); w != nil { if w := ui.Get().Window(); w != nil {
w.Minimize() w.Minimize()
} }
} }
@ -298,7 +300,7 @@ func MinimizeWindow() {
// //
// IsWindowMinimized is concurrent-safe. // IsWindowMinimized is concurrent-safe.
func IsWindowMinimized() bool { func IsWindowMinimized() bool {
if w := uiDriver().Window(); w != nil { if w := ui.Get().Window(); w != nil {
return w.IsMinimized() return w.IsMinimized()
} }
return false return false
@ -313,7 +315,7 @@ func RestoreWindow() {
if !IsWindowMaximized() && !IsWindowMinimized() { if !IsWindowMaximized() && !IsWindowMinimized() {
panic("ebiten: RestoreWindow must be called on a maximized or a minimized window") panic("ebiten: RestoreWindow must be called on a maximized or a minimized window")
} }
if w := uiDriver().Window(); w != nil { if w := ui.Get().Window(); w != nil {
w.Restore() w.Restore()
} }
} }
@ -326,7 +328,7 @@ func RestoreWindow() {
// //
// IsWindowBeingClosed is concurrent-safe. // IsWindowBeingClosed is concurrent-safe.
func IsWindowBeingClosed() bool { func IsWindowBeingClosed() bool {
if w := uiDriver().Window(); w != nil { if w := ui.Get().Window(); w != nil {
return w.IsBeingClosed() return w.IsBeingClosed()
} }
return false return false
@ -344,7 +346,7 @@ func IsWindowBeingClosed() bool {
// //
// SetWindowClosingHandled is concurrent-safe. // SetWindowClosingHandled is concurrent-safe.
func SetWindowClosingHandled(handled bool) { func SetWindowClosingHandled(handled bool) {
if w := uiDriver().Window(); w != nil { if w := ui.Get().Window(); w != nil {
w.SetClosingHandled(handled) w.SetClosingHandled(handled)
} }
} }
@ -355,7 +357,7 @@ func SetWindowClosingHandled(handled bool) {
// //
// IsWindowClosingHandled is concurrent-safe. // IsWindowClosingHandled is concurrent-safe.
func IsWindowClosingHandled() bool { func IsWindowClosingHandled() bool {
if w := uiDriver().Window(); w != nil { if w := ui.Get().Window(); w != nil {
return w.IsClosingHandled() return w.IsClosingHandled()
} }
return false return false