mirror of
				https://github.com/InsanusMokrassar/MicroUtils.git
				synced 2025-11-03 21:51:59 +00:00 
			
		
		
		
	StateHandlingErrorHandler
This commit is contained in:
		@@ -7,6 +7,8 @@
 | 
			
		||||
* `Repos`
 | 
			
		||||
    * `Android`:
 | 
			
		||||
        * New function `SharedPreferencesKeyValueRepo`
 | 
			
		||||
* `FSM`
 | 
			
		||||
    * Add `StateHandlingErrorHandler` and opportunity to handle states handling errors
 | 
			
		||||
 | 
			
		||||
## 0.10.4
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -3,6 +3,8 @@ package dev.inmo.micro_utils.fsm.common
 | 
			
		||||
import dev.inmo.micro_utils.common.Optional
 | 
			
		||||
import dev.inmo.micro_utils.common.onPresented
 | 
			
		||||
import dev.inmo.micro_utils.coroutines.*
 | 
			
		||||
import dev.inmo.micro_utils.fsm.common.utils.StateHandlingErrorHandler
 | 
			
		||||
import dev.inmo.micro_utils.fsm.common.utils.defaultStateHandlingErrorHandler
 | 
			
		||||
import kotlinx.coroutines.*
 | 
			
		||||
import kotlinx.coroutines.sync.Mutex
 | 
			
		||||
import kotlinx.coroutines.sync.withLock
 | 
			
		||||
@@ -13,13 +15,24 @@ import kotlinx.coroutines.sync.withLock
 | 
			
		||||
 * handling until [start] method will be called
 | 
			
		||||
 */
 | 
			
		||||
interface StatesMachine<T : State> : StatesHandler<T, T> {
 | 
			
