mirror of
https://github.com/InsanusMokrassar/MicroUtils.git
synced 2024-12-18 14:47:15 +00:00
SpecialMutableStateFlow : MutableStateFlow
This commit is contained in:
parent
f3f9920bfb
commit
43e782ab6f
@ -3,6 +3,7 @@
|
|||||||
## 0.20.18
|
## 0.20.18
|
||||||
|
|
||||||
* `Coroutines`:
|
* `Coroutines`:
|
||||||
|
* `SpecialMutableStateFlow` now extends `MutableStateFlow`
|
||||||
* `Compose`:
|
* `Compose`:
|
||||||
* Deprecate `FlowState` due to its complexity in fixes
|
* Deprecate `FlowState` due to its complexity in fixes
|
||||||
|
|
||||||
|
@ -1,10 +1,7 @@
|
|||||||
package dev.inmo.micro_utils.coroutines.compose
|
package dev.inmo.micro_utils.coroutines.compose
|
||||||
|
|
||||||
import androidx.compose.runtime.MutableState
|
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.SpecialMutableStateFlow
|
||||||
import dev.inmo.micro_utils.coroutines.doInUI
|
|
||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.CoroutineScope
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
|
||||||
@ -26,9 +23,9 @@ class FlowState<T>(
|
|||||||
tryEmit(value)
|
tryEmit(value)
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun onChange(value: T) {
|
override fun onChangeWithoutSync(value: T) {
|
||||||
internalValue = value
|
internalValue = value
|
||||||
super.onChange(value)
|
super.onChangeWithoutSync(value)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun component1(): T = value
|
override fun component1(): T = value
|
||||||
|
@ -3,10 +3,14 @@ package dev.inmo.micro_utils.coroutines
|
|||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.CoroutineScope
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||||
|
import kotlinx.coroutines.InternalCoroutinesApi
|
||||||
import kotlinx.coroutines.channels.BufferOverflow
|
import kotlinx.coroutines.channels.BufferOverflow
|
||||||
import kotlinx.coroutines.flow.FlowCollector
|
import kotlinx.coroutines.flow.FlowCollector
|
||||||
import kotlinx.coroutines.flow.MutableSharedFlow
|
import kotlinx.coroutines.flow.MutableSharedFlow
|
||||||
|
import kotlinx.coroutines.flow.MutableStateFlow
|
||||||
import kotlinx.coroutines.flow.StateFlow
|
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
|
* 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>(
|
open class SpecialMutableStateFlow<T>(
|
||||||
initialValue: T,
|
initialValue: T,
|
||||||
internalScope: CoroutineScope = CoroutineScope(Dispatchers.Default)
|
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(
|
protected val internalSharedFlow: MutableSharedFlow<T> = MutableSharedFlow(
|
||||||
replay = 0,
|
replay = 0,
|
||||||
extraBufferCapacity = 2,
|
extraBufferCapacity = 2,
|
||||||
@ -28,16 +34,37 @@ open class SpecialMutableStateFlow<T>(
|
|||||||
)
|
)
|
||||||
|
|
||||||
protected var _value: T = initialValue
|
protected var _value: T = initialValue
|
||||||
override val value: T
|
@OptIn(InternalCoroutinesApi::class)
|
||||||
|
override var value: T
|
||||||
get() = _value
|
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
|
_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) {
|
protected val job = internalSharedFlow.subscribe(internalScope) {
|
||||||
if (_value != it) {
|
doOnChangeAction(it)
|
||||||
onChange(it)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override val replayCache: List<T>
|
override val replayCache: List<T>
|
||||||
|
Loading…
Reference in New Issue
Block a user