mirror of
https://github.com/InsanusMokrassar/TelegramBotApiLibraries.git
synced 2024-12-23 00:57:16 +00:00
start working with fsm
This commit is contained in:
parent
7ac8effb5f
commit
f04f065ac5
17
fsm/core/build.gradle
Normal file
17
fsm/core/build.gradle
Normal file
@ -0,0 +1,17 @@
|
||||
plugins {
|
||||
id "org.jetbrains.kotlin.multiplatform"
|
||||
id "org.jetbrains.kotlin.plugin.serialization"
|
||||
id "com.android.library"
|
||||
}
|
||||
|
||||
apply from: "$mppProjectWithSerializationPresetPath"
|
||||
|
||||
kotlin {
|
||||
sourceSets {
|
||||
commonMain {
|
||||
dependencies {
|
||||
api "dev.inmo:micro_utils.coroutines:$micro_utils_version"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,17 @@
|
||||
package dev.inmo.tgbotapi.libraries.fsm.core
|
||||
|
||||
sealed interface State {
|
||||
val context: Any
|
||||
}
|
||||
|
||||
/**
|
||||
* Use this state as parent of your state in case you want to avoid saving of this state in queue for [context] if this
|
||||
* queue is not empty
|
||||
*/
|
||||
interface ImmediateOrNeverState : State
|
||||
|
||||
/**
|
||||
* Use this state as parent of your state in case you want to keep saving of this state in queue for [context] if this
|
||||
* queue is not empty
|
||||
*/
|
||||
interface QueueableState : State
|
@ -0,0 +1,15 @@
|
||||
package dev.inmo.tgbotapi.libraries.fsm.core
|
||||
|
||||
import kotlin.reflect.KClass
|
||||
|
||||
class StateHandlerHolder<I : State, O : State>(
|
||||
private val inputKlass: KClass<I>,
|
||||
private val delegateTo: StatesHandler<I, O>,
|
||||
private val strict: Boolean = false
|
||||
) : StatesHandler<State, O> {
|
||||
fun checkHandleable(state: State) = state::class == inputKlass || (!strict && inputKlass.isInstance(state))
|
||||
|
||||
override suspend fun handleState(state: State): O? {
|
||||
return delegateTo.handleState(state as I)
|
||||
}
|
||||
}
|
@ -0,0 +1,5 @@
|
||||
package dev.inmo.tgbotapi.libraries.fsm.core
|
||||
|
||||
fun interface StatesHandler<I : State, O : State> {
|
||||
suspend fun handleState(state: I): O?
|
||||
}
|
@ -0,0 +1,37 @@
|
||||
package dev.inmo.tgbotapi.libraries.fsm.core
|
||||
|
||||
import dev.inmo.micro_utils.coroutines.*
|
||||
import kotlinx.coroutines.*
|
||||
import kotlinx.coroutines.flow.asFlow
|
||||
|
||||
private suspend fun <I : State, O : State> launchStateHandling(
|
||||
state: State,
|
||||
handlers: List<StateHandlerHolder<out I, out O>>
|
||||
): O? {
|
||||
return handlers.firstOrNull { it.checkHandleable(state) } ?.handleState(
|
||||
state
|
||||
)
|
||||
}
|
||||
|
||||
class StatesMachine<T : State, I : T, O : T>(
|
||||
private val statesRepo: StatesRepo<T>,
|
||||
private val statesQuotaManager: StatesQuotaManager,
|
||||
private val handlers: List<StateHandlerHolder<out I, out O>>
|
||||
) : StatesHandler<T, O> {
|
||||
override suspend fun handleState(state: T): O? {
|
||||
return statesQuotaManager.doOnQuota(
|
||||
state
|
||||
) {
|
||||
launchStateHandling(state, handlers)
|
||||
}
|
||||
}
|
||||
|
||||
fun start(scope: CoroutineScope): Job = scope.launchSafelyWithoutExceptions {
|
||||
val statesFlow = statesRepo.loadStates().asFlow() + statesRepo.onNewState
|
||||
statesFlow.subscribeSafelyWithoutExceptions(this) {
|
||||
val newState = handleState(it)
|
||||
newState ?.also { statesRepo.saveState(newState) }
|
||||
statesRepo.removeState(it)
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,5 @@
|
||||
package dev.inmo.tgbotapi.libraries.fsm.core
|
||||
|
||||
interface StatesQuotaManager {
|
||||
suspend fun <T : State, O : State> doOnQuota(state: T, block: suspend (T) -> O?): O?
|
||||
}
|
@ -0,0 +1,12 @@
|
||||
package dev.inmo.tgbotapi.libraries.fsm.core
|
||||
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
|
||||
interface StatesRepo<T : State> {
|
||||
val onNewState: Flow<T>
|
||||
val onStateRemoved: Flow<T>
|
||||
|
||||
suspend fun saveState(state: T)
|
||||
suspend fun removeState(state: T)
|
||||
suspend fun loadStates(): List<T>
|
||||
}
|
1
fsm/core/src/main/AndroidManifest.xml
Normal file
1
fsm/core/src/main/AndroidManifest.xml
Normal file
@ -0,0 +1 @@
|
||||
<manifest package="dev.inmo.tgbotapi.libraries.fsm.core"/>
|
@ -8,6 +8,7 @@ android.enableJetifier=true
|
||||
|
||||
kotlin_version=1.5.10
|
||||
kotlin_serialisation_core_version=1.2.1
|
||||
kotlin_coroutines_version=1.5.0
|
||||
|
||||
github_release_plugin_version=2.2.12
|
||||
|
||||
|
@ -4,7 +4,9 @@ String[] includes = [
|
||||
":cache:admins:common",
|
||||
":cache:admins:micro_utils",
|
||||
":cache:admins:plagubot",
|
||||
":cache:media"
|
||||
":cache:media",
|
||||
|
||||
":fsm:core"
|
||||
]
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user