@@ -36,7 +36,7 @@ import kotlin.contracts.contract
3636 */
3737class InteractiveConversationBuilder (
3838 private val eventContext : MessageEvent ,
39- private val coroutineScope : CoroutineScope ,
39+ private val coroutineScope : CoroutineScope ? ,
4040 private val timeoutLimitation : Long ,
4141 private val tryCountLimitation : Int
4242) {
@@ -244,6 +244,7 @@ sealed class QuitConversationExceptions : Exception() {
244244 class TimeoutException : QuitConversationExceptions ()
245245}
246246
247+ typealias EIQ = Either <InteractiveConversationBuilder , QuitConversationExceptions >
247248/* *
248249 * 交互式对话的创建器
249250 *
@@ -257,8 +258,7 @@ sealed class QuitConversationExceptions : Exception() {
257258 *
258259 * ```
259260 *
260- * @param scope 协程作用域,默认为全局作用域 [GlobalScope]。
261- * 建议制定为*插件作用域*或自定义协程作用域。
261+ * @param scope 协程作用域,默认为 `null` 即阻塞当前协程。
262262 * @param eachTimeLimit 每一次捕获消息的最大等待时间,默认为 `-1L` 即无限等待。
263263 * 若超过了这个时间未捕获到适合的消息,则在 [exception] 中抛出 [QuitConversationExceptions.IllegalInputException]。
264264 * @param eachTryLimit 每一次捕获消息时允许尝试的最大次数。
@@ -271,29 +271,29 @@ sealed class QuitConversationExceptions : Exception() {
271271 * @see finish
272272 * @see exception
273273 */
274- inline fun <T : MessageEvent > T.interactiveConversation (
275- scope : CoroutineScope = GlobalScope ,
274+ suspend fun <T : MessageEvent > T.interactiveConversation (
275+ scope : CoroutineScope ? = null ,
276276 eachTimeLimit : Long = -1L,
277277 eachTryLimit : Int = -1,
278- crossinline block : suspend InteractiveConversationBuilder .() -> Unit
279- ): Pair <CoroutineScope , Deferred <Either <InteractiveConversationBuilder , QuitConversationExceptions >>> = scope to scope.async (
280- scope.coroutineContext
281- ) {
282- try {
278+ block : suspend InteractiveConversationBuilder .() -> Unit
279+ ): Pair <CoroutineScope ?, Either <EIQ , Deferred <EIQ >>> {
280+ suspend fun executeICB () = try {
283281 InteractiveConversationBuilder (
284282 eventContext = this @interactiveConversation,
285283 coroutineScope = scope,
286284 tryCountLimitation = eachTryLimit,
287285 timeoutLimitation = eachTimeLimit
288286 ).also { block(it) }.let { Either .Left (it) }
289- } catch (ex: Exception ) {
290- when (ex) {
291- is TimeoutCancellationException -> Either .Right (QuitConversationExceptions .TimeoutException ())
292- else -> Either .Right (ex as QuitConversationExceptions )
293- }
287+ } catch (ex: Exception ) { when (ex) {
288+ is TimeoutCancellationException -> Either .Right (QuitConversationExceptions .TimeoutException ())
289+ else -> Either .Right (ex as QuitConversationExceptions )
290+ } }
291+ return if (scope == null ) {
292+ null to Either .Left (executeICB())
293+ } else {
294+ scope to Either .Right (scope.async(scope.coroutineContext) { executeICB() })
294295 }
295296}
296-
297297/* *
298298 * 会话非正常退出时调用这个函数
299299 * 处理方式:
@@ -306,11 +306,19 @@ inline fun <T : MessageEvent> T.interactiveConversation(
306306 * ```
307307 * 不必为 `when` 添加 `else` 分支,因为 [QuitConversationExceptions] 是一个 `sealed class`
308308 */
309- fun Pair <CoroutineScope , Deferred < Either <InteractiveConversationBuilder , QuitConversationExceptions >>>.exception (
309+ suspend fun Pair <CoroutineScope ?, Either <EIQ , Deferred < EIQ >>>.exception (
310310 failed : suspend (QuitConversationExceptions ) -> Unit = { }
311- ) : Pair <CoroutineScope , Deferred <Either <InteractiveConversationBuilder , QuitConversationExceptions >>> {
312- first.launch(first.coroutineContext) {
313- when (val icBuilder = this @exception.second.await()) { is Either .Right -> failed(icBuilder.value) }
311+ ) : Pair <CoroutineScope ?, Either <EIQ , Deferred <EIQ >>> {
312+ if (first != null ) {
313+ first!! .launch(first!! .coroutineContext) {
314+ when (val icBuilder = (second as Either .Right ).value.await()) {
315+ is Either .Right -> failed(icBuilder.value)
316+ }
317+ }
318+ } else {
319+ when (val icBuilder = (second as Either .Left ).value) {
320+ is Either .Right -> failed(icBuilder.value)
321+ }
314322 }
315323 return this
316324}
@@ -348,11 +356,19 @@ fun Pair<CoroutineScope, Deferred<Either<InteractiveConversationBuilder, QuitCon
348356 * 注意:[cast] 会忽略 `Map` 中的 `null` 检查!
349357 *
350358 */
351- fun Pair <CoroutineScope , Deferred < Either <InteractiveConversationBuilder , QuitConversationExceptions >>>.finish (
359+ suspend fun Pair <CoroutineScope ?, Either <EIQ , Deferred < EIQ >>>.finish (
352360 success : suspend (Map <String , Any >) -> Unit = { }
353- ) : Pair <CoroutineScope , Deferred <Either <InteractiveConversationBuilder , QuitConversationExceptions >>> {
354- first.launch(first.coroutineContext) {
355- when (val icBuilder = this @finish.second.await()) { is Either .Left -> success(icBuilder.value.capturedList.toMap()) }
361+ ) : Pair <CoroutineScope ?, Either <EIQ , Deferred <EIQ >>> {
362+ if (first != null ) {
363+ first!! .launch(first!! .coroutineContext) {
364+ when (val icBuilder = (second as Either .Right ).value.await()) {
365+ is Either .Left -> success(icBuilder.value.capturedList)
366+ }
367+ }
368+ } else {
369+ when (val icBuilder = (second as Either .Left ).value) {
370+ is Either .Left -> success(icBuilder.value.capturedList)
371+ }
356372 }
357373 return this
358374}
0 commit comments