From 619dafa1ae237a28cd2d9658f3eb6deb7126cf63 Mon Sep 17 00:00:00 2001 From: Him188 Date: Fri, 8 Jan 2021 12:41:42 +0800 Subject: [PATCH] [Review] Move Listener.ConcurrencyKind and Listener.EventPriority to top-level --- .../src/commonMain/kotlin/event/Event.kt | 4 +- .../commonMain/kotlin/event/EventChannel.kt | 32 +++---- .../event/EventChannelKotlinExtensions.kt | 16 ++-- .../kotlin/event/JvmMethodListeners.kt | 8 +- .../src/commonMain/kotlin/event/Listener.kt | 94 +++++++++---------- .../src/commonMain/kotlin/event/nextEvent.kt | 8 +- .../src/commonMain/kotlin/event/select.kt | 14 +-- .../kotlin/event/subscribeMessages.kt | 30 +++--- .../commonMain/kotlin/event/syncFromEvent.kt | 10 +- .../internal/event/InternalEventListeners.kt | 20 ++-- .../src/commonMain/kotlin/message/utils.kt | 11 +-- .../src/jvmTest/kotlin/event/EventTests.kt | 10 +- .../kotlin/event/JvmMethodEventsTest.kt | 6 +- .../src/commonMain/kotlin/AbstractBot.kt | 4 +- .../network/QQAndroidBotNetworkHandler.kt | 2 +- 15 files changed, 134 insertions(+), 135 deletions(-) diff --git a/mirai-core-api/src/commonMain/kotlin/event/Event.kt b/mirai-core-api/src/commonMain/kotlin/event/Event.kt index 528f97430..cdf4a1620 100644 --- a/mirai-core-api/src/commonMain/kotlin/event/Event.kt +++ b/mirai-core-api/src/commonMain/kotlin/event/Event.kt @@ -53,9 +53,9 @@ public interface Event { * * 当事件被 [拦截][Event.intercept] 后, 优先级较低 (靠右) 的监听器将不会被调用. * - * 优先级为 [Listener.EventPriority.MONITOR] 的监听器不应该调用这个函数. + * 优先级为 [EventPriority.MONITOR] 的监听器不应该调用这个函数. * - * @see Listener.EventPriority 查看优先级相关信息 + * @see EventPriority 查看优先级相关信息 */ public fun intercept() } diff --git a/mirai-core-api/src/commonMain/kotlin/event/EventChannel.kt b/mirai-core-api/src/commonMain/kotlin/event/EventChannel.kt index 4d32e567a..5fcb986d0 100644 --- a/mirai-core-api/src/commonMain/kotlin/event/EventChannel.kt +++ b/mirai-core-api/src/commonMain/kotlin/event/EventChannel.kt @@ -19,8 +19,8 @@ import kotlinx.coroutines.* import kotlinx.coroutines.channels.Channel import kotlinx.coroutines.sync.Mutex import net.mamoe.mirai.Bot -import net.mamoe.mirai.event.Listener.ConcurrencyKind.CONCURRENT -import net.mamoe.mirai.event.Listener.ConcurrencyKind.LOCKED +import net.mamoe.mirai.event.ConcurrencyKind.CONCURRENT +import net.mamoe.mirai.event.ConcurrencyKind.LOCKED import net.mamoe.mirai.event.events.BotEvent import net.mamoe.mirai.internal.event.GlobalEventListeners import net.mamoe.mirai.internal.event.Handler @@ -80,7 +80,7 @@ public open class EventChannel @JvmOverloads internal con public fun asChannel( capacity: Int = Channel.RENDEZVOUS, coroutineContext: CoroutineContext = EmptyCoroutineContext, - concurrency: Listener.ConcurrencyKind = CONCURRENT, + concurrency: ConcurrencyKind = CONCURRENT, priority: EventPriority = EventPriority.NORMAL, ): Channel { val channel = Channel(capacity) @@ -120,7 +120,7 @@ public open class EventChannel @JvmOverloads internal con * [filter] 允许挂起协程. **过滤器的挂起将被认为是事件监听器的挂起**. * * 过滤器挂起是否会影响事件处理, - * 取决于 [subscribe] 时的 [Listener.ConcurrencyKind] 和 [Listener.EventPriority]. + * 取决于 [subscribe] 时的 [ConcurrencyKind] 和 [EventPriority]. * * ## 过滤器异常处理 * 若 [filter] 抛出异常, 将被包装为 [ExceptionInEventChannelFilterException] 并重新抛出. @@ -305,11 +305,11 @@ public open class EventChannel @JvmOverloads internal con * ## 并发安全性 * 基于 [concurrency] 参数, 事件监听器可以被允许并行执行. * - * - 若 [concurrency] 为 [Listener.ConcurrencyKind.CONCURRENT], [handler] 可能被并行调用, 需要保证并发安全. - * - 若 [concurrency] 为 [Listener.ConcurrencyKind.LOCKED], [handler] 会被 [Mutex] 限制. + * - 若 [concurrency] 为 [ConcurrencyKind.CONCURRENT], [handler] 可能被并行调用, 需要保证并发安全. + * - 若 [concurrency] 为 [ConcurrencyKind.LOCKED], [handler] 会被 [Mutex] 限制. * * @param coroutineContext 在 [defaultCoroutineContext] 的基础上, 给事件监听协程的额外的 [CoroutineContext]. - * @param concurrency 并发类型. 查看 [Listener.ConcurrencyKind] + * @param concurrency 并发类型. 查看 [ConcurrencyKind] * @param priority 监听优先级,优先级越高越先执行 * @param handler 事件处理器. 在接收到事件时会调用这个处理器. 其返回值意义参考 [ListeningStatus]. 其异常处理参考上文 * @@ -331,7 +331,7 @@ public open class EventChannel @JvmOverloads internal con @JvmSynthetic public inline fun subscribe( coroutineContext: CoroutineContext = EmptyCoroutineContext, - concurrency: Listener.ConcurrencyKind = LOCKED, + concurrency: ConcurrencyKind = LOCKED, priority: EventPriority = EventPriority.NORMAL, noinline handler: suspend E.(E) -> ListeningStatus ): Listener = subscribe(E::class, coroutineContext, concurrency, priority, handler) @@ -346,7 +346,7 @@ public open class EventChannel @JvmOverloads internal con public fun subscribe( eventClass: KClass, coroutineContext: CoroutineContext = EmptyCoroutineContext, - concurrency: Listener.ConcurrencyKind = LOCKED, + concurrency: ConcurrencyKind = LOCKED, priority: EventPriority = EventPriority.NORMAL, handler: suspend E.(E) -> ListeningStatus ): Listener = subscribeInternal( @@ -372,7 +372,7 @@ public open class EventChannel @JvmOverloads internal con @JvmSynthetic public inline fun subscribeAlways( coroutineContext: CoroutineContext = EmptyCoroutineContext, - concurrency: Listener.ConcurrencyKind = CONCURRENT, + concurrency: ConcurrencyKind = CONCURRENT, priority: EventPriority = EventPriority.NORMAL, noinline handler: suspend E.(E) -> Unit ): Listener = subscribeAlways(E::class, coroutineContext, concurrency, priority, handler) @@ -386,7 +386,7 @@ public open class EventChannel @JvmOverloads internal con public fun subscribeAlways( eventClass: KClass, coroutineContext: CoroutineContext = EmptyCoroutineContext, - concurrency: Listener.ConcurrencyKind = CONCURRENT, + concurrency: ConcurrencyKind = CONCURRENT, priority: EventPriority = EventPriority.NORMAL, handler: suspend E.(E) -> Unit ): Listener = subscribeInternal( @@ -465,7 +465,7 @@ public open class EventChannel @JvmOverloads internal con public fun subscribeAlways( eventClass: Class, coroutineContext: CoroutineContext = EmptyCoroutineContext, - concurrency: Listener.ConcurrencyKind = CONCURRENT, + concurrency: ConcurrencyKind = CONCURRENT, priority: EventPriority = EventPriority.NORMAL, handler: Consumer ): Listener = subscribeInternal( @@ -495,7 +495,7 @@ public open class EventChannel @JvmOverloads internal con public fun subscribe( eventClass: Class, coroutineContext: CoroutineContext = EmptyCoroutineContext, - concurrency: Listener.ConcurrencyKind = CONCURRENT, + concurrency: ConcurrencyKind = CONCURRENT, priority: EventPriority = EventPriority.NORMAL, handler: java.util.function.Function ): Listener = subscribeInternal( @@ -523,7 +523,7 @@ public open class EventChannel @JvmOverloads internal con public fun subscribeOnce( eventClass: Class, coroutineContext: CoroutineContext = EmptyCoroutineContext, - concurrency: Listener.ConcurrencyKind = CONCURRENT, + concurrency: ConcurrencyKind = CONCURRENT, priority: EventPriority = EventPriority.NORMAL, handler: Consumer ): Listener = subscribeInternal( @@ -565,8 +565,8 @@ public open class EventChannel @JvmOverloads internal con @Suppress("FunctionName") private fun createListener( coroutineContext: CoroutineContext, - concurrencyKind: Listener.ConcurrencyKind, - priority: Listener.EventPriority = EventPriority.NORMAL, + concurrencyKind: ConcurrencyKind, + priority: EventPriority = EventPriority.NORMAL, handler: suspend (E) -> ListeningStatus ): Listener { val context = this.defaultCoroutineContext + coroutineContext diff --git a/mirai-core-api/src/commonMain/kotlin/event/EventChannelKotlinExtensions.kt b/mirai-core-api/src/commonMain/kotlin/event/EventChannelKotlinExtensions.kt index a3f5daf33..7fe1ae700 100644 --- a/mirai-core-api/src/commonMain/kotlin/event/EventChannelKotlinExtensions.kt +++ b/mirai-core-api/src/commonMain/kotlin/event/EventChannelKotlinExtensions.kt @@ -34,7 +34,7 @@ import kotlin.internal.LowPriorityInOverloadResolution public inline fun EventChannel.subscribe( crossinline handler: suspend E.(E) -> ListeningStatus, priority: EventPriority = EventPriority.NORMAL, - concurrency: Listener.ConcurrencyKind = Listener.ConcurrencyKind.CONCURRENT, + concurrency: ConcurrencyKind = ConcurrencyKind.CONCURRENT, coroutineContext: CoroutineContext = EmptyCoroutineContext ): Listener = subscribe(E::class, coroutineContext, concurrency, priority) { handler(this) } @@ -56,7 +56,7 @@ public inline fun EventChannel public inline fun EventChannel.subscribe( crossinline handler: suspend (E) -> ListeningStatus, priority: EventPriority = EventPriority.NORMAL, - concurrency: Listener.ConcurrencyKind = Listener.ConcurrencyKind.CONCURRENT, + concurrency: ConcurrencyKind = ConcurrencyKind.CONCURRENT, coroutineContext: CoroutineContext = EmptyCoroutineContext ): Listener = subscribe(E::class, coroutineContext, concurrency, priority) { handler(this) } @@ -77,7 +77,7 @@ public inline fun EventChannel public inline fun EventChannel.subscribe( crossinline handler: E.(E) -> ListeningStatus, priority: EventPriority = EventPriority.NORMAL, - concurrency: Listener.ConcurrencyKind = Listener.ConcurrencyKind.CONCURRENT, + concurrency: ConcurrencyKind = ConcurrencyKind.CONCURRENT, coroutineContext: CoroutineContext = EmptyCoroutineContext ): Listener = subscribe(E::class, coroutineContext, concurrency, priority) { handler(this) } @@ -98,7 +98,7 @@ public inline fun EventChannel public inline fun EventChannel.subscribe( crossinline handler: (E) -> ListeningStatus, priority: EventPriority = EventPriority.NORMAL, - concurrency: Listener.ConcurrencyKind = Listener.ConcurrencyKind.CONCURRENT, + concurrency: ConcurrencyKind = ConcurrencyKind.CONCURRENT, coroutineContext: CoroutineContext = EmptyCoroutineContext ): Listener = subscribe(E::class, coroutineContext, concurrency, priority) { handler(this) } @@ -118,7 +118,7 @@ public inline fun EventChannel public inline fun EventChannel.subscribeAlways( crossinline handler: suspend (E) -> Unit, priority: EventPriority = EventPriority.NORMAL, - concurrency: Listener.ConcurrencyKind = Listener.ConcurrencyKind.CONCURRENT, + concurrency: ConcurrencyKind = ConcurrencyKind.CONCURRENT, coroutineContext: CoroutineContext = EmptyCoroutineContext ): Listener = subscribeAlways(E::class, coroutineContext, concurrency, priority) { handler(this) } @@ -138,7 +138,7 @@ public inline fun EventChannel public inline fun EventChannel.subscribeAlways( crossinline handler: suspend E.(E) -> Unit, priority: EventPriority = EventPriority.NORMAL, - concurrency: Listener.ConcurrencyKind = Listener.ConcurrencyKind.CONCURRENT, + concurrency: ConcurrencyKind = ConcurrencyKind.CONCURRENT, coroutineContext: CoroutineContext = EmptyCoroutineContext ): Listener = subscribeAlways(E::class, coroutineContext, concurrency, priority) { handler(this) } @@ -157,7 +157,7 @@ public inline fun EventChannel public inline fun EventChannel.subscribeAlways( crossinline handler: E.(E) -> Unit, priority: EventPriority = EventPriority.NORMAL, - concurrency: Listener.ConcurrencyKind = Listener.ConcurrencyKind.CONCURRENT, + concurrency: ConcurrencyKind = ConcurrencyKind.CONCURRENT, coroutineContext: CoroutineContext = EmptyCoroutineContext ): Listener = subscribeAlways(E::class, coroutineContext, concurrency, priority) { handler(this) } @@ -176,6 +176,6 @@ public inline fun EventChannel public inline fun EventChannel.subscribeAlways( crossinline handler: (E) -> Unit, priority: EventPriority = EventPriority.NORMAL, - concurrency: Listener.ConcurrencyKind = Listener.ConcurrencyKind.CONCURRENT, + concurrency: ConcurrencyKind = ConcurrencyKind.CONCURRENT, coroutineContext: CoroutineContext = EmptyCoroutineContext ): Listener = subscribeAlways(E::class, coroutineContext, concurrency, priority) { handler(this) } \ No newline at end of file diff --git a/mirai-core-api/src/commonMain/kotlin/event/JvmMethodListeners.kt b/mirai-core-api/src/commonMain/kotlin/event/JvmMethodListeners.kt index 60dfd42a7..21cc8c637 100644 --- a/mirai-core-api/src/commonMain/kotlin/event/JvmMethodListeners.kt +++ b/mirai-core-api/src/commonMain/kotlin/event/JvmMethodListeners.kt @@ -147,10 +147,10 @@ import kotlin.coroutines.EmptyCoroutineContext public annotation class EventHandler( /** * 监听器优先级 - * @see Listener.EventPriority 查看优先级相关信息 + * @see EventPriority 查看优先级相关信息 * @see Event.intercept 拦截事件 */ - public val priority: Listener.EventPriority = EventPriority.NORMAL, + public val priority: EventPriority = EventPriority.NORMAL, /** * 是否自动忽略被 [取消][CancellableEvent.isCancelled] * @see CancellableEvent @@ -158,9 +158,9 @@ public annotation class EventHandler( public val ignoreCancelled: Boolean = true, /** * 并发类型 - * @see Listener.ConcurrencyKind + * @see ConcurrencyKind */ - public val concurrency: Listener.ConcurrencyKind = Listener.ConcurrencyKind.CONCURRENT + public val concurrency: ConcurrencyKind = ConcurrencyKind.CONCURRENT ) /** diff --git a/mirai-core-api/src/commonMain/kotlin/event/Listener.kt b/mirai-core-api/src/commonMain/kotlin/event/Listener.kt index 03cbd8565..e62dbf299 100644 --- a/mirai-core-api/src/commonMain/kotlin/event/Listener.kt +++ b/mirai-core-api/src/commonMain/kotlin/event/Listener.kt @@ -15,7 +15,7 @@ package net.mamoe.mirai.event import kotlinx.coroutines.CompletableJob import kotlinx.coroutines.sync.Mutex -import net.mamoe.mirai.event.Listener.EventPriority.* +import net.mamoe.mirai.event.EventPriority.* /** * 订阅者的状态 @@ -29,9 +29,9 @@ public enum class ListeningStatus { /** * 表示已停止. * - * - 若监听器使用 [Listener.ConcurrencyKind.LOCKED], + * - 若监听器使用 [ConcurrencyKind.LOCKED], * 在这之后监听器将会被从监听器列表中删除, 因此不再能接收到事件. - * - 若使用 [Listener.ConcurrencyKind.CONCURRENT], + * - 若使用 [ConcurrencyKind.CONCURRENT], * 在这之后无法保证立即停止监听. */ STOPPED @@ -45,54 +45,11 @@ public enum class ListeningStatus { */ public interface Listener : CompletableJob { - public enum class ConcurrencyKind { - /** - * 并发地同时处理多个事件, 但无法保证 [onEvent] 返回 [ListeningStatus.STOPPED] 后立即停止事件监听. - */ - CONCURRENT, - - /** - * 使用 [Mutex] 保证同一时刻只处理一个事件. - */ - LOCKED - } - /** * 并发类型 */ public val concurrencyKind: ConcurrencyKind - /** - * 事件优先级. - * - * 在广播时, 事件监听器的调用顺序为 (从左到右): - * `[HIGHEST]` -> `[HIGH]` -> `[NORMAL]` -> `[LOW]` -> `[LOWEST]` -> `[MONITOR]` - * - * - 使用 [MONITOR] 优先级的监听器将会被**并行**调用. - * - 使用其他优先级的监听器都将会**按顺序**调用. - * 因此一个监听器的挂起可以阻塞事件处理过程而导致低优先级的监听器较晚处理. - * - * 当事件被 [拦截][Event.intercept] 后, 优先级较低 (靠右) 的监听器将不会被调用. - */ - public enum class EventPriority { - - HIGHEST, HIGH, NORMAL, LOW, LOWEST, - - /** - * 最低的优先级. - * - * 使用此优先级的监听器应遵循约束: - * - 不 [拦截事件][Event.intercept] - */ - MONITOR; - - internal companion object { - @JvmStatic - internal val prioritiesExcludedMonitor: Array = run { - values().filter { it != MONITOR }.toTypedArray() - } - } - } /** * 事件优先级 @@ -108,4 +65,47 @@ public interface Listener : CompletableJob { public suspend fun onEvent(event: E): ListeningStatus } -public typealias EventPriority = Listener.EventPriority \ No newline at end of file +public enum class ConcurrencyKind { + /** + * 并发地同时处理多个事件, 但无法保证 [Listener.onEvent] 返回 [ListeningStatus.STOPPED] 后立即停止事件监听. + */ + CONCURRENT, + + /** + * 使用 [Mutex] 保证同一时刻只处理一个事件. + */ + LOCKED +} + + +/** + * 事件优先级. + * + * 在广播时, 事件监听器的调用顺序为 (从左到右): + * [HIGHEST] -> [HIGH] -> [NORMAL] -> [LOW] -> [LOWEST] -> [MONITOR] + * + * - 使用 [MONITOR] 优先级的监听器将会被**并行**调用. + * - 使用其他优先级的监听器都将会**按顺序**调用. + * 因此一个监听器的挂起可以阻塞事件处理过程而导致低优先级的监听器较晚处理. + * + * 当事件被 [拦截][Event.intercept] 后, 优先级较低 (靠右) 的监听器将不会被调用. + */ +public enum class EventPriority { + + HIGHEST, HIGH, NORMAL, LOW, LOWEST, + + /** + * 最低的优先级. + * + * 使用此优先级的监听器应遵循约束: + * - 不 [拦截事件][Event.intercept] + */ + MONITOR; + + internal companion object { + @JvmStatic + internal val prioritiesExcludedMonitor: Array = run { + values().filter { it != MONITOR }.toTypedArray() + } + } +} \ No newline at end of file diff --git a/mirai-core-api/src/commonMain/kotlin/event/nextEvent.kt b/mirai-core-api/src/commonMain/kotlin/event/nextEvent.kt index a057623b1..94cd166db 100644 --- a/mirai-core-api/src/commonMain/kotlin/event/nextEvent.kt +++ b/mirai-core-api/src/commonMain/kotlin/event/nextEvent.kt @@ -32,7 +32,7 @@ import kotlin.reflect.KClass @JvmSynthetic public suspend inline fun nextEvent( timeoutMillis: Long = -1, - priority: Listener.EventPriority = EventPriority.MONITOR, + priority: EventPriority = EventPriority.MONITOR, crossinline filter: (E) -> Boolean = { true } ): E { require(timeoutMillis == -1L || timeoutMillis > 0) { "timeoutMillis must be -1 or > 0" } @@ -56,7 +56,7 @@ public suspend inline fun nextEvent( @JvmSynthetic public suspend inline fun nextEventOrNull( timeoutMillis: Long, - priority: Listener.EventPriority = EventPriority.MONITOR, + priority: EventPriority = EventPriority.MONITOR, crossinline filter: (E) -> Boolean = { true } ): E? { return withTimeoutOrNull(timeoutMillis) { @@ -70,7 +70,7 @@ public suspend inline fun nextEventOrNull( internal suspend inline fun nextEventImpl( eventClass: KClass, coroutineScope: CoroutineScope, - priority: Listener.EventPriority, + priority: EventPriority, crossinline filter: (E) -> Boolean ): E = suspendCancellableCoroutine { cont -> coroutineScope.globalEventChannel().subscribe(eventClass, priority = priority) { @@ -90,7 +90,7 @@ internal suspend inline fun nextBotEventImpl( bot: Bot, eventClass: KClass, coroutineScope: CoroutineScope, - priority: Listener.EventPriority + priority: EventPriority ): E = suspendCancellableCoroutine { cont -> coroutineScope.globalEventChannel().subscribe(eventClass, priority = priority) { try { diff --git a/mirai-core-api/src/commonMain/kotlin/event/select.kt b/mirai-core-api/src/commonMain/kotlin/event/select.kt index 4bc36ab00..3c447ca83 100644 --- a/mirai-core-api/src/commonMain/kotlin/event/select.kt +++ b/mirai-core-api/src/commonMain/kotlin/event/select.kt @@ -61,7 +61,7 @@ import net.mamoe.mirai.utils.MiraiExperimentalApi public suspend inline fun T.whileSelectMessages( timeoutMillis: Long = -1, filterContext: Boolean = true, - priority: Listener.EventPriority = EventPriority.MONITOR, + priority: EventPriority = EventPriority.MONITOR, @BuilderInference crossinline selectBuilder: @MessageDsl MessageSelectBuilder.() -> Unit ): Unit = whileSelectMessagesImpl(timeoutMillis, filterContext, priority, selectBuilder) @@ -74,7 +74,7 @@ public suspend inline fun T.whileSelectMessages( public suspend inline fun T.selectMessagesUnit( timeoutMillis: Long = -1, filterContext: Boolean = true, - priority: Listener.EventPriority = EventPriority.MONITOR, + priority: EventPriority = EventPriority.MONITOR, @BuilderInference crossinline selectBuilder: @MessageDsl MessageSelectBuilderUnit.() -> Unit ): Unit = selectMessagesImpl(timeoutMillis, true, filterContext, priority, selectBuilder) @@ -104,7 +104,7 @@ public suspend inline fun T.selectMessagesUnit( public suspend inline fun T.selectMessages( timeoutMillis: Long = -1, filterContext: Boolean = true, - priority: Listener.EventPriority = EventPriority.MONITOR, + priority: EventPriority = EventPriority.MONITOR, @BuilderInference crossinline selectBuilder: @MessageDsl MessageSelectBuilder.() -> Unit ): R = @@ -436,7 +436,7 @@ internal suspend inline fun T.selectMessagesImpl( timeoutMillis: Long = -1, isUnit: Boolean, filterContext: Boolean = true, - priority: Listener.EventPriority, + priority: EventPriority, @BuilderInference crossinline selectBuilder: @MessageDsl MessageSelectBuilderUnit.() -> Unit ): R = withSilentTimeoutOrCoroutineScope(timeoutMillis) { @@ -486,7 +486,7 @@ internal suspend inline fun T.selectMessagesImpl( // we don't have any way to reduce duplication yet, // until local functions are supported in inline functions @Suppress("DuplicatedCode") val subscribeAlways = globalEventChannel().subscribeAlways( - concurrency = Listener.ConcurrencyKind.LOCKED, + concurrency = ConcurrencyKind.LOCKED, priority = priority ) { event -> if (filterContext && !this.isContextIdenticalWith(this@selectMessagesImpl)) @@ -538,7 +538,7 @@ internal suspend inline fun T.selectMessagesImpl( internal suspend inline fun T.whileSelectMessagesImpl( timeoutMillis: Long, filterContext: Boolean, - priority: Listener.EventPriority, + priority: EventPriority, crossinline selectBuilder: @MessageDsl MessageSelectBuilder.() -> Unit ): Unit = withSilentTimeoutOrCoroutineScope(timeoutMillis) { var deferred: CompletableDeferred? = CompletableDeferred() @@ -568,7 +568,7 @@ internal suspend inline fun T.whileSelectMessagesImpl // ensure atomic completing val subscribeAlways = globalEventChannel().subscribeAlways( - concurrency = Listener.ConcurrencyKind.LOCKED, + concurrency = ConcurrencyKind.LOCKED, priority = priority ) { event -> if (filterContext && !this.isContextIdenticalWith(this@whileSelectMessagesImpl)) diff --git a/mirai-core-api/src/commonMain/kotlin/event/subscribeMessages.kt b/mirai-core-api/src/commonMain/kotlin/event/subscribeMessages.kt index 9ff7e9954..f48364a17 100644 --- a/mirai-core-api/src/commonMain/kotlin/event/subscribeMessages.kt +++ b/mirai-core-api/src/commonMain/kotlin/event/subscribeMessages.kt @@ -16,7 +16,7 @@ package net.mamoe.mirai.event import net.mamoe.mirai.Bot import net.mamoe.mirai.contact.OtherClient import net.mamoe.mirai.contact.Stranger -import net.mamoe.mirai.event.Listener.ConcurrencyKind.CONCURRENT +import net.mamoe.mirai.event.ConcurrencyKind.CONCURRENT import net.mamoe.mirai.event.events.* import net.mamoe.mirai.message.data.content import kotlin.contracts.InvocationKind @@ -75,8 +75,8 @@ public typealias MessageEventSubscribersBuilder = MessageSubscribersBuilder EventChannel<*>.subscribeMessages( coroutineContext: CoroutineContext = EmptyCoroutineContext, - concurrencyKind: Listener.ConcurrencyKind = CONCURRENT, - priority: Listener.EventPriority = EventPriority.MONITOR, + concurrencyKind: ConcurrencyKind = CONCURRENT, + priority: EventPriority = EventPriority.MONITOR, listeners: MessageEventSubscribersBuilder.() -> R ): R { contract { callsInPlace(listeners, InvocationKind.EXACTLY_ONCE) } @@ -93,8 +93,8 @@ public typealias GroupMessageSubscribersBuilder = MessageSubscribersBuilder EventChannel<*>.subscribeGroupMessages( coroutineContext: CoroutineContext = EmptyCoroutineContext, - concurrencyKind: Listener.ConcurrencyKind = CONCURRENT, - priority: Listener.EventPriority = EventPriority.MONITOR, + concurrencyKind: ConcurrencyKind = CONCURRENT, + priority: EventPriority = EventPriority.MONITOR, listeners: GroupMessageSubscribersBuilder.() -> R ): R { contract { callsInPlace(listeners, InvocationKind.EXACTLY_ONCE) } @@ -111,8 +111,8 @@ public typealias FriendMessageSubscribersBuilder = MessageSubscribersBuilder EventChannel<*>.subscribeFriendMessages( coroutineContext: CoroutineContext = EmptyCoroutineContext, - concurrencyKind: Listener.ConcurrencyKind = CONCURRENT, - priority: Listener.EventPriority = EventPriority.MONITOR, + concurrencyKind: ConcurrencyKind = CONCURRENT, + priority: EventPriority = EventPriority.MONITOR, listeners: FriendMessageSubscribersBuilder.() -> R ): R { contract { callsInPlace(listeners, InvocationKind.EXACTLY_ONCE) } @@ -129,8 +129,8 @@ public typealias TempMessageSubscribersBuilder = MessageSubscribersBuilder EventChannel<*>.subscribeTempMessages( coroutineContext: CoroutineContext = EmptyCoroutineContext, - concurrencyKind: Listener.ConcurrencyKind = CONCURRENT, - priority: Listener.EventPriority = EventPriority.MONITOR, + concurrencyKind: ConcurrencyKind = CONCURRENT, + priority: EventPriority = EventPriority.MONITOR, listeners: TempMessageSubscribersBuilder.() -> R ): R { contract { callsInPlace(listeners, InvocationKind.EXACTLY_ONCE) } @@ -148,8 +148,8 @@ public typealias StrangerMessageSubscribersBuilder = MessageSubscribersBuilder EventChannel<*>.subscribeStrangerMessages( coroutineContext: CoroutineContext = EmptyCoroutineContext, - concurrencyKind: Listener.ConcurrencyKind = CONCURRENT, - priority: Listener.EventPriority = EventPriority.MONITOR, + concurrencyKind: ConcurrencyKind = CONCURRENT, + priority: EventPriority = EventPriority.MONITOR, listeners: StrangerMessageSubscribersBuilder.() -> R ): R { contract { callsInPlace(listeners, InvocationKind.EXACTLY_ONCE) } @@ -168,8 +168,8 @@ public typealias OtherClientMessageSubscribersBuilder = MessageSubscribersBuilde */ public fun EventChannel<*>.subscribeOtherClientMessages( coroutineContext: CoroutineContext = EmptyCoroutineContext, - concurrencyKind: Listener.ConcurrencyKind = CONCURRENT, - priority: Listener.EventPriority = EventPriority.MONITOR, + concurrencyKind: ConcurrencyKind = CONCURRENT, + priority: EventPriority = EventPriority.MONITOR, listeners: OtherClientMessageSubscribersBuilder.() -> R ): R { contract { callsInPlace(listeners, InvocationKind.EXACTLY_ONCE) } @@ -185,8 +185,8 @@ private typealias MessageSubscriberBuilderConstructor = ( private inline fun EventChannel<*>.createBuilder( constructor: MessageSubscriberBuilderConstructor, coroutineContext: CoroutineContext, - concurrencyKind: Listener.ConcurrencyKind, - priority: Listener.EventPriority + concurrencyKind: ConcurrencyKind, + priority: EventPriority ): MessageSubscribersBuilder, Unit, Unit> = constructor(Unit) { filter, listener -> subscribeAlways(coroutineContext, concurrencyKind, priority) { val toString = this.message.content diff --git a/mirai-core-api/src/commonMain/kotlin/event/syncFromEvent.kt b/mirai-core-api/src/commonMain/kotlin/event/syncFromEvent.kt index 88359e28b..7d1868767 100644 --- a/mirai-core-api/src/commonMain/kotlin/event/syncFromEvent.kt +++ b/mirai-core-api/src/commonMain/kotlin/event/syncFromEvent.kt @@ -34,7 +34,7 @@ import kotlin.reflect.KClass @JvmSynthetic public suspend inline fun syncFromEvent( timeoutMillis: Long = -1, - priority: Listener.EventPriority = EventPriority.MONITOR, + priority: EventPriority = EventPriority.MONITOR, crossinline mapper: suspend E.(E) -> R? ): R { require(timeoutMillis == -1L || timeoutMillis > 0) { "timeoutMillis must be -1 or > 0" } @@ -67,7 +67,7 @@ public suspend inline fun syncFromEvent( @JvmSynthetic public suspend inline fun syncFromEventOrNull( timeoutMillis: Long, - priority: Listener.EventPriority = EventPriority.MONITOR, + priority: EventPriority = EventPriority.MONITOR, crossinline mapper: suspend E.(E) -> R? ): R? { require(timeoutMillis > 0) { "timeoutMillis must be > 0" } @@ -96,7 +96,7 @@ public suspend inline fun syncFromEventOrNull( public inline fun CoroutineScope.asyncFromEventOrNull( timeoutMillis: Long, coroutineContext: CoroutineContext = EmptyCoroutineContext, - priority: Listener.EventPriority = EventPriority.MONITOR, + priority: EventPriority = EventPriority.MONITOR, crossinline mapper: suspend E.(E) -> R? ): Deferred { require(timeoutMillis == -1L || timeoutMillis > 0) { "timeoutMillis must be -1 or > 0" } @@ -125,7 +125,7 @@ public inline fun CoroutineScope.asyncFromEventOrNu public inline fun CoroutineScope.asyncFromEvent( timeoutMillis: Long = -1, coroutineContext: CoroutineContext = EmptyCoroutineContext, - priority: Listener.EventPriority = EventPriority.MONITOR, + priority: EventPriority = EventPriority.MONITOR, crossinline mapper: suspend E.(E) -> R? ): Deferred { require(timeoutMillis == -1L || timeoutMillis > 0) { "timeoutMillis must be -1 or > 0" } @@ -144,7 +144,7 @@ public inline fun CoroutineScope.asyncFromEvent( internal suspend inline fun syncFromEventImpl( eventClass: KClass, coroutineScope: CoroutineScope, - priority: Listener.EventPriority, + priority: EventPriority, crossinline mapper: suspend E.(E) -> R? ): R = suspendCancellableCoroutine { cont -> coroutineScope.globalEventChannel().subscribe(eventClass, priority = priority) { diff --git a/mirai-core-api/src/commonMain/kotlin/internal/event/InternalEventListeners.kt b/mirai-core-api/src/commonMain/kotlin/internal/event/InternalEventListeners.kt index e2b2b37cf..69411f564 100644 --- a/mirai-core-api/src/commonMain/kotlin/internal/event/InternalEventListeners.kt +++ b/mirai-core-api/src/commonMain/kotlin/internal/event/InternalEventListeners.kt @@ -29,14 +29,14 @@ internal class Handler internal constructor( parentJob: Job?, subscriberContext: CoroutineContext, @JvmField val handler: suspend (E) -> ListeningStatus, - override val concurrencyKind: Listener.ConcurrencyKind, - override val priority: Listener.EventPriority + override val concurrencyKind: ConcurrencyKind, + override val priority: EventPriority ) : Listener, CompletableJob by SupervisorJob(parentJob) { // avoid being cancelled on handling event private val subscriberContext: CoroutineContext = subscriberContext + this // override Job. val lock: Mutex? = when (concurrencyKind) { - Listener.ConcurrencyKind.LOCKED -> Mutex() + ConcurrencyKind.LOCKED -> Mutex() else -> null } @@ -78,14 +78,14 @@ internal object GlobalEventListeners { init { val map = - EnumMap>(Listener.EventPriority::class.java) + EnumMap>(EventPriority::class.java) EventPriority.values().forEach { map[it] = ConcurrentLinkedQueue() } ALL_LEVEL_REGISTRIES = map } - operator fun get(priority: Listener.EventPriority): ConcurrentLinkedQueue = + operator fun get(priority: EventPriority): ConcurrentLinkedQueue = ALL_LEVEL_REGISTRIES[priority]!! } @@ -105,7 +105,7 @@ internal inline fun > T.forEach0(block: T.(E) -> Unit) { internal suspend inline fun callAndRemoveIfRequired( event: E ) { - for (p in Listener.EventPriority.prioritiesExcludedMonitor) { + for (p in EventPriority.prioritiesExcludedMonitor) { GlobalEventListeners[p].forEach0 { registeredRegistry -> if (event.isIntercepted) { return @@ -113,14 +113,14 @@ internal suspend inline fun callAndRemoveIfRequired( if (!registeredRegistry.type.isInstance(event)) return@forEach0 val listener = registeredRegistry.listener when (listener.concurrencyKind) { - Listener.ConcurrencyKind.LOCKED -> { + ConcurrencyKind.LOCKED -> { (listener as Handler).lock!!.withLock { if (listener.onEvent(event) == ListeningStatus.STOPPED) { remove(registeredRegistry) } } } - Listener.ConcurrencyKind.CONCURRENT -> { + ConcurrencyKind.CONCURRENT -> { if (listener.onEvent(event) == ListeningStatus.STOPPED) { remove(registeredRegistry) } @@ -137,14 +137,14 @@ internal suspend inline fun callAndRemoveIfRequired( val listener = registeredRegistry.listener launch { when (listener.concurrencyKind) { - Listener.ConcurrencyKind.LOCKED -> { + ConcurrencyKind.LOCKED -> { (listener as Handler).lock!!.withLock { if (listener.onEvent(event) == ListeningStatus.STOPPED) { remove(registeredRegistry) } } } - Listener.ConcurrencyKind.CONCURRENT -> { + ConcurrencyKind.CONCURRENT -> { if (listener.onEvent(event) == ListeningStatus.STOPPED) { remove(registeredRegistry) } diff --git a/mirai-core-api/src/commonMain/kotlin/message/utils.kt b/mirai-core-api/src/commonMain/kotlin/message/utils.kt index 23330203f..69ac4ce6a 100644 --- a/mirai-core-api/src/commonMain/kotlin/message/utils.kt +++ b/mirai-core-api/src/commonMain/kotlin/message/utils.kt @@ -1,5 +1,5 @@ /* - * Copyright 2019-2020 Mamoe Technologies and contributors. + * Copyright 2019-2021 Mamoe Technologies and contributors. * * 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证. * Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link. @@ -16,7 +16,6 @@ package net.mamoe.mirai.message import kotlinx.coroutines.Deferred import kotlinx.coroutines.async import net.mamoe.mirai.event.EventPriority -import net.mamoe.mirai.event.Listener import net.mamoe.mirai.event.events.* import net.mamoe.mirai.event.syncFromEvent import net.mamoe.mirai.event.syncFromEventOrNull @@ -46,7 +45,7 @@ public fun MessageEvent.isContextIdenticalWith(another: MessageEvent): Boolean { @JvmSynthetic public suspend inline fun P.nextMessage( timeoutMillis: Long = -1, - priority: Listener.EventPriority = EventPriority.MONITOR, + priority: EventPriority = EventPriority.MONITOR, noinline filter: suspend P.(P) -> Boolean = { true } ): MessageChain { return syncFromEvent(timeoutMillis, priority) { @@ -68,7 +67,7 @@ public suspend inline fun P.nextMessage( @JvmSynthetic public suspend inline fun P.nextMessageOrNull( timeoutMillis: Long, - priority: Listener.EventPriority = EventPriority.MONITOR, + priority: EventPriority = EventPriority.MONITOR, noinline filter: suspend P.(P) -> Boolean = { true } ): MessageChain? { require(timeoutMillis > 0) { "timeoutMillis must be > 0" } @@ -84,7 +83,7 @@ public suspend inline fun P.nextMessageOrNull( public inline fun P.nextMessageAsync( timeoutMillis: Long = -1, coroutineContext: CoroutineContext = EmptyCoroutineContext, - priority: Listener.EventPriority = EventPriority.MONITOR, + priority: EventPriority = EventPriority.MONITOR, noinline filter: suspend P.(P) -> Boolean = { true } ): Deferred { return this.bot.async(coroutineContext) { @@ -101,7 +100,7 @@ public inline fun P.nextMessageAsync( public inline fun P.nextMessageOrNullAsync( timeoutMillis: Long, coroutineContext: CoroutineContext = EmptyCoroutineContext, - priority: Listener.EventPriority = EventPriority.MONITOR, + priority: EventPriority = EventPriority.MONITOR, noinline filter: suspend P.(P) -> Boolean = { true } ): Deferred { require(timeoutMillis > 0) { "timeoutMillis must be > 0" } diff --git a/mirai-core-api/src/jvmTest/kotlin/event/EventTests.kt b/mirai-core-api/src/jvmTest/kotlin/event/EventTests.kt index 688f89865..e6c870280 100644 --- a/mirai-core-api/src/jvmTest/kotlin/event/EventTests.kt +++ b/mirai-core-api/src/jvmTest/kotlin/event/EventTests.kt @@ -52,7 +52,7 @@ class EventTests { resetEventListeners() var listeners = 0 val counter = AtomicInteger(0) - for (p in Listener.EventPriority.values()) { + for (p in EventPriority.values()) { repeat(2333) { listeners++ GlobalScope.globalEventChannel().subscribeAlways { @@ -78,7 +78,7 @@ class EventTests { val registered = AtomicInteger() coroutineScope { println("Step 0") - for (priority in Listener.EventPriority.values()) { + for (priority in EventPriority.values()) { launch { repeat(5000) { registered.getAndIncrement() @@ -216,7 +216,7 @@ class EventTests { } */ fun resetEventListeners() { - for (p in Listener.EventPriority.values()) { + for (p in EventPriority.values()) { GlobalEventListeners[p].clear() } } @@ -278,11 +278,11 @@ class EventTests { step.step(1) ListeningStatus.LISTENING } - subscribe(priority = Listener.EventPriority.HIGH) { + subscribe(priority = EventPriority.HIGH) { step.step(0) ListeningStatus.LISTENING } - subscribe(priority = Listener.EventPriority.LOW) { + subscribe(priority = EventPriority.LOW) { step.step(3) ListeningStatus.LISTENING } diff --git a/mirai-core-api/src/jvmTest/kotlin/event/JvmMethodEventsTest.kt b/mirai-core-api/src/jvmTest/kotlin/event/JvmMethodEventsTest.kt index 2cf71b7f9..47011683d 100644 --- a/mirai-core-api/src/jvmTest/kotlin/event/JvmMethodEventsTest.kt +++ b/mirai-core-api/src/jvmTest/kotlin/event/JvmMethodEventsTest.kt @@ -1,5 +1,5 @@ /* - * Copyright 2019-2020 Mamoe Technologies and contributors. + * Copyright 2019-2021 Mamoe Technologies and contributors. * * 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证. * Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link. @@ -135,13 +135,13 @@ internal class JvmMethodEventsTest { fun getCalled() = called.get() @Suppress("unused") - @EventHandler(Listener.EventPriority.HIGHEST) + @EventHandler(EventPriority.HIGHEST) private suspend fun TestEvent.`suspend receiver param Unit`(event: TestEvent) { intercept() called.getAndIncrement() } - @EventHandler(Listener.EventPriority.MONITOR) + @EventHandler(EventPriority.MONITOR) @Suppress("unused") private fun TestEvent.`receiver param LS`(event: TestEvent): ListeningStatus { called.getAndIncrement() diff --git a/mirai-core/src/commonMain/kotlin/AbstractBot.kt b/mirai-core/src/commonMain/kotlin/AbstractBot.kt index 945c068b6..36274d95e 100644 --- a/mirai-core/src/commonMain/kotlin/AbstractBot.kt +++ b/mirai-core/src/commonMain/kotlin/AbstractBot.kt @@ -24,7 +24,7 @@ import net.mamoe.mirai.Bot import net.mamoe.mirai.contact.ContactList import net.mamoe.mirai.contact.OtherClient import net.mamoe.mirai.event.* -import net.mamoe.mirai.event.Listener.EventPriority.MONITOR +import net.mamoe.mirai.event.EventPriority.MONITOR import net.mamoe.mirai.event.events.BotEvent import net.mamoe.mirai.event.events.BotOfflineEvent import net.mamoe.mirai.event.events.BotReloginEvent @@ -94,7 +94,7 @@ internal abstract class AbstractBot constructor( private val offlineListener: Listener = this@AbstractBot.eventChannel.subscribeAlways( priority = MONITOR, - concurrency = Listener.ConcurrencyKind.LOCKED + concurrency = ConcurrencyKind.LOCKED ) { event -> if (!event.bot.isActive) { // bot closed diff --git a/mirai-core/src/commonMain/kotlin/network/QQAndroidBotNetworkHandler.kt b/mirai-core/src/commonMain/kotlin/network/QQAndroidBotNetworkHandler.kt index 78e2645dc..d71477cc1 100644 --- a/mirai-core/src/commonMain/kotlin/network/QQAndroidBotNetworkHandler.kt +++ b/mirai-core/src/commonMain/kotlin/network/QQAndroidBotNetworkHandler.kt @@ -479,7 +479,7 @@ internal class QQAndroidBotNetworkHandler(coroutineContext: CoroutineContext, bo init { @Suppress("RemoveRedundantQualifierName") - val listener = bot.eventChannel.subscribeAlways(priority = Listener.EventPriority.MONITOR) { + val listener = bot.eventChannel.subscribeAlways(priority = EventPriority.MONITOR) { this@QQAndroidBotNetworkHandler.launch { syncMessageSvc() } } supervisor.invokeOnCompletion { listener.cancel() }