split queue package into multiple files. other minor fixes
This commit is contained in:
@@ -0,0 +1,132 @@
|
||||
package queue
|
||||
|
||||
import "math/rand/v2"
|
||||
|
||||
// nextIndex returns the next track index respecting shuffle and repeat modes.
|
||||
// Returns -1 if there is no next track (queue exhausted).
|
||||
func (q *Queue) nextIndex() int {
|
||||
if len(q.tracks) == 0 {
|
||||
return -1
|
||||
}
|
||||
|
||||
if q.shuffleMode && len(q.shuffleOrder) > 0 {
|
||||
return q.nextShuffledIndex()
|
||||
}
|
||||
|
||||
next := q.currentIndex + 1
|
||||
if next >= len(q.tracks) {
|
||||
if q.repeatMode == RepeatAll {
|
||||
return 0
|
||||
}
|
||||
|
||||
return -1
|
||||
}
|
||||
|
||||
return next
|
||||
}
|
||||
|
||||
// previousIndex returns the previous track index respecting shuffle and repeat.
|
||||
// Returns -1 if there is no previous track.
|
||||
func (q *Queue) previousIndex() int {
|
||||
if len(q.tracks) == 0 {
|
||||
return -1
|
||||
}
|
||||
|
||||
if q.shuffleMode && len(q.shuffleOrder) > 0 {
|
||||
return q.previousShuffledIndex()
|
||||
}
|
||||
|
||||
prev := q.currentIndex - 1
|
||||
if prev < 0 {
|
||||
if q.repeatMode == RepeatAll {
|
||||
return len(q.tracks) - 1
|
||||
}
|
||||
|
||||
return -1
|
||||
}
|
||||
|
||||
return prev
|
||||
}
|
||||
|
||||
// nextShuffledIndex finds the next index in the shuffle order.
|
||||
func (q *Queue) nextShuffledIndex() int {
|
||||
shufflePos := q.currentShufflePosition()
|
||||
if shufflePos == -1 {
|
||||
// Current track not found in shuffle order — shouldn't happen.
|
||||
return -1
|
||||
}
|
||||
|
||||
nextShufflePos := shufflePos + 1
|
||||
if nextShufflePos >= len(q.shuffleOrder) {
|
||||
if q.repeatMode == RepeatAll {
|
||||
return q.shuffleOrder[0]
|
||||
}
|
||||
|
||||
return -1
|
||||
}
|
||||
|
||||
return q.shuffleOrder[nextShufflePos]
|
||||
}
|
||||
|
||||
// previousShuffledIndex finds the previous index in the shuffle order.
|
||||
func (q *Queue) previousShuffledIndex() int {
|
||||
shufflePos := q.currentShufflePosition()
|
||||
if shufflePos == -1 {
|
||||
return -1
|
||||
}
|
||||
|
||||
prevShufflePos := shufflePos - 1
|
||||
if prevShufflePos < 0 {
|
||||
if q.repeatMode == RepeatAll {
|
||||
return q.shuffleOrder[len(q.shuffleOrder)-1]
|
||||
}
|
||||
|
||||
return -1
|
||||
}
|
||||
|
||||
return q.shuffleOrder[prevShufflePos]
|
||||
}
|
||||
|
||||
// currentShufflePosition finds where the current track index is in the shuffle order.
|
||||
func (q *Queue) currentShufflePosition() int {
|
||||
for i, idx := range q.shuffleOrder {
|
||||
if idx == q.currentIndex {
|
||||
return i
|
||||
}
|
||||
}
|
||||
|
||||
return -1
|
||||
}
|
||||
|
||||
// generateShuffleOrder creates a Fisher-Yates shuffled index order,
|
||||
// placing the current track at position 0 so it doesn't replay immediately.
|
||||
func (q *Queue) generateShuffleOrder() {
|
||||
n := len(q.tracks)
|
||||
if n == 0 {
|
||||
q.shuffleOrder = nil
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
order := make([]int, n)
|
||||
for i := range order {
|
||||
order[i] = i
|
||||
}
|
||||
|
||||
// Fisher-Yates shuffle.
|
||||
for i := n - 1; i > 0; i-- {
|
||||
j := rand.IntN(i + 1)
|
||||
order[i], order[j] = order[j], order[i]
|
||||
}
|
||||
|
||||
// Move the current track to position 0 so it doesn't replay immediately.
|
||||
for i, idx := range order {
|
||||
if idx == q.currentIndex {
|
||||
order[0], order[i] = order[i], order[0]
|
||||
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
q.shuffleOrder = order
|
||||
}
|
||||
Reference in New Issue
Block a user