musikr: fix equality issues

This commit is contained in:
Alexander Capehart 2025-01-06 11:23:04 -07:00
parent 1fb6097b9d
commit bbc4db156e
No known key found for this signature in database
GPG key ID: 37DBE3621FE9AD47
7 changed files with 38 additions and 26 deletions

View file

@ -82,7 +82,8 @@ private constructor(
} }
} }
class SiloedCover(silo: CoverSilo, val innerCover: FileCover) : FileCover by innerCover { data class SiloedCover(private val silo: CoverSilo, val innerCover: FileCover) :
FileCover by innerCover {
private val innerId = SiloedCoverId(silo, innerCover.id) private val innerId = SiloedCoverId(silo, innerCover.id)
override val id = innerId.toString() override val id = innerId.toString()
} }

View file

@ -396,12 +396,33 @@ constructor(
// Music loading completed, update the revision right now so we re-use this work // Music loading completed, update the revision right now so we re-use this work
// later. // later.
musicSettings.revision = newRevision musicSettings.revision = newRevision
// Deliver the library to the rest of the app
// This will more or less block until all required item translation and
// cleanup finishes.
emitLibrary(newLibrary)
// Old cover revisions may be lying around, even during a normal refresh due
// to really lucky cancellations. Now that it is impossible for the rest of
// the app to possible be using them, clean them up.
covers.cleanup(newLibrary.songs.mapNotNull { it.cover })
// Finish up loading.
emitIndexingCompletion(null)
}
// We want to make sure that all reads and writes are synchronized due to the sheer private suspend fun emitIndexingProgress(progress: IndexingProgress) {
// amount of consumers of MusicRepository. yield()
// TODO: Would Atomics not be a better fit here? synchronized(this) {
currentIndexingState = IndexingState.Indexing(progress)
for (listener in indexingListeners) {
listener.onIndexingStateChanged()
}
}
}
private suspend fun emitLibrary(newLibrary: MutableLibrary) {
val deviceLibraryChanged: Boolean val deviceLibraryChanged: Boolean
val userLibraryChanged: Boolean val userLibraryChanged: Boolean
// We want to make sure that all reads and writes are synchronized due to the sheer
// amount of consumers of MusicRepository.
synchronized(this) { synchronized(this) {
// It's possible that this reload might have changed nothing, so make sure that // It's possible that this reload might have changed nothing, so make sure that
// hasn't happened before dispatching a change to all consumers. // hasn't happened before dispatching a change to all consumers.
@ -428,23 +449,6 @@ constructor(
withContext(Dispatchers.Main) { withContext(Dispatchers.Main) {
dispatchLibraryChange(deviceLibraryChanged, userLibraryChanged) dispatchLibraryChange(deviceLibraryChanged, userLibraryChanged)
} }
// Old cover revisions may be lying around, even during a normal refresh due
// to really lucky cancellations. Clean those up now that it's impossible for
// the rest of the app to be using them.
covers.cleanup(newLibrary.songs.mapNotNull { it.cover })
emitIndexingCompletion(null)
}
private suspend fun emitIndexingProgress(progress: IndexingProgress) {
yield()
synchronized(this) {
currentIndexingState = IndexingState.Indexing(progress)
for (listener in indexingListeners) {
listener.onIndexingStateChanged()
}
}
} }
private suspend fun emitIndexingCompletion(error: Exception?) { private suspend fun emitIndexingCompletion(error: Exception?) {

View file

@ -43,6 +43,10 @@ interface Cover {
} }
class CoverCollection private constructor(val covers: List<Cover>) { class CoverCollection private constructor(val covers: List<Cover>) {
override fun hashCode() = covers.hashCode()
override fun equals(other: Any?) = other is CoverCollection && covers == other.covers
companion object { companion object {
fun from(covers: Collection<Cover>) = fun from(covers: Collection<Cover>) =
CoverCollection( CoverCollection(

View file

@ -57,7 +57,8 @@ interface FileCover : Cover {
suspend fun fd(): ParcelFileDescriptor? suspend fun fd(): ParcelFileDescriptor?
} }
private class FileCoverImpl(override val id: String, private val appFile: AppFile) : FileCover { private data class FileCoverImpl(override val id: String, private val appFile: AppFile) :
FileCover {
override suspend fun fd() = appFile.fd() override suspend fun fd() = appFile.fd()
override suspend fun open() = appFile.open() override suspend fun open() = appFile.open()

View file

@ -96,7 +96,7 @@ private class AppFilesImpl(private val dir: File) : AppFiles {
} }
} }
private class AppFileImpl(private val file: File) : AppFile { private data class AppFileImpl(private val file: File) : AppFile {
override suspend fun fd() = override suspend fun fd() =
withContext(Dispatchers.IO) { withContext(Dispatchers.IO) {
try { try {

View file

@ -29,7 +29,7 @@ import org.oxycblt.musikr.util.update
internal interface AlbumCore { internal interface AlbumCore {
val preAlbum: PreAlbum val preAlbum: PreAlbum
val songs: List<Song> val songs: Set<Song>
fun resolveArtists(): List<Artist> fun resolveArtists(): List<Artist>
} }
@ -39,7 +39,7 @@ internal interface AlbumCore {
* *
* @author Alexander Capehart (OxygenCobalt) * @author Alexander Capehart (OxygenCobalt)
*/ */
internal class AlbumImpl(private val core: AlbumCore) : Album { class AlbumImpl internal constructor(private val core: AlbumCore) : Album {
private val preAlbum = core.preAlbum private val preAlbum = core.preAlbum
override val uid = override val uid =
@ -73,4 +73,6 @@ internal class AlbumImpl(private val core: AlbumCore) : Album {
other is AlbumImpl && uid == other.uid && preAlbum == other.preAlbum && songs == other.songs other is AlbumImpl && uid == other.uid && preAlbum == other.preAlbum && songs == other.songs
override fun toString() = "Album(uid=$uid, name=$name)" override fun toString() = "Album(uid=$uid, name=$name)"
fun a(other: AlbumImpl) = uid == other.uid
} }

View file

@ -87,7 +87,7 @@ private class LibraryFactoryImpl() : LibraryFactory {
private class AlbumVertexCore(private val vertex: AlbumVertex) : AlbumCore { private class AlbumVertexCore(private val vertex: AlbumVertex) : AlbumCore {
override val preAlbum = vertex.preAlbum override val preAlbum = vertex.preAlbum
override val songs = vertex.songVertices.map { SongImpl(SongVertexCore(it)) } override val songs = vertex.songVertices.mapTo(mutableSetOf()) { it.tag as Song }
override fun resolveArtists() = vertex.artistVertices.map { it.tag as Artist } override fun resolveArtists() = vertex.artistVertices.map { it.tag as Artist }
} }