mirror of
				https://github.com/InsanusMokrassar/MicroUtils.git
				synced 2025-11-04 06:00:22 +00:00 
			
		
		
		
	rename SpecialMutableStateFlow to MutableRedeliverStateFlow
This commit is contained in:
		@@ -2,6 +2,9 @@
 | 
			
		||||
 | 
			
		||||
## 0.26.2
 | 
			
		||||
 | 
			
		||||
* `Coroutines`:
 | 
			
		||||
  * Rename `SpecialMutableStateFlow` to `MutableRedeliverStateFlow`
 | 
			
		||||
 | 
			
		||||
## 0.26.1
 | 
			
		||||
 | 
			
		||||
* `Versions`:
 | 
			
		||||
 
 | 
			
		||||
@@ -2,11 +2,9 @@ import androidx.compose.runtime.remember
 | 
			
		||||
import androidx.compose.ui.test.ExperimentalTestApi
 | 
			
		||||
import androidx.compose.ui.test.runComposeUiTest
 | 
			
		||||
import dev.inmo.micro_utils.common.compose.LoadableComponent
 | 
			
		||||
import dev.inmo.micro_utils.coroutines.SpecialMutableStateFlow
 | 
			
		||||
import kotlinx.coroutines.flow.MutableSharedFlow
 | 
			
		||||
import dev.inmo.micro_utils.coroutines.MutableRedeliverStateFlow
 | 
			
		||||
import kotlinx.coroutines.flow.filter
 | 
			
		||||
import kotlinx.coroutines.flow.first
 | 
			
		||||
import kotlinx.coroutines.flow.firstOrNull
 | 
			
		||||
import org.jetbrains.annotations.TestOnly
 | 
			
		||||
import kotlin.test.Test
 | 
			
		||||
import kotlin.test.assertTrue
 | 
			
		||||
