From b8d6b836e54c5cd6991baf3fa4fa99bacd10f06d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Yi=C4=9Fit=20=C3=96zg=C3=BCm=C3=BC=C5=9F?= Date: Sat, 14 Dec 2024 22:35:47 +0300 Subject: [PATCH 1/3] Update methods for getting data and effects --- .../components/ComponentViewModel.kt | 32 +++++++------- .../transmission/counter/CounterViewModel.kt | 5 ++- .../trendyol/transmissiontest/TestSuite.kt | 10 ++--- .../trendyol/transmission/router/StreamExt.kt | 43 ++++++++++++++----- .../transmission/router/TransmissionRouter.kt | 14 +++--- .../transmission/TransmissionRouterTest.kt | 12 +++--- 6 files changed, 72 insertions(+), 44 deletions(-) diff --git a/sample/src/main/java/com/trendyol/transmission/components/ComponentViewModel.kt b/sample/src/main/java/com/trendyol/transmission/components/ComponentViewModel.kt index 5255113..0c553ec 100644 --- a/sample/src/main/java/com/trendyol/transmission/components/ComponentViewModel.kt +++ b/sample/src/main/java/com/trendyol/transmission/components/ComponentViewModel.kt @@ -3,16 +3,18 @@ package com.trendyol.transmission.components import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import com.trendyol.transmission.Transmission -import com.trendyol.transmission.effect.RouterEffect -import com.trendyol.transmission.components.features.colorpicker.ColorPickerTransformer -import com.trendyol.transmission.components.features.input.InputTransformer -import com.trendyol.transmission.router.TransmissionRouter -import com.trendyol.transmission.router.onEach -import com.trendyol.transmission.router.toState import com.trendyol.transmission.components.features.ColorPickerUiState import com.trendyol.transmission.components.features.InputUiState import com.trendyol.transmission.components.features.MultiOutputUiState import com.trendyol.transmission.components.features.OutputUiState +import com.trendyol.transmission.components.features.colorpicker.ColorPickerTransformer +import com.trendyol.transmission.components.features.input.InputTransformer +import com.trendyol.transmission.effect.RouterEffect +import com.trendyol.transmission.router.TransmissionRouter +import com.trendyol.transmission.router.asState +import com.trendyol.transmission.router.streamData +import com.trendyol.transmission.router.streamDataAsState +import com.trendyol.transmission.router.streamEffect import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.coroutines.delay import kotlinx.coroutines.flow.MutableStateFlow @@ -27,13 +29,13 @@ class ComponentViewModel @Inject constructor( private val router: TransmissionRouter ) : ViewModel() { - val inputUiState = router.dataStream - .onEach { _transmissionList.value = listOf() } - .toState(viewModelScope, InputUiState()) + val inputUiState = router + .streamData { _transmissionList.value = listOf() } + .asState(viewModelScope, InputUiState()) - val outputUiState = router.dataStream.toState(viewModelScope, OutputUiState()) - val colorPickerUiState = router.dataStream.toState(viewModelScope, ColorPickerUiState()) - val multiOutputUiState = router.dataStream.toState(viewModelScope, MultiOutputUiState()) + val outputUiState = router.streamDataAsState(viewModelScope, OutputUiState()) + val colorPickerUiState = router.streamDataAsState(viewModelScope, ColorPickerUiState()) + val multiOutputUiState = router.streamDataAsState(viewModelScope, MultiOutputUiState()) private val _transmissionList = MutableStateFlow>(emptyList()) val transmissionList = _transmissionList.asStateFlow() @@ -41,16 +43,16 @@ class ComponentViewModel @Inject constructor( init { viewModelScope.launch { launch { - router.dataStream.collect(::onData) + router.streamData().collect(::onData) } launch { - router.effectStream.collect(::onEffect) + router.streamEffect().collect(::onEffect) } } } fun processSignal(signal: Transmission.Signal) { - router.processSignal(signal) + router.process(signal) _transmissionList.update { it.plus("Signal: $signal") } } diff --git a/sample/src/main/java/com/trendyol/transmission/counter/CounterViewModel.kt b/sample/src/main/java/com/trendyol/transmission/counter/CounterViewModel.kt index 094f340..64c7dce 100644 --- a/sample/src/main/java/com/trendyol/transmission/counter/CounterViewModel.kt +++ b/sample/src/main/java/com/trendyol/transmission/counter/CounterViewModel.kt @@ -5,6 +5,7 @@ import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import com.trendyol.transmission.Transmission import com.trendyol.transmission.router.builder.TransmissionRouterBuilder +import com.trendyol.transmission.router.streamData import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Job @@ -34,12 +35,12 @@ class CounterViewModel @Inject constructor() : ViewModel() { init { viewModelScope.launch(Dispatchers.Default) { - router.dataStream.collect(::onData) + router.streamData().collect(::onData) } } fun processSignal(signal: Transmission.Signal) { - router.processSignal(signal) + router.process(signal) _areAllDistinct.tryEmit("Calculating") checkTransmissions() counter.addAndGet(1) diff --git a/transmission-test/src/main/java/com/trendyol/transmissiontest/TestSuite.kt b/transmission-test/src/main/java/com/trendyol/transmissiontest/TestSuite.kt index 463561d..8d7eacf 100644 --- a/transmission-test/src/main/java/com/trendyol/transmissiontest/TestSuite.kt +++ b/transmission-test/src/main/java/com/trendyol/transmissiontest/TestSuite.kt @@ -1,8 +1,8 @@ package com.trendyol.transmissiontest import com.trendyol.transmission.Transmission -import com.trendyol.transmission.router.TransmissionRouter import com.trendyol.transmission.router.RegistryScope +import com.trendyol.transmission.router.TransmissionRouter import com.trendyol.transmission.router.builder.TransmissionTestingRouterBuilder import com.trendyol.transmission.transformer.Transformer import kotlinx.coroutines.ExperimentalCoroutinesApi @@ -64,15 +64,15 @@ class TestSuite { orderedInitialProcessing.forEach { when (it) { is Transmission.Data -> throw IllegalArgumentException("Transmission.Data should not be sent for processing") - is Transmission.Effect -> router.processEffect(it) - is Transmission.Signal -> router.processSignal(it) + is Transmission.Effect -> router.process(it) + is Transmission.Signal -> router.process(it) } transformer?.waitProcessingToFinish() } if (transmission is Transmission.Signal) { - router.processSignal(transmission) + router.process(transmission) } else if (transmission is Transmission.Effect) { - router.processEffect(transmission) + router.process(transmission) } transformer?.waitProcessingToFinish() testScope.scope(this) diff --git a/transmission/src/main/java/com/trendyol/transmission/router/StreamExt.kt b/transmission/src/main/java/com/trendyol/transmission/router/StreamExt.kt index d831e35..11fb84b 100644 --- a/transmission/src/main/java/com/trendyol/transmission/router/StreamExt.kt +++ b/transmission/src/main/java/com/trendyol/transmission/router/StreamExt.kt @@ -3,31 +3,52 @@ package com.trendyol.transmission.router import com.trendyol.transmission.Transmission import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.flow.Flow -import kotlinx.coroutines.flow.SharedFlow import kotlinx.coroutines.flow.SharingStarted import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.filterIsInstance import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.flow.stateIn -inline fun SharedFlow.toState( +fun TransmissionRouter.streamData(): Flow { + return this.dataStream +} + +inline fun TransmissionRouter.streamData(): Flow { + return this.dataStream.filterIsInstance() +} + +inline fun TransmissionRouter.streamData( + noinline action: suspend (T) -> Unit +): Flow { + return this.dataStream.filterIsInstance().onEach(action) +} + +inline fun TransmissionRouter.streamEffect(): Flow { + return this.effectStream.filterIsInstance() +} + +fun TransmissionRouter.streamEffect(): Flow { + return this.effectStream +} + +inline fun TransmissionRouter.streamEffect( + noinline action: suspend (T) -> Unit +): Flow { + return this.effectStream.filterIsInstance().onEach(action) +} + +inline fun TransmissionRouter.streamDataAsState( scope: CoroutineScope, initialValue: T, sharingStarted: SharingStarted = SharingStarted.WhileSubscribed(), ): StateFlow { - return this.filterIsInstance().stateIn(scope, sharingStarted, initialValue) + return this.dataStream.filterIsInstance().stateIn(scope, sharingStarted, initialValue) } -inline fun Flow.toState( +inline fun Flow.asState( scope: CoroutineScope, initialValue: T, sharingStarted: SharingStarted = SharingStarted.WhileSubscribed(), -): StateFlow { - return this.filterIsInstance().stateIn(scope, sharingStarted, initialValue) -} - -inline fun Flow.onEach( - noinline action: suspend (T) -> Unit ): Flow { - return this.filterIsInstance().onEach(action) + return this.filterIsInstance().stateIn(scope, sharingStarted, initialValue) } diff --git a/transmission/src/main/java/com/trendyol/transmission/router/TransmissionRouter.kt b/transmission/src/main/java/com/trendyol/transmission/router/TransmissionRouter.kt index 3b824c5..871c122 100644 --- a/transmission/src/main/java/com/trendyol/transmission/router/TransmissionRouter.kt +++ b/transmission/src/main/java/com/trendyol/transmission/router/TransmissionRouter.kt @@ -45,9 +45,13 @@ class TransmissionRouter internal constructor( private val checkpointTracker = CheckpointTracker() - val dataStream = dataBroadcast.output - val effectStream: SharedFlow = effectBroadcast.output.map { it.effect } - .shareIn(routerScope, SharingStarted.WhileSubscribed()) + @PublishedApi + internal val dataStream = dataBroadcast.output + + @PublishedApi + internal val effectStream: SharedFlow = + effectBroadcast.output.map { it.effect } + .shareIn(routerScope, SharingStarted.WhileSubscribed()) private val _requestDelegate = RequestDelegate( queryScope = routerScope, @@ -76,13 +80,13 @@ class TransmissionRouter internal constructor( initializeInternal(loader) } - fun processSignal(signal: Transmission.Signal) { + fun process(signal: Transmission.Signal) { routerScope.launch { signalBroadcast.producer.send(signal) } } - fun processEffect(effect: Transmission.Effect) { + fun process(effect: Transmission.Effect) { routerScope.launch { effectBroadcast.producer.send(EffectWrapper(effect)) } diff --git a/transmission/src/test/kotlin/com/trendyol/transmission/TransmissionRouterTest.kt b/transmission/src/test/kotlin/com/trendyol/transmission/TransmissionRouterTest.kt index b3e66ab..7e6093b 100644 --- a/transmission/src/test/kotlin/com/trendyol/transmission/TransmissionRouterTest.kt +++ b/transmission/src/test/kotlin/com/trendyol/transmission/TransmissionRouterTest.kt @@ -73,7 +73,7 @@ class TransmissionRouterTest { addDispatcher(testDispatcher) } // When - sut.processSignal(TestSignal) + sut.process(TestSignal) // Then assertEquals(transformer.signalList.last(), TestSignal) @@ -90,7 +90,7 @@ class TransmissionRouterTest { addDispatcher(testDispatcher) } // When - sut.processSignal(TestSignal) + sut.process(TestSignal) // Then assertEquals(transformer1.signalList.last(), TestSignal) @@ -113,7 +113,7 @@ class TransmissionRouterTest { addDispatcher(testDispatcher) } // When - sut.processSignal(TestSignal) + sut.process(TestSignal) // Then assertEquals(transformer1.effectList.last(), TestEffect) @@ -135,7 +135,7 @@ class TransmissionRouterTest { } // When val effects = sut.effectStream.testIn(backgroundScope) - sut.processSignal(TestSignal) + sut.process(TestSignal) assertEquals(6, effects.cancelAndConsumeRemainingEvents().size) // Then } @@ -154,7 +154,7 @@ class TransmissionRouterTest { addDispatcher(testDispatcher) } // When - sut.processSignal(TestSignal) + sut.process(TestSignal) sut.dataStream.test { assertEquals(TestData("update with TestTransformer1"), awaitItem()) assertEquals(TestData("update with TestTransformer2"), awaitItem()) @@ -176,7 +176,7 @@ class TransmissionRouterTest { addDispatcher(testDispatcher) } // When - sut.processSignal(TestSignal) + sut.process(TestSignal) // Then assertEquals(transformer1.effectList.contains(RouterEffect("")), false) From 6c2baf315c48613ded559faab2ab95447efa3c57 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Yi=C4=9Fit=20=C3=96zg=C3=BCm=C3=BC=C5=9F?= Date: Sun, 15 Dec 2024 21:34:58 +0300 Subject: [PATCH 2/3] Add JvmName for declaration crash and fix return type of asState --- .../java/com/trendyol/transmission/router/StreamExt.kt | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/transmission/src/main/java/com/trendyol/transmission/router/StreamExt.kt b/transmission/src/main/java/com/trendyol/transmission/router/StreamExt.kt index 11fb84b..abdf4af 100644 --- a/transmission/src/main/java/com/trendyol/transmission/router/StreamExt.kt +++ b/transmission/src/main/java/com/trendyol/transmission/router/StreamExt.kt @@ -9,28 +9,34 @@ import kotlinx.coroutines.flow.filterIsInstance import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.flow.stateIn +@JvmName("streamData") fun TransmissionRouter.streamData(): Flow { return this.dataStream } +@JvmName("streamDataWithType") inline fun TransmissionRouter.streamData(): Flow { return this.dataStream.filterIsInstance() } +@JvmName("streamDataWithAction") inline fun TransmissionRouter.streamData( noinline action: suspend (T) -> Unit ): Flow { return this.dataStream.filterIsInstance().onEach(action) } +@JvmName("streamEffect") inline fun TransmissionRouter.streamEffect(): Flow { return this.effectStream.filterIsInstance() } +@JvmName("streamEffectWithType") fun TransmissionRouter.streamEffect(): Flow { return this.effectStream } +@JvmName("streamEffectWithAction") inline fun TransmissionRouter.streamEffect( noinline action: suspend (T) -> Unit ): Flow { @@ -49,6 +55,6 @@ inline fun Flow.asState( scope: CoroutineScope, initialValue: T, sharingStarted: SharingStarted = SharingStarted.WhileSubscribed(), -): Flow { +): StateFlow { return this.filterIsInstance().stateIn(scope, sharingStarted, initialValue) } From e4d2be363a0fb7fe0a2b74eedb087f027dd4d556 Mon Sep 17 00:00:00 2001 From: Yigit Ozgumus Date: Mon, 16 Dec 2024 09:05:17 +0300 Subject: [PATCH 3/3] Change old usage in TestSuite with new stream extensions --- .../main/java/com/trendyol/transmissiontest/TestSuite.kt | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/transmission-test/src/main/java/com/trendyol/transmissiontest/TestSuite.kt b/transmission-test/src/main/java/com/trendyol/transmissiontest/TestSuite.kt index 846408f..bfd8e2a 100644 --- a/transmission-test/src/main/java/com/trendyol/transmissiontest/TestSuite.kt +++ b/transmission-test/src/main/java/com/trendyol/transmissiontest/TestSuite.kt @@ -3,6 +3,8 @@ package com.trendyol.transmissiontest import com.trendyol.transmission.Transmission import com.trendyol.transmission.router.TransmissionRouter import com.trendyol.transmission.router.builder.TransmissionRouterBuilder +import com.trendyol.transmission.router.streamData +import com.trendyol.transmission.router.streamEffect import com.trendyol.transmission.transformer.Transformer import com.trendyol.transmission.transformer.request.Contract import com.trendyol.transmissiontest.computation.ComputationTransformer @@ -72,10 +74,10 @@ class TestSuite { val effectStream: MutableList = mutableListOf() try { backgroundScope.launch(UnconfinedTestDispatcher(testScheduler)) { - router.dataStream.toList(dataStream) + router.streamData().toList(dataStream) } backgroundScope.launch(UnconfinedTestDispatcher(testScheduler)) { - router.effectStream.toList(effectStream) + router.streamEffect().toList(effectStream) } val testScope = object : TransformerTestScope { override val dataStream: List = dataStream