From 8c66924be9686e186162e8c3c7e51bfc5a461e19 Mon Sep 17 00:00:00 2001 From: ganfra Date: Mon, 26 Jun 2023 18:18:48 +0200 Subject: [PATCH] Timeline: refactor a bit --- .../matrix/impl/room/RustMatrixRoom.kt | 17 ++++---- .../timeline/MatrixTimelineDiffProcessor.kt | 41 +++++++++++-------- .../impl/timeline/RustMatrixTimeline.kt | 8 ++-- 3 files changed, 35 insertions(+), 31 deletions(-) diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/room/RustMatrixRoom.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/room/RustMatrixRoom.kt index 66c30be0da..39d829c6a8 100644 --- a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/room/RustMatrixRoom.kt +++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/room/RustMatrixRoom.kt @@ -108,13 +108,13 @@ class RustMatrixRoom( timelineLimit = null ) roomListItem.subscribe(settings) - innerRoom.timelineDiffFlow { initialList -> - timeline.postItems(initialList) - }.onEach { - syncUpdateFlow.value = systemClock.epochMillis() - timeline.postDiff(it) - }.launchIn(roomCoroutineScope) - roomCoroutineScope.launch { + roomCoroutineScope.launch(coroutineDispatchers.computation) { + innerRoom.timelineDiffFlow { initialList -> + timeline.postItems(initialList) + }.onEach { + syncUpdateFlow.value = systemClock.epochMillis() + timeline.postDiff(it) + }.launchIn(this) fetchMembers() } isInit.value = true @@ -122,7 +122,7 @@ class RustMatrixRoom( } override fun close() { - if(isInit.value) { + if (isInit.value) { isInit.value = false roomCoroutineScope.cancel() roomListItem.unsubscribe() @@ -360,7 +360,6 @@ class RustMatrixRoom( } } - private suspend fun fetchMembers() = withContext(coroutineDispatchers.io) { runCatching { innerRoom.fetchMembers() diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/timeline/MatrixTimelineDiffProcessor.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/timeline/MatrixTimelineDiffProcessor.kt index bd30d826f2..02b34757da 100644 --- a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/timeline/MatrixTimelineDiffProcessor.kt +++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/timeline/MatrixTimelineDiffProcessor.kt @@ -19,11 +19,9 @@ package io.element.android.libraries.matrix.impl.timeline import io.element.android.libraries.matrix.api.timeline.MatrixTimeline import io.element.android.libraries.matrix.api.timeline.MatrixTimelineItem import io.element.android.libraries.matrix.api.timeline.item.virtual.VirtualTimelineItem -import kotlinx.coroutines.CoroutineDispatcher -import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.flow.MutableStateFlow -import kotlinx.coroutines.launch -import kotlinx.coroutines.withContext +import kotlinx.coroutines.sync.Mutex +import kotlinx.coroutines.sync.withLock import org.matrix.rustcomponents.sdk.TimelineChange import org.matrix.rustcomponents.sdk.TimelineDiff import org.matrix.rustcomponents.sdk.TimelineItem @@ -31,20 +29,23 @@ import org.matrix.rustcomponents.sdk.TimelineItem internal class MatrixTimelineDiffProcessor( private val paginationState: MutableStateFlow, private val timelineItems: MutableStateFlow>, - private val coroutineScope: CoroutineScope, - private val diffDispatcher: CoroutineDispatcher, private val timelineItemFactory: MatrixTimelineItemMapper, ) { - fun postDiff(diff: TimelineDiff) { - coroutineScope.launch { - updateTimelineItems { - applyDiff(diff) - } - when (val firstItem = timelineItems.value.firstOrNull()) { - is MatrixTimelineItem.Virtual -> updateBackPaginationState(firstItem.virtual) - else -> updateBackPaginationState(null) - } + private val mutex = Mutex() + + suspend fun postItems(items: List) { + updateTimelineItems { + val mappedItems = items.map { it.asMatrixTimelineItem() } + addAll(mappedItems) + updateBackPaginationState() + } + } + + suspend fun postDiff(diff: TimelineDiff) { + updateTimelineItems { + applyDiff(diff) + updateBackPaginationState() } } @@ -68,7 +69,7 @@ internal class MatrixTimelineDiffProcessor( } private suspend fun updateTimelineItems(block: MutableList.() -> Unit) = - withContext(diffDispatcher) { + mutex.withLock { val mutableTimelineItems = timelineItems.value.toMutableList() block(mutableTimelineItems) timelineItems.value = mutableTimelineItems @@ -119,8 +120,14 @@ internal class MatrixTimelineDiffProcessor( } } + private fun List.updateBackPaginationState() { + when (val firstItem = firstOrNull()) { + is MatrixTimelineItem.Virtual -> updateBackPaginationState(firstItem.virtual) + else -> updateBackPaginationState(null) + } + } + private fun TimelineItem.asMatrixTimelineItem(): MatrixTimelineItem { return timelineItemFactory.map(this) } - } diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/timeline/RustMatrixTimeline.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/timeline/RustMatrixTimeline.kt index 906ffa0967..1893c452bb 100644 --- a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/timeline/RustMatrixTimeline.kt +++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/timeline/RustMatrixTimeline.kt @@ -66,8 +66,6 @@ class RustMatrixTimeline( private val timelineDiffProcessor = MatrixTimelineDiffProcessor( paginationState = paginationState, timelineItems = timelineItems, - coroutineScope = roomCoroutineScope, - diffDispatcher = coroutineDispatchers.diffUpdateDispatcher, timelineItemFactory = timelineItemFactory, ) @@ -80,11 +78,11 @@ class RustMatrixTimeline( return timelineItems.sample(50) } - internal fun postItems(items: List) { - timelineItems.value = items.map(timelineItemFactory::map) + internal suspend fun postItems(items: List) { + timelineDiffProcessor.postItems(items) } - internal fun postDiff(timelineDiff: TimelineDiff) { + internal suspend fun postDiff(timelineDiff: TimelineDiff) { timelineDiffProcessor.postDiff(timelineDiff) }