mirror of
https://github.com/InsanusMokrassar/MicroUtils.git
synced 2025-09-07 09:09:26 +00:00
rework of FSM + 0.8.0
This commit is contained in:
@@ -5,21 +5,21 @@ import dev.inmo.micro_utils.fsm.common.managers.DefaultStatesManagerRepo
|
||||
import dev.inmo.micro_utils.repos.*
|
||||
import dev.inmo.micro_utils.repos.pagination.getAll
|
||||
|
||||
class KeyValueBasedDefaultStatesManagerRepo(
|
||||
private val keyValueRepo: KeyValueRepo<Any, State>
|
||||
) : DefaultStatesManagerRepo {
|
||||
override suspend fun set(state: State) {
|
||||
class KeyValueBasedDefaultStatesManagerRepo<T : State>(
|
||||
private val keyValueRepo: KeyValueRepo<Any, T>
|
||||
) : DefaultStatesManagerRepo<T> {
|
||||
override suspend fun set(state: T) {
|
||||
keyValueRepo.set(state.context, state)
|
||||
}
|
||||
|
||||
override suspend fun removeState(state: State) {
|
||||
override suspend fun removeState(state: T) {
|
||||
if (keyValueRepo.get(state.context) == state) {
|
||||
keyValueRepo.unset(state.context)
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun getStates(): List<State> = keyValueRepo.getAll { keys(it) }.map { it.second }
|
||||
override suspend fun getContextState(context: Any): State? = keyValueRepo.get(context)
|
||||
override suspend fun getStates(): List<T> = keyValueRepo.getAll { keys(it) }.map { it.second }
|
||||
override suspend fun getContextState(context: Any): T? = keyValueRepo.get(context)
|
||||
|
||||
override suspend fun contains(context: Any): Boolean = keyValueRepo.contains(context)
|
||||
}
|
||||
|
@@ -1,84 +0,0 @@
|
||||
package dev.inmo.micro_utils.fsm.repos.common
|
||||
|
||||
import dev.inmo.micro_utils.fsm.common.State
|
||||
import dev.inmo.micro_utils.fsm.common.StatesManager
|
||||
import dev.inmo.micro_utils.repos.*
|
||||
import dev.inmo.micro_utils.repos.mappers.withMapper
|
||||
import dev.inmo.micro_utils.repos.pagination.getAll
|
||||
import kotlinx.coroutines.flow.*
|
||||
import kotlinx.coroutines.sync.Mutex
|
||||
import kotlinx.coroutines.sync.withLock
|
||||
|
||||
@Deprecated("Replace with DefaultStatesManager and KeyValueBasedDefaultStatesManagerRepo")
|
||||
class KeyValueBasedStatesManager(
|
||||
private val keyValueRepo: KeyValueRepo<Any, State>,
|
||||
private val onContextsConflictResolver: suspend (old: State, new: State, currentNew: State) -> Boolean = { _, _, _ -> true }
|
||||
) : StatesManager {
|
||||
private val _onChainStateUpdated = MutableSharedFlow<Pair<State, State>>(0)
|
||||
override val onChainStateUpdated: Flow<Pair<State, State>> = _onChainStateUpdated.asSharedFlow()
|
||||
private val _onEndChain = MutableSharedFlow<State>(0)
|
||||
override val onEndChain: Flow<State> = _onEndChain.asSharedFlow()
|
||||
|
||||
override val onStartChain: Flow<State> = keyValueRepo.onNewValue.map { it.second }
|
||||
|
||||
private val mutex = Mutex()
|
||||
|
||||
override suspend fun update(old: State, new: State) {
|
||||
mutex.withLock {
|
||||
when {
|
||||
keyValueRepo.get(old.context) != old -> return@withLock
|
||||
old.context == new.context || !keyValueRepo.contains(new.context) -> {
|
||||
keyValueRepo.set(old.context, new)
|
||||
_onChainStateUpdated.emit(old to new)
|
||||
}
|
||||
else -> {
|
||||
val stateOnNewOneContext = keyValueRepo.get(new.context)!!
|
||||
if (onContextsConflictResolver(old, new, stateOnNewOneContext)) {
|
||||
endChainWithoutLock(stateOnNewOneContext)
|
||||
keyValueRepo.unset(old.context)
|
||||
keyValueRepo.set(new.context, new)
|
||||
_onChainStateUpdated.emit(old to new)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun startChain(state: State) {
|
||||
if (!keyValueRepo.contains(state.context)) {
|
||||
keyValueRepo.set(state.context, state)
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun endChainWithoutLock(state: State) {
|
||||
if (keyValueRepo.get(state.context) == state) {
|
||||
keyValueRepo.unset(state.context)
|
||||
_onEndChain.emit(state)
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun endChain(state: State) {
|
||||
mutex.withLock { endChainWithoutLock(state) }
|
||||
}
|
||||
|
||||
override suspend fun getActiveStates(): List<State> {
|
||||
return keyValueRepo.getAll { keys(it) }.map { it.second }
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
inline fun <reified TargetContextType, reified TargetStateType> createStatesManager(
|
||||
targetKeyValueRepo: KeyValueRepo<TargetContextType, TargetStateType>,
|
||||
noinline contextToOutTransformer: suspend Any.() -> TargetContextType,
|
||||
noinline stateToOutTransformer: suspend State.() -> TargetStateType,
|
||||
noinline outToContextTransformer: suspend TargetContextType.() -> Any,
|
||||
noinline outToStateTransformer: suspend TargetStateType.() -> State,
|
||||
) = KeyValueBasedStatesManager(
|
||||
targetKeyValueRepo.withMapper<Any, State, TargetContextType, TargetStateType>(
|
||||
contextToOutTransformer,
|
||||
stateToOutTransformer,
|
||||
outToContextTransformer,
|
||||
outToStateTransformer
|
||||
)
|
||||
)
|
Reference in New Issue
Block a user