fix coalescing logic of multiple seekFwdBackN commands
This commit is contained in:
+43
-12
@@ -35,6 +35,10 @@ type playbackCommand struct {
|
|||||||
Arg3 any
|
Arg3 any
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// playbackCommandQueue is a queue to accumulate player commands from the UI
|
||||||
|
// commands are processed by the playback engine as fast as they can, but if
|
||||||
|
// more commands arrive before the player can respond to them, they will queue up
|
||||||
|
// and some commands may coalesce together (e.g. multiple volume commands into just one)
|
||||||
type playbackCommandQueue struct {
|
type playbackCommandQueue struct {
|
||||||
mutex sync.Mutex
|
mutex sync.Mutex
|
||||||
queue []playbackCommand
|
queue []playbackCommand
|
||||||
@@ -157,21 +161,48 @@ func (c *playbackCommandQueue) filterCommandsAndAdd(excludeTypes []playbackComma
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *playbackCommandQueue) seekBackOrFwd(direction int) {
|
func (c *playbackCommandQueue) seekBackOrFwd(direction int) {
|
||||||
|
// find the index of the last seekBackOrFwd command
|
||||||
|
// in the queue that can be coalesced with this one
|
||||||
|
lastIdx := -1
|
||||||
c.mutex.Lock()
|
c.mutex.Lock()
|
||||||
j := 0
|
done := false
|
||||||
n := 0
|
for i := len(c.queue) - 1; i >= 0 && !done; i-- {
|
||||||
for _, cmd := range c.queue {
|
cmd := c.queue[i]
|
||||||
if cmd.Type == cmdSeekFwdBackN {
|
switch cmd.Type {
|
||||||
n += cmd.Arg.(int)
|
case cmdSeekFwdBackN:
|
||||||
} else {
|
lastIdx = i
|
||||||
c.queue[j] = cmd
|
case cmdRemoveTracksFromQueue, cmdLoadItems, cmdPlayTrackAt,
|
||||||
j++
|
cmdLoadRadioStation, cmdUpdatePlayQueue, cmdStopAndClearPlayQueue:
|
||||||
|
// any queue-modifying command means we can't coalesce any
|
||||||
|
// more seekFwdBackN commands before here
|
||||||
|
done = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
c.queue = c.queue[:j]
|
|
||||||
c.queue = append(c.queue, playbackCommand{
|
if lastIdx == -1 {
|
||||||
Type: cmdSeekFwdBackN,
|
// no coalescable seekFwdBackN commands, just append new one
|
||||||
Arg: n + direction})
|
c.queue = append(c.queue, playbackCommand{Type: cmdSeekFwdBackN, Arg: direction})
|
||||||
|
} else {
|
||||||
|
newQueue := make([]playbackCommand, 0, len(c.queue))
|
||||||
|
// copy over all cmds past the first coalescable idx
|
||||||
|
newQueue = append(newQueue, c.queue[0:lastIdx]...)
|
||||||
|
n := direction
|
||||||
|
for i := lastIdx; i < len(c.queue); i++ {
|
||||||
|
if cmd := c.queue[i]; cmd.Type == cmdSeekFwdBackN {
|
||||||
|
// coalesce this cmd with the new one
|
||||||
|
n += cmd.Arg.(int)
|
||||||
|
} else {
|
||||||
|
// copy over other non-seekFwdBackN command
|
||||||
|
newQueue = append(newQueue, cmd)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
newQueue = append(newQueue, playbackCommand{
|
||||||
|
Type: cmdSeekFwdBackN,
|
||||||
|
Arg: n,
|
||||||
|
})
|
||||||
|
c.queue = newQueue
|
||||||
|
}
|
||||||
|
|
||||||
c.mutex.Unlock()
|
c.mutex.Unlock()
|
||||||
c.cmdAvailable.Signal()
|
c.cmdAvailable.Signal()
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user