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