From 334065199894e1917f7ad3b3ec53e84a3802b894 Mon Sep 17 00:00:00 2001 From: Him188 Date: Tue, 18 Aug 2020 22:37:26 +0800 Subject: [PATCH] Enhance `nextEvent` and `nextEventOrNull`: add filter --- .../kotlin/net.mamoe.mirai/event/nextEvent.kt | 24 +++++++++++++------ 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/event/nextEvent.kt b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/event/nextEvent.kt index dfa147d19..04db48bb8 100644 --- a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/event/nextEvent.kt +++ b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/event/nextEvent.kt @@ -15,50 +15,57 @@ import kotlinx.coroutines.* import net.mamoe.mirai.Bot import net.mamoe.mirai.event.events.BotEvent import net.mamoe.mirai.utils.PlannedRemoval +import net.mamoe.mirai.utils.SinceMirai import kotlin.coroutines.resume import kotlin.jvm.JvmSynthetic import kotlin.reflect.KClass /** - * 挂起当前协程, 直到监听到事件 [E] 的广播, 返回这个事件实例. + * 挂起当前协程, 直到监听到事件 [E] 的广播并通过 [filter], 返回这个事件实例. * * @param timeoutMillis 超时. 单位为毫秒. `-1` 为不限制. + * @param filter 过滤器. 返回 `true` 时表示得到了需要的实例. 返回 `false` 时表示继续监听 * * @see subscribe 普通地监听一个事件 * @see syncFromEvent 挂起当前协程, 并尝试从事件中同步一个值 * * @throws TimeoutCancellationException 在超时后抛出. */ +@SinceMirai("1.2.0") @JvmSynthetic public suspend inline fun nextEvent( timeoutMillis: Long = -1, - priority: Listener.EventPriority = EventPriority.MONITOR + priority: Listener.EventPriority = EventPriority.MONITOR, + crossinline filter: E.(E) -> Boolean = { true } ): E { require(timeoutMillis == -1L || timeoutMillis > 0) { "timeoutMillis must be -1 or > 0" } return withTimeoutOrCoroutineScope(timeoutMillis) { - nextEventImpl(E::class, this, priority) + nextEventImpl(E::class, this, priority, filter) } } /** - * 挂起当前协程, 直到监听到事件 [E] 的广播, 返回这个事件实例. + * 挂起当前协程, 直到监听到事件 [E] 的广播并通过 [filter], 返回这个事件实例. * * @param timeoutMillis 超时. 单位为毫秒. `-1` 为不限制. + * @param filter 过滤器. 返回 `true` 时表示得到了需要的实例. 返回 `false` 时表示继续监听 * * @see subscribe 普通地监听一个事件 * @see syncFromEvent 挂起当前协程, 并尝试从事件中同步一个值 * * @return 事件实例, 在超时后返回 `null` */ +@SinceMirai("1.2.0") @JvmSynthetic public suspend inline fun nextEventOrNull( timeoutMillis: Long, - priority: Listener.EventPriority = EventPriority.MONITOR + priority: Listener.EventPriority = EventPriority.MONITOR, + crossinline filter: E.(E) -> Boolean = { true } ): E? { return withTimeoutOrNull(timeoutMillis) { - nextEventImpl(E::class, this, priority) + nextEventImpl(E::class, this, priority, filter) } } @@ -92,9 +99,12 @@ public suspend inline fun Bot.nextEvent( internal suspend inline fun nextEventImpl( eventClass: KClass, coroutineScope: CoroutineScope, - priority: Listener.EventPriority + priority: Listener.EventPriority, + crossinline filter: E.(E) -> Boolean ): E = suspendCancellableCoroutine { cont -> coroutineScope.subscribe(eventClass, priority = priority) { + if (!filter(this, this)) return@subscribe ListeningStatus.LISTENING + try { cont.resume(this) } catch (e: Exception) {