mirror of
https://github.com/austinried/subtracks.git
synced 2026-11-10 15:11:58 +01:00
address fourth review: reset the saved position per track and serialize cursor writes
This commit is contained in:
@@ -10,6 +10,8 @@ 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 kotlinx.coroutines.sync.Mutex
|
||||
import kotlinx.coroutines.sync.withLock
|
||||
import java.util.concurrent.atomic.AtomicLong
|
||||
|
||||
const val QUEUE_CHUNK = 60
|
||||
@@ -71,6 +73,8 @@ class QueueRepository(
|
||||
@Volatile
|
||||
private var cachedFlatVersion = -1L
|
||||
|
||||
private val cursorMutex = Mutex()
|
||||
|
||||
fun playlistEntry(
|
||||
sourceId: Long,
|
||||
playlistId: String,
|
||||
@@ -94,7 +98,7 @@ class QueueRepository(
|
||||
) {
|
||||
write(entries)
|
||||
setShuffle(shuffleOrder != null, shuffleOrder)
|
||||
dao.setCursor(cursorRow().copy(queuePosition = 0))
|
||||
cursorMutex.withLock { dao.setCursor(cursorRow().copy(queuePosition = 0, positionMs = 0)) }
|
||||
}
|
||||
|
||||
suspend fun snapshot(): QueueSnapshot {
|
||||
@@ -124,13 +128,15 @@ class QueueRepository(
|
||||
order: LongArray?,
|
||||
) {
|
||||
val seed = if (enabled && order != null) System.nanoTime() else 0L
|
||||
db.useWriterConnection { transactor ->
|
||||
transactor.immediateTransaction {
|
||||
dao.clearShuffleOrder()
|
||||
if (enabled && order != null) {
|
||||
dao.insertShuffleOrder(order.mapIndexed { index, flat -> ShuffleOrder(index.toLong(), flat) })
|
||||
cursorMutex.withLock {
|
||||
db.useWriterConnection { transactor ->
|
||||
transactor.immediateTransaction {
|
||||
dao.clearShuffleOrder()
|
||||
if (enabled && order != null) {
|
||||
dao.insertShuffleOrder(order.mapIndexed { index, flat -> ShuffleOrder(index.toLong(), flat) })
|
||||
}
|
||||
dao.setCursor(cursorRow().copy(shuffleEnabled = enabled, shuffleSeed = seed))
|
||||
}
|
||||
dao.setCursor(cursorRow().copy(shuffleEnabled = enabled, shuffleSeed = seed))
|
||||
}
|
||||
}
|
||||
cachedShuffleSeed = 0
|
||||
@@ -142,7 +148,7 @@ class QueueRepository(
|
||||
queueVersion.incrementAndGet()
|
||||
}
|
||||
|
||||
suspend fun setRepeat(mode: Int) = dao.setCursor(cursorRow().copy(repeatMode = mode))
|
||||
suspend fun setRepeat(mode: Int) = cursorMutex.withLock { dao.setCursor(cursorRow().copy(repeatMode = mode)) }
|
||||
|
||||
private suspend fun loadShuffleOrder(
|
||||
seed: Long,
|
||||
@@ -272,9 +278,16 @@ class QueueRepository(
|
||||
|
||||
suspend fun cursorPositionMs(): Long = dao.cursor()?.positionMs ?: 0
|
||||
|
||||
suspend fun setPosition(positionMs: Long) = dao.setCursor(cursorRow().copy(positionMs = positionMs.coerceAtLeast(0)))
|
||||
suspend fun setPosition(positionMs: Long) =
|
||||
cursorMutex.withLock {
|
||||
dao.setCursor(cursorRow().copy(positionMs = positionMs.coerceAtLeast(0)))
|
||||
}
|
||||
|
||||
suspend fun setCursor(position: Long) = dao.setCursor(cursorRow().copy(queuePosition = position))
|
||||
suspend fun setCursor(position: Long) =
|
||||
cursorMutex.withLock {
|
||||
val row = cursorRow()
|
||||
dao.setCursor(row.copy(queuePosition = position, positionMs = if (row.queuePosition == position) row.positionMs else 0))
|
||||
}
|
||||
|
||||
private suspend fun cursorRow(): PlaybackCursor = dao.cursor() ?: PlaybackCursor(queuePosition = 0)
|
||||
|
||||
|
||||
@@ -234,6 +234,7 @@ class PlaybackController(
|
||||
val order = withContext(Dispatchers.Default) { shuffledOrder(snap.size, start) }
|
||||
queueRepository.setShuffle(true, order)
|
||||
shuffleEnabled = true
|
||||
queueSourceId = entry.sourceId
|
||||
queueRepository.setCursor(0)
|
||||
snap = queueRepository.snapshot()
|
||||
this@PlaybackController.snapshot = snap
|
||||
|
||||
@@ -116,7 +116,7 @@ class QueueViewModel(
|
||||
rows.addAll(queueRepository.range(snapshot, start, end).map(::newRow))
|
||||
first = rows.firstOrNull()?.position ?: 0
|
||||
last = rows.lastOrNull()?.position ?: -1
|
||||
initialIndex = (cursor - first).toInt().coerceAtLeast(0)
|
||||
initialIndex = rows.indexOfFirst { it.position == cursor }.coerceAtLeast(0)
|
||||
}
|
||||
ready = true
|
||||
generation++
|
||||
|
||||
@@ -932,6 +932,26 @@ class PlaybackControllerTest {
|
||||
restored.close()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun changingTrackResetsTheSavedPosition() {
|
||||
seedAlbum(3, sourceId = 1)
|
||||
controller.playAlbum(1, "al1", 0)
|
||||
await {
|
||||
controller.state.value.item
|
||||
?.id == "s1"
|
||||
}
|
||||
|
||||
runBlocking { queues.setPosition(60_000L) }
|
||||
|
||||
controller.next()
|
||||
await {
|
||||
controller.state.value.item
|
||||
?.id == "s2"
|
||||
}
|
||||
|
||||
assertEquals(0L, runBlocking { queues.cursorPositionMs() })
|
||||
}
|
||||
|
||||
private fun seedAlbum(
|
||||
count: Int,
|
||||
sourceId: Long,
|
||||
|
||||
Reference in New Issue
Block a user