Skip to content

Commit 89ffd19

Browse files
committed
Restore source compatibility with the Interactor lifecycle changes (StateFlow over SharedFlow).
1 parent 1af2f57 commit 89ffd19

File tree

3 files changed

+28
-18
lines changed

3 files changed

+28
-18
lines changed

libraries/rib-base/src/main/kotlin/com/uber/rib/core/FlowAsScope.kt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -38,17 +38,17 @@ import kotlinx.coroutines.rx2.rxCompletable
3838
* [range].
3939
*/
4040
@CoreFriendModuleApi
41-
public fun <T : Comparable<T>> SharedFlow<T?>.asScopeCompletable(
41+
public fun <T : Comparable<T>> SharedFlow<T>.asScopeCompletable(
4242
range: ClosedRange<T>,
4343
context: CoroutineContext = EmptyCoroutineContext,
4444
): CompletableSource {
4545
ensureAlive(range)
4646
return rxCompletable(RibDispatchers.Unconfined + context) {
47-
takeWhile { it == null || it < range.endInclusive }.collect()
47+
takeWhile { it < range.endInclusive }.collect()
4848
}
4949
}
5050

51-
private fun <T : Comparable<T>> SharedFlow<T?>.ensureAlive(range: ClosedRange<T>) {
51+
private fun <T : Comparable<T>> SharedFlow<T>.ensureAlive(range: ClosedRange<T>) {
5252
val lastEmitted = replayCache.lastOrNull()
5353
when {
5454
lastEmitted == null || lastEmitted < range.start -> throw LifecycleNotStartedException()

libraries/rib-base/src/main/kotlin/com/uber/rib/core/Interactor.kt

Lines changed: 25 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -27,11 +27,12 @@ import io.reactivex.Observable
2727
import javax.inject.Inject
2828
import kotlin.properties.ReadWriteProperty
2929
import kotlin.reflect.KProperty
30+
import kotlinx.coroutines.ExperimentalForInheritanceCoroutinesApi
3031
import kotlinx.coroutines.channels.BufferOverflow
31-
import kotlinx.coroutines.flow.Flow
32+
import kotlinx.coroutines.flow.FlowCollector
3233
import kotlinx.coroutines.flow.MutableSharedFlow
3334
import kotlinx.coroutines.flow.MutableStateFlow
34-
import kotlinx.coroutines.flow.filterNotNull
35+
import kotlinx.coroutines.flow.SharedFlow
3536
import kotlinx.coroutines.rx2.asObservable
3637

3738
/**
@@ -48,8 +49,7 @@ public abstract class Interactor<P : Any, R : Router<*>>() : InteractorType, Rib
4849
private val useStateFlow
4950
get() = RibEvents.useStateFlowInteractorEvent
5051

51-
@VisibleForTesting
52-
internal val _lifecycleFlow: MutableSharedFlow<InteractorEvent?> =
52+
private val _lifecycleFlow: MutableSharedFlow<InteractorEvent?> =
5353
if (useStateFlow) {
5454
MutableStateFlow(null)
5555
} else {
@@ -59,8 +59,7 @@ public abstract class Interactor<P : Any, R : Router<*>>() : InteractorType, Rib
5959
BufferOverflow.DROP_OLDEST,
6060
)
6161
}
62-
public open val lifecycleFlow: Flow<InteractorEvent>
63-
get() = _lifecycleFlow.filterNotNull()
62+
public open val lifecycleFlow: SharedFlow<InteractorEvent> = NonNullSharedFlow(_lifecycleFlow)
6463

6564
@Volatile private var _lifecycleObservable: Observable<InteractorEvent>? = null
6665

@@ -86,16 +85,16 @@ public abstract class Interactor<P : Any, R : Router<*>>() : InteractorType, Rib
8685
final override fun correspondingEvents(): CorrespondingEventsFunction<InteractorEvent> =
8786
LIFECYCLE_MAP_FUNCTION
8887

89-
final override fun peekLifecycle(): InteractorEvent? = _lifecycleFlow.replayCache.lastOrNull()
88+
final override fun peekLifecycle(): InteractorEvent? = lifecycleFlow.replayCache.lastOrNull()
9089

9190
@OptIn(CoreFriendModuleApi::class)
9291
final override fun requestScope(): CompletableSource =
93-
_lifecycleFlow.asScopeCompletable(lifecycleRange)
92+
lifecycleFlow.asScopeCompletable(lifecycleRange)
9493

9594
// ---- InteractorType overrides ---- //
9695

9796
override fun isAttached(): Boolean =
98-
_lifecycleFlow.replayCache.lastOrNull() == InteractorEvent.ACTIVE
97+
lifecycleFlow.replayCache.lastOrNull() == InteractorEvent.ACTIVE
9998

10099
override fun handleBackPress(): Boolean = false
101100

@@ -233,3 +232,20 @@ public abstract class Interactor<P : Any, R : Router<*>>() : InteractorType, Rib
233232
}
234233
}
235234
}
235+
236+
// See https://github.com/Kotlin/kotlinx.coroutines/issues/2514
237+
@OptIn(ExperimentalForInheritanceCoroutinesApi::class)
238+
private class NonNullSharedFlow<R : Any>(
239+
private val upstream: SharedFlow<R?>,
240+
) : SharedFlow<R> {
241+
override val replayCache: List<R>
242+
get() = upstream.replayCache.filterNotNull()
243+
244+
override suspend fun collect(collector: FlowCollector<R>): Nothing {
245+
upstream.collect { value ->
246+
if (value != null) {
247+
collector.emit(value)
248+
}
249+
}
250+
}
251+
}

libraries/rib-base/src/test/kotlin/com/uber/rib/core/InteractorAndRouterTest.kt

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,6 @@ import com.uber.rib.core.RibRefWatcher.Companion.getInstance
2525
import com.uber.rib.core.lifecycle.InteractorEvent
2626
import io.reactivex.Completable
2727
import io.reactivex.observers.TestObserver
28-
import kotlinx.coroutines.flow.MutableSharedFlow
29-
import kotlinx.coroutines.flow.MutableStateFlow
3028
import kotlinx.coroutines.test.runTest
3129
import kotlinx.coroutines.withTimeoutOrNull
3230
import org.junit.Assert.fail
@@ -229,13 +227,11 @@ class InteractorAndRouterTest {
229227
setupInteractorForStateFlow()
230228
var eventCount = 0
231229
val lifecycleFlow = interactor.lifecycleFlow
232-
val _lifecycleFlow = interactor._lifecycleFlow
233230

234231
// When
235232
withTimeoutOrNull(10) { lifecycleFlow.collect { eventCount++ } }
236233

237234
// Then
238-
assertThat(_lifecycleFlow).isInstanceOf(MutableStateFlow::class.java)
239235
assertThat(eventCount).isEqualTo(0)
240236
}
241237

@@ -244,13 +240,11 @@ class InteractorAndRouterTest {
244240
// When
245241
var eventCount = 0
246242
val lifecycleFlow = interactor.lifecycleFlow
247-
val _lifecycleFlow = interactor._lifecycleFlow
248243

249244
// When
250245
withTimeoutOrNull(10) { lifecycleFlow.collect { eventCount++ } }
251246

252247
// Then
253-
assertThat(_lifecycleFlow).isInstanceOf(MutableSharedFlow::class.java)
254248
assertThat(eventCount).isEqualTo(0)
255249
}
256250

0 commit comments

Comments
 (0)