beginning of reworking playback to use a command queue
This commit is contained in:
@@ -0,0 +1,102 @@
|
||||
package backend
|
||||
|
||||
import (
|
||||
"slices"
|
||||
"sync"
|
||||
)
|
||||
|
||||
type PlaybackCommandType int
|
||||
|
||||
const (
|
||||
CmdStop PlaybackCommandType = iota
|
||||
CmdContinue
|
||||
CmdPause
|
||||
CmdPlayTrackAt
|
||||
CmdSeekSeconds
|
||||
CmdSeekFwdBackN
|
||||
CmdVolume
|
||||
CmdLoopMode
|
||||
)
|
||||
|
||||
type PlaybackCommand struct {
|
||||
Type PlaybackCommandType
|
||||
Arg any
|
||||
}
|
||||
|
||||
type CommandQueue struct {
|
||||
mutex sync.Mutex
|
||||
queue []PlaybackCommand
|
||||
cmdAvailable *sync.Cond
|
||||
nextChan chan (PlaybackCommand)
|
||||
}
|
||||
|
||||
func NewCommandQueue() *CommandQueue {
|
||||
c := &CommandQueue{}
|
||||
c.cmdAvailable = sync.NewCond(&c.mutex)
|
||||
go c.chanWriter()
|
||||
return c
|
||||
}
|
||||
|
||||
func (c *CommandQueue) C() <-chan PlaybackCommand {
|
||||
return c.nextChan
|
||||
}
|
||||
|
||||
func (c *CommandQueue) Stop() {
|
||||
c.filterCommandsAndAdd([]PlaybackCommandType{CmdContinue, CmdPause, CmdStop},
|
||||
PlaybackCommand{Type: CmdStop})
|
||||
}
|
||||
|
||||
func (c *CommandQueue) Continue() {
|
||||
c.filterCommandsAndAdd([]PlaybackCommandType{CmdContinue, CmdPause, CmdStop},
|
||||
PlaybackCommand{Type: CmdContinue})
|
||||
}
|
||||
|
||||
func (c *CommandQueue) Pause() {
|
||||
c.filterCommandsAndAdd([]PlaybackCommandType{CmdContinue, CmdPause, CmdStop},
|
||||
PlaybackCommand{Type: CmdPause})
|
||||
}
|
||||
|
||||
func (c *CommandQueue) Volume(vol int) {
|
||||
c.filterCommandsAndAdd([]PlaybackCommandType{CmdVolume},
|
||||
PlaybackCommand{Type: CmdVolume, Arg: vol})
|
||||
}
|
||||
|
||||
func (c *CommandQueue) LoopMode(mode LoopMode) {
|
||||
c.filterCommandsAndAdd([]PlaybackCommandType{CmdLoopMode},
|
||||
PlaybackCommand{Type: CmdLoopMode, Arg: mode})
|
||||
}
|
||||
|
||||
func (c *CommandQueue) SeekSeconds(s float64) {
|
||||
c.filterCommandsAndAdd([]PlaybackCommandType{CmdVolume},
|
||||
PlaybackCommand{Type: CmdSeekSeconds, Arg: s})
|
||||
}
|
||||
|
||||
func (c *CommandQueue) filterCommandsAndAdd(excludeTypes []PlaybackCommandType, command PlaybackCommand) {
|
||||
c.mutex.Lock()
|
||||
defer c.mutex.Unlock()
|
||||
|
||||
j := 0
|
||||
for _, cmd := range c.queue {
|
||||
if slices.Contains(excludeTypes, cmd.Type) {
|
||||
continue
|
||||
}
|
||||
c.queue[j] = cmd
|
||||
j++
|
||||
}
|
||||
c.queue = c.queue[:j]
|
||||
c.queue = append(c.queue, command)
|
||||
}
|
||||
|
||||
func (c *CommandQueue) chanWriter() {
|
||||
for {
|
||||
c.mutex.Lock()
|
||||
for len(c.queue) == 0 {
|
||||
c.cmdAvailable.Wait()
|
||||
}
|
||||
cmd := c.queue[0]
|
||||
copy(c.queue, c.queue[1:])
|
||||
c.queue = c.queue[:len(c.queue)-1]
|
||||
c.mutex.Unlock()
|
||||
c.nextChan <- cmd
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user