Fix observe order#2761
Conversation
|
This still relies on unproven semantics. I feel like we need to refactor this part rather than patching it. I will take a closer look on how we can solve this correctly. |
|
Fair enough and yeah it does. I just thought a better fix then relying on .value, as simply changing observe order and couldn't reproduce the issue anymore but yeah it is still just a patch fix. I didnt really like either but this one just felt "safer" and more reliable then the other way. |
I will possibly make a pull request tomorrow, but the core idea is to have some immutable state to store all data needed to display the video. This state can then be efficiently modified using a persistent data type, and avoid concurrency issues by having it copy the data structure. We can then have a single source of truth for the entire player that exists within the viewmodel and can be exposed with e.g. ConsistentLiveData for both observe and typealias VideoLink = Pair<ExtractorLink?, ExtractorUri?>
/** Immutable state of all current links relevant to displaying the video */
data class VideoState(
val subtitles: PersistentSet<SubtitleData>,
val links: PersistentSet<VideoLink>,
val stamps: PersistentSet<VideoSkipStamp>
) {
/** This acts as a local cache for sorted links that are not copied over by the copy constructor */
private val sortedLinks: ConcurrentHashMap<Int, List<VideoLink>> = ConcurrentHashMap()
fun sortLinks(qualityProfile: Int) : List<VideoLink> {
return sortedLinks[qualityProfile] ?: links.sortedBy { link ->
// negative because we want to sort highest quality first
-getLinkPriority(qualityProfile, link.first)
}.also { value -> sortedLinks[qualityProfile] = value }
}
fun add(item: SubtitleData): VideoState = copy(subtitles = subtitles.add(item))
fun add(item: VideoLink): VideoState = copy(links = links.add(item))
fun add(item: VideoSkipStamp): VideoState = copy(stamps = stamps.add(item))
fun add(items: Collection<SubtitleData>): VideoState = copy(subtitles = subtitles.addAll(items))
fun add(items: Collection<VideoLink>): VideoState = copy(links = links.addAll(items))
fun add(items: Collection<VideoSkipStamp>): VideoState = copy(stamps = stamps.addAll(items))
} |
Fixes #2746
Closes #2750