From 5c4885c9887d374315cf689d6582462c04866983 Mon Sep 17 00:00:00 2001 From: Hajime Hoshi Date: Sat, 10 Jul 2021 23:28:32 +0900 Subject: [PATCH] inpututil: Add AppendJustConnectedTouchIDs Closes #1705 --- examples/audio/main.go | 36 ++++++++++++++++++++++-------------- examples/drag/main.go | 8 +++++--- examples/flappy/main.go | 4 +++- examples/touch/main.go | 3 ++- inpututil/inpututil.go | 30 ++++++++++++++++++------------ 5 files changed, 50 insertions(+), 31 deletions(-) diff --git a/examples/audio/main.go b/examples/audio/main.go index 02256a1ed..54a19c3c4 100644 --- a/examples/audio/main.go +++ b/examples/audio/main.go @@ -112,6 +112,7 @@ func (t musicType) String() string { // Player represents the current audio state. type Player struct { + game *Game audioContext *audio.Context audioPlayer *audio.Player current time.Duration @@ -129,7 +130,7 @@ func playerBarRect() (x, y, w, h int) { return } -func NewPlayer(audioContext *audio.Context, musicType musicType) (*Player, error) { +func NewPlayer(game *Game, audioContext *audio.Context, musicType musicType) (*Player, error) { type audioStream interface { io.ReadSeeker Length() int64 @@ -160,6 +161,7 @@ func NewPlayer(audioContext *audio.Context, musicType musicType) (*Player, error return nil, err } player := &Player{ + game: game, audioContext: audioContext, audioPlayer: p, total: time.Second * time.Duration(s.Length()) / bytesPerSample / sampleRate, @@ -232,7 +234,7 @@ func (p *Player) shouldPlaySE() bool { return true } } - for _, id := range inpututil.JustPressedTouchIDs() { + for _, id := range p.game.justPressedTouchIDs { if image.Pt(ebiten.TouchPosition(id)).In(r) { return true } @@ -277,7 +279,7 @@ func (p *Player) shouldSwitchPlayStateIfNeeded() bool { return true } } - for _, id := range inpututil.JustPressedTouchIDs() { + for _, id := range p.game.justPressedTouchIDs { if image.Pt(ebiten.TouchPosition(id)).In(r) { return true } @@ -296,14 +298,14 @@ func (p *Player) switchPlayStateIfNeeded() { p.audioPlayer.Play() } -func justPressedPosition() (int, int, bool) { +func (p *Player) justPressedPosition() (int, int, bool) { if inpututil.IsMouseButtonJustPressed(ebiten.MouseButtonLeft) { x, y := ebiten.CursorPosition() return x, y, true } - if ts := inpututil.JustPressedTouchIDs(); len(ts) > 0 { - x, y := ebiten.TouchPosition(ts[0]) + if len(p.game.justPressedTouchIDs) > 0 { + x, y := ebiten.TouchPosition(p.game.justPressedTouchIDs[0]) return x, y, true } @@ -312,7 +314,7 @@ func justPressedPosition() (int, int, bool) { func (p *Player) seekBarIfNeeded() { // Calculate the next seeking position from the current cursor position. - x, y, ok := justPressedPosition() + x, y, ok := p.justPressedPosition() if !ok { return } @@ -376,21 +378,25 @@ type Game struct { musicPlayer *Player musicPlayerCh chan *Player errCh chan error + + justPressedTouchIDs []ebiten.TouchID } func NewGame() (*Game, error) { audioContext := audio.NewContext(sampleRate) - m, err := NewPlayer(audioContext, typeOgg) + g := &Game{ + musicPlayerCh: make(chan *Player), + errCh: make(chan error), + } + + m, err := NewPlayer(g, audioContext, typeOgg) if err != nil { return nil, err } - return &Game{ - musicPlayer: m, - musicPlayerCh: make(chan *Player), - errCh: make(chan error), - }, nil + g.musicPlayer = m + return g, nil } func (g *Game) Update() error { @@ -402,6 +408,8 @@ func (g *Game) Update() error { default: } + g.justPressedTouchIDs = inpututil.AppendJustPressedTouchIDs(g.justPressedTouchIDs[:0]) + if g.musicPlayer != nil && inpututil.IsKeyJustPressed(ebiten.KeyA) { var t musicType switch g.musicPlayer.musicType { @@ -417,7 +425,7 @@ func (g *Game) Update() error { g.musicPlayer = nil go func() { - p, err := NewPlayer(audio.CurrentContext(), t) + p, err := NewPlayer(g, audio.CurrentContext(), t) if err != nil { g.errCh <- err return diff --git a/examples/drag/main.go b/examples/drag/main.go index 01f8ad358..39c31268b 100644 --- a/examples/drag/main.go +++ b/examples/drag/main.go @@ -184,8 +184,9 @@ func (s *Stroke) SetDraggingObject(object interface{}) { } type Game struct { - strokes map[*Stroke]struct{} - sprites []*Sprite + touchIDs []ebiten.TouchID + strokes map[*Stroke]struct{} + sprites []*Sprite } var ebitenImage *ebiten.Image @@ -273,7 +274,8 @@ func (g *Game) Update() error { s.SetDraggingObject(g.spriteAt(s.Position())) g.strokes[s] = struct{}{} } - for _, id := range inpututil.JustPressedTouchIDs() { + g.touchIDs = inpututil.AppendJustPressedTouchIDs(g.touchIDs[:0]) + for _, id := range g.touchIDs { s := NewStroke(&TouchStrokeSource{id}) s.SetDraggingObject(g.spriteAt(s.Position())) g.strokes[s] = struct{}{} diff --git a/examples/flappy/main.go b/examples/flappy/main.go index 3b2bc638b..568c8038b 100644 --- a/examples/flappy/main.go +++ b/examples/flappy/main.go @@ -178,6 +178,7 @@ type Game struct { gameoverCount int keys []ebiten.Key + touchIDs []ebiten.TouchID gamepadIDs []ebiten.GamepadID } @@ -215,7 +216,8 @@ func (g *Game) jump() bool { if inpututil.IsMouseButtonJustPressed(ebiten.MouseButtonLeft) { return true } - if len(inpututil.JustPressedTouchIDs()) > 0 { + g.touchIDs = inpututil.AppendJustPressedTouchIDs(g.touchIDs) + if len(g.touchIDs) > 0 { return true } g.gamepadIDs = ebiten.AppendGamepadIDs(g.gamepadIDs[:0]) diff --git a/examples/touch/main.go b/examples/touch/main.go index 85c7675b1..27d62f1f6 100644 --- a/examples/touch/main.go +++ b/examples/touch/main.go @@ -110,7 +110,8 @@ func (g *Game) Update() error { } // What touches are new in this frame? - for _, id := range inpututil.JustPressedTouchIDs() { + g.touchIDs = inpututil.AppendJustPressedTouchIDs(g.touchIDs[:0]) + for _, id := range g.touchIDs { x, y := ebiten.TouchPosition(id) g.touches[id] = &touch{ originX: x, originY: y, diff --git a/inpututil/inpututil.go b/inpututil/inpututil.go index f6f045498..e6f8607bd 100644 --- a/inpututil/inpututil.go +++ b/inpututil/inpututil.go @@ -253,8 +253,6 @@ func MouseButtonPressDuration(button ebiten.MouseButton) int { // and returns the extended buffer. // Giving a slice that already has enough capacity works efficiently. // -// AppendJustConnectedGamepadIDs might append nothing when there is no connected gamepad. -// // AppendJustConnectedGamepadIDs is concurrent safe. func AppendJustConnectedGamepadIDs(gamepadIDs []ebiten.GamepadID) []ebiten.GamepadID { origLen := len(gamepadIDs) @@ -330,24 +328,32 @@ func GamepadButtonPressDuration(id ebiten.GamepadID, button ebiten.GamepadButton return s } -// JustPressedTouchIDs returns touch IDs that are created just in the current frame. +// AppendJustPressedTouchIDs append touch IDs that are created just in the current frame to touchIDs, +// and returns the extended buffer. +// Giving a slice that already has enough capacity works efficiently. // -// JustPressedTouchIDs might return nil when there is not touch. -// -// JustPressedTouchIDs is concurrent safe. -func JustPressedTouchIDs() []ebiten.TouchID { - var ids []ebiten.TouchID +// AppendJustPressedTouchIDs is concurrent safe. +func AppendJustPressedTouchIDs(touchIDs []ebiten.TouchID) []ebiten.TouchID { + origLen := len(touchIDs) theInputState.m.RLock() for id, s := range theInputState.touchDurations { if s == 1 { - ids = append(ids, id) + touchIDs = append(touchIDs, id) } } theInputState.m.RUnlock() - sort.Slice(ids, func(a, b int) bool { - return ids[a] < ids[b] + s := touchIDs[origLen:] + sort.Slice(s, func(a, b int) bool { + return s[a] < s[b] }) - return ids + return touchIDs +} + +// JustPressedTouchIDs returns touch IDs that are created just in the current frame. +// +// Deprecated: as of v2.2. Use AppendJustPressedTouchIDs instead. +func JustPressedTouchIDs() []ebiten.TouchID { + return AppendJustPressedTouchIDs(nil) } // IsTouchJustReleased returns a boolean value indicating