1
0
mirror of https://github.com/InsanusMokrassar/TelegramBotAPI.git synced 2024-11-22 16:23:48 +00:00

start migrate fsm part

This commit is contained in:
InsanusMokrassar 2021-11-06 21:21:49 +06:00
parent c5bf9ab1a2
commit 20b1645935
5 changed files with 76 additions and 69 deletions

View File

@ -10,16 +10,6 @@ import kotlinx.coroutines.*
import kotlinx.coroutines.channels.BufferOverflow import kotlinx.coroutines.channels.BufferOverflow
import kotlinx.coroutines.flow.* import kotlinx.coroutines.flow.*
private suspend fun <I : State> BehaviourContextWithFSM.launchStateHandling(
state: State,
contextUpdatesFlow: Flow<Update>,
handlers: List<BehaviourWithFSMStateHandlerHolder<out I>>
): State? {
return handlers.firstOrNull { it.checkHandleable(state) } ?.run {
handleState(contextUpdatesFlow, state)
}
}
/** /**
* Interface which combine [BehaviourContext] and [StatesMachine]. Subcontext of triggers and states contexts must have * Interface which combine [BehaviourContext] and [StatesMachine]. Subcontext of triggers and states contexts must have
* one common flow of updates and must not lose updates between updates * one common flow of updates and must not lose updates between updates
@ -27,9 +17,19 @@ private suspend fun <I : State> BehaviourContextWithFSM.launchStateHandling(
* @see DefaultBehaviourContextWithFSM * @see DefaultBehaviourContextWithFSM
* @see buildBehaviourWithFSM * @see buildBehaviourWithFSM
*/ */
interface BehaviourContextWithFSM : BehaviourContext, StatesMachine { interface BehaviourContextWithFSM<T : State> : BehaviourContext, StatesMachine<T> {
suspend fun start() = start(this) suspend fun start() = start(this)
suspend fun launchStateHandling(
state: T,
contextUpdatesFlow: Flow<Update>,
handlers: List<BehaviourWithFSMStateHandlerHolder<*, T>>
): T? {
return handlers.firstOrNull { it.checkHandleable(state) } ?.run {
handleState(contextUpdatesFlow, state)
}
}
override fun copy( override fun copy(
bot: TelegramBot, bot: TelegramBot,
scope: CoroutineScope, scope: CoroutineScope,
@ -37,14 +37,14 @@ interface BehaviourContextWithFSM : BehaviourContext, StatesMachine {
onBufferOverflow: BufferOverflow, onBufferOverflow: BufferOverflow,
upstreamUpdatesFlow: Flow<Update>?, upstreamUpdatesFlow: Flow<Update>?,
updatesFilter: BehaviourContextAndTypeReceiver<Boolean, Update>? updatesFilter: BehaviourContextAndTypeReceiver<Boolean, Update>?
): BehaviourContextWithFSM ): BehaviourContextWithFSM<T>
companion object { companion object {
operator fun invoke( operator fun <T : State> invoke(
behaviourContext: BehaviourContext, behaviourContext: BehaviourContext,
handlers: List<BehaviourWithFSMStateHandlerHolder<*>>, handlers: List<BehaviourWithFSMStateHandlerHolder<*, T>>,
statesManager: StatesManager statesManager: StatesManager<T>
) = DefaultBehaviourContextWithFSM(behaviourContext, statesManager, handlers) ) = DefaultBehaviourContextWithFSM<T>(behaviourContext, statesManager, handlers)
} }
} }
@ -52,23 +52,24 @@ interface BehaviourContextWithFSM : BehaviourContext, StatesMachine {
* Default realization of [BehaviourContextWithFSM]. It uses [behaviourContext] as a base for this object as * Default realization of [BehaviourContextWithFSM]. It uses [behaviourContext] as a base for this object as
* [BehaviourContext], but managing substates contexts updates for avoiding of updates lost between states * [BehaviourContext], but managing substates contexts updates for avoiding of updates lost between states
*/ */
class DefaultBehaviourContextWithFSM( class DefaultBehaviourContextWithFSM<T : State>(
private val behaviourContext: BehaviourContext, private val behaviourContext: BehaviourContext,
private val statesManager: StatesManager, private val statesManager: StatesManager<T>,
private val handlers: List<BehaviourWithFSMStateHandlerHolder<*>> private val handlers: List<BehaviourWithFSMStateHandlerHolder<*, T>>
) : BehaviourContext by behaviourContext, BehaviourContextWithFSM { ) : BehaviourContext by behaviourContext, BehaviourContextWithFSM<T> {
private val updatesFlows = mutableMapOf<Any, Flow<Update>>() private val updatesFlows = mutableMapOf<Any, Flow<Update>>()
private fun getContextUpdatesFlow(context: Any) = updatesFlows.getOrPut(context) { private fun getContextUpdatesFlow(context: Any) = updatesFlows.getOrPut(context) {
allUpdatesFlow.accumulatorFlow(scope) allUpdatesFlow.accumulatorFlow(scope)
} }
override suspend fun StatesMachine.handleState(state: State): State? = launchStateHandling(
override suspend fun StatesMachine<in T>.handleState(state: T): T? = launchStateHandling(
state, state,
allUpdatesFlow, allUpdatesFlow,
handlers handlers
) )
override fun start(scope: CoroutineScope): Job = scope.launchSafelyWithoutExceptions { override fun start(scope: CoroutineScope): Job = scope.launchSafelyWithoutExceptions {
val statePerformer: suspend (State) -> Unit = { state: State -> val statePerformer: suspend (T) -> Unit = { state: T ->
val newState = launchStateHandling(state, getContextUpdatesFlow(state.context), handlers) val newState = launchStateHandling(state, getContextUpdatesFlow(state.context), handlers)
if (newState != null) { if (newState != null) {
statesManager.update(state, newState) statesManager.update(state, newState)
@ -94,7 +95,7 @@ class DefaultBehaviourContextWithFSM(
} }
} }
override suspend fun startChain(state: State) { override suspend fun startChain(state: T) {
statesManager.startChain(state) statesManager.startChain(state)
} }
@ -105,7 +106,7 @@ class DefaultBehaviourContextWithFSM(
onBufferOverflow: BufferOverflow, onBufferOverflow: BufferOverflow,
upstreamUpdatesFlow: Flow<Update>?, upstreamUpdatesFlow: Flow<Update>?,
updatesFilter: BehaviourContextAndTypeReceiver<Boolean, Update>? updatesFilter: BehaviourContextAndTypeReceiver<Boolean, Update>?
): BehaviourContextWithFSM = BehaviourContextWithFSM( ): BehaviourContextWithFSM<T> = BehaviourContextWithFSM(
behaviourContext.copy(bot, scope, broadcastChannelsSize, onBufferOverflow, upstreamUpdatesFlow, updatesFilter), behaviourContext.copy(bot, scope, broadcastChannelsSize, onBufferOverflow, upstreamUpdatesFlow, updatesFilter),
handlers, handlers,
statesManager statesManager

View File

@ -14,14 +14,14 @@ import kotlinx.coroutines.*
import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.Flow
import kotlin.reflect.KClass import kotlin.reflect.KClass
class BehaviourContextWithFSMBuilder internal constructor( class BehaviourContextWithFSMBuilder<T : State> internal constructor(
private val resultBehaviourContext: BehaviourContextWithFSM, private val resultBehaviourContext: BehaviourContextWithFSM<T>,
private val handlers: MutableList<BehaviourWithFSMStateHandlerHolder<*>> private val handlers: MutableList<BehaviourWithFSMStateHandlerHolder<*, T>>
) : BehaviourContextWithFSM by resultBehaviourContext { ) : BehaviourContextWithFSM<T> by resultBehaviourContext {
internal constructor( internal constructor(
baseBehaviourContext: BehaviourContext, baseBehaviourContext: BehaviourContext,
statesManager: StatesManager = DefaultStatesManager(InMemoryDefaultStatesManagerRepo()), statesManager: StatesManager<T> = DefaultStatesManager(InMemoryDefaultStatesManagerRepo()),
handlers: MutableList<BehaviourWithFSMStateHandlerHolder<*>> = mutableListOf() handlers: MutableList<BehaviourWithFSMStateHandlerHolder<*, T>> = mutableListOf()
) : this(DefaultBehaviourContextWithFSM(baseBehaviourContext, statesManager, handlers), handlers) ) : this(DefaultBehaviourContextWithFSM(baseBehaviourContext, statesManager, handlers), handlers)
/** /**
@ -31,7 +31,7 @@ class BehaviourContextWithFSMBuilder internal constructor(
* @see BehaviourWithFSMStateHandlerHolder * @see BehaviourWithFSMStateHandlerHolder
* @see onStateOrSubstate * @see onStateOrSubstate
*/ */
fun <I : State> add(kClass: KClass<I>, handler: BehaviourWithFSMStateHandler<I>) { fun <I : T> add(kClass: KClass<I>, handler: BehaviourWithFSMStateHandler<I, T>) {
handlers.add(BehaviourWithFSMStateHandlerHolder(kClass, false, handler)) handlers.add(BehaviourWithFSMStateHandlerHolder(kClass, false, handler))
} }
@ -43,7 +43,7 @@ class BehaviourContextWithFSMBuilder internal constructor(
* @see BehaviourWithFSMStateHandlerHolder * @see BehaviourWithFSMStateHandlerHolder
* @see strictlyOn * @see strictlyOn
*/ */
fun <I : State> addStrict(kClass: KClass<I>, handler: BehaviourWithFSMStateHandler<I>) { fun <I : T> addStrict(kClass: KClass<I>, handler: BehaviourWithFSMStateHandler<I, T>) {
handlers.add(BehaviourWithFSMStateHandlerHolder(kClass, true, handler)) handlers.add(BehaviourWithFSMStateHandlerHolder(kClass, true, handler))
} }
@ -56,7 +56,7 @@ class BehaviourContextWithFSMBuilder internal constructor(
* @see BehaviourContextWithFSMBuilder.add * @see BehaviourContextWithFSMBuilder.add
*/ */
@Suppress("MemberVisibilityCanBePrivate") @Suppress("MemberVisibilityCanBePrivate")
inline fun <reified I : State> onStateOrSubstate(handler: BehaviourWithFSMStateHandler<I>) { inline fun <reified I : T> onStateOrSubstate(handler: BehaviourWithFSMStateHandler<I, T>) {
add(I::class, handler) add(I::class, handler)
} }
@ -69,7 +69,7 @@ class BehaviourContextWithFSMBuilder internal constructor(
* @see BehaviourContextWithFSMBuilder.addStrict * @see BehaviourContextWithFSMBuilder.addStrict
*/ */
@Suppress("MemberVisibilityCanBePrivate") @Suppress("MemberVisibilityCanBePrivate")
inline fun <reified I : State> strictlyOn(handler: BehaviourWithFSMStateHandler<I>) { inline fun <reified I : T> strictlyOn(handler: BehaviourWithFSMStateHandler<I, T>) {
addStrict(I::class, handler) addStrict(I::class, handler)
} }
@ -89,14 +89,14 @@ class BehaviourContextWithFSMBuilder internal constructor(
* start any updates retrieving. See [buildBehaviourWithFSMAndStartLongPolling] or * start any updates retrieving. See [buildBehaviourWithFSMAndStartLongPolling] or
* [telegramBotWithBehaviourAndFSMAndStartLongPolling] in case you wish to start [longPolling] automatically * [telegramBotWithBehaviourAndFSMAndStartLongPolling] in case you wish to start [longPolling] automatically
*/ */
suspend fun TelegramBot.buildBehaviourWithFSM( suspend fun <T : State> TelegramBot.buildBehaviourWithFSM(
upstreamUpdatesFlow: Flow<Update>? = null, upstreamUpdatesFlow: Flow<Update>? = null,
scope: CoroutineScope = defaultCoroutineScopeProvider(), scope: CoroutineScope = defaultCoroutineScopeProvider(),
defaultExceptionsHandler: ExceptionHandler<Unit>? = null, defaultExceptionsHandler: ExceptionHandler<Unit>? = null,
statesManager: StatesManager = DefaultStatesManager(InMemoryDefaultStatesManagerRepo()), statesManager: StatesManager<T> = DefaultStatesManager(InMemoryDefaultStatesManagerRepo()),
presetHandlers: MutableList<BehaviourWithFSMStateHandlerHolder<*>> = mutableListOf(), presetHandlers: MutableList<BehaviourWithFSMStateHandlerHolder<*, T>> = mutableListOf(),
block: CustomBehaviourContextReceiver<BehaviourContextWithFSMBuilder, Unit> block: CustomBehaviourContextReceiver<BehaviourContextWithFSMBuilder<T>, Unit>
): BehaviourContextWithFSM = BehaviourContextWithFSMBuilder( ): BehaviourContextWithFSM<T> = BehaviourContextWithFSMBuilder(
DefaultBehaviourContext( DefaultBehaviourContext(
this, this,
defaultExceptionsHandler ?.let { scope + ContextSafelyExceptionHandler(it) } ?: scope, defaultExceptionsHandler ?.let { scope + ContextSafelyExceptionHandler(it) } ?: scope,
@ -111,14 +111,14 @@ suspend fun TelegramBot.buildBehaviourWithFSM(
* using [longPolling]. For [longPolling] will be used result [BehaviourContextWithFSM] for both parameters * using [longPolling]. For [longPolling] will be used result [BehaviourContextWithFSM] for both parameters
* flowsUpdatesFilter and scope * flowsUpdatesFilter and scope
*/ */
suspend fun TelegramBot.buildBehaviourWithFSMAndStartLongPolling( suspend fun <T : State> TelegramBot.buildBehaviourWithFSMAndStartLongPolling(
upstreamUpdatesFlow: Flow<Update>? = null, upstreamUpdatesFlow: Flow<Update>? = null,
scope: CoroutineScope = defaultCoroutineScopeProvider(), scope: CoroutineScope = defaultCoroutineScopeProvider(),
defaultExceptionsHandler: ExceptionHandler<Unit>? = null, defaultExceptionsHandler: ExceptionHandler<Unit>? = null,
statesManager: StatesManager = DefaultStatesManager(InMemoryDefaultStatesManagerRepo()), statesManager: StatesManager<T> = DefaultStatesManager(InMemoryDefaultStatesManagerRepo()),
presetHandlers: MutableList<BehaviourWithFSMStateHandlerHolder<*>> = mutableListOf(), presetHandlers: MutableList<BehaviourWithFSMStateHandlerHolder<*, T>> = mutableListOf(),
block: CustomBehaviourContextReceiver<BehaviourContextWithFSMBuilder, Unit> block: CustomBehaviourContextReceiver<BehaviourContextWithFSMBuilder<T>, Unit>
): Pair<BehaviourContextWithFSM, Job> = buildBehaviourWithFSM( ): Pair<BehaviourContextWithFSM<T>, Job> = buildBehaviourWithFSM(
upstreamUpdatesFlow, upstreamUpdatesFlow,
scope, scope,
defaultExceptionsHandler, defaultExceptionsHandler,
@ -151,14 +151,14 @@ suspend fun TelegramBot.buildBehaviourWithFSMAndStartLongPolling(
* @see BehaviourContextWithFSMBuilder.onStateOrSubstate * @see BehaviourContextWithFSMBuilder.onStateOrSubstate
*/ */
@PreviewFeature @PreviewFeature
suspend fun TelegramBot.buildBehaviourWithFSM( suspend fun <T : State> TelegramBot.buildBehaviourWithFSM(
flowUpdatesFilter: FlowsUpdatesFilter, flowUpdatesFilter: FlowsUpdatesFilter,
scope: CoroutineScope = defaultCoroutineScopeProvider(), scope: CoroutineScope = defaultCoroutineScopeProvider(),
defaultExceptionsHandler: ExceptionHandler<Unit>? = null, defaultExceptionsHandler: ExceptionHandler<Unit>? = null,
statesManager: StatesManager = DefaultStatesManager(InMemoryDefaultStatesManagerRepo()), statesManager: StatesManager<T> = DefaultStatesManager(InMemoryDefaultStatesManagerRepo()),
presetHandlers: MutableList<BehaviourWithFSMStateHandlerHolder<*>> = mutableListOf(), presetHandlers: MutableList<BehaviourWithFSMStateHandlerHolder<*, T>> = mutableListOf(),
block: CustomBehaviourContextReceiver<BehaviourContextWithFSMBuilder, Unit> block: CustomBehaviourContextReceiver<BehaviourContextWithFSMBuilder<T>, Unit>
): BehaviourContextWithFSM = BehaviourContextWithFSMBuilder( ): BehaviourContextWithFSM<T> = BehaviourContextWithFSMBuilder(
DefaultBehaviourContext( DefaultBehaviourContext(
this, this,
defaultExceptionsHandler ?.let { scope + ContextSafelyExceptionHandler(it) } ?: scope, defaultExceptionsHandler ?.let { scope + ContextSafelyExceptionHandler(it) } ?: scope,
@ -180,12 +180,12 @@ suspend fun TelegramBot.buildBehaviourWithFSM(
* @see BehaviourContextWithFSMBuilder.onStateOrSubstate * @see BehaviourContextWithFSMBuilder.onStateOrSubstate
*/ */
@PreviewFeature @PreviewFeature
suspend fun TelegramBot.buildBehaviourWithFSMAndStartLongPolling( suspend fun <T : State> TelegramBot.buildBehaviourWithFSMAndStartLongPolling(
scope: CoroutineScope = defaultCoroutineScopeProvider(), scope: CoroutineScope = defaultCoroutineScopeProvider(),
defaultExceptionsHandler: ExceptionHandler<Unit>? = null, defaultExceptionsHandler: ExceptionHandler<Unit>? = null,
statesManager: StatesManager = DefaultStatesManager(InMemoryDefaultStatesManagerRepo()), statesManager: StatesManager<T> = DefaultStatesManager(InMemoryDefaultStatesManagerRepo()),
presetHandlers: MutableList<BehaviourWithFSMStateHandlerHolder<*>> = mutableListOf(), presetHandlers: MutableList<BehaviourWithFSMStateHandlerHolder<*, T>> = mutableListOf(),
block: CustomBehaviourContextReceiver<BehaviourContextWithFSMBuilder, Unit> block: CustomBehaviourContextReceiver<BehaviourContextWithFSMBuilder<T>, Unit>
) = FlowsUpdatesFilter().let { ) = FlowsUpdatesFilter().let {
buildBehaviourWithFSM( buildBehaviourWithFSM(
it, it,

View File

@ -2,6 +2,6 @@ package dev.inmo.tgbotapi.extensions.behaviour_builder
import dev.inmo.micro_utils.fsm.common.* import dev.inmo.micro_utils.fsm.common.*
fun interface BehaviourWithFSMStateHandler<T : State> { fun interface BehaviourWithFSMStateHandler<I : O, O : State> {
suspend fun BehaviourContextWithFSM.handleState(state: T): State? suspend fun BehaviourContextWithFSM<in O>.handleState(state: I): O?
} }

View File

@ -19,10 +19,10 @@ import kotlin.reflect.KClass
* @param delegateTo This handler will be called in case [checkHandleable] returns true with class caster incoming * @param delegateTo This handler will be called in case [checkHandleable] returns true with class caster incoming
* [State] in [handleState] * [State] in [handleState]
*/ */
class BehaviourWithFSMStateHandlerHolder<I : State>( class BehaviourWithFSMStateHandlerHolder<I : O, O : State>(
private val inputKlass: KClass<I>, private val inputKlass: KClass<I>,
private val strict: Boolean = false, private val strict: Boolean = false,
private val delegateTo: BehaviourWithFSMStateHandler<I> private val delegateTo: BehaviourWithFSMStateHandler<I, O>
) { ) {
/** /**
* Check ability of [delegateTo] to handle this [state] * Check ability of [delegateTo] to handle this [state]
@ -30,7 +30,7 @@ class BehaviourWithFSMStateHandlerHolder<I : State>(
* @return When [state]::class exactly equals to [inputKlass] will always return true. Otherwise when [strict] * @return When [state]::class exactly equals to [inputKlass] will always return true. Otherwise when [strict]
* mode is disabled, will be used [KClass.isInstance] of [inputKlass] for checking * mode is disabled, will be used [KClass.isInstance] of [inputKlass] for checking
*/ */
fun checkHandleable(state: State) = state::class == inputKlass || (!strict && inputKlass.isInstance(state)) fun checkHandleable(state: O): Boolean = state::class == inputKlass || (!strict && inputKlass.isInstance(state))
/** /**
* Handling of state :) * Handling of state :)
@ -38,10 +38,10 @@ class BehaviourWithFSMStateHandlerHolder<I : State>(
* @param contextUpdatesFlow This [Flow] will be used as source of updates. By contract, this [Flow] must be common * @param contextUpdatesFlow This [Flow] will be used as source of updates. By contract, this [Flow] must be common
* for all [State]s of incoming [state] [State.context] and for the whole chain inside of [BehaviourContextWithFSM] * for all [State]s of incoming [state] [State.context] and for the whole chain inside of [BehaviourContextWithFSM]
*/ */
suspend fun BehaviourContextWithFSM.handleState( suspend fun BehaviourContextWithFSM<in O>.handleState(
contextUpdatesFlow: Flow<Update>, contextUpdatesFlow: Flow<Update>,
state: State state: O
): State? { ): O? {
val subscope = scope.LinkedSupervisorScope() val subscope = scope.LinkedSupervisorScope()
return with(copy(scope = subscope, upstreamUpdatesFlow = contextUpdatesFlow)) { return with(copy(scope = subscope, upstreamUpdatesFlow = contextUpdatesFlow)) {
with(delegateTo) { with(delegateTo) {
@ -50,3 +50,8 @@ class BehaviourWithFSMStateHandlerHolder<I : State>(
} }
} }
} }
inline fun <reified I : O, O : State> BehaviourWithFSMStateHandlerHolder(
strict: Boolean = false,
delegateTo: BehaviourWithFSMStateHandler<I, O>
) = BehaviourWithFSMStateHandlerHolder(I::class, strict, delegateTo)

View File

@ -1,6 +1,7 @@
package dev.inmo.tgbotapi.extensions.behaviour_builder package dev.inmo.tgbotapi.extensions.behaviour_builder
import dev.inmo.micro_utils.coroutines.ExceptionHandler import dev.inmo.micro_utils.coroutines.ExceptionHandler
import dev.inmo.micro_utils.fsm.common.State
import dev.inmo.micro_utils.fsm.common.StatesManager import dev.inmo.micro_utils.fsm.common.StatesManager
import dev.inmo.micro_utils.fsm.common.managers.DefaultStatesManager import dev.inmo.micro_utils.fsm.common.managers.DefaultStatesManager
import dev.inmo.micro_utils.fsm.common.managers.InMemoryDefaultStatesManagerRepo import dev.inmo.micro_utils.fsm.common.managers.InMemoryDefaultStatesManagerRepo
@ -28,16 +29,16 @@ import kotlin.coroutines.coroutineContext
* @see [buildBehaviourWithFSM] * @see [buildBehaviourWithFSM]
* @see startGettingOfUpdatesByLongPolling * @see startGettingOfUpdatesByLongPolling
*/ */
suspend fun telegramBotWithBehaviourAndFSM( suspend fun <T : State> telegramBotWithBehaviourAndFSM(
token: String, token: String,
flowsUpdatesFilter: FlowsUpdatesFilter, flowsUpdatesFilter: FlowsUpdatesFilter,
scope: CoroutineScope? = null, scope: CoroutineScope? = null,
apiUrl: String = telegramBotAPIDefaultUrl, apiUrl: String = telegramBotAPIDefaultUrl,
builder: KtorRequestsExecutorBuilder.() -> Unit = {}, builder: KtorRequestsExecutorBuilder.() -> Unit = {},
defaultExceptionsHandler: ExceptionHandler<Unit>? = null, defaultExceptionsHandler: ExceptionHandler<Unit>? = null,
statesManager: StatesManager = DefaultStatesManager(InMemoryDefaultStatesManagerRepo()), statesManager: StatesManager<T> = DefaultStatesManager(InMemoryDefaultStatesManagerRepo()),
presetHandlers: MutableList<BehaviourWithFSMStateHandlerHolder<*>> = mutableListOf(), presetHandlers: MutableList<BehaviourWithFSMStateHandlerHolder<*, T>> = mutableListOf(),
block: CustomBehaviourContextReceiver<BehaviourContextWithFSMBuilder, Unit> block: CustomBehaviourContextReceiver<BehaviourContextWithFSMBuilder<T>, Unit>
): TelegramBot = telegramBot( ): TelegramBot = telegramBot(
token, token,
apiUrl, apiUrl,
@ -64,15 +65,15 @@ suspend fun telegramBotWithBehaviourAndFSM(
* @see buildBehaviourWithFSMAndStartLongPolling * @see buildBehaviourWithFSMAndStartLongPolling
* @see startGettingOfUpdatesByLongPolling * @see startGettingOfUpdatesByLongPolling
*/ */
suspend fun telegramBotWithBehaviourAndFSMAndStartLongPolling( suspend fun <T : State> telegramBotWithBehaviourAndFSMAndStartLongPolling(
token: String, token: String,
scope: CoroutineScope? = null, scope: CoroutineScope? = null,
apiUrl: String = telegramBotAPIDefaultUrl, apiUrl: String = telegramBotAPIDefaultUrl,
builder: KtorRequestsExecutorBuilder.() -> Unit = {}, builder: KtorRequestsExecutorBuilder.() -> Unit = {},
defaultExceptionsHandler: ExceptionHandler<Unit>? = null, defaultExceptionsHandler: ExceptionHandler<Unit>? = null,
statesManager: StatesManager = DefaultStatesManager(InMemoryDefaultStatesManagerRepo()), statesManager: StatesManager<T> = DefaultStatesManager(InMemoryDefaultStatesManagerRepo()),
presetHandlers: MutableList<BehaviourWithFSMStateHandlerHolder<*>> = mutableListOf(), presetHandlers: MutableList<BehaviourWithFSMStateHandlerHolder<*, T>> = mutableListOf(),
block: CustomBehaviourContextReceiver<BehaviourContextWithFSMBuilder, Unit> block: CustomBehaviourContextReceiver<BehaviourContextWithFSMBuilder<T>, Unit>
): Pair<TelegramBot, Job> { ): Pair<TelegramBot, Job> {
return telegramBot( return telegramBot(
token, token,