@@ -16,8 +14,8 @@ class LoadableComponentTests {
 | 
			
		||||
    @Test
 | 
			
		||||
    @TestOnly
 | 
			
		||||
    fun testSimpleLoad() = runComposeUiTest {
 | 
			
		||||
        val loadingFlow = SpecialMutableStateFlow<Int>(0)
 | 
			
		||||
        val loadedFlow = SpecialMutableStateFlow<Int>(0)
 | 
			
		||||
        val loadingFlow = MutableRedeliverStateFlow<Int>(0)
 | 
			
		||||
        val loadedFlow = MutableRedeliverStateFlow<Int>(0)
 | 
			
		||||
        setContent {
 | 
			
		||||
            LoadableComponent<Int>({
 | 
			
		||||
                loadingFlow.filter { it == 1 }.first()
 | 
			
		||||
 
 | 
			
		||||
@@ -3,7 +3,7 @@ package dev.inmo.micro_utils.coroutines.compose
 | 
			
		||||
import androidx.compose.runtime.Composable
 | 
			
		||||
import androidx.compose.runtime.collectAsState
 | 
			
		||||
import androidx.compose.runtime.remember
 | 
			
		||||
import dev.inmo.micro_utils.coroutines.SpecialMutableStateFlow
 | 
			
		||||
import dev.inmo.micro_utils.coroutines.MutableRedeliverStateFlow
 | 
			
		||||
import kotlinx.coroutines.flow.StateFlow
 | 
			
		||||
import kotlinx.coroutines.flow.asStateFlow
 | 
			
		||||
import kotlinx.coroutines.flow.debounce
 | 
			
		||||
@@ -16,7 +16,7 @@ import org.jetbrains.compose.web.css.StyleSheet
 | 
			
		||||
 * to add `Style(stylesheet)` on every compose function call
 | 
			
		||||
 */
 | 
			
		||||
object StyleSheetsAggregator {
 | 
			
		||||
    private val _stylesFlow = SpecialMutableStateFlow<Set<CSSRulesHolder>>(emptySet())
 | 
			
		||||
    private val _stylesFlow = MutableRedeliverStateFlow<Set<CSSRulesHolder>>(emptySet())
 | 
			
		||||
    val stylesFlow: StateFlow<Set<CSSRulesHolder>> = _stylesFlow.asStateFlow()
 | 
			
		||||
 | 
			
		||||
    @Composable
 | 
			
		||||
 
 | 
			
		||||
@@ -2,7 +2,7 @@ import androidx.compose.material.Button
 | 
			
		||||
import androidx.compose.material.Text
 | 
			
		||||
import androidx.compose.runtime.collectAsState
 | 
			
		||||
import androidx.compose.ui.test.*
 | 
			
		||||
import dev.inmo.micro_utils.coroutines.SpecialMutableStateFlow
 | 
			
		||||
import dev.inmo.micro_utils.coroutines.MutableRedeliverStateFlow
 | 
			
		||||
import org.jetbrains.annotations.TestOnly
 | 
			
		||||
import kotlin.test.Test
 | 
			
		||||
 | 
			
		||||
@@ -11,7 +11,7 @@ class FlowStateTests {
 | 
			
		||||
    @Test
 | 
			
		||||
    @TestOnly
 | 
			
		||||
    fun simpleTest() = runComposeUiTest {
 | 
			
		||||
        val flowState = SpecialMutableStateFlow(0)
 | 
			
		||||
        val flowState = MutableRedeliverStateFlow(0)
 | 
			
		||||
        setContent {
 | 
			
		||||
            Button({ flowState.value++ }) { Text("Click") }
 | 
			
		||||
            Text(flowState.collectAsState().value.toString())
 | 
			
		||||
 
 | 
			
		||||
@@ -1,7 +1,5 @@
 | 
			
		||||
package dev.inmo.micro_utils.coroutines
 | 
			
		||||
 | 
			
		||||
import kotlinx.coroutines.CoroutineScope
 | 
			
		||||
import kotlinx.coroutines.Dispatchers
 | 
			
		||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
 | 
			
		||||
import kotlinx.coroutines.InternalCoroutinesApi
 | 
			
		||||
import kotlinx.coroutines.channels.BufferOverflow
 | 
			
		||||
@@ -11,13 +9,12 @@ import kotlinx.coroutines.flow.MutableStateFlow
 | 
			
		||||
import kotlinx.coroutines.flow.StateFlow
 | 
			
		||||
import kotlinx.coroutines.internal.SynchronizedObject
 | 
			
		||||
import kotlinx.coroutines.internal.synchronized
 | 
			
		||||
import kotlin.coroutines.CoroutineContext
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Works like [StateFlow], but guarantee that latest value update will always be delivered to
 | 
			
		||||
 * each active subscriber
 | 
			
		||||
 */
 | 
			
		||||
open class SpecialMutableStateFlow<T>(
 | 
			
		||||
open class MutableRedeliverStateFlow<T>(
 | 
			
		||||
    initialValue: T
 | 
			
		||||
) : MutableStateFlow<T>, FlowCollector<T>, MutableSharedFlow<T> {
 | 
			
		||||
    @OptIn(InternalCoroutinesApi::class)
 | 
			
		||||
@@ -68,3 +65,6 @@ open class SpecialMutableStateFlow<T>(
 | 
			
		||||
 | 
			
		||||
    override suspend fun collect(collector: FlowCollector<T>) = sharingFlow.collect(collector)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@Deprecated("Renamed to MutableRedeliverStateFlow", ReplaceWith("MutableRedeliverStateFlow<T>"))
 | 
			
		||||
typealias SpecialMutableStateFlow<T> = MutableRedeliverStateFlow<T>
 | 
			
		||||
@@ -1,7 +1,6 @@
 | 
			
		||||
package dev.inmo.micro_utils.coroutines
 | 
			
		||||
 | 
			
		||||
import kotlinx.coroutines.currentCoroutineContext
 | 
			
		||||
import kotlinx.coroutines.flow.MutableStateFlow
 | 
			
		||||
import kotlinx.coroutines.flow.StateFlow
 | 
			
		||||
import kotlinx.coroutines.flow.asStateFlow
 | 
			
		||||
import kotlinx.coroutines.flow.first
 | 
			
		||||
@@ -44,7 +43,7 @@ sealed interface SmartMutex {
 | 
			
		||||
     * @param locked Preset state of [isLocked] and its internal [_lockStateFlow]
 | 
			
		||||
     */
 | 
			
		||||
    class Mutable(locked: Boolean = false) : SmartMutex {
 | 
			
		||||
        private val _lockStateFlow = SpecialMutableStateFlow<Boolean>(locked)
 | 
			
		||||
        private val _lockStateFlow = MutableRedeliverStateFlow<Boolean>(locked)
 | 
			
		||||
        override val lockStateFlow: StateFlow<Boolean> = _lockStateFlow.asStateFlow()
 | 
			
		||||
 | 
			
		||||
        private val internalChangesMutex = Mutex()
 | 
			
		||||
 
 | 
			
		||||
@@ -1,7 +1,6 @@
 | 
			
		||||
package dev.inmo.micro_utils.coroutines
 | 
			
		||||
 | 
			
		||||
import kotlinx.coroutines.currentCoroutineContext
 | 
			
		||||
import kotlinx.coroutines.flow.MutableStateFlow
 | 
			
		||||
import kotlinx.coroutines.flow.StateFlow
 | 
			
		||||
import kotlinx.coroutines.flow.asStateFlow
 | 
			
		||||
import kotlinx.coroutines.flow.first
 | 
			
		||||
@@ -47,7 +46,7 @@ sealed interface SmartSemaphore {
 | 
			
		||||
     */
 | 
			
		||||
    class Mutable(permits: Int, acquiredPermits: Int = 0) : SmartSemaphore {
 | 
			
		||||
        override val maxPermits: Int = permits
 | 
			
		||||
        private val _freePermitsStateFlow = SpecialMutableStateFlow<Int>(permits - acquiredPermits)
 | 
			
		||||
        private val _freePermitsStateFlow = MutableRedeliverStateFlow<Int>(permits - acquiredPermits)
 | 
			
		||||
        override val permitsStateFlow: StateFlow<Int> = _freePermitsStateFlow.asStateFlow()
 | 
			
		||||
 | 
			
		||||
        private val internalChangesMutex = Mutex(false)
 | 
			
		||||
 
 | 
			
		||||
@@ -1,33 +1,31 @@
 | 
			
		||||
import dev.inmo.micro_utils.coroutines.SpecialMutableStateFlow
 | 
			
		||||
import dev.inmo.micro_utils.coroutines.asDeferred
 | 
			
		||||
import dev.inmo.micro_utils.coroutines.MutableRedeliverStateFlow
 | 
			
		||||
import dev.inmo.micro_utils.coroutines.subscribe
 | 
			
		||||
import kotlinx.coroutines.Job
 | 
			
		||||
import kotlinx.coroutines.flow.first
 | 
			
		||||
import kotlinx.coroutines.test.runTest
 | 
			
		||||
import kotlin.test.Test
 | 
			
		||||
import kotlin.test.assertEquals
 | 
			
		||||
import kotlin.test.assertTrue
 | 
			
		||||
 | 
			
		||||
class SpecialMutableStateFlowTests {
 | 
			
		||||
    @Test
 | 
			
		||||
    fun simpleTest() = runTest {
 | 
			
		||||
        val specialMutableStateFlow = SpecialMutableStateFlow(0)
 | 
			
		||||
        specialMutableStateFlow.value = 1
 | 
			
		||||
        specialMutableStateFlow.first { it == 1 }
 | 
			
		||||
        assertEquals(1, specialMutableStateFlow.value)
 | 
			
		||||
        val mutableRedeliverStateFlow = MutableRedeliverStateFlow(0)
 | 
			
		||||
        mutableRedeliverStateFlow.value = 1
 | 
			
		||||
        mutableRedeliverStateFlow.first { it == 1 }
 | 
			
		||||
        assertEquals(1, mutableRedeliverStateFlow.value)
 | 
			
		||||
    }
 | 
			
		||||
    @Test
 | 
			
		||||
    fun specialTest() = runTest {
 | 
			
		||||
        val specialMutableStateFlow = SpecialMutableStateFlow(0)
 | 
			
		||||
        val mutableRedeliverStateFlow = MutableRedeliverStateFlow(0)
 | 
			
		||||
        lateinit var subscriberJob: Job
 | 
			
		||||
        subscriberJob = specialMutableStateFlow.subscribe(this) {
 | 
			
		||||
        subscriberJob = mutableRedeliverStateFlow.subscribe(this) {
 | 
			
		||||
            when (it) {
 | 
			
		||||
                1 -> specialMutableStateFlow.value = 2
 | 
			
		||||
                1 -> mutableRedeliverStateFlow.value = 2
 | 
			
		||||
                2 -> subscriberJob.cancel()
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        specialMutableStateFlow.value = 1
 | 
			
		||||
        mutableRedeliverStateFlow.value = 1
 | 
			
		||||
        subscriberJob.join()
 | 
			
		||||
        assertEquals(2, specialMutableStateFlow.value)
 | 
			
		||||
        assertEquals(2, mutableRedeliverStateFlow.value)
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,9 +1,8 @@
 | 
			
		||||
package dev.inmo.micro_utils.pagination.compose
 | 
			
		||||
 | 
			
		||||
import androidx.compose.runtime.*
 | 
			
		||||
import dev.inmo.micro_utils.coroutines.SpecialMutableStateFlow
 | 
			
		||||
import dev.inmo.micro_utils.coroutines.MutableRedeliverStateFlow
 | 
			
		||||
import dev.inmo.micro_utils.coroutines.launchLoggingDropExceptions
 | 
			
		||||
import dev.inmo.micro_utils.coroutines.runCatchingLogging
 | 
			
		||||
import dev.inmo.micro_utils.pagination.*
 | 
			
		||||
import kotlinx.coroutines.CoroutineScope
 | 
			
		||||
import kotlinx.coroutines.Job
 | 
			
		||||
@@ -27,8 +26,8 @@ class InfinityPagedComponentContext<T> internal constructor(
 | 
			
		||||
    private val loader: suspend InfinityPagedComponentContext<T>.(Pagination) -> PaginationResult<T>
 | 
			
		||||
) {
 | 
			
		||||
    internal val startPage = SimplePagination(page, size)
 | 
			
		||||
    internal val latestLoadedPage = SpecialMutableStateFlow<PaginationResult<T>?>(null)
 | 
			
		||||
    internal val dataState = SpecialMutableStateFlow<List<T>?>(null)
 | 
			
		||||
    internal val latestLoadedPage = MutableRedeliverStateFlow<PaginationResult<T>?>(null)
 | 
			
		||||
    internal val dataState = MutableRedeliverStateFlow<List<T>?>(null)
 | 
			
		||||
    internal var loadingJob: Job? = null
 | 
			
		||||
    internal val loadingMutex = Mutex()
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -1,7 +1,7 @@
 | 
			
		||||
package dev.inmo.micro_utils.pagination.compose
 | 
			
		||||
 | 
			
		||||
import androidx.compose.runtime.*
 | 
			
		||||
import dev.inmo.micro_utils.coroutines.SpecialMutableStateFlow
 | 
			
		||||
import dev.inmo.micro_utils.coroutines.MutableRedeliverStateFlow
 | 
			
		||||
import dev.inmo.micro_utils.coroutines.launchLoggingDropExceptions
 | 
			
		||||
import dev.inmo.micro_utils.pagination.*
 | 
			
		||||
import kotlinx.coroutines.CoroutineScope
 | 
			
		||||
@@ -28,8 +28,8 @@ class PagedComponentContext<T> internal constructor(
 | 
			
		||||
    private val loader: suspend PagedComponentContext<T>.(Pagination) -> PaginationResult<T>
 | 
			
		||||
) {
 | 
			
		||||
    internal val startPage = SimplePagination(initialPage, size)
 | 
			
		||||
    internal val latestLoadedPage = SpecialMutableStateFlow<PaginationResult<T>?>(null)
 | 
			
		||||
    internal val dataState = SpecialMutableStateFlow<PaginationResult<T>?>(null)
 | 
			
		||||
    internal val latestLoadedPage = MutableRedeliverStateFlow<PaginationResult<T>?>(null)
 | 
			
		||||
    internal val dataState = MutableRedeliverStateFlow<PaginationResult<T>?>(null)
 | 
			
		||||
    internal var loadingJob: Job? = null
 | 
			
		||||
    internal val loadingMutex = Mutex()
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user