		||||
    suspend fun launchStateHandling(
 | 
			
		||||
        state: T,
 | 
			
		||||
        handlers: List<CheckableHandlerHolder<in T, T>>,
 | 
			
		||||
        onStateHandlingErrorHandler: StateHandlingErrorHandler<T>
 | 
			
		||||
    ): T? {
 | 
			
		||||
        return runCatchingSafely {
 | 
			
		||||
            handlers.firstOrNull { it.checkHandleable(state) } ?.run {
 | 
			
		||||
                handleState(state)
 | 
			
		||||
            }
 | 
			
		||||
        }.getOrElse {
 | 
			
		||||
            onStateHandlingErrorHandler(state, it)
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    suspend fun launchStateHandling(
 | 
			
		||||
        state: T,
 | 
			
		||||
        handlers: List<CheckableHandlerHolder<in T, T>>
 | 
			
		||||
    ): T? {
 | 
			
		||||
        return handlers.firstOrNull { it.checkHandleable(state) } ?.run {
 | 
			
		||||
            handleState(state)
 | 
			
		||||
        }
 | 
			
		||||
        return launchStateHandling(state, handlers, defaultStateHandlingErrorHandler())
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
@@ -38,8 +51,9 @@ interface StatesMachine<T : State> : StatesHandler<T, T> {
 | 
			
		||||
         */
 | 
			
		||||
        operator fun <T: State> invoke(
 | 
			
		||||
            statesManager: StatesManager<T>,
 | 
			
		||||
            handlers: List<CheckableHandlerHolder<in T, T>>
 | 
			
		||||
        ) = DefaultStatesMachine(statesManager, handlers)
 | 
			
		||||
            handlers: List<CheckableHandlerHolder<in T, T>>,
 | 
			
		||||
            onStateHandlingErrorHandler: StateHandlingErrorHandler<T> = defaultStateHandlingErrorHandler()
 | 
			
		||||
        ) = DefaultStatesMachine(statesManager, handlers, onStateHandlingErrorHandler)
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -52,11 +66,12 @@ interface StatesMachine<T : State> : StatesHandler<T, T> {
 | 
			
		||||
open class DefaultStatesMachine <T: State>(
 | 
			
		||||
    protected val statesManager: StatesManager<T>,
 | 
			
		||||
    protected val handlers: List<CheckableHandlerHolder<in T, T>>,
 | 
			
		||||
    protected val onStateHandlingErrorHandler: StateHandlingErrorHandler<T> = defaultStateHandlingErrorHandler()
 | 
			
		||||
) : StatesMachine<T> {
 | 
			
		||||
    /**
 | 
			
		||||
     * Will call [launchStateHandling] for state handling
 | 
			
		||||
     */
 | 
			
		||||
    override suspend fun StatesMachine<in T>.handleState(state: T): T? = launchStateHandling(state, handlers)
 | 
			
		||||
    override suspend fun StatesMachine<in T>.handleState(state: T): T? = launchStateHandling(state, handlers, onStateHandlingErrorHandler)
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * This
 | 
			
		||||
@@ -65,7 +80,7 @@ open class DefaultStatesMachine <T: State>(
 | 
			
		||||
    protected val statesJobsMutex = Mutex()
 | 
			
		||||
 | 
			
		||||
    protected open suspend fun performUpdate(state: T) {
 | 
			
		||||
        val newState = launchStateHandling(state, handlers)
 | 
			
		||||
        val newState = launchStateHandling(state, handlers, onStateHandlingErrorHandler)
 | 
			
		||||
        if (newState != null) {
 | 
			
		||||
            statesManager.update(state, newState)
 | 
			
		||||
        } else {
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,8 @@
 | 
			
		||||
package dev.inmo.micro_utils.fsm.common
 | 
			
		||||
 | 
			
		||||
import dev.inmo.micro_utils.common.*
 | 
			
		||||
import dev.inmo.micro_utils.fsm.common.utils.StateHandlingErrorHandler
 | 
			
		||||
import dev.inmo.micro_utils.fsm.common.utils.defaultStateHandlingErrorHandler
 | 
			
		||||
import kotlinx.coroutines.*
 | 
			
		||||
import kotlinx.coroutines.sync.withLock
 | 
			
		||||
 | 
			
		||||
@@ -20,9 +22,11 @@ interface UpdatableStatesMachine<T : State> : StatesMachine<T> {
 | 
			
		||||
open class DefaultUpdatableStatesMachine<T : State>(
 | 
			
		||||
    statesManager: StatesManager<T>,
 | 
			
		||||
    handlers: List<CheckableHandlerHolder<in T, T>>,
 | 
			
		||||
    onStateHandlingErrorHandler: StateHandlingErrorHandler<T> = defaultStateHandlingErrorHandler()
 | 
			
		||||
) : DefaultStatesMachine<T>(
 | 
			
		||||
    statesManager,
 | 
			
		||||
    handlers
 | 
			
		||||
    handlers,
 | 
			
		||||
    onStateHandlingErrorHandler
 | 
			
		||||
), UpdatableStatesMachine<T> {
 | 
			
		||||
    protected val jobsStates = mutableMapOf<Job, T>()
 | 
			
		||||
 | 
			
		||||
@@ -34,7 +38,7 @@ open class DefaultUpdatableStatesMachine<T : State>(
 | 
			
		||||
     */
 | 
			
		||||
    override suspend fun performStateUpdate(previousState: Optional<T>, actualState: T, scope: CoroutineScope) {
 | 
			
		||||
        statesJobsMutex.withLock {
 | 
			
		||||
            if (compare(previousState, actualState)) {
 | 
			
		||||
            if (shouldReplaceJob(previousState, actualState)) {
 | 
			
		||||
                statesJobs[actualState] ?.cancel()
 | 
			
		||||
            }
 | 
			
		||||
            val job = previousState.mapOnPresented {
 | 
			
		||||
 
 | 
			
		||||
@@ -0,0 +1,6 @@
 | 
			
		||||
package dev.inmo.micro_utils.fsm.common.utils
 | 
			
		||||
 | 
			
		||||
typealias StateHandlingErrorHandler<T> = suspend (T, Throwable) -> T?
 | 
			
		||||
val DefaultStateHandlingErrorHandler: StateHandlingErrorHandler<*> = { _, _ -> null }
 | 
			
		||||
inline fun <T> defaultStateHandlingErrorHandler(): StateHandlingErrorHandler<T> = DefaultStateHandlingErrorHandler as StateHandlingErrorHandler<T>
 | 
			
		||||
 | 
			
		||||
		Reference in New Issue
	
	Block a user