Commit f5a60406 authored by Him188's avatar Him188

Add additional `coroutineScope` parameter

parent 37cea58a
...@@ -22,6 +22,7 @@ import kotlin.contracts.ExperimentalContracts ...@@ -22,6 +22,7 @@ import kotlin.contracts.ExperimentalContracts
import kotlin.contracts.InvocationKind import kotlin.contracts.InvocationKind
import kotlin.contracts.contract import kotlin.contracts.contract
import kotlin.coroutines.CoroutineContext import kotlin.coroutines.CoroutineContext
import kotlin.coroutines.EmptyCoroutineContext
import kotlin.jvm.JvmName import kotlin.jvm.JvmName
/* /*
...@@ -98,6 +99,8 @@ interface Listener<in E : Event> : CompletableJob { ...@@ -98,6 +99,8 @@ interface Listener<in E : Event> : CompletableJob {
* *
* **注意:** 事件处理是 `suspend` , 请规范处理 JVM 阻塞方法. * **注意:** 事件处理是 `suspend` , 请规范处理 JVM 阻塞方法.
* *
* @param coroutineContext 给事件监听协程的额外的 [CoroutineContext]
*
* @see subscribeAlways 一直监听 * @see subscribeAlways 一直监听
* @see subscribeOnce 只监听一次 * @see subscribeOnce 只监听一次
* *
...@@ -106,8 +109,11 @@ interface Listener<in E : Event> : CompletableJob { ...@@ -106,8 +109,11 @@ interface Listener<in E : Event> : CompletableJob {
* @see subscribeFriendMessages 监听好友消息 DSL * @see subscribeFriendMessages 监听好友消息 DSL
*/ */
@UseExperimental(MiraiInternalAPI::class) @UseExperimental(MiraiInternalAPI::class)
inline fun <reified E : Event> CoroutineScope.subscribe(noinline handler: suspend E.(E) -> ListeningStatus): Listener<E> = inline fun <reified E : Event> CoroutineScope.subscribe(
E::class.subscribeInternal(Handler { it.handler(it); }) coroutineContext: CoroutineContext = EmptyCoroutineContext,
noinline handler: suspend E.(E) -> ListeningStatus
): Listener<E> =
E::class.subscribeInternal(Handler(coroutineContext) { it.handler(it); })
/** /**
* 在指定的 [CoroutineScope] 下订阅所有 [E] 及其子类事件. * 在指定的 [CoroutineScope] 下订阅所有 [E] 及其子类事件.
...@@ -116,14 +122,19 @@ inline fun <reified E : Event> CoroutineScope.subscribe(noinline handler: suspen ...@@ -116,14 +122,19 @@ inline fun <reified E : Event> CoroutineScope.subscribe(noinline handler: suspen
* 可在任意时候通过 [Listener.complete] 来主动停止监听. * 可在任意时候通过 [Listener.complete] 来主动停止监听.
* [Bot] 被关闭后事件监听会被 [取消][Listener.cancel]. * [Bot] 被关闭后事件监听会被 [取消][Listener.cancel].
* *
* @param coroutineContext 给事件监听协程的额外的 [CoroutineContext]
*
* @see subscribe 获取更多说明 * @see subscribe 获取更多说明
*/ */
@UseExperimental(MiraiInternalAPI::class, ExperimentalContracts::class) @UseExperimental(MiraiInternalAPI::class, ExperimentalContracts::class)
inline fun <reified E : Event> CoroutineScope.subscribeAlways(noinline listener: suspend E.(E) -> Unit): Listener<E> { inline fun <reified E : Event> CoroutineScope.subscribeAlways(
coroutineContext: CoroutineContext = EmptyCoroutineContext,
noinline listener: suspend E.(E) -> Unit
): Listener<E> {
contract { contract {
callsInPlace(listener, InvocationKind.UNKNOWN) 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 <reified E : Event> CoroutineScope.subscribeAlways(noinline listener: ...@@ -133,11 +144,16 @@ inline fun <reified E : Event> CoroutineScope.subscribeAlways(noinline listener:
* 可在任意时候通过 [Listener.complete] 来主动停止监听. * 可在任意时候通过 [Listener.complete] 来主动停止监听.
* [Bot] 被关闭后事件监听会被 [取消][Listener.cancel]. * [Bot] 被关闭后事件监听会被 [取消][Listener.cancel].
* *
* @param coroutineContext 给事件监听协程的额外的 [CoroutineContext]
*
* @see subscribe 获取更多说明 * @see subscribe 获取更多说明
*/ */
@UseExperimental(MiraiInternalAPI::class) @UseExperimental(MiraiInternalAPI::class)
inline fun <reified E : Event> CoroutineScope.subscribeOnce(noinline listener: suspend E.(E) -> Unit): Listener<E> = inline fun <reified E : Event> CoroutineScope.subscribeOnce(
E::class.subscribeInternal(Handler { it.listener(it); ListeningStatus.STOPPED }) coroutineContext: CoroutineContext = EmptyCoroutineContext,
noinline listener: suspend E.(E) -> Unit
): Listener<E> =
E::class.subscribeInternal(Handler(coroutineContext) { it.listener(it); ListeningStatus.STOPPED })
// //
...@@ -153,12 +169,17 @@ inline fun <reified E : Event> CoroutineScope.subscribeOnce(noinline listener: s ...@@ -153,12 +169,17 @@ inline fun <reified E : Event> CoroutineScope.subscribeOnce(noinline listener: s
* 可在任意时候通过 [Listener.complete] 来主动停止监听. * 可在任意时候通过 [Listener.complete] 来主动停止监听.
* [Bot] 被关闭后事件监听会被 [取消][Listener.cancel]. * [Bot] 被关闭后事件监听会被 [取消][Listener.cancel].
* *
* @param coroutineContext 给事件监听协程的额外的 [CoroutineContext]
*
* @see subscribe 获取更多说明 * @see subscribe 获取更多说明
*/ */
@JvmName("subscribeAlwaysForBot") @JvmName("subscribeAlwaysForBot")
@UseExperimental(MiraiInternalAPI::class) @UseExperimental(MiraiInternalAPI::class)
inline fun <reified E : BotEvent> Bot.subscribe(noinline handler: suspend E.(E) -> ListeningStatus): Listener<E> = inline fun <reified E : BotEvent> Bot.subscribe(
E::class.subscribeInternal(Handler { if (it.bot === this) it.handler(it) else ListeningStatus.LISTENING }) coroutineContext: CoroutineContext = EmptyCoroutineContext,
noinline handler: suspend E.(E) -> ListeningStatus
): Listener<E> =
E::class.subscribeInternal(Handler(coroutineContext) { if (it.bot === this) it.handler(it) else ListeningStatus.LISTENING })
/** /**
...@@ -168,12 +189,17 @@ inline fun <reified E : BotEvent> Bot.subscribe(noinline handler: suspend E.(E) ...@@ -168,12 +189,17 @@ inline fun <reified E : BotEvent> Bot.subscribe(noinline handler: suspend E.(E)
* 可在任意时候通过 [Listener.complete] 来主动停止监听. * 可在任意时候通过 [Listener.complete] 来主动停止监听.
* [Bot] 被关闭后事件监听会被 [取消][Listener.cancel]. * [Bot] 被关闭后事件监听会被 [取消][Listener.cancel].
* *
* @param coroutineContext 给事件监听协程的额外的 [CoroutineContext]
*
* @see subscribe 获取更多说明 * @see subscribe 获取更多说明
*/ */
@JvmName("subscribeAlwaysForBot1") @JvmName("subscribeAlwaysForBot1")
@UseExperimental(MiraiInternalAPI::class) @UseExperimental(MiraiInternalAPI::class)
inline fun <reified E : BotEvent> Bot.subscribeAlways(noinline listener: suspend E.(E) -> Unit): Listener<E> { inline fun <reified E : BotEvent> Bot.subscribeAlways(
return E::class.subscribeInternal(Handler { if (it.bot === this) it.listener(it); ListeningStatus.LISTENING }) coroutineContext: CoroutineContext = EmptyCoroutineContext,
noinline listener: suspend E.(E) -> Unit
): Listener<E> {
return E::class.subscribeInternal(Handler(coroutineContext) { if (it.bot === this) it.listener(it); ListeningStatus.LISTENING })
} }
/** /**
...@@ -183,12 +209,17 @@ inline fun <reified E : BotEvent> Bot.subscribeAlways(noinline listener: suspend ...@@ -183,12 +209,17 @@ inline fun <reified E : BotEvent> Bot.subscribeAlways(noinline listener: suspend
* 可在任意时候通过 [Listener.complete] 来主动停止监听. * 可在任意时候通过 [Listener.complete] 来主动停止监听.
* [Bot] 被关闭后事件监听会被 [取消][Listener.cancel]. * [Bot] 被关闭后事件监听会被 [取消][Listener.cancel].
* *
* @param coroutineContext 给事件监听协程的额外的 [CoroutineContext]
*
* @see subscribe 获取更多说明 * @see subscribe 获取更多说明
*/ */
@JvmName("subscribeOnceForBot2") @JvmName("subscribeOnceForBot2")
@UseExperimental(MiraiInternalAPI::class) @UseExperimental(MiraiInternalAPI::class)
inline fun <reified E : BotEvent> Bot.subscribeOnce(noinline listener: suspend E.(E) -> Unit): Listener<E> = inline fun <reified E : BotEvent> Bot.subscribeOnce(
E::class.subscribeInternal(Handler { coroutineContext: CoroutineContext = EmptyCoroutineContext,
noinline listener: suspend E.(E) -> Unit
): Listener<E> =
E::class.subscribeInternal(Handler(coroutineContext) {
if (it.bot === this) { if (it.bot === this) {
it.listener(it) it.listener(it)
ListeningStatus.STOPPED ListeningStatus.STOPPED
......
...@@ -31,8 +31,12 @@ fun <L : Listener<E>, E : Event> KClass<out E>.subscribeInternal(listener: L): L ...@@ -31,8 +31,12 @@ fun <L : Listener<E>, E : Event> KClass<out E>.subscribeInternal(listener: L): L
@PublishedApi @PublishedApi
@Suppress("FunctionName") @Suppress("FunctionName")
internal fun <E : Event> CoroutineScope.Handler(handler: suspend (E) -> ListeningStatus): Handler<E> { internal fun <E : Event> CoroutineScope.Handler(
return Handler(coroutineContext[Job], coroutineContext, handler) coroutineContext: CoroutineContext,
handler: suspend (E) -> ListeningStatus
): Handler<E> {
val context = this.newCoroutineContext(coroutineContext)
return Handler(context[Job], context, handler)
} }
private inline fun inline(block: () -> Unit) = block() private inline fun inline(block: () -> Unit) = block()
......
...@@ -16,15 +16,16 @@ import net.mamoe.mirai.event.ListeningStatus ...@@ -16,15 +16,16 @@ import net.mamoe.mirai.event.ListeningStatus
import net.mamoe.mirai.utils.MiraiInternalAPI import net.mamoe.mirai.utils.MiraiInternalAPI
import java.util.function.Consumer import java.util.function.Consumer
import java.util.function.Function import java.util.function.Function
import kotlin.coroutines.EmptyCoroutineContext
@MiraiInternalAPI @MiraiInternalAPI
@Suppress("FunctionName") @Suppress("FunctionName")
fun <E : Event> Class<E>._subscribeEventForJaptOnly(scope: CoroutineScope, onEvent: Function<E, ListeningStatus>): Listener<E> { fun <E : Event> Class<E>._subscribeEventForJaptOnly(scope: CoroutineScope, onEvent: Function<E, ListeningStatus>): Listener<E> {
return this.kotlin.subscribeInternal(scope.Handler { onEvent.apply(it) }) return this.kotlin.subscribeInternal(scope.Handler(EmptyCoroutineContext) { onEvent.apply(it) })
} }
@MiraiInternalAPI @MiraiInternalAPI
@Suppress("FunctionName") @Suppress("FunctionName")
fun <E : Event> Class<E>._subscribeEventForJaptOnly(scope: CoroutineScope, onEvent: Consumer<E>): Listener<E> { fun <E : Event> Class<E>._subscribeEventForJaptOnly(scope: CoroutineScope, onEvent: Consumer<E>): Listener<E> {
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
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment