From 32451f4e1cd142072089fb7ffbf7e1116a366dbb Mon Sep 17 00:00:00 2001 From: InsanusMokrassar Date: Tue, 3 May 2022 09:44:39 +0600 Subject: [PATCH 1/9] start 0.38.19 --- CHANGELOG.md | 2 ++ gradle.properties | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9f05e77f22..36ae24b52e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,7 @@ # TelegramBotAPI changelog +## 0.38.19 + ## 0.38.18 * `Core`: diff --git a/gradle.properties b/gradle.properties index 876f4856d8..0401f4f412 100644 --- a/gradle.properties +++ b/gradle.properties @@ -20,6 +20,6 @@ javax_activation_version=1.1.1 dokka_version=1.6.10 library_group=dev.inmo -library_version=0.38.18 +library_version=0.38.19 github_release_plugin_version=2.3.7 From 89d13de3076a4ce2a096178ec9fd8480d9b21475 Mon Sep 17 00:00:00 2001 From: InsanusMokrassar Date: Tue, 3 May 2022 10:38:48 +0600 Subject: [PATCH 2/9] deprecation of BehaviourContextWithFSMBuilder --- .../BehaviourContextWithFSM.kt | 61 +++++++++++- .../BehaviourContextWithFSMBuilder.kt | 98 ++++--------------- .../behaviour_builder/TelegramBotWithFSM.kt | 4 +- 3 files changed, 77 insertions(+), 86 deletions(-) diff --git a/tgbotapi.behaviour_builder.fsm/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/behaviour_builder/BehaviourContextWithFSM.kt b/tgbotapi.behaviour_builder.fsm/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/behaviour_builder/BehaviourContextWithFSM.kt index be5cdb8923..98ec32c183 100644 --- a/tgbotapi.behaviour_builder.fsm/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/behaviour_builder/BehaviourContextWithFSM.kt +++ b/tgbotapi.behaviour_builder.fsm/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/behaviour_builder/BehaviourContextWithFSM.kt @@ -9,6 +9,8 @@ import dev.inmo.micro_utils.coroutines.accumulatorFlow import kotlinx.coroutines.* import kotlinx.coroutines.channels.BufferOverflow import kotlinx.coroutines.flow.* +import kotlin.jvm.JvmName +import kotlin.reflect.KClass /** * Interface which combine [BehaviourContext] and [StatesMachine]. Subcontext of triggers and states contexts must have @@ -30,6 +32,25 @@ interface BehaviourContextWithFSM : BehaviourContext, StatesMachine add(kClass: KClass, strict: Boolean = false, handler: BehaviourWithFSMStateHandler) + + /** + * Add STRICT [handler] to list of available in future [BehaviourContextWithFSM]. Strict means that + * for input [State] will be used [State]::class == [kClass] and any [State] with exactly the same type will pass + * requirements + * + * @see BehaviourWithFSMStateHandlerHolder + * @see strictlyOn + */ + fun addStrict(kClass: KClass, handler: BehaviourWithFSMStateHandler) = add(kClass, strict = true, handler) + override fun copy( bot: TelegramBot, scope: CoroutineScope, @@ -40,14 +61,42 @@ interface BehaviourContextWithFSM : BehaviourContext, StatesMachine companion object { + @JvmName("invokeWithMutableList") + operator fun invoke( + behaviourContext: BehaviourContext, + handlers: MutableList>, + statesManager: StatesManager + ) = DefaultBehaviourContextWithFSM(behaviourContext, statesManager, handlers.toMutableList()) operator fun invoke( behaviourContext: BehaviourContext, handlers: List>, statesManager: StatesManager - ) = DefaultBehaviourContextWithFSM(behaviourContext, statesManager, handlers) + ) = invoke(behaviourContext, handlers.toMutableList(), statesManager) } } + +/** + * Add NON STRICT [handler] to list of available in future [BehaviourContextWithFSM]. Non strict means that + * for input [State] will be used [KClass.isInstance] and any inheritor of [kClass] will pass this requirement + * + * @see BehaviourWithFSMStateHandlerHolder + * @see BehaviourContextWithFSM.add + */ +@Suppress("MemberVisibilityCanBePrivate") +inline fun BehaviourContextWithFSM.onStateOrSubstate(handler: BehaviourWithFSMStateHandler) = add(I::class, strict = false, handler) + +/** + * Add STRICT [handler] to list of available in future [BehaviourContextWithFSM]. Strict means that + * for input [State] will be used [State]::class == [kClass] and any [State] with exactly the same type will pass + * requirements + * + * @see BehaviourWithFSMStateHandlerHolder + * @see BehaviourContextWithFSM.addStrict + */ +@Suppress("MemberVisibilityCanBePrivate") +inline fun BehaviourContextWithFSM.strictlyOn(handler: BehaviourWithFSMStateHandler) = addStrict(I::class, handler) + /** * 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 @@ -55,7 +104,7 @@ interface BehaviourContextWithFSM : BehaviourContext, StatesMachine( private val behaviourContext: BehaviourContext, private val statesManager: StatesManager, - private val handlers: List> + private val handlers: MutableList> ) : BehaviourContext by behaviourContext, BehaviourContextWithFSM { private val updatesFlows = mutableMapOf>() private fun getContextUpdatesFlow(context: Any) = updatesFlows.getOrPut(context) { @@ -68,6 +117,10 @@ class DefaultBehaviourContextWithFSM( handlers ) + override fun add(kClass: KClass, strict: Boolean, handler: BehaviourWithFSMStateHandler) { + handlers.add(BehaviourWithFSMStateHandlerHolder(kClass, strict, handler)) + } + override fun start(scope: CoroutineScope): Job = scope.launchSafelyWithoutExceptions { val statePerformer: suspend (T) -> Unit = { state: T -> val newState = launchStateHandling(state, getContextUpdatesFlow(state.context), handlers) @@ -106,9 +159,9 @@ class DefaultBehaviourContextWithFSM( onBufferOverflow: BufferOverflow, upstreamUpdatesFlow: Flow?, updatesFilter: BehaviourContextAndTypeReceiver? - ): BehaviourContextWithFSM = BehaviourContextWithFSM( + ): DefaultBehaviourContextWithFSM = BehaviourContextWithFSM( behaviourContext.copy(bot, scope, broadcastChannelsSize, onBufferOverflow, upstreamUpdatesFlow, updatesFilter), - handlers, + handlers.toMutableList(), statesManager ) } diff --git a/tgbotapi.behaviour_builder.fsm/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/behaviour_builder/BehaviourContextWithFSMBuilder.kt b/tgbotapi.behaviour_builder.fsm/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/behaviour_builder/BehaviourContextWithFSMBuilder.kt index 7723b81c70..2e5cfe4615 100644 --- a/tgbotapi.behaviour_builder.fsm/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/behaviour_builder/BehaviourContextWithFSMBuilder.kt +++ b/tgbotapi.behaviour_builder.fsm/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/behaviour_builder/BehaviourContextWithFSMBuilder.kt @@ -14,70 +14,8 @@ import kotlinx.coroutines.* import kotlinx.coroutines.flow.Flow import kotlin.reflect.KClass -class BehaviourContextWithFSMBuilder internal constructor( - private val resultBehaviourContext: BehaviourContextWithFSM, - private val handlers: MutableList> -) : BehaviourContextWithFSM by resultBehaviourContext { - internal constructor( - baseBehaviourContext: BehaviourContext, - statesManager: StatesManager = DefaultStatesManager(InMemoryDefaultStatesManagerRepo()), - handlers: MutableList> = mutableListOf() - ) : this(DefaultBehaviourContextWithFSM(baseBehaviourContext, statesManager, handlers), handlers) - - /** - * Add NON STRICT [handler] to list of available in future [BehaviourContextWithFSM]. Non strict means that - * for input [State] will be used [KClass.isInstance] and any inheritor of [kClass] will pass this requirement - * - * @see BehaviourWithFSMStateHandlerHolder - * @see onStateOrSubstate - */ - fun add(kClass: KClass, handler: BehaviourWithFSMStateHandler) { - handlers.add(BehaviourWithFSMStateHandlerHolder(kClass, false, handler)) - } - - /** - * Add STRICT [handler] to list of available in future [BehaviourContextWithFSM]. Strict means that - * for input [State] will be used [State]::class == [kClass] and any [State] with exactly the same type will pass - * requirements - * - * @see BehaviourWithFSMStateHandlerHolder - * @see strictlyOn - */ - fun addStrict(kClass: KClass, handler: BehaviourWithFSMStateHandler) { - handlers.add(BehaviourWithFSMStateHandlerHolder(kClass, true, handler)) - } - - - /** - * Add NON STRICT [handler] to list of available in future [BehaviourContextWithFSM]. Non strict means that - * for input [State] will be used [KClass.isInstance] and any inheritor of [kClass] will pass this requirement - * - * @see BehaviourWithFSMStateHandlerHolder - * @see BehaviourContextWithFSMBuilder.add - */ - @Suppress("MemberVisibilityCanBePrivate") - inline fun onStateOrSubstate(handler: BehaviourWithFSMStateHandler) { - add(I::class, handler) - } - - /** - * Add STRICT [handler] to list of available in future [BehaviourContextWithFSM]. Strict means that - * for input [State] will be used [State]::class == [kClass] and any [State] with exactly the same type will pass - * requirements - * - * @see BehaviourWithFSMStateHandlerHolder - * @see BehaviourContextWithFSMBuilder.addStrict - */ - @Suppress("MemberVisibilityCanBePrivate") - inline fun strictlyOn(handler: BehaviourWithFSMStateHandler) { - addStrict(I::class, handler) - } - - /** - * Returns completed [resultBehaviourContext], [handlers] and [statesManager] - */ - internal fun build() = resultBehaviourContext -} +@Deprecated("Will be removed soon") +typealias BehaviourContextWithFSMBuilder = BehaviourContextWithFSM /** * Creates [BehaviourContextWithFSM] via creating of [DefaultBehaviourContext] with [this] as [TelegramBot], @@ -95,16 +33,16 @@ suspend fun TelegramBot.buildBehaviourWithFSM( defaultExceptionsHandler: ExceptionHandler? = null, statesManager: StatesManager = DefaultStatesManager(InMemoryDefaultStatesManagerRepo()), presetHandlers: MutableList> = mutableListOf(), - block: CustomBehaviourContextReceiver, Unit> -): BehaviourContextWithFSM = BehaviourContextWithFSMBuilder( + block: CustomBehaviourContextReceiver, Unit> +): BehaviourContextWithFSM = BehaviourContextWithFSM( DefaultBehaviourContext( this, defaultExceptionsHandler ?.let { scope + ContextSafelyExceptionHandler(it) } ?: scope, upstreamUpdatesFlow = upstreamUpdatesFlow ), - statesManager, - presetHandlers -).apply { block() }.build() + presetHandlers, + statesManager +).apply { block() } /** * Use [buildBehaviourWithFSM] to create [BehaviourContextWithFSM] and launch getting of updates @@ -117,7 +55,7 @@ suspend fun TelegramBot.buildBehaviourWithFSMAndStartLongPolling( defaultExceptionsHandler: ExceptionHandler? = null, statesManager: StatesManager = DefaultStatesManager(InMemoryDefaultStatesManagerRepo()), presetHandlers: MutableList> = mutableListOf(), - block: CustomBehaviourContextReceiver, Unit> + block: CustomBehaviourContextReceiver, Unit> ): Pair, Job> = buildBehaviourWithFSM( upstreamUpdatesFlow, scope, @@ -147,8 +85,8 @@ suspend fun TelegramBot.buildBehaviourWithFSMAndStartLongPolling( * @see BehaviourContext * @see BehaviourContextWithFSM * @see longPolling - * @see BehaviourContextWithFSMBuilder.strictlyOn - * @see BehaviourContextWithFSMBuilder.onStateOrSubstate + * @see BehaviourContextWithFSM.strictlyOn + * @see BehaviourContextWithFSM.onStateOrSubstate */ @PreviewFeature suspend fun TelegramBot.buildBehaviourWithFSM( @@ -157,16 +95,16 @@ suspend fun TelegramBot.buildBehaviourWithFSM( defaultExceptionsHandler: ExceptionHandler? = null, statesManager: StatesManager = DefaultStatesManager(InMemoryDefaultStatesManagerRepo()), presetHandlers: MutableList> = mutableListOf(), - block: CustomBehaviourContextReceiver, Unit> -): BehaviourContextWithFSM = BehaviourContextWithFSMBuilder( + block: CustomBehaviourContextReceiver, Unit> +): BehaviourContextWithFSM = BehaviourContextWithFSM( DefaultBehaviourContext( this, defaultExceptionsHandler ?.let { scope + ContextSafelyExceptionHandler(it) } ?: scope, upstreamUpdatesFlow = flowUpdatesFilter.allUpdatesFlow ), - statesManager, - presetHandlers -).apply { block() }.build() + presetHandlers, + statesManager +).apply { block() } /** * Use [buildBehaviourWithFSM] to create [BehaviourContextWithFSM] and launch getting of updates @@ -176,8 +114,8 @@ suspend fun TelegramBot.buildBehaviourWithFSM( * @see buildBehaviourWithFSMAndStartLongPolling * @see BehaviourContext * @see longPolling - * @see BehaviourContextWithFSMBuilder.strictlyOn - * @see BehaviourContextWithFSMBuilder.onStateOrSubstate + * @see BehaviourContextWithFSM.strictlyOn + * @see BehaviourContextWithFSM.onStateOrSubstate */ @PreviewFeature suspend fun TelegramBot.buildBehaviourWithFSMAndStartLongPolling( @@ -185,7 +123,7 @@ suspend fun TelegramBot.buildBehaviourWithFSMAndStartLongPolling( defaultExceptionsHandler: ExceptionHandler? = null, statesManager: StatesManager = DefaultStatesManager(InMemoryDefaultStatesManagerRepo()), presetHandlers: MutableList> = mutableListOf(), - block: CustomBehaviourContextReceiver, Unit> + block: CustomBehaviourContextReceiver, Unit> ) = FlowsUpdatesFilter().let { buildBehaviourWithFSM( it, diff --git a/tgbotapi.behaviour_builder.fsm/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/behaviour_builder/TelegramBotWithFSM.kt b/tgbotapi.behaviour_builder.fsm/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/behaviour_builder/TelegramBotWithFSM.kt index edfc67de48..91e5d64e43 100644 --- a/tgbotapi.behaviour_builder.fsm/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/behaviour_builder/TelegramBotWithFSM.kt +++ b/tgbotapi.behaviour_builder.fsm/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/behaviour_builder/TelegramBotWithFSM.kt @@ -39,7 +39,7 @@ suspend fun telegramBotWithBehaviourAndFSM( statesManager: StatesManager = DefaultStatesManager(InMemoryDefaultStatesManagerRepo()), presetHandlers: MutableList> = mutableListOf(), testServer: Boolean = false, - block: CustomBehaviourContextReceiver, Unit> + block: CustomBehaviourContextReceiver, Unit> ): TelegramBot = telegramBot( token, apiUrl, @@ -76,7 +76,7 @@ suspend fun telegramBotWithBehaviourAndFSMAndStartLongPolling( statesManager: StatesManager = DefaultStatesManager(InMemoryDefaultStatesManagerRepo()), presetHandlers: MutableList> = mutableListOf(), testServer: Boolean = false, - block: CustomBehaviourContextReceiver, Unit> + block: CustomBehaviourContextReceiver, Unit> ): Pair { return telegramBot( token, From 3e3adab46b263729caf5152f5a4288c6d70e3901 Mon Sep 17 00:00:00 2001 From: InsanusMokrassar Date: Tue, 3 May 2022 13:58:13 +0600 Subject: [PATCH 3/9] complete fix of issue with subcontexts --- .../BehaviourContextWithFSM.kt | 20 +++++++++++++++++++ .../BehaviourContextWithFSMBuilder.kt | 14 ++++++------- .../behaviour_builder/TelegramBotWithFSM.kt | 4 ++-- 3 files changed, 29 insertions(+), 9 deletions(-) diff --git a/tgbotapi.behaviour_builder.fsm/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/behaviour_builder/BehaviourContextWithFSM.kt b/tgbotapi.behaviour_builder.fsm/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/behaviour_builder/BehaviourContextWithFSM.kt index 98ec32c183..74ae650f11 100644 --- a/tgbotapi.behaviour_builder.fsm/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/behaviour_builder/BehaviourContextWithFSM.kt +++ b/tgbotapi.behaviour_builder.fsm/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/behaviour_builder/BehaviourContextWithFSM.kt @@ -147,6 +147,26 @@ class DefaultBehaviourContextWithFSM( launch { statePerformer(it) } } } + /** + * Add NON STRICT [handler] to list of available in future [BehaviourContextWithFSM]. Non strict means that + * for input [State] will be used [KClass.isInstance] and any inheritor of [kClass] will pass this requirement + * + * @see BehaviourWithFSMStateHandlerHolder + * @see BehaviourContextWithFSM.add + */ + @Suppress("MemberVisibilityCanBePrivate") + inline fun onStateOrSubstate(handler: BehaviourWithFSMStateHandler) = add(I::class, strict = false, handler) + + /** + * Add STRICT [handler] to list of available in future [BehaviourContextWithFSM]. Strict means that + * for input [State] will be used [State]::class == [kClass] and any [State] with exactly the same type will pass + * requirements + * + * @see BehaviourWithFSMStateHandlerHolder + * @see BehaviourContextWithFSM.addStrict + */ + @Suppress("MemberVisibilityCanBePrivate") + inline fun strictlyOn(handler: BehaviourWithFSMStateHandler) = addStrict(I::class, handler) override suspend fun startChain(state: T) { statesManager.startChain(state) diff --git a/tgbotapi.behaviour_builder.fsm/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/behaviour_builder/BehaviourContextWithFSMBuilder.kt b/tgbotapi.behaviour_builder.fsm/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/behaviour_builder/BehaviourContextWithFSMBuilder.kt index 2e5cfe4615..4e968c8b51 100644 --- a/tgbotapi.behaviour_builder.fsm/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/behaviour_builder/BehaviourContextWithFSMBuilder.kt +++ b/tgbotapi.behaviour_builder.fsm/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/behaviour_builder/BehaviourContextWithFSMBuilder.kt @@ -33,8 +33,8 @@ suspend fun TelegramBot.buildBehaviourWithFSM( defaultExceptionsHandler: ExceptionHandler? = null, statesManager: StatesManager = DefaultStatesManager(InMemoryDefaultStatesManagerRepo()), presetHandlers: MutableList> = mutableListOf(), - block: CustomBehaviourContextReceiver, Unit> -): BehaviourContextWithFSM = BehaviourContextWithFSM( + block: CustomBehaviourContextReceiver, Unit> +): DefaultBehaviourContextWithFSM = BehaviourContextWithFSM( DefaultBehaviourContext( this, defaultExceptionsHandler ?.let { scope + ContextSafelyExceptionHandler(it) } ?: scope, @@ -55,8 +55,8 @@ suspend fun TelegramBot.buildBehaviourWithFSMAndStartLongPolling( defaultExceptionsHandler: ExceptionHandler? = null, statesManager: StatesManager = DefaultStatesManager(InMemoryDefaultStatesManagerRepo()), presetHandlers: MutableList> = mutableListOf(), - block: CustomBehaviourContextReceiver, Unit> -): Pair, Job> = buildBehaviourWithFSM( + block: CustomBehaviourContextReceiver, Unit> +): Pair, Job> = buildBehaviourWithFSM( upstreamUpdatesFlow, scope, defaultExceptionsHandler, @@ -95,8 +95,8 @@ suspend fun TelegramBot.buildBehaviourWithFSM( defaultExceptionsHandler: ExceptionHandler? = null, statesManager: StatesManager = DefaultStatesManager(InMemoryDefaultStatesManagerRepo()), presetHandlers: MutableList> = mutableListOf(), - block: CustomBehaviourContextReceiver, Unit> -): BehaviourContextWithFSM = BehaviourContextWithFSM( + block: CustomBehaviourContextReceiver, Unit> +): DefaultBehaviourContextWithFSM = BehaviourContextWithFSM( DefaultBehaviourContext( this, defaultExceptionsHandler ?.let { scope + ContextSafelyExceptionHandler(it) } ?: scope, @@ -123,7 +123,7 @@ suspend fun TelegramBot.buildBehaviourWithFSMAndStartLongPolling( defaultExceptionsHandler: ExceptionHandler? = null, statesManager: StatesManager = DefaultStatesManager(InMemoryDefaultStatesManagerRepo()), presetHandlers: MutableList> = mutableListOf(), - block: CustomBehaviourContextReceiver, Unit> + block: CustomBehaviourContextReceiver, Unit> ) = FlowsUpdatesFilter().let { buildBehaviourWithFSM( it, diff --git a/tgbotapi.behaviour_builder.fsm/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/behaviour_builder/TelegramBotWithFSM.kt b/tgbotapi.behaviour_builder.fsm/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/behaviour_builder/TelegramBotWithFSM.kt index 91e5d64e43..ffc7af1215 100644 --- a/tgbotapi.behaviour_builder.fsm/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/behaviour_builder/TelegramBotWithFSM.kt +++ b/tgbotapi.behaviour_builder.fsm/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/behaviour_builder/TelegramBotWithFSM.kt @@ -39,7 +39,7 @@ suspend fun telegramBotWithBehaviourAndFSM( statesManager: StatesManager = DefaultStatesManager(InMemoryDefaultStatesManagerRepo()), presetHandlers: MutableList> = mutableListOf(), testServer: Boolean = false, - block: CustomBehaviourContextReceiver, Unit> + block: CustomBehaviourContextReceiver, Unit> ): TelegramBot = telegramBot( token, apiUrl, @@ -76,7 +76,7 @@ suspend fun telegramBotWithBehaviourAndFSMAndStartLongPolling( statesManager: StatesManager = DefaultStatesManager(InMemoryDefaultStatesManagerRepo()), presetHandlers: MutableList> = mutableListOf(), testServer: Boolean = false, - block: CustomBehaviourContextReceiver, Unit> + block: CustomBehaviourContextReceiver, Unit> ): Pair { return telegramBot( token, From d0add888c44c53332d5d53dc4411a2453a9fa09f Mon Sep 17 00:00:00 2001 From: InsanusMokrassar Date: Tue, 3 May 2022 14:28:03 +0600 Subject: [PATCH 4/9] now the handlers from the upstream lists are not modified in the whole fsm behaviour context --- .../BehaviourContextWithFSM.kt | 22 +++++++++---------- .../BehaviourContextWithFSMBuilder.kt | 8 +++---- .../behaviour_builder/TelegramBotWithFSM.kt | 4 ++-- 3 files changed, 16 insertions(+), 18 deletions(-) diff --git a/tgbotapi.behaviour_builder.fsm/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/behaviour_builder/BehaviourContextWithFSM.kt b/tgbotapi.behaviour_builder.fsm/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/behaviour_builder/BehaviourContextWithFSM.kt index 74ae650f11..6212a4134a 100644 --- a/tgbotapi.behaviour_builder.fsm/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/behaviour_builder/BehaviourContextWithFSM.kt +++ b/tgbotapi.behaviour_builder.fsm/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/behaviour_builder/BehaviourContextWithFSM.kt @@ -61,17 +61,11 @@ interface BehaviourContextWithFSM : BehaviourContext, StatesMachine companion object { - @JvmName("invokeWithMutableList") - operator fun invoke( - behaviourContext: BehaviourContext, - handlers: MutableList>, - statesManager: StatesManager - ) = DefaultBehaviourContextWithFSM(behaviourContext, statesManager, handlers.toMutableList()) operator fun invoke( behaviourContext: BehaviourContext, handlers: List>, statesManager: StatesManager - ) = invoke(behaviourContext, handlers.toMutableList(), statesManager) + ) = DefaultBehaviourContextWithFSM(behaviourContext, statesManager, handlers) } } @@ -104,9 +98,12 @@ inline fun BehaviourContextWithFSM.strictlyOn(handl class DefaultBehaviourContextWithFSM( private val behaviourContext: BehaviourContext, private val statesManager: StatesManager, - private val handlers: MutableList> + private val handlers: List> ) : BehaviourContext by behaviourContext, BehaviourContextWithFSM { private val updatesFlows = mutableMapOf>() + private val additionalHandlers = mutableListOf>() + private var actualHandlersList = additionalHandlers + handlers + private fun getContextUpdatesFlow(context: Any) = updatesFlows.getOrPut(context) { allUpdatesFlow.accumulatorFlow(scope) } @@ -114,16 +111,17 @@ class DefaultBehaviourContextWithFSM( override suspend fun StatesMachine.handleState(state: T): T? = launchStateHandling( state, allUpdatesFlow, - handlers + actualHandlersList ) override fun add(kClass: KClass, strict: Boolean, handler: BehaviourWithFSMStateHandler) { - handlers.add(BehaviourWithFSMStateHandlerHolder(kClass, strict, handler)) + additionalHandlers.add(BehaviourWithFSMStateHandlerHolder(kClass, strict, handler)) + actualHandlersList = additionalHandlers + handlers } override fun start(scope: CoroutineScope): Job = scope.launchSafelyWithoutExceptions { val statePerformer: suspend (T) -> Unit = { state: T -> - val newState = launchStateHandling(state, getContextUpdatesFlow(state.context), handlers) + val newState = launchStateHandling(state, getContextUpdatesFlow(state.context), actualHandlersList) if (newState != null) { statesManager.update(state, newState) } else { @@ -181,7 +179,7 @@ class DefaultBehaviourContextWithFSM( updatesFilter: BehaviourContextAndTypeReceiver? ): DefaultBehaviourContextWithFSM = BehaviourContextWithFSM( behaviourContext.copy(bot, scope, broadcastChannelsSize, onBufferOverflow, upstreamUpdatesFlow, updatesFilter), - handlers.toMutableList(), + handlers, statesManager ) } diff --git a/tgbotapi.behaviour_builder.fsm/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/behaviour_builder/BehaviourContextWithFSMBuilder.kt b/tgbotapi.behaviour_builder.fsm/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/behaviour_builder/BehaviourContextWithFSMBuilder.kt index 4e968c8b51..b1dd83032b 100644 --- a/tgbotapi.behaviour_builder.fsm/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/behaviour_builder/BehaviourContextWithFSMBuilder.kt +++ b/tgbotapi.behaviour_builder.fsm/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/behaviour_builder/BehaviourContextWithFSMBuilder.kt @@ -32,7 +32,7 @@ suspend fun TelegramBot.buildBehaviourWithFSM( scope: CoroutineScope = defaultCoroutineScopeProvider(), defaultExceptionsHandler: ExceptionHandler? = null, statesManager: StatesManager = DefaultStatesManager(InMemoryDefaultStatesManagerRepo()), - presetHandlers: MutableList> = mutableListOf(), + presetHandlers: List> = listOf(), block: CustomBehaviourContextReceiver, Unit> ): DefaultBehaviourContextWithFSM = BehaviourContextWithFSM( DefaultBehaviourContext( @@ -54,7 +54,7 @@ suspend fun TelegramBot.buildBehaviourWithFSMAndStartLongPolling( scope: CoroutineScope = defaultCoroutineScopeProvider(), defaultExceptionsHandler: ExceptionHandler? = null, statesManager: StatesManager = DefaultStatesManager(InMemoryDefaultStatesManagerRepo()), - presetHandlers: MutableList> = mutableListOf(), + presetHandlers: List> = listOf(), block: CustomBehaviourContextReceiver, Unit> ): Pair, Job> = buildBehaviourWithFSM( upstreamUpdatesFlow, @@ -94,7 +94,7 @@ suspend fun TelegramBot.buildBehaviourWithFSM( scope: CoroutineScope = defaultCoroutineScopeProvider(), defaultExceptionsHandler: ExceptionHandler? = null, statesManager: StatesManager = DefaultStatesManager(InMemoryDefaultStatesManagerRepo()), - presetHandlers: MutableList> = mutableListOf(), + presetHandlers: List> = listOf(), block: CustomBehaviourContextReceiver, Unit> ): DefaultBehaviourContextWithFSM = BehaviourContextWithFSM( DefaultBehaviourContext( @@ -122,7 +122,7 @@ suspend fun TelegramBot.buildBehaviourWithFSMAndStartLongPolling( scope: CoroutineScope = defaultCoroutineScopeProvider(), defaultExceptionsHandler: ExceptionHandler? = null, statesManager: StatesManager = DefaultStatesManager(InMemoryDefaultStatesManagerRepo()), - presetHandlers: MutableList> = mutableListOf(), + presetHandlers: List> = listOf(), block: CustomBehaviourContextReceiver, Unit> ) = FlowsUpdatesFilter().let { buildBehaviourWithFSM( diff --git a/tgbotapi.behaviour_builder.fsm/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/behaviour_builder/TelegramBotWithFSM.kt b/tgbotapi.behaviour_builder.fsm/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/behaviour_builder/TelegramBotWithFSM.kt index ffc7af1215..2d55cf322a 100644 --- a/tgbotapi.behaviour_builder.fsm/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/behaviour_builder/TelegramBotWithFSM.kt +++ b/tgbotapi.behaviour_builder.fsm/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/behaviour_builder/TelegramBotWithFSM.kt @@ -37,7 +37,7 @@ suspend fun telegramBotWithBehaviourAndFSM( builder: KtorRequestsExecutorBuilder.() -> Unit = {}, defaultExceptionsHandler: ExceptionHandler? = null, statesManager: StatesManager = DefaultStatesManager(InMemoryDefaultStatesManagerRepo()), - presetHandlers: MutableList> = mutableListOf(), + presetHandlers: List> = listOf(), testServer: Boolean = false, block: CustomBehaviourContextReceiver, Unit> ): TelegramBot = telegramBot( @@ -74,7 +74,7 @@ suspend fun telegramBotWithBehaviourAndFSMAndStartLongPolling( builder: KtorRequestsExecutorBuilder.() -> Unit = {}, defaultExceptionsHandler: ExceptionHandler? = null, statesManager: StatesManager = DefaultStatesManager(InMemoryDefaultStatesManagerRepo()), - presetHandlers: MutableList> = mutableListOf(), + presetHandlers: List> = listOf(), testServer: Boolean = false, block: CustomBehaviourContextReceiver, Unit> ): Pair { From 3c3607d81777c0c58dddbfe5e65d9e21bfe37ef8 Mon Sep 17 00:00:00 2001 From: InsanusMokrassar Date: Tue, 3 May 2022 14:32:29 +0600 Subject: [PATCH 5/9] fill changelog --- CHANGELOG.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 36ae24b52e..ececa0b868 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,12 @@ ## 0.38.19 +* `BehaviourBuilder`: + * Hotfixes +* `BehaviourBuilder FSM`: + * `BehaviourContextWithFSMBuilder` deprecated in favor to `BehaviourContextWithFSM` + * Now it is possible to define additional handlers in subcontexts of `BehaviourBuilderWithFSM` + ## 0.38.18 * `Core`: From 08147fc33b9c32db7be22b00b5ecda0ca96a5d86 Mon Sep 17 00:00:00 2001 From: InsanusMokrassar Date: Tue, 3 May 2022 23:11:02 +0600 Subject: [PATCH 6/9] start 0.38.20 --- CHANGELOG.md | 2 ++ gradle.properties | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ececa0b868..fe13a60008 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,7 @@ # TelegramBotAPI changelog +## 0.38.20 + ## 0.38.19 * `BehaviourBuilder`: diff --git a/gradle.properties b/gradle.properties index 0401f4f412..f9b76a73b9 100644 --- a/gradle.properties +++ b/gradle.properties @@ -20,6 +20,6 @@ javax_activation_version=1.1.1 dokka_version=1.6.10 library_group=dev.inmo -library_version=0.38.19 +library_version=0.38.20 github_release_plugin_version=2.3.7 From bd23d3fbdba575378ed710e53f633c3e619fc32f Mon Sep 17 00:00:00 2001 From: InsanusMokrassar Date: Tue, 3 May 2022 23:12:03 +0600 Subject: [PATCH 7/9] hotfixes --- CHANGELOG.md | 3 +++ .../behaviour_builder/BehaviourContextWithFSM.kt | 4 +++- .../BehaviourWithFSMStateHandlerHolder.kt | 13 ++----------- 3 files changed, 8 insertions(+), 12 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index fe13a60008..3e046ea721 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,9 @@ ## 0.38.20 +* `BehaviourBuilder FSM`: + * Hotfixes + ## 0.38.19 * `BehaviourBuilder`: diff --git a/tgbotapi.behaviour_builder.fsm/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/behaviour_builder/BehaviourContextWithFSM.kt b/tgbotapi.behaviour_builder.fsm/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/behaviour_builder/BehaviourContextWithFSM.kt index 6212a4134a..2bb6b3ea89 100644 --- a/tgbotapi.behaviour_builder.fsm/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/behaviour_builder/BehaviourContextWithFSM.kt +++ b/tgbotapi.behaviour_builder.fsm/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/behaviour_builder/BehaviourContextWithFSM.kt @@ -28,7 +28,9 @@ interface BehaviourContextWithFSM : BehaviourContext, StatesMachine> ): T? { return handlers.firstOrNull { it.checkHandleable(state) } ?.run { - handleState(contextUpdatesFlow, state) + doInSubContext(updatesUpstreamFlow = contextUpdatesFlow) { + handleState(state) + } } } diff --git a/tgbotapi.behaviour_builder.fsm/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/behaviour_builder/BehaviourWithFSMStateHandlerHolder.kt b/tgbotapi.behaviour_builder.fsm/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/behaviour_builder/BehaviourWithFSMStateHandlerHolder.kt index 788c1cf3c1..fa3bdbd0e2 100644 --- a/tgbotapi.behaviour_builder.fsm/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/behaviour_builder/BehaviourWithFSMStateHandlerHolder.kt +++ b/tgbotapi.behaviour_builder.fsm/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/behaviour_builder/BehaviourWithFSMStateHandlerHolder.kt @@ -34,20 +34,11 @@ class BehaviourWithFSMStateHandlerHolder( /** * Handling of state :) - * - * @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] */ suspend fun BehaviourContextWithFSM.handleState( - contextUpdatesFlow: Flow, state: O - ): O? { - val subscope = scope.LinkedSupervisorScope() - return with(copy(scope = subscope, upstreamUpdatesFlow = contextUpdatesFlow)) { - with(delegateTo) { - handleState(state as I) - } - } + ): O? = with(delegateTo) { + handleState(state as I) } } From 7ff6412ec58bd4217106adf0b3f4bed66045b5a7 Mon Sep 17 00:00:00 2001 From: InsanusMokrassar Date: Wed, 4 May 2022 10:50:08 +0600 Subject: [PATCH 8/9] TelegramBot#answerWebAppQuery --- CHANGELOG.md | 2 ++ .../dev/inmo/tgbotapi/webapps/AnswerWebAppQuery.kt | 11 +++++++++++ 2 files changed, 13 insertions(+) create mode 100644 tgbotapi.webapps/src/jsMain/kotlin/dev/inmo/tgbotapi/webapps/AnswerWebAppQuery.kt diff --git a/CHANGELOG.md b/CHANGELOG.md index 3e046ea721..c0df72cb80 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,8 @@ * `BehaviourBuilder FSM`: * Hotfixes +* `WebApps`: + * New extension `TelegramBot#answerWebAppQuery` ## 0.38.19 diff --git a/tgbotapi.webapps/src/jsMain/kotlin/dev/inmo/tgbotapi/webapps/AnswerWebAppQuery.kt b/tgbotapi.webapps/src/jsMain/kotlin/dev/inmo/tgbotapi/webapps/AnswerWebAppQuery.kt new file mode 100644 index 0000000000..c77aa0b763 --- /dev/null +++ b/tgbotapi.webapps/src/jsMain/kotlin/dev/inmo/tgbotapi/webapps/AnswerWebAppQuery.kt @@ -0,0 +1,11 @@ +package dev.inmo.tgbotapi.webapps + +import dev.inmo.tgbotapi.bot.TelegramBot +import dev.inmo.tgbotapi.requests.answers.AnswerWebAppQuery +import dev.inmo.tgbotapi.types.InlineQueries.InlineQueryResult.abstracts.InlineQueryResult + +suspend fun TelegramBot.answerWebAppQuery( + result: InlineQueryResult +) = webApp.initDataUnsafe.queryId ?.let { + execute(AnswerWebAppQuery(it, result)) +} From 1b5b3af45bb333b10df530b0440886ebc077f5c1 Mon Sep 17 00:00:00 2001 From: InsanusMokrassar Date: Wed, 4 May 2022 11:01:26 +0600 Subject: [PATCH 9/9] add handleResult --- CHANGELOG.md | 1 + .../requests/answers/AnswerWebAppQuery.kt | 3 +++ .../dev/inmo/tgbotapi/webapps/SendData.kt | 18 ++++++++++++++++++ 3 files changed, 22 insertions(+) create mode 100644 tgbotapi.webapps/src/jsMain/kotlin/dev/inmo/tgbotapi/webapps/SendData.kt diff --git a/CHANGELOG.md b/CHANGELOG.md index c0df72cb80..7390ed2954 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,7 @@ * Hotfixes * `WebApps`: * New extension `TelegramBot#answerWebAppQuery` + * New function `handleResult` ## 0.38.19 diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/requests/answers/AnswerWebAppQuery.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/requests/answers/AnswerWebAppQuery.kt index ceacda665f..859959aebb 100644 --- a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/requests/answers/AnswerWebAppQuery.kt +++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/requests/answers/AnswerWebAppQuery.kt @@ -6,6 +6,9 @@ import dev.inmo.tgbotapi.types.InlineQueries.InlineQueryResult.abstracts.InlineQ import dev.inmo.tgbotapi.types.webapps.query.SentWebAppMessage import kotlinx.serialization.* +/** + * @param webAppQueryId [dev.inmo.tgbotapi.webapps.WebAppInitData.queryId] + */ @Serializable data class AnswerWebAppQuery( @SerialName(webAppQueryIdField) diff --git a/tgbotapi.webapps/src/jsMain/kotlin/dev/inmo/tgbotapi/webapps/SendData.kt b/tgbotapi.webapps/src/jsMain/kotlin/dev/inmo/tgbotapi/webapps/SendData.kt new file mode 100644 index 0000000000..5f469cfd0f --- /dev/null +++ b/tgbotapi.webapps/src/jsMain/kotlin/dev/inmo/tgbotapi/webapps/SendData.kt @@ -0,0 +1,18 @@ +package dev.inmo.tgbotapi.webapps + +import dev.inmo.tgbotapi.types.WebAppQueryId + +/** + * @param onSendData Should return the data which must be used in [WebApp.sendData]. If returns null, data will not be sent + * @param onAnswerWebAppQuery In case if [WebAppInitData.queryId] is presented in [WebApp.initDataUnsafe], will be called + * that callback. Before and after calling of this callback will not be used any method of answering to the telegram + * system, so, you must use something like [answerWebAppQuery] by yourself to send the result + */ +inline fun handleResult( + onSendData: () -> String?, + onAnswerWebAppQuery: (WebAppQueryId) -> Unit +) { + webApp.initDataUnsafe.queryId ?.let { + onAnswerWebAppQuery(it) + } ?: webApp.sendData(onSendData() ?: return) +}