mirror of
https://github.com/InsanusMokrassar/MicroUtils.git
synced 2024-11-17 13:53:49 +00:00
SpecialMutableStateFlow : MutableStateFlow
This commit is contained in:
parent
f3f9920bfb
commit
43e782ab6f
@ -3,6 +3,7 @@
|
||||
## 0.20.18
|
||||
|
||||
* `Coroutines`:
|
||||
* `SpecialMutableStateFlow` now extends `MutableStateFlow`
|
||||
* `Compose`:
|
||||
* Deprecate `FlowState` due to its complexity in fixes
|
||||
|
||||
|
@ -1,10 +1,7 @@
|
||||
package dev.inmo.micro_utils.coroutines.compose
|
||||
|
||||
import androidx.compose.runtime.MutableState
|
||||
import androidx.compose.runtime.State
|
||||
import androidx.compose.runtime.derivedStateOf
|
||||
import dev.inmo.micro_utils.coroutines.SpecialMutableStateFlow
|
||||
import dev.inmo.micro_utils.coroutines.doInUI
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
|
||||
@ -26,9 +23,9 @@ class FlowState<T>(
|
||||
tryEmit(value)
|
||||
}
|
||||
|
||||
override suspend fun onChange(value: T) {
|
||||
override fun onChangeWithoutSync(value: T) {
|
||||
internalValue = value
|
||||
super.onChange(value)
|
||||
super.onChangeWithoutSync(value)
|
||||
}
|
||||
|
||||
override fun component1(): T = value
|
||||
|
@ -3,10 +3,14 @@ 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
|
||||
import kotlinx.coroutines.flow.FlowCollector
|
||||
import kotlinx.coroutines.flow.MutableSharedFlow
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.StateFlow
|
||||
import kotlinx.coroutines.internal.SynchronizedObject
|
||||
import kotlinx.coroutines.internal.synchronized
|
||||
|
||||
/**
|
||||
* Works like [StateFlow], but guarantee that latest value update will always be delivered to
|
||||
@ -15,7 +19,9 @@ import kotlinx.coroutines.flow.StateFlow
|
||||
open class SpecialMutableStateFlow<T>(
|
||||
initialValue: T,
|
||||
internalScope: CoroutineScope = CoroutineScope(Dispatchers.Default)
|
||||
) : StateFlow<T>, FlowCollector<T>, MutableSharedFlow<T> {
|
||||
) : MutableStateFlow<T>, FlowCollector<T>, MutableSharedFlow<T> {
|
||||
@OptIn(InternalCoroutinesApi::class)
|
||||
private val syncObject = SynchronizedObject()
|
||||
protected val internalSharedFlow: MutableSharedFlow<T> = MutableSharedFlow(
|
||||
replay = 0,
|
||||
extraBufferCapacity = 2,
|
||||
@ -28,16 +34,37 @@ open class SpecialMutableStateFlow<T>(
|
||||
)
|
||||
|
||||
protected var _value: T = initialValue
|
||||
override val value: T
|
||||
@OptIn(InternalCoroutinesApi::class)
|
||||
override var value: T
|
||||
get() = _value
|
||||
protected open suspend fun onChange(value: T) {
|
||||
set(value) {
|
||||
doOnChangeAction(value)
|
||||
}
|
||||
|
||||
@OptIn(InternalCoroutinesApi::class)
|
||||
override fun compareAndSet(expect: T, update: T): Boolean {
|
||||
return synchronized(syncObject) {
|
||||
if (expect == _value && update != _value) {
|
||||
doOnChangeAction(update)
|
||||
}
|
||||
expect == _value
|
||||
}
|
||||
}
|
||||
|
||||
protected open fun onChangeWithoutSync(value: T) {
|
||||
_value = value
|
||||
publicSharedFlow.emit(value)
|
||||
publicSharedFlow.tryEmit(value)
|
||||
}
|
||||
@OptIn(InternalCoroutinesApi::class)
|
||||
protected open fun doOnChangeAction(value: T) {
|
||||
synchronized(syncObject) {
|
||||
if (_value != value) {
|
||||
onChangeWithoutSync(value)
|
||||
}
|
||||
}
|
||||
}
|
||||
protected val job = internalSharedFlow.subscribe(internalScope) {
|
||||
if (_value != it) {
|
||||
onChange(it)
|
||||
}
|
||||
doOnChangeAction(it)
|
||||
}
|
||||
|
||||
override val replayCache: List<T>
|
||||
|
Loading…
Reference in New Issue
Block a user