mirror of
https://github.com/InsanusMokrassar/TelegramBotApiLibraries.git
synced 2024-12-23 09:07: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_version=1.5.10
|
||||||
kotlin_serialisation_core_version=1.2.1
|
kotlin_serialisation_core_version=1.2.1
|
||||||
|
kotlin_coroutines_version=1.5.0
|
||||||
|
|
||||||
github_release_plugin_version=2.2.12
|
github_release_plugin_version=2.2.12
|
||||||
|
|
||||||
|
@ -4,7 +4,9 @@ String[] includes = [
|
|||||||
":cache:admins:common",
|
":cache:admins:common",
|
||||||
":cache:admins:micro_utils",
|
":cache:admins:micro_utils",
|
||||||
":cache:admins:plagubot",
|
":cache:admins:plagubot",
|
||||||
":cache:media"
|
":cache:media",
|
||||||
|
|
||||||
|
":fsm:core"
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user