mirror of
https://github.com/austinried/subtracks.git
synced 2026-11-11 07:29:14 +01:00
address third review: rebuild the window when the shuffle is dropped, atomic queue version
This commit is contained in:
@@ -10,6 +10,7 @@ import com.subtracks.data.model.QueueEntry
|
||||
import com.subtracks.data.model.QueueKind
|
||||
import com.subtracks.data.model.ShuffleOrder
|
||||
import com.subtracks.data.model.SongListItem
|
||||
import java.util.concurrent.atomic.AtomicLong
|
||||
|
||||
const val QUEUE_CHUNK = 60
|
||||
|
||||
@@ -62,8 +63,7 @@ class QueueRepository(
|
||||
@Volatile
|
||||
private var cachedShuffleOrder: LongArray? = null
|
||||
|
||||
@Volatile
|
||||
private var queueVersion = 0L
|
||||
private val queueVersion = AtomicLong()
|
||||
|
||||
@Volatile
|
||||
private var cachedFlatIds: List<String>? = null
|
||||
@@ -98,6 +98,7 @@ class QueueRepository(
|
||||
}
|
||||
|
||||
suspend fun snapshot(): QueueSnapshot {
|
||||
val version = queueVersion.get()
|
||||
val loaded =
|
||||
db.useReaderConnection { transactor ->
|
||||
transactor.deferredTransaction {
|
||||
@@ -110,7 +111,7 @@ class QueueRepository(
|
||||
}
|
||||
val (entries, order, shuffled) = loaded
|
||||
val valid = if (shuffled && order == null) null else order
|
||||
return QueueSnapshot(entries, valid, queueVersion)
|
||||
return QueueSnapshot(entries, valid, version)
|
||||
}
|
||||
|
||||
suspend fun modes(): QueueModes {
|
||||
@@ -138,7 +139,7 @@ class QueueRepository(
|
||||
|
||||
fun invalidateLibraryCache() {
|
||||
cachedFlatIds = null
|
||||
queueVersion++
|
||||
queueVersion.incrementAndGet()
|
||||
}
|
||||
|
||||
suspend fun setRepeat(mode: Int) = dao.setCursor(cursorRow().copy(repeatMode = mode))
|
||||
@@ -173,6 +174,15 @@ class QueueRepository(
|
||||
return rows(entry, entry.offset + offset, 1).firstOrNull()
|
||||
}
|
||||
|
||||
suspend fun flatIndexOf(
|
||||
snapshot: QueueSnapshot,
|
||||
songId: String,
|
||||
): Long? {
|
||||
if (!snapshot.shuffled) return null
|
||||
val index = flatIds(snapshot).indexOf(songId)
|
||||
return if (index >= 0) index.toLong() else null
|
||||
}
|
||||
|
||||
suspend fun range(
|
||||
snapshot: QueueSnapshot,
|
||||
first: Long,
|
||||
@@ -271,7 +281,7 @@ class QueueRepository(
|
||||
dao.insert(entries.mapIndexed { index, entry -> entry.copy(id = 0, position = index.toLong()) })
|
||||
}
|
||||
}
|
||||
queueVersion++
|
||||
queueVersion.incrementAndGet()
|
||||
cachedFlatIds = null
|
||||
}
|
||||
|
||||
|
||||
@@ -398,8 +398,10 @@ class PlaybackController(
|
||||
fun previous() {
|
||||
val player = player ?: return
|
||||
if (player.currentPositionMs > RESTART_THRESHOLD_MS) {
|
||||
player.seekTo(0)
|
||||
refresh()
|
||||
scope.launch {
|
||||
startLock.withLock { player.seekTo(0) }
|
||||
refresh()
|
||||
}
|
||||
return
|
||||
}
|
||||
val snapshot = snapshot ?: return
|
||||
@@ -657,9 +659,20 @@ class PlaybackController(
|
||||
|
||||
private suspend fun shiftWindowLocked(center: Long) {
|
||||
val player = player ?: return
|
||||
val previous = snapshot
|
||||
val snapshot = readSnapshot()
|
||||
this.snapshot = snapshot
|
||||
if (snapshot.size == 0L) return
|
||||
if (previous != null && previous.shuffled != snapshot.shuffled) {
|
||||
val currentId = player.currentItem?.id
|
||||
val position =
|
||||
(currentId?.let { queueRepository.flatIndexOf(snapshot, it) } ?: center)
|
||||
.coerceIn(0, snapshot.size - 1)
|
||||
queueRepository.setCursor(position)
|
||||
rebuildWindow(queueRepository.window(snapshot, position, QUEUE_WINDOW_RADIUS), position)
|
||||
refresh(position)
|
||||
return
|
||||
}
|
||||
val target = center.coerceIn(0, snapshot.size - 1)
|
||||
val desiredStart = (target - QUEUE_WINDOW_RADIUS).coerceAtLeast(0)
|
||||
val desiredEnd = (target + QUEUE_WINDOW_RADIUS).coerceAtMost(snapshot.size - 1)
|
||||
|
||||
Reference in New Issue
Block a user