From bbc4db156e2d5579a3f5ca66468cad720973be01 Mon Sep 17 00:00:00 2001 From: Alexander Capehart Date: Mon, 6 Jan 2025 11:23:04 -0700 Subject: [PATCH] musikr: fix equality issues --- .../auxio/image/covers/SiloedCovers.kt | 3 +- .../oxycblt/auxio/music/MusicRepository.kt | 44 ++++++++++--------- .../java/org/oxycblt/musikr/cover/Covers.kt | 4 ++ .../org/oxycblt/musikr/cover/FileCovers.kt | 3 +- .../org/oxycblt/musikr/fs/app/AppFiles.kt | 2 +- .../org/oxycblt/musikr/model/AlbumImpl.kt | 6 ++- .../oxycblt/musikr/model/LibraryFactory.kt | 2 +- 7 files changed, 38 insertions(+), 26 deletions(-) diff --git a/app/src/main/java/org/oxycblt/auxio/image/covers/SiloedCovers.kt b/app/src/main/java/org/oxycblt/auxio/image/covers/SiloedCovers.kt index 3ff8a90d3..253d0dacf 100644 --- a/app/src/main/java/org/oxycblt/auxio/image/covers/SiloedCovers.kt +++ b/app/src/main/java/org/oxycblt/auxio/image/covers/SiloedCovers.kt @@ -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) override val id = innerId.toString() } diff --git a/app/src/main/java/org/oxycblt/auxio/music/MusicRepository.kt b/app/src/main/java/org/oxycblt/auxio/music/MusicRepository.kt index 0262efac7..e0b3873a7 100644 --- a/app/src/main/java/org/oxycblt/auxio/music/MusicRepository.kt +++ b/app/src/main/java/org/oxycblt/auxio/music/MusicRepository.kt @@ -396,12 +396,33 @@ constructor( // Music loading completed, update the revision right now so we re-use this work // later. 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 - // amount of consumers of MusicRepository. - // TODO: Would Atomics not be a better fit here? + private suspend fun emitIndexingProgress(progress: IndexingProgress) { + yield() + synchronized(this) { + currentIndexingState = IndexingState.Indexing(progress) + for (listener in indexingListeners) { + listener.onIndexingStateChanged() + } + } + } + + private suspend fun emitLibrary(newLibrary: MutableLibrary) { val deviceLibraryChanged: 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) { // It's possible that this reload might have changed nothing, so make sure that // hasn't happened before dispatching a change to all consumers. @@ -428,23 +449,6 @@ constructor( withContext(Dispatchers.Main) { 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?) { diff --git a/musikr/src/main/java/org/oxycblt/musikr/cover/Covers.kt b/musikr/src/main/java/org/oxycblt/musikr/cover/Covers.kt index dfdf96ede..e3f41b386 100644 --- a/musikr/src/main/java/org/oxycblt/musikr/cover/Covers.kt +++ b/musikr/src/main/java/org/oxycblt/musikr/cover/Covers.kt @@ -43,6 +43,10 @@ interface Cover { } class CoverCollection private constructor(val covers: List) { + override fun hashCode() = covers.hashCode() + + override fun equals(other: Any?) = other is CoverCollection && covers == other.covers + companion object { fun from(covers: Collection) = CoverCollection( diff --git a/musikr/src/main/java/org/oxycblt/musikr/cover/FileCovers.kt b/musikr/src/main/java/org/oxycblt/musikr/cover/FileCovers.kt index 5a8a54195..4c8390869 100644 --- a/musikr/src/main/java/org/oxycblt/musikr/cover/FileCovers.kt +++ b/musikr/src/main/java/org/oxycblt/musikr/cover/FileCovers.kt @@ -57,7 +57,8 @@ interface FileCover : Cover { 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 open() = appFile.open() diff --git a/musikr/src/main/java/org/oxycblt/musikr/fs/app/AppFiles.kt b/musikr/src/main/java/org/oxycblt/musikr/fs/app/AppFiles.kt index 151a9d158..9c8f2a407 100644 --- a/musikr/src/main/java/org/oxycblt/musikr/fs/app/AppFiles.kt +++ b/musikr/src/main/java/org/oxycblt/musikr/fs/app/AppFiles.kt @@ -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() = withContext(Dispatchers.IO) { try { diff --git a/musikr/src/main/java/org/oxycblt/musikr/model/AlbumImpl.kt b/musikr/src/main/java/org/oxycblt/musikr/model/AlbumImpl.kt index 10b7aabc3..53a17152d 100644 --- a/musikr/src/main/java/org/oxycblt/musikr/model/AlbumImpl.kt +++ b/musikr/src/main/java/org/oxycblt/musikr/model/AlbumImpl.kt @@ -29,7 +29,7 @@ import org.oxycblt.musikr.util.update internal interface AlbumCore { val preAlbum: PreAlbum - val songs: List + val songs: Set fun resolveArtists(): List } @@ -39,7 +39,7 @@ internal interface AlbumCore { * * @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 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 override fun toString() = "Album(uid=$uid, name=$name)" + + fun a(other: AlbumImpl) = uid == other.uid } diff --git a/musikr/src/main/java/org/oxycblt/musikr/model/LibraryFactory.kt b/musikr/src/main/java/org/oxycblt/musikr/model/LibraryFactory.kt index bffe06b0c..1bcd6d752 100644 --- a/musikr/src/main/java/org/oxycblt/musikr/model/LibraryFactory.kt +++ b/musikr/src/main/java/org/oxycblt/musikr/model/LibraryFactory.kt @@ -87,7 +87,7 @@ private class LibraryFactoryImpl() : LibraryFactory { private class AlbumVertexCore(private val vertex: AlbumVertex) : AlbumCore { 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 } }