|
|
@@ -7,22 +7,28 @@
|
|
|
* https://github.com/mamoe/mirai/blob/master/LICENSE
|
|
|
*/
|
|
|
|
|
|
+@file:Suppress("unused")
|
|
|
+
|
|
|
package net.mamoe.mirai.event
|
|
|
|
|
|
import kotlinx.coroutines.CompletableJob
|
|
|
import kotlinx.coroutines.CoroutineExceptionHandler
|
|
|
import kotlinx.coroutines.CoroutineScope
|
|
|
-import kotlinx.coroutines.GlobalScope
|
|
|
+import kotlinx.coroutines.Job
|
|
|
import kotlinx.coroutines.sync.Mutex
|
|
|
import net.mamoe.mirai.Bot
|
|
|
+import net.mamoe.mirai.event.Listener.EventPriority.*
|
|
|
import net.mamoe.mirai.event.events.BotEvent
|
|
|
import net.mamoe.mirai.event.internal.Handler
|
|
|
import net.mamoe.mirai.event.internal.subscribeInternal
|
|
|
import net.mamoe.mirai.utils.MiraiInternalAPI
|
|
|
+import net.mamoe.mirai.utils.MiraiLogger
|
|
|
+import net.mamoe.mirai.utils.PlannedRemoval
|
|
|
import net.mamoe.mirai.utils.SinceMirai
|
|
|
import kotlin.coroutines.CoroutineContext
|
|
|
import kotlin.coroutines.EmptyCoroutineContext
|
|
|
import kotlin.jvm.JvmName
|
|
|
+import kotlin.jvm.JvmStatic
|
|
|
import kotlin.jvm.JvmSynthetic
|
|
|
import kotlin.reflect.KClass
|
|
|
|
|
|
@@ -40,7 +46,12 @@ enum class ListeningStatus {
|
|
|
LISTENING,
|
|
|
|
|
|
/**
|
|
|
- * 表示已停止
|
|
|
+ * 表示已停止.
|
|
|
+ *
|
|
|
+ * - 若监听器使用 [Listener.ConcurrencyKind.LOCKED],
|
|
|
+ * 在这之后监听器将会被从监听器列表中删除, 因此不再能接收到事件.
|
|
|
+ * - 若使用 [Listener.ConcurrencyKind.CONCURRENT],
|
|
|
+ * 在这之后无法保证立即停止监听.
|
|
|
*/
|
|
|
STOPPED
|
|
|
}
|
|
|
@@ -70,15 +81,45 @@ interface Listener<in E : Event> : CompletableJob {
|
|
|
*/
|
|
|
val concurrencyKind: ConcurrencyKind
|
|
|
|
|
|
+ /**
|
|
|
+ * 事件优先级.
|
|
|
+ *
|
|
|
+ * 在广播时, 事件监听器的调用顺序为 (从左到右):
|
|
|
+ * `[HIGHEST]` -> `[HIGH]` -> `[NORMAL]` -> `[LOW]` -> `[LOWEST]` -> `[MONITOR]`
|
|
|
+ *
|
|
|
+ * - 使用 [MONITOR] 优先级的监听器将会被**并行**调用.
|
|
|
+ * - 使用其他优先级的监听器都将会**按顺序**调用.
|
|
|
+ * 因此一个监听器的挂起可以阻塞事件处理过程而导致低优先级的监听器较晚处理.
|
|
|
+ */
|
|
|
+ @SinceMirai("1.0.0")
|
|
|
enum class EventPriority {
|
|
|
- MONITOR, HIGHEST, HIGH, NORMAL, LOW, LOWEST
|
|
|
|
|
|
+ HIGHEST, HIGH, NORMAL, LOW, LOWEST,
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 最低的优先级.
|
|
|
+ *
|
|
|
+ * 只监听事件而不拦截事件的监听器应使用此监听器.
|
|
|
+ */
|
|
|
+ MONITOR;
|
|
|
+
|
|
|
+ companion object {
|
|
|
+ @JvmStatic
|
|
|
+ internal val valuesExceptMonitor: Array<EventPriority> = arrayOf(HIGHEST, HIGH, NORMAL, LOW, LOWEST)
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
- val priority: EventPriority get() = EventPriority.NORMAL
|
|
|
+ /**
|
|
|
+ * 事件优先级
|
|
|
+ * @see [EventPriority]
|
|
|
+ */
|
|
|
+ val priority: EventPriority get() = NORMAL
|
|
|
|
|
|
+ /**
|
|
|
+ * 这个方法将会调用 [subscribe] 时提供的参数 `noinline handler: suspend E.(E) -> ListeningStatus`.
|
|
|
+ * 并捕捉其异常.
|
|
|
+ */
|
|
|
suspend fun onEvent(event: E): ListeningStatus
|
|
|
-
|
|
|
}
|
|
|
|
|
|
// region 顶层方法 创建当前 coroutineContext 下的子 Job
|
|
|
@@ -87,50 +128,59 @@ interface Listener<in E : Event> : CompletableJob {
|
|
|
* 在指定的 [CoroutineScope] 下订阅所有 [E] 及其子类事件.
|
|
|
* 每当 [事件广播][Event.broadcast] 时, [handler] 都会被执行.
|
|
|
*
|
|
|
- * 当 [handler] 返回 [ListeningStatus.STOPPED] 时停止监听.
|
|
|
- * 或 [Listener.complete] 后结束.
|
|
|
- *
|
|
|
- * 这个函数返回 [Listener], 它是一个 [CompletableJob]. 请注意它除非被 [Listener.complete] 或 [Listener.cancel], 则不会完成.
|
|
|
- * 例:
|
|
|
- * ```kotlin
|
|
|
- * runBlocking { // this: CoroutineScope
|
|
|
- * subscribe<Event> { /* 一些处理 */ } // 返回 Listener, 即 CompletableJob
|
|
|
- * }
|
|
|
- * foo()
|
|
|
- * ```
|
|
|
- * `runBlocking` 不会结束, 也就是下一行 `foo()` 不会被执行. 直到监听时创建的 `Listener` 被停止.
|
|
|
*
|
|
|
+ * ### 创建监听
|
|
|
*
|
|
|
+ * #### 单个 [Bot] 的事件监听
|
|
|
* 要创建一个仅在某个机器人在线时的监听, 请在 [Bot] 下调用本函数 (因为 [Bot] 也实现 [CoroutineScope]).
|
|
|
* 这种方式创建的监听会自动筛选 [Bot].
|
|
|
- * ```kotlin
|
|
|
+ * ```
|
|
|
* bot1.subscribe<BotEvent> { /* 只会处理来自 bot1 的事件 */ }
|
|
|
* ```
|
|
|
*
|
|
|
- *
|
|
|
- * 要创建一个全局都存在的监听(不推荐), 即守护协程, 请在 [GlobalScope] 下调用本函数:
|
|
|
- * ```kotlin
|
|
|
+ * #### 全局范围监听
|
|
|
+ * 要创建一个全局都存在的监听(不推荐), 请使用除 [Bot] 外的任意 [协程作用域][CoroutineScope] 调用本函数:
|
|
|
+ * ```
|
|
|
* GlobalScope.subscribe<Event> { /* 会收到来自全部 Bot 的事件和与 Bot 不相关的事件 */ }
|
|
|
* ```
|
|
|
*
|
|
|
*
|
|
|
+ * ### 异常处理
|
|
|
* 事件处理时的 [CoroutineContext] 为调用本函数时的 [receiver][this] 的 [CoroutineScope.coroutineContext].
|
|
|
* 因此:
|
|
|
- * - 事件处理时抛出的异常将会在 [this] 的 [CoroutineExceptionHandler] 中处理
|
|
|
- * 若 [this] 没有 [CoroutineExceptionHandler], 则在事件广播方的 [CoroutineExceptionHandler] 处理
|
|
|
- * 若均找不到, 则会触发 logger warning.
|
|
|
+ * - 当参数 [handler] 处理抛出异常时, 将会按如下顺序寻找 [CoroutineExceptionHandler] 处理异常:
|
|
|
+ * 1. 参数 [coroutineContext]
|
|
|
+ * 2. 接收者 [this] 的 [CoroutineScope.coroutineContext]
|
|
|
+ * 3. [Event.broadcast] 调用者的 [coroutineContext]
|
|
|
+ * 4. 若事件为 [BotEvent], 则从 [BotEvent.bot] 获取到 [Bot], 进而在 [Bot.coroutineContext] 中寻找
|
|
|
+ * 5. 若以上四个步骤均无法获取 [CoroutineExceptionHandler], 则使用 [MiraiLogger.Companion] 通过日志记录. 但这种情况理论上不应发生.
|
|
|
* - 事件处理时抛出异常不会停止监听器.
|
|
|
* - 建议在事件处理中 (即 [handler] 里) 处理异常,
|
|
|
- * 或在 [this] 的 [CoroutineScope.coroutineContext] 中添加 [CoroutineExceptionHandler].
|
|
|
+ * 或在参数 [coroutineContext] 中添加 [CoroutineExceptionHandler].
|
|
|
+ *
|
|
|
+ *
|
|
|
+ * ### 停止监听
|
|
|
+ * 当 [handler] 返回 [ListeningStatus.STOPPED] 时停止监听.
|
|
|
+ * 或 [Listener.complete] 后结束.
|
|
|
+ *
|
|
|
+ * 这个函数返回 [Listener], 它是一个 [CompletableJob]. 它会成为 [CoroutineScope] 的一个 [子任务][Job]
|
|
|
+ * 例:
|
|
|
+ * ```
|
|
|
+ * runBlocking { // this: CoroutineScope
|
|
|
+ * subscribe<Event> { /* 一些处理 */ } // 返回 Listener, 即 CompletableJob
|
|
|
+ * }
|
|
|
+ * foo()
|
|
|
+ * ```
|
|
|
+ * `runBlocking` 不会结束, 也就是下一行 `foo()` 不会被执行. 直到监听时创建的 `Listener` 被停止.
|
|
|
*
|
|
|
*
|
|
|
- * **注意:** 事件处理是 `suspend` 的, 请规范处理 JVM 阻塞方法.
|
|
|
*
|
|
|
* @param coroutineContext 给事件监听协程的额外的 [CoroutineContext].
|
|
|
* @param concurrency 并发类型. 查看 [Listener.ConcurrencyKind]
|
|
|
* @param priority 监听优先级,优先级越高越先执行
|
|
|
+ * @param handler 事件处理器. 在接收到事件时会调用这个处理器. 其返回值意义参考 [ListeningStatus]. 其异常处理参考上文
|
|
|
*
|
|
|
- * @see syncFromEvent 监听一个事件, 并尝试从这个事件中获取一个值.
|
|
|
+ * @see syncFromEvent 挂起当前协程, 监听一个事件, 并尝试从这个事件中**同步**一个值
|
|
|
* @see asyncFromEvent 异步监听一个事件, 并尝试从这个事件中获取一个值.
|
|
|
*
|
|
|
* @see selectMessages 以 `when` 的语法 '选择' 即将到来的一条消息.
|
|
|
@@ -142,15 +192,18 @@ interface Listener<in E : Event> : CompletableJob {
|
|
|
* @see subscribeMessages 监听消息 DSL
|
|
|
* @see subscribeGroupMessages 监听群消息 DSL
|
|
|
* @see subscribeFriendMessages 监听好友消息 DSL
|
|
|
+ * @see subscribeTempMessages 监听临时会话消息 DSL
|
|
|
*/
|
|
|
inline fun <reified E : Event> CoroutineScope.subscribe(
|
|
|
coroutineContext: CoroutineContext = EmptyCoroutineContext,
|
|
|
concurrency: Listener.ConcurrencyKind = Listener.ConcurrencyKind.LOCKED,
|
|
|
- priority: Listener.EventPriority = Listener.EventPriority.NORMAL,
|
|
|
+ priority: Listener.EventPriority = NORMAL,
|
|
|
noinline handler: suspend E.(E) -> ListeningStatus
|
|
|
): Listener<E> = subscribe(E::class, coroutineContext, concurrency, priority, handler)
|
|
|
|
|
|
/**
|
|
|
+ * 与 [subscribe] 的区别是接受 [eventClass] 参数, 而不使用 `reified` 泛型
|
|
|
+ *
|
|
|
* @see CoroutineScope.subscribe
|
|
|
*/
|
|
|
@SinceMirai("0.38.0")
|
|
|
@@ -158,7 +211,7 @@ fun <E : Event> CoroutineScope.subscribe(
|
|
|
eventClass: KClass<E>,
|
|
|
coroutineContext: CoroutineContext = EmptyCoroutineContext,
|
|
|
concurrency: Listener.ConcurrencyKind = Listener.ConcurrencyKind.LOCKED,
|
|
|
- priority: Listener.EventPriority = Listener.EventPriority.NORMAL,
|
|
|
+ priority: Listener.EventPriority = NORMAL,
|
|
|
handler: suspend E.(E) -> ListeningStatus
|
|
|
): Listener<E> = eventClass.subscribeInternal(Handler(coroutineContext, concurrency, priority) { it.handler(it); })
|
|
|
|
|
|
@@ -167,7 +220,7 @@ fun <E : Event> CoroutineScope.subscribe(
|
|
|
* 每当 [事件广播][Event.broadcast] 时, [listener] 都会被执行.
|
|
|
*
|
|
|
* 可在任意时候通过 [Listener.complete] 来主动停止监听.
|
|
|
- * [Bot] 被关闭后事件监听会被 [取消][Listener.cancel].
|
|
|
+ * [CoroutineScope] 被关闭后事件监听会被 [取消][Listener.cancel].
|
|
|
*
|
|
|
* @param coroutineContext 给事件监听协程的额外的 [CoroutineContext]
|
|
|
* @param priority 处理优先级, 优先级高的先执行
|
|
|
@@ -177,7 +230,7 @@ fun <E : Event> CoroutineScope.subscribe(
|
|
|
inline fun <reified E : Event> CoroutineScope.subscribeAlways(
|
|
|
coroutineContext: CoroutineContext = EmptyCoroutineContext,
|
|
|
concurrency: Listener.ConcurrencyKind = Listener.ConcurrencyKind.LOCKED,
|
|
|
- priority: Listener.EventPriority = Listener.EventPriority.NORMAL,
|
|
|
+ priority: Listener.EventPriority = NORMAL,
|
|
|
noinline listener: suspend E.(E) -> Unit
|
|
|
): Listener<E> = subscribeAlways(E::class, coroutineContext, concurrency, priority, listener)
|
|
|
|
|
|
@@ -190,7 +243,7 @@ fun <E : Event> CoroutineScope.subscribeAlways(
|
|
|
eventClass: KClass<E>,
|
|
|
coroutineContext: CoroutineContext = EmptyCoroutineContext,
|
|
|
concurrency: Listener.ConcurrencyKind = Listener.ConcurrencyKind.LOCKED,
|
|
|
- priority: Listener.EventPriority = Listener.EventPriority.NORMAL,
|
|
|
+ priority: Listener.EventPriority = NORMAL,
|
|
|
listener: suspend E.(E) -> Unit
|
|
|
): Listener<E> = eventClass.subscribeInternal(
|
|
|
Handler(coroutineContext, concurrency, priority) { it.listener(it); ListeningStatus.LISTENING }
|
|
|
@@ -201,7 +254,7 @@ fun <E : Event> CoroutineScope.subscribeAlways(
|
|
|
* 仅在第一次 [事件广播][Event.broadcast] 时, [listener] 会被执行.
|
|
|
*
|
|
|
* 可在任意时候通过 [Listener.complete] 来主动停止监听.
|
|
|
- * [Bot] 被关闭后事件监听会被 [取消][Listener.cancel].
|
|
|
+ * [CoroutineScope] 被关闭后事件监听会被 [取消][Listener.cancel].
|
|
|
*
|
|
|
* @param coroutineContext 给事件监听协程的额外的 [CoroutineContext]
|
|
|
* @param priority 处理优先级, 优先级高的先执行
|
|
|
@@ -211,7 +264,7 @@ fun <E : Event> CoroutineScope.subscribeAlways(
|
|
|
@JvmSynthetic
|
|
|
inline fun <reified E : Event> CoroutineScope.subscribeOnce(
|
|
|
coroutineContext: CoroutineContext = EmptyCoroutineContext,
|
|
|
- priority: Listener.EventPriority = Listener.EventPriority.NORMAL,
|
|
|
+ priority: Listener.EventPriority = NORMAL,
|
|
|
noinline listener: suspend E.(E) -> Unit
|
|
|
): Listener<E> = subscribeOnce(E::class, coroutineContext, priority, listener)
|
|
|
|
|
|
@@ -222,7 +275,7 @@ inline fun <reified E : Event> CoroutineScope.subscribeOnce(
|
|
|
fun <E : Event> CoroutineScope.subscribeOnce(
|
|
|
eventClass: KClass<E>,
|
|
|
coroutineContext: CoroutineContext = EmptyCoroutineContext,
|
|
|
- priority: Listener.EventPriority = Listener.EventPriority.NORMAL,
|
|
|
+ priority: Listener.EventPriority = NORMAL,
|
|
|
listener: suspend E.(E) -> Unit
|
|
|
): Listener<E> = eventClass.subscribeInternal(
|
|
|
Handler(coroutineContext, Listener.ConcurrencyKind.LOCKED, priority) { it.listener(it); ListeningStatus.STOPPED }
|
|
|
@@ -234,17 +287,10 @@ fun <E : Event> CoroutineScope.subscribeOnce(
|
|
|
|
|
|
|
|
|
/**
|
|
|
- * 在 [Bot] 的 [CoroutineScope] 下订阅所有 [E] 及其子类事件.
|
|
|
- * 每当 [事件广播][Event.broadcast] 时, [handler] 都会被执行,
|
|
|
- * 当 [handler] 返回 [ListeningStatus.STOPPED] 时停止监听
|
|
|
- *
|
|
|
- * 可在任意时候通过 [Listener.complete] 来主动停止监听.
|
|
|
- * [Bot] 被关闭后事件监听会被 [取消][Listener.cancel].
|
|
|
- *
|
|
|
- * @param coroutineContext 给事件监听协程的额外的 [CoroutineContext]
|
|
|
- * @param priority 事件优先级, 优先级高的先处理
|
|
|
+ * **注意:** 与 [CoroutineScope.subscribe] 不同的是,
|
|
|
+ * [Bot.subscribe] 会筛选事件来源 [Bot], 只监听来自 [this] 的事件.
|
|
|
*
|
|
|
- * @see subscribe 获取更多说明
|
|
|
+ * @see CoroutineScope.subscribe 获取更多说明
|
|
|
*/
|
|
|
@JvmSynthetic
|
|
|
@JvmName("subscribeAlwaysForBot")
|
|
|
@@ -252,11 +298,14 @@ fun <E : Event> CoroutineScope.subscribeOnce(
|
|
|
inline fun <reified E : BotEvent> Bot.subscribe(
|
|
|
coroutineContext: CoroutineContext = EmptyCoroutineContext,
|
|
|
concurrency: Listener.ConcurrencyKind = Listener.ConcurrencyKind.LOCKED,
|
|
|
- priority: Listener.EventPriority = Listener.EventPriority.NORMAL,
|
|
|
+ priority: Listener.EventPriority = NORMAL,
|
|
|
noinline handler: suspend E.(E) -> ListeningStatus
|
|
|
): Listener<E> = this.subscribe(E::class, coroutineContext, concurrency, priority, handler)
|
|
|
|
|
|
/**
|
|
|
+ * **注意:** 与 [CoroutineScope.subscribe] 不同的是,
|
|
|
+ * [Bot.subscribe] 会筛选事件来源 [Bot], 只监听来自 [this] 的事件.
|
|
|
+ *
|
|
|
* @see Bot.subscribe
|
|
|
*/
|
|
|
@SinceMirai("0.38.0")
|
|
|
@@ -264,7 +313,7 @@ fun <E : BotEvent> Bot.subscribe(
|
|
|
eventClass: KClass<E>,
|
|
|
coroutineContext: CoroutineContext = EmptyCoroutineContext,
|
|
|
concurrency: Listener.ConcurrencyKind = Listener.ConcurrencyKind.LOCKED,
|
|
|
- priority: Listener.EventPriority = Listener.EventPriority.NORMAL,
|
|
|
+ priority: Listener.EventPriority = NORMAL,
|
|
|
handler: suspend E.(E) -> ListeningStatus
|
|
|
): Listener<E> = eventClass.subscribeInternal(
|
|
|
Handler(
|
|
|
@@ -275,16 +324,10 @@ fun <E : BotEvent> Bot.subscribe(
|
|
|
)
|
|
|
|
|
|
/**
|
|
|
- * 在 [Bot] 的 [CoroutineScope] 下订阅所有 [E] 及其子类事件.
|
|
|
- * 每当 [事件广播][Event.broadcast] 时, [listener] 都会被执行.
|
|
|
- *
|
|
|
- * 可在任意时候通过 [Listener.complete] 来主动停止监听.
|
|
|
- * [Bot] 被关闭后事件监听会被 [取消][Listener.cancel].
|
|
|
- *
|
|
|
- * @param coroutineContext 给事件监听协程的额外的 [CoroutineContext]
|
|
|
- * @param priority 事件优先级, 优先级高的先处理
|
|
|
+ * **注意:** 与 [CoroutineScope.subscribe] 不同的是,
|
|
|
+ * [Bot.subscribe] 会筛选事件来源 [Bot], 只监听来自 [this] 的事件.
|
|
|
*
|
|
|
- * @see subscribe 获取更多说明
|
|
|
+ * @see CoroutineScope.subscribeAlways 获取更多说明
|
|
|
*/
|
|
|
@JvmSynthetic
|
|
|
@JvmName("subscribeAlwaysForBot1")
|
|
|
@@ -292,11 +335,14 @@ fun <E : BotEvent> Bot.subscribe(
|
|
|
inline fun <reified E : BotEvent> Bot.subscribeAlways(
|
|
|
coroutineContext: CoroutineContext = EmptyCoroutineContext,
|
|
|
concurrency: Listener.ConcurrencyKind = Listener.ConcurrencyKind.CONCURRENT,
|
|
|
- priority: Listener.EventPriority = Listener.EventPriority.NORMAL,
|
|
|
+ priority: Listener.EventPriority = NORMAL,
|
|
|
noinline listener: suspend E.(E) -> Unit
|
|
|
): Listener<E> = subscribeAlways(E::class, coroutineContext, concurrency, priority, listener)
|
|
|
|
|
|
/**
|
|
|
+ * **注意:** 与 [CoroutineScope.subscribe] 不同的是,
|
|
|
+ * [Bot.subscribe] 会筛选事件来源 [Bot], 只监听来自 [this] 的事件.
|
|
|
+ *
|
|
|
* @see Bot.subscribeAlways
|
|
|
*/
|
|
|
@SinceMirai("0.38.0")
|
|
|
@@ -304,40 +350,37 @@ fun <E : BotEvent> Bot.subscribeAlways(
|
|
|
eventClass: KClass<E>,
|
|
|
coroutineContext: CoroutineContext = EmptyCoroutineContext,
|
|
|
concurrency: Listener.ConcurrencyKind = Listener.ConcurrencyKind.CONCURRENT,
|
|
|
- priority: Listener.EventPriority = Listener.EventPriority.NORMAL,
|
|
|
+ priority: Listener.EventPriority = NORMAL,
|
|
|
listener: suspend E.(E) -> Unit
|
|
|
): Listener<E> = eventClass.subscribeInternal(
|
|
|
Handler(coroutineContext, concurrency, priority) { if (it.bot === this) it.listener(it); ListeningStatus.LISTENING }
|
|
|
)
|
|
|
|
|
|
/**
|
|
|
- * 在 [Bot] 的 [CoroutineScope] 下订阅所有 [E] 及其子类事件.
|
|
|
- * 仅在第一次 [事件广播][Event.broadcast] 时, [listener] 会被执行.
|
|
|
- *
|
|
|
- * 可在任意时候通过 [Listener.complete] 来主动停止监听.
|
|
|
- * [Bot] 被关闭后事件监听会被 [取消][Listener.cancel].
|
|
|
+ * **注意:** 与 [CoroutineScope.subscribe] 不同的是,
|
|
|
+ * [Bot.subscribe] 会筛选事件来源 [Bot], 只监听来自 [this] 的事件.
|
|
|
*
|
|
|
- * @param coroutineContext 给事件监听协程的额外的 [CoroutineContext]
|
|
|
- * @param priority 事件优先级, 高的先处理
|
|
|
- *
|
|
|
- * @see subscribe 获取更多说明
|
|
|
+ * @see subscribeOnce 获取更多说明
|
|
|
*/
|
|
|
@JvmSynthetic
|
|
|
@JvmName("subscribeOnceForBot2")
|
|
|
inline fun <reified E : BotEvent> Bot.subscribeOnce(
|
|
|
coroutineContext: CoroutineContext = EmptyCoroutineContext,
|
|
|
- priority: Listener.EventPriority = Listener.EventPriority.NORMAL,
|
|
|
+ priority: Listener.EventPriority = NORMAL,
|
|
|
noinline listener: suspend E.(E) -> Unit
|
|
|
): Listener<E> = subscribeOnce(E::class, coroutineContext, priority, listener)
|
|
|
|
|
|
/**
|
|
|
+ * **注意:** 与 [CoroutineScope.subscribe] 不同的是,
|
|
|
+ * [Bot.subscribe] 会筛选事件来源 [Bot], 只监听来自 [this] 的事件.
|
|
|
+ *
|
|
|
* @see Bot.subscribeOnce
|
|
|
*/
|
|
|
@SinceMirai("0.38.0")
|
|
|
fun <E : BotEvent> Bot.subscribeOnce(
|
|
|
eventClass: KClass<E>,
|
|
|
coroutineContext: CoroutineContext = EmptyCoroutineContext,
|
|
|
- priority: Listener.EventPriority = Listener.EventPriority.NORMAL,
|
|
|
+ priority: Listener.EventPriority = NORMAL,
|
|
|
listener: suspend E.(E) -> Unit
|
|
|
): Listener<E> =
|
|
|
eventClass.subscribeInternal(Handler(coroutineContext, Listener.ConcurrencyKind.LOCKED, priority) {
|
|
|
@@ -351,6 +394,7 @@ fun <E : BotEvent> Bot.subscribeOnce(
|
|
|
|
|
|
// region 为了兼容旧版本的方法
|
|
|
|
|
|
+@PlannedRemoval("1.2.0")
|
|
|
@JvmName("subscribe")
|
|
|
@JvmSynthetic
|
|
|
@Deprecated("for binary compatibility", level = DeprecationLevel.HIDDEN)
|
|
|
@@ -362,9 +406,11 @@ inline fun <reified E : Event> CoroutineScope.subscribeDeprecated(
|
|
|
): Listener<E> = subscribe(
|
|
|
coroutineContext = coroutineContext,
|
|
|
concurrency = concurrency,
|
|
|
+ priority = MONITOR,
|
|
|
handler = handler
|
|
|
)
|
|
|
|
|
|
+@PlannedRemoval("1.2.0")
|
|
|
@JvmName("subscribe")
|
|
|
@JvmSynthetic
|
|
|
@Deprecated("for binary compatibility", level = DeprecationLevel.HIDDEN)
|
|
|
@@ -378,9 +424,11 @@ fun <E : Event> CoroutineScope.subscribeDeprecated(
|
|
|
eventClass = eventClass,
|
|
|
coroutineContext = coroutineContext,
|
|
|
concurrency = concurrency,
|
|
|
+ priority = MONITOR,
|
|
|
handler = handler
|
|
|
)
|
|
|
|
|
|
+@PlannedRemoval("1.2.0")
|
|
|
@JvmName("subscribeAlways")
|
|
|
@JvmSynthetic
|
|
|
@Deprecated("for binary compatibility", level = DeprecationLevel.HIDDEN)
|
|
|
@@ -392,9 +440,11 @@ inline fun <reified E : Event> CoroutineScope.subscribeAlwaysDeprecated(
|
|
|
): Listener<E> = subscribeAlways(
|
|
|
coroutineContext = coroutineContext,
|
|
|
concurrency = concurrency,
|
|
|
+ priority = MONITOR,
|
|
|
listener = listener
|
|
|
)
|
|
|
|
|
|
+@PlannedRemoval("1.2.0")
|
|
|
@JvmName("subscribeAlways")
|
|
|
@JvmSynthetic
|
|
|
@Deprecated("for binary compatibility", level = DeprecationLevel.HIDDEN)
|
|
|
@@ -408,9 +458,11 @@ fun <E : Event> CoroutineScope.subscribeAlwaysDeprecated(
|
|
|
eventClass = eventClass,
|
|
|
coroutineContext = coroutineContext,
|
|
|
concurrency = concurrency,
|
|
|
+ priority = MONITOR,
|
|
|
listener = listener
|
|
|
)
|
|
|
|
|
|
+@PlannedRemoval("1.2.0")
|
|
|
@JvmName("subscribeOnce")
|
|
|
@JvmSynthetic
|
|
|
@Deprecated("for binary compatibility", level = DeprecationLevel.HIDDEN)
|
|
|
@@ -418,8 +470,13 @@ fun <E : Event> CoroutineScope.subscribeAlwaysDeprecated(
|
|
|
inline fun <reified E : Event> CoroutineScope.subscribeOnceDeprecated(
|
|
|
coroutineContext: CoroutineContext = EmptyCoroutineContext,
|
|
|
noinline listener: suspend E.(E) -> Unit
|
|
|
-): Listener<E> = subscribeOnce(coroutineContext = coroutineContext, listener = listener)
|
|
|
+): Listener<E> = subscribeOnce(
|
|
|
+ coroutineContext = coroutineContext,
|
|
|
+ priority = MONITOR,
|
|
|
+ listener = listener
|
|
|
+)
|
|
|
|
|
|
+@PlannedRemoval("1.2.0")
|
|
|
@JvmName("subscribeOnce")
|
|
|
@JvmSynthetic
|
|
|
@Deprecated("for binary compatibility", level = DeprecationLevel.HIDDEN)
|
|
|
@@ -431,9 +488,11 @@ fun <E : Event> CoroutineScope.subscribeOnceDeprecated(
|
|
|
): Listener<E> = subscribeOnce(
|
|
|
eventClass = eventClass,
|
|
|
coroutineContext = coroutineContext,
|
|
|
+ priority = MONITOR,
|
|
|
listener = listener
|
|
|
)
|
|
|
|
|
|
+@PlannedRemoval("1.2.0")
|
|
|
@JvmSynthetic
|
|
|
@JvmName("subscribeAlwaysForBot")
|
|
|
@OptIn(MiraiInternalAPI::class)
|
|
|
@@ -446,9 +505,11 @@ inline fun <reified E : BotEvent> Bot.subscribeDeprecated(
|
|
|
): Listener<E> = this.subscribe(
|
|
|
coroutineContext = coroutineContext,
|
|
|
concurrency = concurrency,
|
|
|
+ priority = MONITOR,
|
|
|
handler = handler
|
|
|
)
|
|
|
|
|
|
+@PlannedRemoval("1.2.0")
|
|
|
@JvmSynthetic
|
|
|
@JvmName("subscribe")
|
|
|
@Deprecated("for binary compatibility", level = DeprecationLevel.HIDDEN)
|
|
|
@@ -462,9 +523,11 @@ fun <E : BotEvent> Bot.subscribeDeprecated(
|
|
|
eventClass = eventClass,
|
|
|
coroutineContext = coroutineContext,
|
|
|
concurrency = concurrency,
|
|
|
+ priority = MONITOR,
|
|
|
handler = handler
|
|
|
)
|
|
|
|
|
|
+@PlannedRemoval("1.2.0")
|
|
|
@JvmSynthetic
|
|
|
@JvmName("subscribeAlwaysForBot1")
|
|
|
@Deprecated("for binary compatibility", level = DeprecationLevel.HIDDEN)
|
|
|
@@ -477,9 +540,11 @@ inline fun <reified E : BotEvent> Bot.subscribeAlwaysDeprecated(
|
|
|
): Listener<E> = subscribeAlways(
|
|
|
coroutineContext = coroutineContext,
|
|
|
concurrency = concurrency,
|
|
|
+ priority = MONITOR,
|
|
|
listener = listener
|
|
|
)
|
|
|
|
|
|
+@PlannedRemoval("1.2.0")
|
|
|
@JvmSynthetic
|
|
|
@JvmName("subscribeAlways")
|
|
|
@Deprecated("for binary compatibility", level = DeprecationLevel.HIDDEN)
|
|
|
@@ -493,9 +558,11 @@ fun <E : BotEvent> Bot.subscribeAlwaysDeprecated(
|
|
|
eventClass = eventClass,
|
|
|
coroutineContext = coroutineContext,
|
|
|
concurrency = concurrency,
|
|
|
+ priority = MONITOR,
|
|
|
listener = listener
|
|
|
)
|
|
|
|
|
|
+@PlannedRemoval("1.2.0")
|
|
|
@JvmSynthetic
|
|
|
@JvmName("subscribeOnceForBot2")
|
|
|
@Deprecated("for binary compatibility", level = DeprecationLevel.HIDDEN)
|
|
|
@@ -505,9 +572,11 @@ inline fun <reified E : BotEvent> Bot.subscribeOnceDeprecated(
|
|
|
noinline listener: suspend E.(E) -> Unit
|
|
|
): Listener<E> = subscribeOnce(
|
|
|
coroutineContext = coroutineContext,
|
|
|
+ priority = MONITOR,
|
|
|
listener = listener
|
|
|
)
|
|
|
|
|
|
+@PlannedRemoval("1.2.0")
|
|
|
@JvmSynthetic
|
|
|
@JvmName("subscribeOnce")
|
|
|
@Deprecated("for binary compatibility", level = DeprecationLevel.HIDDEN)
|
|
|
@@ -519,6 +588,7 @@ fun <E : BotEvent> Bot.subscribeOnceDeprecated(
|
|
|
): Listener<E> = subscribeOnce(
|
|
|
eventClass = eventClass,
|
|
|
coroutineContext = coroutineContext,
|
|
|
+ priority = MONITOR,
|
|
|
listener = listener
|
|
|
)
|
|
|
// endregion
|