mirror of
https://github.com/mamoe/mirai.git
synced 2025-01-05 07:30:09 +08:00
Add nextEvent
, add docs
This commit is contained in:
parent
37ce266091
commit
96a5825283
@ -24,6 +24,8 @@ import kotlin.reflect.KClass
|
||||
* @param mapper 过滤转换器. 返回非 null 则代表得到了需要的值. [syncFromEvent] 会返回这个值
|
||||
*
|
||||
* @see asyncFromEvent 本函数的异步版本
|
||||
* @see subscribe 普通地监听一个事件
|
||||
* @see nextEvent 挂起当前协程, 并获取下一个事件实例
|
||||
*
|
||||
* @throws TimeoutCancellationException 在超时后抛出.
|
||||
* @throws Throwable 当 [mapper] 抛出任何异常时, 本函数会抛出该异常
|
||||
@ -55,6 +57,9 @@ suspend inline fun <reified E : Event, R : Any> syncFromEvent(
|
||||
* @return 超时返回 `null`, 否则返回 [mapper] 返回的第一个非 `null` 值.
|
||||
*
|
||||
* @see asyncFromEvent 本函数的异步版本
|
||||
* @see subscribe 普通地监听一个事件
|
||||
* @see nextEvent 挂起当前协程, 并获取下一个事件实例
|
||||
*
|
||||
* @throws Throwable 当 [mapper] 抛出任何异常时, 本函数会抛出该异常
|
||||
*/
|
||||
@JvmSynthetic
|
||||
@ -77,6 +82,11 @@ suspend inline fun <reified E : Event, R : Any> syncFromEventOrNull(
|
||||
* @param timeoutMillis 超时. 单位为毫秒. `-1` 为不限制
|
||||
* @param coroutineContext 额外的 [CoroutineContext]
|
||||
* @param mapper 过滤转换器. 返回非 `null` 则代表得到了需要的值. [syncFromEvent] 会返回这个值
|
||||
*
|
||||
* @see syncFromEvent
|
||||
* @see asyncFromEvent
|
||||
* @see subscribe 普通地监听一个事件
|
||||
* @see nextEvent 挂起当前协程, 并获取下一个事件实例
|
||||
*/
|
||||
@JvmSynthetic
|
||||
@Suppress("DeferredIsResult")
|
||||
@ -100,6 +110,11 @@ inline fun <reified E : Event, R : Any> CoroutineScope.asyncFromEventOrNull(
|
||||
* @param timeoutMillis 超时. 单位为毫秒. `-1` 为不限制
|
||||
* @param coroutineContext 额外的 [CoroutineContext]
|
||||
* @param mapper 过滤转换器. 返回非 null 则代表得到了需要的值. [syncFromEvent] 会返回这个值
|
||||
*
|
||||
* @see syncFromEvent
|
||||
* @see asyncFromEventOrNull
|
||||
* @see subscribe 普通地监听一个事件
|
||||
* @see nextEvent 挂起当前协程, 并获取下一个事件实例
|
||||
*/
|
||||
@JvmSynthetic
|
||||
@Suppress("DeferredIsResult")
|
||||
@ -127,9 +142,12 @@ internal suspend inline fun <E : Event, R> syncFromEventImpl(
|
||||
crossinline mapper: suspend E.(E) -> R?
|
||||
): R = suspendCancellableCoroutine { cont ->
|
||||
coroutineScope.subscribe(eventClass) {
|
||||
cont.resumeWith(kotlin.runCatching {
|
||||
mapper.invoke(this, it) ?: return@subscribe ListeningStatus.LISTENING
|
||||
})
|
||||
try {
|
||||
cont.resumeWith(kotlin.runCatching {
|
||||
mapper.invoke(this, it) ?: return@subscribe ListeningStatus.LISTENING
|
||||
})
|
||||
} catch (e: Exception) {
|
||||
}
|
||||
return@subscribe ListeningStatus.STOPPED
|
||||
}
|
||||
}
|
@ -0,0 +1,106 @@
|
||||
/*
|
||||
* Copyright 2020 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.
|
||||
*
|
||||
* https://github.com/mamoe/mirai/blob/master/LICENSE
|
||||
*/
|
||||
|
||||
package net.mamoe.mirai.event
|
||||
|
||||
import kotlinx.coroutines.*
|
||||
import net.mamoe.mirai.Bot
|
||||
import net.mamoe.mirai.event.events.BotEvent
|
||||
import kotlin.coroutines.resume
|
||||
import kotlin.jvm.JvmSynthetic
|
||||
import kotlin.reflect.KClass
|
||||
|
||||
|
||||
/**
|
||||
* 挂起当前协程, 直到监听到事件 [E] 的广播, 返回这个事件实例.
|
||||
*
|
||||
* @param timeoutMillis 超时. 单位为毫秒. `-1` 为不限制.
|
||||
*
|
||||
* @see subscribe 普通地监听一个事件
|
||||
* @see syncFromEvent 挂起当前协程, 并尝试从事件中同步一个值
|
||||
*
|
||||
* @throws TimeoutCancellationException 在超时后抛出.
|
||||
*/
|
||||
@JvmSynthetic
|
||||
suspend inline fun <reified E : Event> nextEvent(
|
||||
timeoutMillis: Long = -1
|
||||
): E {
|
||||
require(timeoutMillis == -1L || timeoutMillis > 0) { "timeoutMillis must be -1 or > 0" }
|
||||
return withTimeoutOrCoroutineScope(timeoutMillis) {
|
||||
nextEventImpl(E::class, this)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 挂起当前协程, 直到监听到事件 [E] 的广播, 返回这个事件实例.
|
||||
* 将筛选 [BotEvent.bot] 与 [this] 相等的事件.
|
||||
*
|
||||
* @param timeoutMillis 超时. 单位为毫秒. `-1` 为不限制.
|
||||
*
|
||||
* @see subscribe 普通地监听一个事件
|
||||
* @see syncFromEvent 挂起当前协程, 并尝试从事件中同步一个值
|
||||
*
|
||||
* @throws TimeoutCancellationException 在超时后抛出.
|
||||
*/
|
||||
@JvmSynthetic
|
||||
suspend inline fun <reified E : BotEvent> Bot.nextEvent(
|
||||
timeoutMillis: Long = -1
|
||||
): E {
|
||||
require(timeoutMillis == -1L || timeoutMillis > 0) { "timeoutMillis must be -1 or > 0" }
|
||||
return withTimeoutOrCoroutineScope(timeoutMillis) {
|
||||
nextBotEventImpl(this@nextEvent, E::class, this)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@JvmSynthetic
|
||||
@PublishedApi
|
||||
internal suspend inline fun <E : Event> nextEventImpl(
|
||||
eventClass: KClass<E>,
|
||||
coroutineScope: CoroutineScope
|
||||
): E = suspendCancellableCoroutine { cont ->
|
||||
coroutineScope.subscribe(eventClass) {
|
||||
try {
|
||||
cont.resume(this)
|
||||
} catch (e: Exception) {
|
||||
}
|
||||
return@subscribe ListeningStatus.STOPPED
|
||||
}
|
||||
}
|
||||
|
||||
@JvmSynthetic
|
||||
@PublishedApi
|
||||
internal suspend inline fun <E : BotEvent> nextBotEventImpl(
|
||||
bot: Bot,
|
||||
eventClass: KClass<E>,
|
||||
coroutineScope: CoroutineScope
|
||||
): E = suspendCancellableCoroutine { cont ->
|
||||
coroutineScope.subscribe(eventClass) {
|
||||
try {
|
||||
if (this.bot == bot) cont.resume(this)
|
||||
} catch (e: Exception) {
|
||||
}
|
||||
return@subscribe ListeningStatus.STOPPED
|
||||
}
|
||||
}
|
||||
|
||||
@JvmSynthetic
|
||||
@PublishedApi
|
||||
internal suspend inline fun <R> withTimeoutOrCoroutineScope(
|
||||
timeoutMillis: Long,
|
||||
noinline block: suspend CoroutineScope.() -> R
|
||||
): R {
|
||||
require(timeoutMillis == -1L || timeoutMillis > 0) { "timeoutMillis must be -1 or > 0 " }
|
||||
|
||||
return if (timeoutMillis == -1L) {
|
||||
coroutineScope(block)
|
||||
} else {
|
||||
withTimeout(timeoutMillis, block)
|
||||
}
|
||||
}
|
@ -446,7 +446,7 @@ class MessageSelectionTimeoutException : RuntimeException()
|
||||
|
||||
@JvmSynthetic
|
||||
@PublishedApi
|
||||
internal suspend inline fun <R> withTimeoutOrCoroutineScope(
|
||||
internal suspend inline fun <R> withSilentTimeoutOrCoroutineScope(
|
||||
timeoutMillis: Long,
|
||||
noinline block: suspend CoroutineScope.() -> R
|
||||
): R {
|
||||
@ -480,7 +480,7 @@ internal suspend inline fun <reified T : MessageEvent, R> T.selectMessagesImpl(
|
||||
filterContext: Boolean = true,
|
||||
@BuilderInference
|
||||
crossinline selectBuilder: @MessageDsl MessageSelectBuilderUnit<T, R>.() -> Unit
|
||||
): R = withTimeoutOrCoroutineScope(timeoutMillis) {
|
||||
): R = withSilentTimeoutOrCoroutineScope(timeoutMillis) {
|
||||
var deferred: CompletableDeferred<R>? = CompletableDeferred()
|
||||
coroutineContext[Job]!!.invokeOnCompletion {
|
||||
deferred?.cancel()
|
||||
@ -500,7 +500,7 @@ internal suspend inline fun <reified T : MessageEvent, R> T.selectMessagesImpl(
|
||||
SELECT_MESSAGE_STUB,
|
||||
outside
|
||||
) {
|
||||
override fun obtainCurrentCoroutineScope(): CoroutineScope = this@withTimeoutOrCoroutineScope
|
||||
override fun obtainCurrentCoroutineScope(): CoroutineScope = this@withSilentTimeoutOrCoroutineScope
|
||||
override fun obtainCurrentDeferred(): CompletableDeferred<R>? = deferred
|
||||
override fun default(onEvent: MessageListener<T, R>) {
|
||||
defaultListeners += onEvent
|
||||
@ -516,7 +516,7 @@ internal suspend inline fun <reified T : MessageEvent, R> T.selectMessagesImpl(
|
||||
SELECT_MESSAGE_STUB,
|
||||
outside
|
||||
) {
|
||||
override fun obtainCurrentCoroutineScope(): CoroutineScope = this@withTimeoutOrCoroutineScope
|
||||
override fun obtainCurrentCoroutineScope(): CoroutineScope = this@withSilentTimeoutOrCoroutineScope
|
||||
override fun obtainCurrentDeferred(): CompletableDeferred<R>? = deferred
|
||||
override fun default(onEvent: MessageListener<T, R>) {
|
||||
defaultListeners += onEvent
|
||||
@ -577,7 +577,7 @@ internal suspend inline fun <reified T : MessageEvent> T.whileSelectMessagesImpl
|
||||
timeoutMillis: Long = -1,
|
||||
filterContext: Boolean = true,
|
||||
crossinline selectBuilder: @MessageDsl MessageSelectBuilder<T, Boolean>.() -> Unit
|
||||
) = withTimeoutOrCoroutineScope(timeoutMillis) {
|
||||
) = withSilentTimeoutOrCoroutineScope(timeoutMillis) {
|
||||
var deferred: CompletableDeferred<Boolean>? = CompletableDeferred()
|
||||
coroutineContext[Job]!!.invokeOnCompletion {
|
||||
deferred?.cancel()
|
||||
@ -596,7 +596,7 @@ internal suspend inline fun <reified T : MessageEvent> T.whileSelectMessagesImpl
|
||||
SELECT_MESSAGE_STUB,
|
||||
outside
|
||||
) {
|
||||
override fun obtainCurrentCoroutineScope(): CoroutineScope = this@withTimeoutOrCoroutineScope
|
||||
override fun obtainCurrentCoroutineScope(): CoroutineScope = this@withSilentTimeoutOrCoroutineScope
|
||||
override fun obtainCurrentDeferred(): CompletableDeferred<Boolean>? = deferred
|
||||
override fun default(onEvent: MessageListener<T, Boolean>) {
|
||||
defaultListeners += onEvent
|
||||
|
Loading…
Reference in New Issue
Block a user