Compare commits

..

9 Commits

7 changed files with 56 additions and 11 deletions

View File

@ -1,5 +1,15 @@
# Changelog # Changelog
## 0.10.5
* `Versions`
* `Compose`: `1.2.0-alpha01-dev683` -> `1.2.0-alpha01-dev686`
* `Repos`
* `Android`:
* New function `SharedPreferencesKeyValueRepo`
* `FSM`
* Add `StateHandlingErrorHandler` and opportunity to handle states handling errors
## 0.10.4 ## 0.10.4
* `Versions`: * `Versions`:

View File

@ -3,6 +3,8 @@ package dev.inmo.micro_utils.fsm.common
import dev.inmo.micro_utils.common.Optional import dev.inmo.micro_utils.common.Optional
import dev.inmo.micro_utils.common.onPresented import dev.inmo.micro_utils.common.onPresented
import dev.inmo.micro_utils.coroutines.* 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.*
import kotlinx.coroutines.sync.Mutex import kotlinx.coroutines.sync.Mutex
import kotlinx.coroutines.sync.withLock import kotlinx.coroutines.sync.withLock
@ -15,11 +17,22 @@ import kotlinx.coroutines.sync.withLock
interface StatesMachine<T : State> : StatesHandler<T, T> { interface StatesMachine<T : State> : StatesHandler<T, T> {
suspend fun launchStateHandling( suspend fun launchStateHandling(
state: T, state: T,
handlers: List<CheckableHandlerHolder<in T, T>> handlers: List<CheckableHandlerHolder<in T, T>>,
onStateHandlingErrorHandler: StateHandlingErrorHandler<T>
): T? { ): T? {
return handlers.firstOrNull { it.checkHandleable(state) } ?.run { return runCatchingSafely {
handlers.firstOrNull { it.checkHandleable(state) } ?.run {
handleState(state) handleState(state)
} }
}.getOrElse {
onStateHandlingErrorHandler(state, it)
}
}
suspend fun launchStateHandling(
state: T,
handlers: List<CheckableHandlerHolder<in T, T>>
): T? {
return launchStateHandling(state, handlers, defaultStateHandlingErrorHandler())
} }
/** /**
@ -38,8 +51,9 @@ interface StatesMachine<T : State> : StatesHandler<T, T> {
*/ */
operator fun <T: State> invoke( operator fun <T: State> invoke(
statesManager: StatesManager<T>, statesManager: StatesManager<T>,
handlers: List<CheckableHandlerHolder<in T, T>> handlers: List<CheckableHandlerHolder<in T, T>>,
) = DefaultStatesMachine(statesManager, handlers) onStateHandlingErrorHandler: StateHandlingErrorHandler<T> = defaultStateHandlingErrorHandler()
) = DefaultStatesMachine(statesManager, handlers, onStateHandlingErrorHandler)
} }
} }
@ -52,12 +66,17 @@ interface StatesMachine<T : State> : StatesHandler<T, T> {
open class DefaultStatesMachine <T: State>( open class DefaultStatesMachine <T: State>(
protected val statesManager: StatesManager<T>, protected val statesManager: StatesManager<T>,
protected val handlers: List<CheckableHandlerHolder<in T, T>>, protected val handlers: List<CheckableHandlerHolder<in T, T>>,
protected val onStateHandlingErrorHandler: StateHandlingErrorHandler<T> = defaultStateHandlingErrorHandler()
) : StatesMachine<T> { ) : StatesMachine<T> {
/** /**
* Will call [launchStateHandling] for state handling * 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)
override suspend fun launchStateHandling(state: T, handlers: List<CheckableHandlerHolder<in T, T>>): T? {
return launchStateHandling(state, handlers, onStateHandlingErrorHandler)
}
/** /**
* This * This
*/ */

View File

@ -1,6 +1,8 @@
package dev.inmo.micro_utils.fsm.common package dev.inmo.micro_utils.fsm.common
import dev.inmo.micro_utils.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.*
import kotlinx.coroutines.sync.withLock import kotlinx.coroutines.sync.withLock
@ -20,9 +22,11 @@ interface UpdatableStatesMachine<T : State> : StatesMachine<T> {
open class DefaultUpdatableStatesMachine<T : State>( open class DefaultUpdatableStatesMachine<T : State>(
statesManager: StatesManager<T>, statesManager: StatesManager<T>,
handlers: List<CheckableHandlerHolder<in T, T>>, handlers: List<CheckableHandlerHolder<in T, T>>,
onStateHandlingErrorHandler: StateHandlingErrorHandler<T> = defaultStateHandlingErrorHandler()
) : DefaultStatesMachine<T>( ) : DefaultStatesMachine<T>(
statesManager, statesManager,
handlers handlers,
onStateHandlingErrorHandler
), UpdatableStatesMachine<T> { ), UpdatableStatesMachine<T> {
protected val jobsStates = mutableMapOf<Job, 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) { override suspend fun performStateUpdate(previousState: Optional<T>, actualState: T, scope: CoroutineScope) {
statesJobsMutex.withLock { statesJobsMutex.withLock {
if (compare(previousState, actualState)) { if (shouldReplaceJob(previousState, actualState)) {
statesJobs[actualState] ?.cancel() statesJobs[actualState] ?.cancel()
} }
val job = previousState.mapOnPresented { val job = previousState.mapOnPresented {

View File

@ -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>

View File

@ -14,5 +14,5 @@ crypto_js_version=4.1.1
# Project data # Project data
group=dev.inmo group=dev.inmo
version=0.10.4 version=0.10.5
android_code_version=119 android_code_version=120

View File

@ -4,7 +4,7 @@ kt = "1.6.21"
kt-serialization = "1.3.3" kt-serialization = "1.3.3"
kt-coroutines = "1.6.1" kt-coroutines = "1.6.1"
jb-compose = "1.2.0-alpha01-dev683" jb-compose = "1.2.0-alpha01-dev686"
jb-exposed = "0.38.2" jb-exposed = "0.38.2"
jb-dokka = "1.6.21" jb-dokka = "1.6.21"
@ -16,7 +16,7 @@ ktor = "2.0.1"
gh-release = "2.3.7" gh-release = "2.3.7"
android-gradle = "7.0.4" android-gradle = "7.0.4"
dexcount = "3.0.1" dexcount = "3.1.0"
android-coreKtx = "1.7.0" android-coreKtx = "1.7.0"
android-recyclerView = "1.2.1" android-recyclerView = "1.2.1"

View File

@ -160,3 +160,9 @@ class KeyValueStore<T : Any> internal constructor (
} }
} }
} }
inline fun <T : Any> SharedPreferencesKeyValueRepo(
context: Context,
name: String = "default",
cacheValues: Boolean = false
) = context.keyValueStore<T>(name, cacheValues)