internal/gamepad: simplify the implementation by making the APIs concurrent-unsafe

This commit is contained in:
Hajime Hoshi 2022-01-29 02:07:11 +09:00
parent 5edfd1b743
commit 71e17efd80
3 changed files with 31 additions and 43 deletions

View File

@ -39,7 +39,6 @@ const (
type gamepads struct { type gamepads struct {
gamepads []*Gamepad gamepads []*Gamepad
m sync.Mutex
nativeGamepads nativeGamepads
} }
@ -51,14 +50,17 @@ func init() {
theGamepads.nativeGamepads.gamepads = &theGamepads theGamepads.nativeGamepads.gamepads = &theGamepads
} }
// AppendGamepadIDs must be called on the main thread.
func AppendGamepadIDs(ids []driver.GamepadID) []driver.GamepadID { func AppendGamepadIDs(ids []driver.GamepadID) []driver.GamepadID {
return theGamepads.appendGamepadIDs(ids) return theGamepads.appendGamepadIDs(ids)
} }
// Update must be called on the main thread.
func Update() { func Update() {
theGamepads.update() theGamepads.update()
} }
// Get must be called on the main thread.
func Get(id driver.GamepadID) *Gamepad { func Get(id driver.GamepadID) *Gamepad {
return theGamepads.get(id) return theGamepads.get(id)
} }
@ -73,9 +75,6 @@ func (g *gamepads) appendGamepadIDs(ids []driver.GamepadID) []driver.GamepadID {
} }
func (g *gamepads) update() { func (g *gamepads) update() {
g.m.Lock()
defer g.m.Unlock()
g.nativeGamepads.update() g.nativeGamepads.update()
for _, gp := range g.gamepads { for _, gp := range g.gamepads {
if gp != nil { if gp != nil {
@ -85,12 +84,6 @@ func (g *gamepads) update() {
} }
func (g *gamepads) get(id driver.GamepadID) *Gamepad { func (g *gamepads) get(id driver.GamepadID) *Gamepad {
g.m.Lock()
defer g.m.Unlock()
return g.getImpl(id)
}
func (g *gamepads) getImpl(id driver.GamepadID) *Gamepad {
if id < 0 || int(id) >= len(g.gamepads) { if id < 0 || int(id) >= len(g.gamepads) {
return nil return nil
} }
@ -98,12 +91,6 @@ func (g *gamepads) getImpl(id driver.GamepadID) *Gamepad {
} }
func (g *gamepads) find(cond func(*Gamepad) bool) *Gamepad { func (g *gamepads) find(cond func(*Gamepad) bool) *Gamepad {
g.m.Lock()
defer g.m.Unlock()
return g.findImpl(cond)
}
func (g *gamepads) findImpl(cond func(*Gamepad) bool) *Gamepad {
for _, gp := range g.gamepads { for _, gp := range g.gamepads {
if gp == nil { if gp == nil {
continue continue
@ -116,12 +103,6 @@ func (g *gamepads) findImpl(cond func(*Gamepad) bool) *Gamepad {
} }
func (g *gamepads) add(name, sdlID string) *Gamepad { func (g *gamepads) add(name, sdlID string) *Gamepad {
g.m.Lock()
defer g.m.Unlock()
return g.addImpl(name, sdlID)
}
func (g *gamepads) addImpl(name, sdlID string) *Gamepad {
for i, gp := range g.gamepads { for i, gp := range g.gamepads {
if gp == nil { if gp == nil {
gp := &Gamepad{ gp := &Gamepad{
@ -142,12 +123,6 @@ func (g *gamepads) addImpl(name, sdlID string) *Gamepad {
} }
func (g *gamepads) remove(cond func(*Gamepad) bool) { func (g *gamepads) remove(cond func(*Gamepad) bool) {
g.m.Lock()
defer g.m.Unlock()
g.removeImpl(cond)
}
func (g *gamepads) removeImpl(cond func(*Gamepad) bool) {
for i, gp := range g.gamepads { for i, gp := range g.gamepads {
if gp == nil { if gp == nil {
continue continue

View File

@ -67,7 +67,7 @@ func (g *nativeGamepads) update() {
g.indices[index] = struct{}{} g.indices[index] = struct{}{}
// The gamepad is not registered yet, register this. // The gamepad is not registered yet, register this.
gamepad := g.gamepads.findImpl(func(gamepad *Gamepad) bool { gamepad := g.gamepads.find(func(gamepad *Gamepad) bool {
return index == gamepad.index return index == gamepad.index
}) })
if gamepad == nil { if gamepad == nil {
@ -78,7 +78,7 @@ func (g *nativeGamepads) update() {
var sdlID [16]byte var sdlID [16]byte
copy(sdlID[:], []byte(name)) copy(sdlID[:], []byte(name))
gamepad = g.gamepads.addImpl(name, hex.EncodeToString(sdlID[:])) gamepad = g.gamepads.add(name, hex.EncodeToString(sdlID[:]))
gamepad.index = index gamepad.index = index
gamepad.mapping = gp.Get("mapping").String() gamepad.mapping = gp.Get("mapping").String()
} }
@ -86,7 +86,7 @@ func (g *nativeGamepads) update() {
} }
// Remove an unused gamepads. // Remove an unused gamepads.
g.gamepads.removeImpl(func(gamepad *Gamepad) bool { g.gamepads.remove(func(gamepad *Gamepad) bool {
_, ok := g.indices[gamepad.index] _, ok := g.indices[gamepad.index]
return !ok return !ok
}) })

View File

@ -26,16 +26,29 @@ import (
type nativeGamepads struct{} type nativeGamepads struct{}
// updateGamepads must be called on the main thread.
func (i *Input) updateGamepads() { func (i *Input) updateGamepads() {
gamepadpkg.Update() gamepadpkg.Update()
} }
func (i *Input) AppendGamepadIDs(gamepadIDs []driver.GamepadID) []driver.GamepadID { func (i *Input) AppendGamepadIDs(gamepadIDs []driver.GamepadID) []driver.GamepadID {
return gamepadpkg.AppendGamepadIDs(gamepadIDs) var gs []driver.GamepadID
i.ui.t.Call(func() {
gs = gamepadpkg.AppendGamepadIDs(gamepadIDs)
})
return gs
}
func (i *Input) gamepad(id driver.GamepadID) *gamepadpkg.Gamepad {
var g *gamepadpkg.Gamepad
i.ui.t.Call(func() {
g = gamepadpkg.Get(id)
})
return g
} }
func (i *Input) GamepadSDLID(id driver.GamepadID) string { func (i *Input) GamepadSDLID(id driver.GamepadID) string {
g := gamepadpkg.Get(id) g := i.gamepad(id)
if g == nil { if g == nil {
return "" return ""
} }
@ -43,7 +56,7 @@ func (i *Input) GamepadSDLID(id driver.GamepadID) string {
} }
func (i *Input) GamepadName(id driver.GamepadID) string { func (i *Input) GamepadName(id driver.GamepadID) string {
g := gamepadpkg.Get(id) g := i.gamepad(id)
if g == nil { if g == nil {
return "" return ""
} }
@ -51,7 +64,7 @@ func (i *Input) GamepadName(id driver.GamepadID) string {
} }
func (i *Input) GamepadAxisNum(id driver.GamepadID) int { func (i *Input) GamepadAxisNum(id driver.GamepadID) int {
g := gamepadpkg.Get(id) g := i.gamepad(id)
if g == nil { if g == nil {
return 0 return 0
} }
@ -59,7 +72,7 @@ func (i *Input) GamepadAxisNum(id driver.GamepadID) int {
} }
func (i *Input) GamepadAxisValue(id driver.GamepadID, axis int) float64 { func (i *Input) GamepadAxisValue(id driver.GamepadID, axis int) float64 {
g := gamepadpkg.Get(id) g := i.gamepad(id)
if g == nil { if g == nil {
return 0 return 0
} }
@ -67,7 +80,7 @@ func (i *Input) GamepadAxisValue(id driver.GamepadID, axis int) float64 {
} }
func (i *Input) GamepadButtonNum(id driver.GamepadID) int { func (i *Input) GamepadButtonNum(id driver.GamepadID) int {
g := gamepadpkg.Get(id) g := i.gamepad(id)
if g == nil { if g == nil {
return 0 return 0
} }
@ -77,7 +90,7 @@ func (i *Input) GamepadButtonNum(id driver.GamepadID) int {
} }
func (i *Input) IsGamepadButtonPressed(id driver.GamepadID, button driver.GamepadButton) bool { func (i *Input) IsGamepadButtonPressed(id driver.GamepadID, button driver.GamepadButton) bool {
g := gamepadpkg.Get(id) g := i.gamepad(id)
if g == nil { if g == nil {
return false return false
} }
@ -97,7 +110,7 @@ func (i *Input) IsGamepadButtonPressed(id driver.GamepadID, button driver.Gamepa
} }
func (i *Input) IsStandardGamepadLayoutAvailable(id driver.GamepadID) bool { func (i *Input) IsStandardGamepadLayoutAvailable(id driver.GamepadID) bool {
g := gamepadpkg.Get(id) g := i.gamepad(id)
if g == nil { if g == nil {
return false return false
} }
@ -105,7 +118,7 @@ func (i *Input) IsStandardGamepadLayoutAvailable(id driver.GamepadID) bool {
} }
func (i *Input) StandardGamepadAxisValue(id driver.GamepadID, axis driver.StandardGamepadAxis) float64 { func (i *Input) StandardGamepadAxisValue(id driver.GamepadID, axis driver.StandardGamepadAxis) float64 {
g := gamepadpkg.Get(id) g := i.gamepad(id)
if g == nil { if g == nil {
return 0 return 0
} }
@ -113,7 +126,7 @@ func (i *Input) StandardGamepadAxisValue(id driver.GamepadID, axis driver.Standa
} }
func (i *Input) StandardGamepadButtonValue(id driver.GamepadID, button driver.StandardGamepadButton) float64 { func (i *Input) StandardGamepadButtonValue(id driver.GamepadID, button driver.StandardGamepadButton) float64 {
g := gamepadpkg.Get(id) g := i.gamepad(id)
if g == nil { if g == nil {
return 0 return 0
} }
@ -121,7 +134,7 @@ func (i *Input) StandardGamepadButtonValue(id driver.GamepadID, button driver.St
} }
func (i *Input) IsStandardGamepadButtonPressed(id driver.GamepadID, button driver.StandardGamepadButton) bool { func (i *Input) IsStandardGamepadButtonPressed(id driver.GamepadID, button driver.StandardGamepadButton) bool {
g := gamepadpkg.Get(id) g := i.gamepad(id)
if g == nil { if g == nil {
return false return false
} }
@ -129,7 +142,7 @@ func (i *Input) IsStandardGamepadButtonPressed(id driver.GamepadID, button drive
} }
func (i *Input) VibrateGamepad(id driver.GamepadID, duration time.Duration, strongMagnitude float64, weakMagnitude float64) { func (i *Input) VibrateGamepad(id driver.GamepadID, duration time.Duration, strongMagnitude float64, weakMagnitude float64) {
g := gamepadpkg.Get(id) g := i.gamepad(id)
if g == nil { if g == nil {
return return
} }