mirror of
https://github.com/hajimehoshi/ebiten.git
synced 2024-11-10 04:57:26 +01:00
uidriver/glfw: Reduce (*thread).Call at (*Input).update
This commit is contained in:
parent
495b2b722a
commit
1864c22ad6
@ -22,7 +22,9 @@ import (
|
||||
type UIContext interface {
|
||||
Update() error
|
||||
Layout(outsideWidth, outsideHeight float64)
|
||||
AdjustPosition(x, y float64) (float64, float64)
|
||||
|
||||
// AdjustPosition can be called from a different goroutine from Update's or Layout's.
|
||||
AdjustPosition(x, y float64, deviceScaleFactor float64) (float64, float64)
|
||||
}
|
||||
|
||||
// RegularTermination represents a regular termination.
|
||||
|
@ -308,81 +308,73 @@ func (i *Input) setWheel(xoff, yoff float64) {
|
||||
i.scrollY = yoff
|
||||
}
|
||||
|
||||
// update must be called from the main thread.
|
||||
func (i *Input) update(window *glfw.Window, context driver.UIContext) {
|
||||
var cx, cy float64
|
||||
_ = i.ui.t.Call(func() error {
|
||||
i.onceCallback.Do(func() {
|
||||
window.SetCharModsCallback(func(w *glfw.Window, char rune, mods glfw.ModifierKey) {
|
||||
i.appendRuneBuffer(char)
|
||||
})
|
||||
window.SetScrollCallback(func(w *glfw.Window, xoff float64, yoff float64) {
|
||||
i.setWheel(xoff, yoff)
|
||||
})
|
||||
i.onceCallback.Do(func() {
|
||||
window.SetCharModsCallback(func(w *glfw.Window, char rune, mods glfw.ModifierKey) {
|
||||
i.appendRuneBuffer(char)
|
||||
})
|
||||
window.SetScrollCallback(func(w *glfw.Window, xoff float64, yoff float64) {
|
||||
i.setWheel(xoff, yoff)
|
||||
})
|
||||
if i.keyPressed == nil {
|
||||
i.keyPressed = map[glfw.Key]bool{}
|
||||
}
|
||||
for gk := range glfwKeyToDriverKey {
|
||||
i.keyPressed[gk] = window.GetKey(gk) == glfw.Press
|
||||
}
|
||||
if i.mouseButtonPressed == nil {
|
||||
i.mouseButtonPressed = map[glfw.MouseButton]bool{}
|
||||
}
|
||||
for gb := range glfwMouseButtonToMouseButton {
|
||||
i.mouseButtonPressed[gb] = window.GetMouseButton(gb) == glfw.Press
|
||||
}
|
||||
cx, cy = window.GetCursorPos()
|
||||
// TODO: This is tricky. Rename the function?
|
||||
cx = i.ui.fromGLFWMonitorPixel(cx)
|
||||
cy = i.ui.fromGLFWMonitorPixel(cy)
|
||||
return nil
|
||||
})
|
||||
if i.keyPressed == nil {
|
||||
i.keyPressed = map[glfw.Key]bool{}
|
||||
}
|
||||
for gk := range glfwKeyToDriverKey {
|
||||
i.keyPressed[gk] = window.GetKey(gk) == glfw.Press
|
||||
}
|
||||
if i.mouseButtonPressed == nil {
|
||||
i.mouseButtonPressed = map[glfw.MouseButton]bool{}
|
||||
}
|
||||
for gb := range glfwMouseButtonToMouseButton {
|
||||
i.mouseButtonPressed[gb] = window.GetMouseButton(gb) == glfw.Press
|
||||
}
|
||||
cx, cy := window.GetCursorPos()
|
||||
// TODO: This is tricky. Rename the function?
|
||||
cx = i.ui.fromGLFWMonitorPixel(cx)
|
||||
cy = i.ui.fromGLFWMonitorPixel(cy)
|
||||
cx, cy = context.AdjustPosition(cx, cy, i.ui.deviceScaleFactor())
|
||||
i.cursorX, i.cursorY = int(cx), int(cy)
|
||||
|
||||
cx, cy = context.AdjustPosition(cx, cy)
|
||||
for id := glfw.Joystick(0); id < glfw.Joystick(len(i.gamepads)); id++ {
|
||||
i.gamepads[id].valid = false
|
||||
if !id.Present() {
|
||||
continue
|
||||
}
|
||||
|
||||
_ = i.ui.t.Call(func() error {
|
||||
i.cursorX, i.cursorY = int(cx), int(cy)
|
||||
buttons := id.GetButtons()
|
||||
|
||||
for id := glfw.Joystick(0); id < glfw.Joystick(len(i.gamepads)); id++ {
|
||||
i.gamepads[id].valid = false
|
||||
if !id.Present() {
|
||||
// A gamepad can be detected even though there are not. Apparently, some special devices are
|
||||
// recognized as gamepads by GLFW. In this case, the number of the 'buttons' can exceeds the
|
||||
// maximum. Skip such devices as a tentative solution (#1173).
|
||||
if len(buttons) > driver.GamepadButtonNum {
|
||||
continue
|
||||
}
|
||||
|
||||
i.gamepads[id].valid = true
|
||||
|
||||
i.gamepads[id].buttonNum = len(buttons)
|
||||
for b := 0; b < len(i.gamepads[id].buttonPressed); b++ {
|
||||
if len(buttons) <= b {
|
||||
i.gamepads[id].buttonPressed[b] = false
|
||||
continue
|
||||
}
|
||||
i.gamepads[id].buttonPressed[b] = glfw.Action(buttons[b]) == glfw.Press
|
||||
}
|
||||
|
||||
buttons := id.GetButtons()
|
||||
|
||||
// A gamepad can be detected even though there are not. Apparently, some special devices are
|
||||
// recognized as gamepads by GLFW. In this case, the number of the 'buttons' can exceeds the
|
||||
// maximum. Skip such devices as a tentative solution (#1173).
|
||||
if len(buttons) > driver.GamepadButtonNum {
|
||||
axes32 := id.GetAxes()
|
||||
i.gamepads[id].axisNum = len(axes32)
|
||||
for a := 0; a < len(i.gamepads[id].axes); a++ {
|
||||
if len(axes32) <= a {
|
||||
i.gamepads[id].axes[a] = 0
|
||||
continue
|
||||
}
|
||||
|
||||
i.gamepads[id].valid = true
|
||||
|
||||
i.gamepads[id].buttonNum = len(buttons)
|
||||
for b := 0; b < len(i.gamepads[id].buttonPressed); b++ {
|
||||
if len(buttons) <= b {
|
||||
i.gamepads[id].buttonPressed[b] = false
|
||||
continue
|
||||
}
|
||||
i.gamepads[id].buttonPressed[b] = glfw.Action(buttons[b]) == glfw.Press
|
||||
}
|
||||
|
||||
axes32 := id.GetAxes()
|
||||
i.gamepads[id].axisNum = len(axes32)
|
||||
for a := 0; a < len(i.gamepads[id].axes); a++ {
|
||||
if len(axes32) <= a {
|
||||
i.gamepads[id].axes[a] = 0
|
||||
continue
|
||||
}
|
||||
i.gamepads[id].axes[a] = float64(axes32[a])
|
||||
}
|
||||
|
||||
// Note that GLFW's gamepad GUID follows SDL's GUID.
|
||||
i.gamepads[id].guid = id.GetGUID()
|
||||
i.gamepads[id].name = id.GetName()
|
||||
i.gamepads[id].axes[a] = float64(axes32[a])
|
||||
}
|
||||
return nil
|
||||
})
|
||||
|
||||
// Note that GLFW's gamepad GUID follows SDL's GUID.
|
||||
i.gamepads[id].guid = id.GetGUID()
|
||||
i.gamepads[id].name = id.GetName()
|
||||
}
|
||||
}
|
||||
|
@ -834,12 +834,9 @@ func (u *UserInterface) update() error {
|
||||
|
||||
_ = u.t.Call(func() error {
|
||||
glfw.PollEvents()
|
||||
return nil
|
||||
})
|
||||
u.input.update(u.window, u.context)
|
||||
_ = u.t.Call(func() error {
|
||||
defer hooks.ResumeAudio()
|
||||
u.input.update(u.window, u.context)
|
||||
|
||||
defer hooks.ResumeAudio()
|
||||
for !u.isRunnableOnUnfocused() && u.window.GetAttrib(glfw.Focused) == 0 && !u.window.ShouldClose() {
|
||||
hooks.SuspendAudio()
|
||||
// Wait for an arbitrary period to avoid busy loop.
|
||||
|
@ -52,7 +52,7 @@ type Input struct {
|
||||
}
|
||||
|
||||
func (i *Input) CursorPosition() (x, y int) {
|
||||
xf, yf := i.ui.context.AdjustPosition(float64(i.cursorX), float64(i.cursorY))
|
||||
xf, yf := i.ui.context.AdjustPosition(float64(i.cursorX), float64(i.cursorY), i.ui.DeviceScaleFactor())
|
||||
return int(xf), int(yf)
|
||||
}
|
||||
|
||||
@ -131,9 +131,10 @@ func (i *Input) TouchIDs() []driver.TouchID {
|
||||
}
|
||||
|
||||
func (i *Input) TouchPosition(id driver.TouchID) (x, y int) {
|
||||
d := i.ui.DeviceScaleFactor()
|
||||
for tid, pos := range i.touches {
|
||||
if id == tid {
|
||||
x, y := i.ui.context.AdjustPosition(float64(pos.X), float64(pos.Y))
|
||||
x, y := i.ui.context.AdjustPosition(float64(pos.X), float64(pos.Y), d)
|
||||
return int(x), int(y)
|
||||
}
|
||||
}
|
||||
|
@ -402,7 +402,7 @@ func (u *UserInterface) setGBuildSize(widthPx, heightPx int) {
|
||||
}
|
||||
|
||||
func (u *UserInterface) adjustPosition(x, y int) (int, int) {
|
||||
xf, yf := u.context.AdjustPosition(float64(x), float64(y))
|
||||
xf, yf := u.context.AdjustPosition(float64(x), float64(y), deviceScale())
|
||||
return int(xf), int(yf)
|
||||
}
|
||||
|
||||
|
29
uicontext.go
29
uicontext.go
@ -112,27 +112,27 @@ func (c *uiContext) setWindowResizable(resizable bool) {
|
||||
}
|
||||
}
|
||||
|
||||
func (c *uiContext) screenScale() float64 {
|
||||
func (c *uiContext) screenScale(deviceScaleFactor float64) float64 {
|
||||
if c.offscreen == nil {
|
||||
return 0
|
||||
}
|
||||
sw, sh := c.offscreen.Size()
|
||||
d := uiDriver().DeviceScaleFactor()
|
||||
scaleX := c.outsideWidth / float64(sw) * d
|
||||
scaleY := c.outsideHeight / float64(sh) * d
|
||||
scaleX := c.outsideWidth / float64(sw) * deviceScaleFactor
|
||||
scaleY := c.outsideHeight / float64(sh) * deviceScaleFactor
|
||||
return math.Min(scaleX, scaleY)
|
||||
}
|
||||
|
||||
func (c *uiContext) offsets() (float64, float64) {
|
||||
func (c *uiContext) offsets(deviceScaleFactor float64) (float64, float64) {
|
||||
if c.offscreen == nil {
|
||||
return 0, 0
|
||||
}
|
||||
sw, sh := c.offscreen.Size()
|
||||
d := uiDriver().DeviceScaleFactor()
|
||||
s := c.screenScale()
|
||||
s := c.screenScale(deviceScaleFactor)
|
||||
width := float64(sw) * s
|
||||
height := float64(sh) * s
|
||||
return (c.outsideWidth*d - width) / 2, (c.outsideHeight*d - height) / 2
|
||||
x := (c.outsideWidth*deviceScaleFactor - width) / 2
|
||||
y := (c.outsideHeight*deviceScaleFactor - height) / 2
|
||||
return x, y
|
||||
}
|
||||
|
||||
func (c *uiContext) Update() error {
|
||||
@ -185,7 +185,7 @@ func (c *uiContext) update() error {
|
||||
|
||||
op := &DrawImageOptions{}
|
||||
|
||||
s := c.screenScale()
|
||||
s := c.screenScale(uiDriver().DeviceScaleFactor())
|
||||
switch vd := uiDriver().Graphics().FramebufferYDirection(); vd {
|
||||
case driver.Upward:
|
||||
op.GeoM.Scale(s, -s)
|
||||
@ -197,7 +197,7 @@ func (c *uiContext) update() error {
|
||||
panic(fmt.Sprintf("ebiten: invalid v-direction: %d", vd))
|
||||
}
|
||||
|
||||
op.GeoM.Translate(c.offsets())
|
||||
op.GeoM.Translate(c.offsets(uiDriver().DeviceScaleFactor()))
|
||||
op.CompositeMode = CompositeModeCopy
|
||||
|
||||
// filterScreen works with >=1 scale, but does not well with <1 scale.
|
||||
@ -211,9 +211,8 @@ func (c *uiContext) update() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *uiContext) AdjustPosition(x, y float64) (float64, float64) {
|
||||
d := uiDriver().DeviceScaleFactor()
|
||||
ox, oy := c.offsets()
|
||||
s := c.screenScale()
|
||||
return (x*d - ox) / s, (y*d - oy) / s
|
||||
func (c *uiContext) AdjustPosition(x, y float64, deviceScaleFactor float64) (float64, float64) {
|
||||
ox, oy := c.offsets(deviceScaleFactor)
|
||||
s := c.screenScale(deviceScaleFactor)
|
||||
return (x*deviceScaleFactor - ox) / s, (y*deviceScaleFactor - oy) / s
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user