music: implement genre linking
This commit is contained in:
parent
d633a6b9f1
commit
db391da4b8
3 changed files with 66 additions and 4 deletions
|
@ -0,0 +1,18 @@
|
|||
package org.oxycblt.auxio.music.stack.interpret.linker
|
||||
|
||||
class Contribution<T> {
|
||||
private val map = mutableMapOf<T, Int>()
|
||||
|
||||
val candidates: Collection<T> get() = map.keys
|
||||
|
||||
fun contribute(key: T) {
|
||||
map[key] = map.getOrDefault(key, 0) + 1
|
||||
}
|
||||
|
||||
fun contribute(keys: Collection<T>) {
|
||||
keys.forEach { contribute(it) }
|
||||
}
|
||||
|
||||
fun resolve() = map.maxByOrNull { it.value }?.key ?: error("Nothing was contributed")
|
||||
|
||||
}
|
|
@ -2,16 +2,60 @@ package org.oxycblt.auxio.music.stack.interpret.linker
|
|||
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.emptyFlow
|
||||
import kotlinx.coroutines.flow.map
|
||||
import kotlinx.coroutines.flow.transform
|
||||
import org.oxycblt.auxio.music.stack.interpret.model.GenreImpl
|
||||
import org.oxycblt.auxio.music.stack.interpret.model.SongImpl
|
||||
import org.oxycblt.auxio.music.stack.interpret.prepare.PreGenre
|
||||
import org.oxycblt.auxio.music.stack.interpret.prepare.PreSong
|
||||
|
||||
class GenreLinker {
|
||||
fun register(preSong: Flow<PreSong>): Flow<LinkedSong> = emptyFlow()
|
||||
fun resolve(): Collection<GenreImpl> = setOf()
|
||||
class GenreTree {
|
||||
private val tree = mutableMapOf<String?, GenreLink>()
|
||||
|
||||
fun register(preSong: Flow<PreSong>): Flow<LinkedSong> = preSong.map {
|
||||
val genreLinks = it.preGenres.map { genre ->
|
||||
val nameKey = genre.rawName?.lowercase()
|
||||
val link = tree.getOrPut(nameKey) { GenreLink(GenreNode(Contribution())) }
|
||||
link.node.contributors.contribute(genre)
|
||||
link
|
||||
}
|
||||
LinkedSong(it, MultiGenreLink(genreLinks))
|
||||
}
|
||||
|
||||
fun resolve() =
|
||||
tree.values.map { it.node.resolve() }
|
||||
|
||||
data class LinkedSong(
|
||||
val preSong: PreSong,
|
||||
val genres: Linked<List<GenreImpl>, SongImpl>
|
||||
)
|
||||
|
||||
private class MultiGenreLink(
|
||||
val links: List<Linked<GenreImpl, SongImpl>>
|
||||
) : Linked<List<GenreImpl>, SongImpl> {
|
||||
override fun resolve(child: SongImpl): List<GenreImpl> {
|
||||
return links.map { it.resolve(child) }.distinct()
|
||||
}
|
||||
}
|
||||
|
||||
private data class GenreLink(
|
||||
var node: GenreNode
|
||||
) : Linked<GenreImpl, SongImpl> {
|
||||
override fun resolve(child: SongImpl): GenreImpl {
|
||||
return requireNotNull(node.genreImpl) { "Link" }
|
||||
}
|
||||
}
|
||||
|
||||
private class GenreNode(
|
||||
val contributors: Contribution<PreGenre>
|
||||
) {
|
||||
var genreImpl: GenreImpl? = null
|
||||
private set
|
||||
|
||||
fun resolve(): GenreImpl {
|
||||
val impl = GenreImpl(contributors.resolve())
|
||||
genreImpl = impl
|
||||
return impl
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,7 +16,7 @@ import java.util.UUID
|
|||
data class PreSong(
|
||||
val musicBrainzId: UUID?,
|
||||
val name: Name,
|
||||
val rawName: String?,
|
||||
val rawName: String,
|
||||
val track: Int?,
|
||||
val disc: Disc?,
|
||||
val date: Date?,
|
||||
|
|
Loading…
Reference in a new issue