From f5a6040668cc3892cdccc14cabfb1336e23582f8 Mon Sep 17 00:00:00 2001 From: Him188 Date: Thu, 20 Feb 2020 13:20:36 +0800 Subject: [PATCH] Add additional `coroutineScope` parameter --- .../net.mamoe.mirai/event/Subscribers.kt | 55 +++++++++++++++---- .../event/internal/InternalEventListeners.kt | 8 ++- .../mirai/event/internal/EventInternalJvm.kt | 5 +- 3 files changed, 52 insertions(+), 16 deletions(-) diff --git a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/event/Subscribers.kt b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/event/Subscribers.kt index c42584f55..eeca3a407 100644 --- a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/event/Subscribers.kt +++ b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/event/Subscribers.kt @@ -22,6 +22,7 @@ import kotlin.contracts.ExperimentalContracts import kotlin.contracts.InvocationKind import kotlin.contracts.contract import kotlin.coroutines.CoroutineContext +import kotlin.coroutines.EmptyCoroutineContext import kotlin.jvm.JvmName /* @@ -98,6 +99,8 @@ interface Listener : CompletableJob { * * **注意:** 事件处理是 `suspend` 的, 请规范处理 JVM 阻塞方法. * + * @param coroutineContext 给事件监听协程的额外的 [CoroutineContext] + * * @see subscribeAlways 一直监听 * @see subscribeOnce 只监听一次 * @@ -106,8 +109,11 @@ interface Listener : CompletableJob { * @see subscribeFriendMessages 监听好友消息 DSL */ @UseExperimental(MiraiInternalAPI::class) -inline fun CoroutineScope.subscribe(noinline handler: suspend E.(E) -> ListeningStatus): Listener = - E::class.subscribeInternal(Handler { it.handler(it); }) +inline fun CoroutineScope.subscribe( + coroutineContext: CoroutineContext = EmptyCoroutineContext, + noinline handler: suspend E.(E) -> ListeningStatus +): Listener = + E::class.subscribeInternal(Handler(coroutineContext) { it.handler(it); }) /** * 在指定的 [CoroutineScope] 下订阅所有 [E] 及其子类事件. @@ -116,14 +122,19 @@ inline fun CoroutineScope.subscribe(noinline handler: suspen * 可在任意时候通过 [Listener.complete] 来主动停止监听. * [Bot] 被关闭后事件监听会被 [取消][Listener.cancel]. * + * @param coroutineContext 给事件监听协程的额外的 [CoroutineContext] + * * @see subscribe 获取更多说明 */ @UseExperimental(MiraiInternalAPI::class, ExperimentalContracts::class) -inline fun CoroutineScope.subscribeAlways(noinline listener: suspend E.(E) -> Unit): Listener { +inline fun CoroutineScope.subscribeAlways( + coroutineContext: CoroutineContext = EmptyCoroutineContext, + noinline listener: suspend E.(E) -> Unit +): Listener { contract { callsInPlace(listener, InvocationKind.UNKNOWN) } - return E::class.subscribeInternal(Handler { it.listener(it); ListeningStatus.LISTENING }) + return E::class.subscribeInternal(Handler(coroutineContext) { it.listener(it); ListeningStatus.LISTENING }) } /** @@ -133,11 +144,16 @@ inline fun CoroutineScope.subscribeAlways(noinline listener: * 可在任意时候通过 [Listener.complete] 来主动停止监听. * [Bot] 被关闭后事件监听会被 [取消][Listener.cancel]. * + * @param coroutineContext 给事件监听协程的额外的 [CoroutineContext] + * * @see subscribe 获取更多说明 */ @UseExperimental(MiraiInternalAPI::class) -inline fun CoroutineScope.subscribeOnce(noinline listener: suspend E.(E) -> Unit): Listener = - E::class.subscribeInternal(Handler { it.listener(it); ListeningStatus.STOPPED }) +inline fun CoroutineScope.subscribeOnce( + coroutineContext: CoroutineContext = EmptyCoroutineContext, + noinline listener: suspend E.(E) -> Unit +): Listener = + E::class.subscribeInternal(Handler(coroutineContext) { it.listener(it); ListeningStatus.STOPPED }) // @@ -153,12 +169,17 @@ inline fun CoroutineScope.subscribeOnce(noinline listener: s * 可在任意时候通过 [Listener.complete] 来主动停止监听. * [Bot] 被关闭后事件监听会被 [取消][Listener.cancel]. * + * @param coroutineContext 给事件监听协程的额外的 [CoroutineContext] + * * @see subscribe 获取更多说明 */ @JvmName("subscribeAlwaysForBot") @UseExperimental(MiraiInternalAPI::class) -inline fun Bot.subscribe(noinline handler: suspend E.(E) -> ListeningStatus): Listener = - E::class.subscribeInternal(Handler { if (it.bot === this) it.handler(it) else ListeningStatus.LISTENING }) +inline fun Bot.subscribe( + coroutineContext: CoroutineContext = EmptyCoroutineContext, + noinline handler: suspend E.(E) -> ListeningStatus +): Listener = + E::class.subscribeInternal(Handler(coroutineContext) { if (it.bot === this) it.handler(it) else ListeningStatus.LISTENING }) /** @@ -168,12 +189,17 @@ inline fun Bot.subscribe(noinline handler: suspend E.(E) * 可在任意时候通过 [Listener.complete] 来主动停止监听. * [Bot] 被关闭后事件监听会被 [取消][Listener.cancel]. * + * @param coroutineContext 给事件监听协程的额外的 [CoroutineContext] + * * @see subscribe 获取更多说明 */ @JvmName("subscribeAlwaysForBot1") @UseExperimental(MiraiInternalAPI::class) -inline fun Bot.subscribeAlways(noinline listener: suspend E.(E) -> Unit): Listener { - return E::class.subscribeInternal(Handler { if (it.bot === this) it.listener(it); ListeningStatus.LISTENING }) +inline fun Bot.subscribeAlways( + coroutineContext: CoroutineContext = EmptyCoroutineContext, + noinline listener: suspend E.(E) -> Unit +): Listener { + return E::class.subscribeInternal(Handler(coroutineContext) { if (it.bot === this) it.listener(it); ListeningStatus.LISTENING }) } /** @@ -183,12 +209,17 @@ inline fun Bot.subscribeAlways(noinline listener: suspend * 可在任意时候通过 [Listener.complete] 来主动停止监听. * [Bot] 被关闭后事件监听会被 [取消][Listener.cancel]. * + * @param coroutineContext 给事件监听协程的额外的 [CoroutineContext] + * * @see subscribe 获取更多说明 */ @JvmName("subscribeOnceForBot2") @UseExperimental(MiraiInternalAPI::class) -inline fun Bot.subscribeOnce(noinline listener: suspend E.(E) -> Unit): Listener = - E::class.subscribeInternal(Handler { +inline fun Bot.subscribeOnce( + coroutineContext: CoroutineContext = EmptyCoroutineContext, + noinline listener: suspend E.(E) -> Unit +): Listener = + E::class.subscribeInternal(Handler(coroutineContext) { if (it.bot === this) { it.listener(it) ListeningStatus.STOPPED diff --git a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/event/internal/InternalEventListeners.kt b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/event/internal/InternalEventListeners.kt index fe2ff0f8c..fb604edaa 100644 --- a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/event/internal/InternalEventListeners.kt +++ b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/event/internal/InternalEventListeners.kt @@ -31,8 +31,12 @@ fun , E : Event> KClass.subscribeInternal(listener: L): L @PublishedApi @Suppress("FunctionName") -internal fun CoroutineScope.Handler(handler: suspend (E) -> ListeningStatus): Handler { - return Handler(coroutineContext[Job], coroutineContext, handler) +internal fun CoroutineScope.Handler( + coroutineContext: CoroutineContext, + handler: suspend (E) -> ListeningStatus +): Handler { + val context = this.newCoroutineContext(coroutineContext) + return Handler(context[Job], context, handler) } private inline fun inline(block: () -> Unit) = block() diff --git a/mirai-core/src/jvmMain/kotlin/net/mamoe/mirai/event/internal/EventInternalJvm.kt b/mirai-core/src/jvmMain/kotlin/net/mamoe/mirai/event/internal/EventInternalJvm.kt index ccc2a718f..ddae0cdd2 100644 --- a/mirai-core/src/jvmMain/kotlin/net/mamoe/mirai/event/internal/EventInternalJvm.kt +++ b/mirai-core/src/jvmMain/kotlin/net/mamoe/mirai/event/internal/EventInternalJvm.kt @@ -16,15 +16,16 @@ import net.mamoe.mirai.event.ListeningStatus import net.mamoe.mirai.utils.MiraiInternalAPI import java.util.function.Consumer import java.util.function.Function +import kotlin.coroutines.EmptyCoroutineContext @MiraiInternalAPI @Suppress("FunctionName") fun Class._subscribeEventForJaptOnly(scope: CoroutineScope, onEvent: Function): Listener { - return this.kotlin.subscribeInternal(scope.Handler { onEvent.apply(it) }) + return this.kotlin.subscribeInternal(scope.Handler(EmptyCoroutineContext) { onEvent.apply(it) }) } @MiraiInternalAPI @Suppress("FunctionName") fun Class._subscribeEventForJaptOnly(scope: CoroutineScope, onEvent: Consumer): Listener { - return this.kotlin.subscribeInternal(scope.Handler { onEvent.accept(it); ListeningStatus.LISTENING; }) + return this.kotlin.subscribeInternal(scope.Handler(EmptyCoroutineContext) { onEvent.accept(it); ListeningStatus.LISTENING; }) } \ No newline at end of file