mirror of
https://github.com/InsanusMokrassar/MicroUtils.git
synced 2024-12-18 14:47:15 +00:00
add conflicts resolver for default states managers
This commit is contained in:
parent
a328c4425a
commit
99b09c8b28
@ -5,8 +5,9 @@
|
|||||||
* `Common`:
|
* `Common`:
|
||||||
* New extensions `Element#onVisibilityChanged`, `Element#onVisible` and `Element#onInvisible`
|
* New extensions `Element#onVisibilityChanged`, `Element#onVisible` and `Element#onInvisible`
|
||||||
* `Coroutines`:
|
* `Coroutines`:
|
||||||
* New extension `Element.visibilityFlow()`
|
* New extension `Element.visibilityFlow()`
|
||||||
|
* `FSM`:
|
||||||
|
* Now it is possible to resolve conflicts on `startChain`
|
||||||
|
|
||||||
## 0.9.16
|
## 0.9.16
|
||||||
|
|
||||||
|
@ -39,13 +39,14 @@ interface DefaultStatesManagerRepo<T : State> {
|
|||||||
* @param repo This repo will be used as repository for storing states. All operations with this repo will happen BEFORE
|
* @param repo This repo will be used as repository for storing states. All operations with this repo will happen BEFORE
|
||||||
* any event will be sent to [onChainStateUpdated], [onStartChain] or [onEndChain]. By default, will be used
|
* any event will be sent to [onChainStateUpdated], [onStartChain] or [onEndChain]. By default, will be used
|
||||||
* [InMemoryDefaultStatesManagerRepo] or you may create custom [DefaultStatesManagerRepo] and pass as [repo] parameter
|
* [InMemoryDefaultStatesManagerRepo] or you may create custom [DefaultStatesManagerRepo] and pass as [repo] parameter
|
||||||
* @param onContextsConflictResolver Receive old [State], new one and the state currently placed on new [State.context]
|
* @param onUpdateContextsConflictResolver Receive old [State], new one and the state currently placed on new [State.context]
|
||||||
* key. In case when this callback will returns true, the state placed on [State.context] of new will be replaced by
|
* key. In case when this callback will returns true, the state placed on [State.context] of new will be replaced by
|
||||||
* new state by using [endChain] with that state
|
* new state by using [endChain] with that state
|
||||||
*/
|
*/
|
||||||
open class DefaultStatesManager<T : State>(
|
open class DefaultStatesManager<T : State>(
|
||||||
protected val repo: DefaultStatesManagerRepo<T> = InMemoryDefaultStatesManagerRepo(),
|
protected val repo: DefaultStatesManagerRepo<T> = InMemoryDefaultStatesManagerRepo(),
|
||||||
protected val onContextsConflictResolver: suspend (old: T, new: T, currentNew: T) -> Boolean = { _, _, _ -> true }
|
protected val onStartContextsConflictResolver: suspend (old: T, new: T) -> Boolean = { _, _ -> true },
|
||||||
|
protected val onUpdateContextsConflictResolver: suspend (old: T, new: T, currentNew: T) -> Boolean = { _, _, _ -> true }
|
||||||
) : StatesManager<T> {
|
) : StatesManager<T> {
|
||||||
protected val _onChainStateUpdated = MutableSharedFlow<Pair<T, T>>(0)
|
protected val _onChainStateUpdated = MutableSharedFlow<Pair<T, T>>(0)
|
||||||
override val onChainStateUpdated: Flow<Pair<T, T>> = _onChainStateUpdated.asSharedFlow()
|
override val onChainStateUpdated: Flow<Pair<T, T>> = _onChainStateUpdated.asSharedFlow()
|
||||||
@ -56,6 +57,14 @@ open class DefaultStatesManager<T : State>(
|
|||||||
|
|
||||||
protected val mapMutex = Mutex()
|
protected val mapMutex = Mutex()
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
repo: DefaultStatesManagerRepo<T>,
|
||||||
|
onContextsConflictResolver: suspend (old: T, new: T, currentNew: T) -> Boolean
|
||||||
|
) : this (
|
||||||
|
repo,
|
||||||
|
onUpdateContextsConflictResolver = onContextsConflictResolver
|
||||||
|
)
|
||||||
|
|
||||||
override suspend fun update(old: T, new: T) = mapMutex.withLock {
|
override suspend fun update(old: T, new: T) = mapMutex.withLock {
|
||||||
val stateByOldContext: T? = repo.getContextState(old.context)
|
val stateByOldContext: T? = repo.getContextState(old.context)
|
||||||
when {
|
when {
|
||||||
@ -67,7 +76,7 @@ open class DefaultStatesManager<T : State>(
|
|||||||
}
|
}
|
||||||
else -> {
|
else -> {
|
||||||
val stateOnNewOneContext = repo.getContextState(new.context)
|
val stateOnNewOneContext = repo.getContextState(new.context)
|
||||||
if (stateOnNewOneContext == null || onContextsConflictResolver(old, new, stateOnNewOneContext)) {
|
if (stateOnNewOneContext == null || onUpdateContextsConflictResolver(old, new, stateOnNewOneContext)) {
|
||||||
stateOnNewOneContext ?.let { endChainWithoutLock(it) }
|
stateOnNewOneContext ?.let { endChainWithoutLock(it) }
|
||||||
repo.removeState(old)
|
repo.removeState(old)
|
||||||
repo.set(new)
|
repo.set(new)
|
||||||
@ -78,7 +87,11 @@ open class DefaultStatesManager<T : State>(
|
|||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun startChain(state: T) = mapMutex.withLock {
|
override suspend fun startChain(state: T) = mapMutex.withLock {
|
||||||
if (!repo.contains(state.context)) {
|
val stateOnContext = repo.getContextState(state.context)
|
||||||
|
if (stateOnContext == null || onStartContextsConflictResolver(stateOnContext, state)) {
|
||||||
|
stateOnContext ?.let {
|
||||||
|
endChainWithoutLock(it)
|
||||||
|
}
|
||||||
repo.set(state)
|
repo.set(state)
|
||||||
_onStartChain.emit(state)
|
_onStartChain.emit(state)
|
||||||
}
|
}
|
||||||
|
@ -12,5 +12,6 @@ import kotlinx.coroutines.flow.*
|
|||||||
*/
|
*/
|
||||||
@Deprecated("Use DefaultStatesManager instead", ReplaceWith("DefaultStatesManager"))
|
@Deprecated("Use DefaultStatesManager instead", ReplaceWith("DefaultStatesManager"))
|
||||||
fun <T: State> InMemoryStatesManager(
|
fun <T: State> InMemoryStatesManager(
|
||||||
onContextsConflictResolver: suspend (old: T, new: T, currentNew: T) -> Boolean = { _, _, _ -> true }
|
onStartContextsConflictResolver: suspend (old: T, new: T) -> Boolean = { _, _ -> true },
|
||||||
) = DefaultStatesManager(onContextsConflictResolver = onContextsConflictResolver)
|
onUpdateContextsConflictResolver: suspend (old: T, new: T, currentNew: T) -> Boolean = { _, _, _ -> true }
|
||||||
|
) = DefaultStatesManager(onStartContextsConflictResolver = onStartContextsConflictResolver, onUpdateContextsConflictResolver = onUpdateContextsConflictResolver)
|
||||||
|
Loading…
Reference in New Issue
Block a user