mirror of
https://github.com/InsanusMokrassar/MicroUtils.git
synced 2024-12-18 14:47:15 +00:00
FSM updates
This commit is contained in:
parent
72bc8da1e7
commit
8f928e16e1
@ -2,6 +2,10 @@
|
|||||||
|
|
||||||
## 0.9.15
|
## 0.9.15
|
||||||
|
|
||||||
|
* `FSM`:
|
||||||
|
* Rename `DefaultUpdatableStatesMachine#compare` to `DefaultUpdatableStatesMachine#shouldReplaceJob`
|
||||||
|
* `DefaultStatesManager` now is extendable
|
||||||
|
|
||||||
## 0.9.14
|
## 0.9.14
|
||||||
|
|
||||||
* `Versions`:
|
* `Versions`:
|
||||||
|
@ -26,6 +26,12 @@ open class DefaultUpdatableStatesMachine<T : State>(
|
|||||||
), UpdatableStatesMachine<T> {
|
), UpdatableStatesMachine<T> {
|
||||||
protected val jobsStates = mutableMapOf<Job, T>()
|
protected val jobsStates = mutableMapOf<Job, T>()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Realization of this update will use the [Job] of [previousState] in [statesJobs] and [jobsStates] if
|
||||||
|
* [previousState] is [Optional.presented] and [shouldReplaceJob] has returned true for [previousState] and [actualState]. In
|
||||||
|
* other words, [Job] of [previousState] WILL NOT be replaced with the new one if they are "equal". Equality of
|
||||||
|
* states is solved in [shouldReplaceJob] and can be rewritten in subclasses
|
||||||
|
*/
|
||||||
override suspend fun performStateUpdate(previousState: Optional<T>, actualState: T, scope: CoroutineScope) {
|
override suspend fun performStateUpdate(previousState: Optional<T>, actualState: T, scope: CoroutineScope) {
|
||||||
statesJobsMutex.withLock {
|
statesJobsMutex.withLock {
|
||||||
if (compare(previousState, actualState)) {
|
if (compare(previousState, actualState)) {
|
||||||
@ -52,7 +58,13 @@ open class DefaultUpdatableStatesMachine<T : State>(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected open suspend fun compare(previous: Optional<T>, new: T): Boolean = previous.dataOrNull() != new
|
/**
|
||||||
|
* Compare if [previous] potentially lead to the same behaviour with [new]
|
||||||
|
*/
|
||||||
|
protected open suspend fun shouldReplaceJob(previous: Optional<T>, new: T): Boolean = previous.dataOrNull() != new
|
||||||
|
|
||||||
|
@Deprecated("Overwrite shouldReplaceJob instead")
|
||||||
|
protected open suspend fun compare(previous: Optional<T>, new: T): Boolean = shouldReplaceJob(previous, new)
|
||||||
|
|
||||||
override suspend fun updateChain(currentState: T, newState: T) {
|
override suspend fun updateChain(currentState: T, newState: T) {
|
||||||
statesManager.update(currentState, newState)
|
statesManager.update(currentState, newState)
|
||||||
|
@ -37,24 +37,24 @@ 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 onContextsConflictResolver 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
|
||||||
*/
|
*/
|
||||||
class DefaultStatesManager<T : State>(
|
open class DefaultStatesManager<T : State>(
|
||||||
private val repo: DefaultStatesManagerRepo<T> = InMemoryDefaultStatesManagerRepo(),
|
protected val repo: DefaultStatesManagerRepo<T> = InMemoryDefaultStatesManagerRepo(),
|
||||||
private val onContextsConflictResolver: suspend (old: T, new: T, currentNew: T) -> Boolean = { _, _, _ -> true }
|
protected val onContextsConflictResolver: suspend (old: T, new: T, currentNew: T) -> Boolean = { _, _, _ -> true }
|
||||||
) : StatesManager<T> {
|
) : StatesManager<T> {
|
||||||
private 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()
|
||||||
private val _onStartChain = MutableSharedFlow<T>(0)
|
protected val _onStartChain = MutableSharedFlow<T>(0)
|
||||||
override val onStartChain: Flow<T> = _onStartChain.asSharedFlow()
|
override val onStartChain: Flow<T> = _onStartChain.asSharedFlow()
|
||||||
private val _onEndChain = MutableSharedFlow<T>(0)
|
protected val _onEndChain = MutableSharedFlow<T>(0)
|
||||||
override val onEndChain: Flow<T> = _onEndChain.asSharedFlow()
|
override val onEndChain: Flow<T> = _onEndChain.asSharedFlow()
|
||||||
|
|
||||||
private val mapMutex = Mutex()
|
protected val mapMutex = Mutex()
|
||||||
|
|
||||||
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)
|
||||||
@ -83,7 +83,7 @@ class DefaultStatesManager<T : State>(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private suspend fun endChainWithoutLock(state: T) {
|
protected open suspend fun endChainWithoutLock(state: T) {
|
||||||
if (repo.getContextState(state.context) == state) {
|
if (repo.getContextState(state.context) == state) {
|
||||||
repo.removeState(state)
|
repo.removeState(state)
|
||||||
_onEndChain.emit(state)
|
_onEndChain.emit(state)
|
||||||
|
Loading…
Reference in New Issue
Block a user