mirror of
https://github.com/mamoe/mirai.git
synced 2025-02-08 19:54:44 +08:00
Rename subscribingGet
to syncFromEvent
, subscribingGetAsync
to asyncFromEvent
; Improve docs
This commit is contained in:
parent
5234226788
commit
d94b1d3279
@ -7,47 +7,53 @@
|
||||
* https://github.com/mamoe/mirai/blob/master/LICENSE
|
||||
*/
|
||||
|
||||
@file:Suppress("unused")
|
||||
|
||||
package net.mamoe.mirai.event
|
||||
|
||||
import kotlinx.coroutines.*
|
||||
import net.mamoe.mirai.utils.MiraiExperimentalAPI
|
||||
import net.mamoe.mirai.utils.SinceMirai
|
||||
import kotlin.coroutines.CoroutineContext
|
||||
import kotlin.coroutines.EmptyCoroutineContext
|
||||
import kotlin.coroutines.suspendCoroutine
|
||||
import kotlin.jvm.JvmSynthetic
|
||||
import kotlin.reflect.KClass
|
||||
|
||||
/**
|
||||
* 挂起当前协程, 监听这个事件, 并尝试从这个事件中获取一个值.
|
||||
* 挂起当前协程, 监听事件 [E], 并尝试从这个事件中**同步**一个值, 在超时时抛出 [TimeoutCancellationException]
|
||||
*
|
||||
* 若 [mapper] 抛出了一个异常, 本函数会立即抛出这个异常.
|
||||
* @param timeoutMillis 超时. 单位为毫秒. `-1` 为不限制.
|
||||
* @param mapper 过滤转换器. 返回非 null 则代表得到了需要的值. [syncFromEvent] 会返回这个值
|
||||
*
|
||||
* @param timeoutMillis 超时. 单位为毫秒. `-1` 为不限制
|
||||
* @param mapper 过滤转换器. 返回非 null 则代表得到了需要的值. [subscribingGet] 会返回这个值
|
||||
* @see asyncFromEvent 本函数的异步版本
|
||||
*
|
||||
* @see subscribingGetAsync 本函数的异步版本
|
||||
* @throws TimeoutCancellationException 在超时后抛出.
|
||||
* @throws Throwable 当 [mapper] 抛出任何异常时, 本函数会抛出该异常
|
||||
*/
|
||||
@SinceMirai("0.29.0")
|
||||
@MiraiExperimentalAPI
|
||||
suspend inline fun <reified E : Event, R : Any> subscribingGet(
|
||||
@JvmSynthetic
|
||||
@SinceMirai("0.38.0")
|
||||
suspend inline fun <reified E : Event, R : Any> syncFromEvent(
|
||||
timeoutMillis: Long = -1,
|
||||
noinline mapper: suspend E.(E) -> R? // 不要 crossinline: crossinline 后 stacktrace 会不正常
|
||||
): R {
|
||||
require(timeoutMillis == -1L || timeoutMillis > 0) { "timeoutMillis must be -1 or > 0" }
|
||||
return subscribingGetOrNull(timeoutMillis, mapper) ?: error("timeout subscribingGet")
|
||||
return syncFromEventOrNull(timeoutMillis, mapper) ?: error("timeout $timeoutMillis ms asyncFromEvent")
|
||||
}
|
||||
|
||||
/**
|
||||
* 挂起当前协程, 监听这个事件, 并尝试从这个事件中获取一个值.
|
||||
*
|
||||
* 若 [mapper] 抛出了一个异常, 本函数会立即抛出这个异常.
|
||||
* 挂起当前协程, 监听这个事件, 并尝试从这个事件中获取一个值, 在超时时返回 `null`
|
||||
*
|
||||
* @param timeoutMillis 超时. 单位为毫秒. `-1` 为不限制
|
||||
* @param mapper 过滤转换器. 返回非 null 则代表得到了需要的值. [subscribingGet] 会返回这个值
|
||||
* @param mapper 过滤转换器. 返回非 null 则代表得到了需要的值.
|
||||
*
|
||||
* @see subscribingGetAsync 本函数的异步版本
|
||||
* @return 超时返回 `null`, 否则返回 [mapper] 返回的第一个非 `null` 值.
|
||||
*
|
||||
* @see asyncFromEvent 本函数的异步版本
|
||||
* @throws Throwable 当 [mapper] 抛出任何异常时, 本函数会抛出该异常
|
||||
*/
|
||||
@SinceMirai("0.29.0")
|
||||
@MiraiExperimentalAPI
|
||||
suspend inline fun <reified E : Event, R : Any> subscribingGetOrNull(
|
||||
@JvmSynthetic
|
||||
@SinceMirai("0.38.0")
|
||||
suspend inline fun <reified E : Event, R : Any> syncFromEventOrNull(
|
||||
timeoutMillis: Long = -1,
|
||||
noinline mapper: suspend E.(E) -> R? // 不要 crossinline: crossinline 后 stacktrace 会不正常
|
||||
): R? {
|
||||
@ -55,11 +61,11 @@ suspend inline fun <reified E : Event, R : Any> subscribingGetOrNull(
|
||||
|
||||
return if (timeoutMillis == -1L) {
|
||||
coroutineScope {
|
||||
subscribingGetOrNullImpl<E, R>(this, mapper)
|
||||
syncFromEventOrNullImpl<E, R>(E::class, this, mapper)
|
||||
}
|
||||
} else {
|
||||
withTimeoutOrNull(timeoutMillis) {
|
||||
subscribingGetOrNullImpl<E, R>(this, mapper)
|
||||
syncFromEventOrNullImpl<E, R>(E::class, this, mapper)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -71,16 +77,42 @@ suspend inline fun <reified E : Event, R : Any> subscribingGetOrNull(
|
||||
*
|
||||
* @param timeoutMillis 超时. 单位为毫秒. `-1` 为不限制
|
||||
* @param coroutineContext 额外的 [CoroutineContext]
|
||||
* @param mapper 过滤转换器. 返回非 null 则代表得到了需要的值. [subscribingGet] 会返回这个值
|
||||
* @param mapper 过滤转换器. 返回非 `null` 则代表得到了需要的值. [syncFromEvent] 会返回这个值
|
||||
*/
|
||||
@SinceMirai("0.29.0")
|
||||
@MiraiExperimentalAPI
|
||||
inline fun <reified E : Event, R : Any> CoroutineScope.subscribingGetAsync(
|
||||
@Suppress("DeferredIsResult")
|
||||
@SinceMirai("0.38.0")
|
||||
inline fun <reified E : Event, R : Any> CoroutineScope.asyncFromEventOrNull(
|
||||
timeoutMillis: Long = -1,
|
||||
coroutineContext: CoroutineContext = EmptyCoroutineContext,
|
||||
noinline mapper: suspend E.(E) -> R? // 不要 crossinline: crossinline 后 stacktrace 会不正常
|
||||
): Deferred<R> = this.async(coroutineContext) {
|
||||
subscribingGet(timeoutMillis, mapper)
|
||||
): Deferred<R?> {
|
||||
require(timeoutMillis == -1L || timeoutMillis > 0) { "timeoutMillis must be -1 or > 0" }
|
||||
return this.async(coroutineContext) {
|
||||
syncFromEventOrNull(timeoutMillis, mapper)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 异步监听这个事件, 并尝试从这个事件中获取一个值.
|
||||
*
|
||||
* 若 [mapper] 抛出的异常将会被传递给 [Deferred.await] 抛出.
|
||||
*
|
||||
* @param timeoutMillis 超时. 单位为毫秒. `-1` 为不限制
|
||||
* @param coroutineContext 额外的 [CoroutineContext]
|
||||
* @param mapper 过滤转换器. 返回非 null 则代表得到了需要的值. [syncFromEvent] 会返回这个值
|
||||
*/
|
||||
@Suppress("DeferredIsResult")
|
||||
@SinceMirai("0.38.0")
|
||||
inline fun <reified E : Event, R : Any> CoroutineScope.asyncFromEvent(
|
||||
timeoutMillis: Long = -1,
|
||||
coroutineContext: CoroutineContext = EmptyCoroutineContext,
|
||||
noinline mapper: suspend E.(E) -> R? // 不要 crossinline: crossinline 后 stacktrace 会不正常
|
||||
): Deferred<R> {
|
||||
require(timeoutMillis == -1L || timeoutMillis > 0) { "timeoutMillis must be -1 or > 0" }
|
||||
return this.async(coroutineContext) {
|
||||
syncFromEvent(timeoutMillis, mapper)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -88,24 +120,19 @@ inline fun <reified E : Event, R : Any> CoroutineScope.subscribingGetAsync(
|
||||
//// internal
|
||||
//////////////
|
||||
|
||||
|
||||
@PublishedApi
|
||||
internal suspend inline fun <reified E : Event, R> subscribingGetOrNullImpl(
|
||||
internal suspend fun <E : Event, R> syncFromEventOrNullImpl(
|
||||
eventClass: KClass<E>,
|
||||
coroutineScope: CoroutineScope,
|
||||
noinline mapper: suspend E.(E) -> R?
|
||||
): R? {
|
||||
var result: Result<R?> = Result.success(null) // stub
|
||||
mapper: suspend E.(E) -> R?
|
||||
): R? = suspendCoroutine { cont ->
|
||||
var listener: Listener<E>? = null
|
||||
@Suppress("DuplicatedCode") // for better performance
|
||||
listener = coroutineScope.subscribe {
|
||||
result = kotlin.runCatching {
|
||||
listener = coroutineScope.subscribe(eventClass) {
|
||||
cont.resumeWith(kotlin.runCatching {
|
||||
mapper.invoke(this, it) ?: return@subscribe ListeningStatus.LISTENING
|
||||
}
|
||||
})
|
||||
listener!!.complete()
|
||||
return@subscribe ListeningStatus.STOPPED
|
||||
|
||||
}
|
||||
listener.join()
|
||||
|
||||
return result.getOrThrow()
|
||||
}
|
Loading…
Reference in New Issue
Block a user