mirror of
https://github.com/mamoe/mirai.git
synced 2025-01-10 02:20:14 +08:00
Add subscribingGet
, CoroutineScope.subscribingGetAsync
This commit is contained in:
parent
e580992e0b
commit
03c6143269
@ -9,3 +9,104 @@
|
|||||||
|
|
||||||
package net.mamoe.mirai.event
|
package net.mamoe.mirai.event
|
||||||
|
|
||||||
|
import kotlinx.coroutines.*
|
||||||
|
import net.mamoe.mirai.utils.MiraiExperimentalAPI
|
||||||
|
import kotlin.coroutines.CoroutineContext
|
||||||
|
import kotlin.coroutines.EmptyCoroutineContext
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 监听这个事件, 并尝试从这个事件中获取一个值.
|
||||||
|
*
|
||||||
|
* 若 [filter] 抛出了一个异常, 本函数会立即抛出这个异常.
|
||||||
|
*
|
||||||
|
* @param timeoutMillis 超时. 单位为毫秒. `-1` 为不限制
|
||||||
|
* @param filter 过滤器. 返回非 null 则代表得到了需要的值. [subscribingGet] 会返回这个值
|
||||||
|
*
|
||||||
|
* @see subscribingGetAsync 本函数的异步版本
|
||||||
|
*/
|
||||||
|
@MiraiExperimentalAPI
|
||||||
|
suspend inline fun <reified E : Event, R : Any> subscribingGet(
|
||||||
|
timeoutMillis: Long = -1,
|
||||||
|
noinline filter: E.(E) -> R?
|
||||||
|
): R {
|
||||||
|
require(timeoutMillis == -1L || timeoutMillis > 0) { "timeoutMillis must be -1 or > 0" }
|
||||||
|
return subscribingGetOrNull(timeoutMillis, filter) ?: error("timeout subscribingGet")
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 监听这个事件, 并尝试从这个事件中获取一个值.
|
||||||
|
*
|
||||||
|
* 若 [filter] 抛出了一个异常, 本函数会立即抛出这个异常.
|
||||||
|
*
|
||||||
|
* @param timeoutMillis 超时. 单位为毫秒. `-1` 为不限制
|
||||||
|
* @param filter 过滤器. 返回非 null 则代表得到了需要的值. [subscribingGet] 会返回这个值
|
||||||
|
*
|
||||||
|
* @see subscribingGetAsync 本函数的异步版本
|
||||||
|
*/
|
||||||
|
@MiraiExperimentalAPI
|
||||||
|
suspend inline fun <reified E : Event, R : Any> subscribingGetOrNull(
|
||||||
|
timeoutMillis: Long = -1,
|
||||||
|
noinline filter: E.(E) -> R?
|
||||||
|
): R? {
|
||||||
|
require(timeoutMillis == -1L || timeoutMillis > 0) { "timeoutMillis must be -1 or > 0" }
|
||||||
|
var result: R? = null
|
||||||
|
var resultThrowable: Throwable? = null
|
||||||
|
|
||||||
|
if (timeoutMillis == -1L) {
|
||||||
|
@Suppress("DuplicatedCode") // for better performance
|
||||||
|
coroutineScope {
|
||||||
|
var listener: Listener<E>? = null
|
||||||
|
listener = this.subscribe {
|
||||||
|
val value = try {
|
||||||
|
filter.invoke(this, it)
|
||||||
|
} catch (e: Exception) {
|
||||||
|
resultThrowable = e
|
||||||
|
return@subscribe ListeningStatus.STOPPED.also { listener!!.complete() }
|
||||||
|
}
|
||||||
|
|
||||||
|
if (value != null) {
|
||||||
|
result = value
|
||||||
|
return@subscribe ListeningStatus.STOPPED.also { listener!!.complete() }
|
||||||
|
} else return@subscribe ListeningStatus.LISTENING
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
withTimeoutOrNull(timeoutMillis) {
|
||||||
|
var listener: Listener<E>? = null
|
||||||
|
@Suppress("DuplicatedCode") // for better performance
|
||||||
|
listener = this.subscribe {
|
||||||
|
val value = try {
|
||||||
|
filter.invoke(this, it)
|
||||||
|
} catch (e: Exception) {
|
||||||
|
resultThrowable = e
|
||||||
|
return@subscribe ListeningStatus.STOPPED.also { listener!!.complete() }
|
||||||
|
}
|
||||||
|
|
||||||
|
if (value != null) {
|
||||||
|
result = value
|
||||||
|
return@subscribe ListeningStatus.STOPPED.also { listener!!.complete() }
|
||||||
|
} else return@subscribe ListeningStatus.LISTENING
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
resultThrowable?.let { throw it }
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 异步监听这个事件, 并尝试从这个事件中获取一个值.
|
||||||
|
*
|
||||||
|
* 若 [filter] 抛出了一个异常, [Deferred.await] 会抛出这个异常或.
|
||||||
|
*
|
||||||
|
* @param timeoutMillis 超时. 单位为毫秒. `-1` 为不限制
|
||||||
|
* @param coroutineContext 额外的 [CoroutineContext]
|
||||||
|
* @param filter 过滤器. 返回非 null 则代表得到了需要的值. [subscribingGet] 会返回这个值
|
||||||
|
*/
|
||||||
|
@MiraiExperimentalAPI
|
||||||
|
inline fun <reified E : Event, R : Any> CoroutineScope.subscribingGetAsync(
|
||||||
|
coroutineContext: CoroutineContext = EmptyCoroutineContext,
|
||||||
|
timeoutMillis: Long = -1,
|
||||||
|
noinline filter: E.(E) -> R?
|
||||||
|
): Deferred<R> = this.async(coroutineContext) {
|
||||||
|
subscribingGet(timeoutMillis, filter)
|
||||||
|
}
|
@ -101,6 +101,9 @@ interface Listener<in E : Event> : CompletableJob {
|
|||||||
*
|
*
|
||||||
* @param coroutineContext 给事件监听协程的额外的 [CoroutineContext]
|
* @param coroutineContext 给事件监听协程的额外的 [CoroutineContext]
|
||||||
*
|
*
|
||||||
|
* @see subscribingGet 监听一个事件, 并尝试从这个事件中获取一个值.
|
||||||
|
* @see subscribingGetAsync 异步监听一个事件, 并尝试从这个事件中获取一个值.
|
||||||
|
*
|
||||||
* @see subscribeAlways 一直监听
|
* @see subscribeAlways 一直监听
|
||||||
* @see subscribeOnce 只监听一次
|
* @see subscribeOnce 只监听一次
|
||||||
*
|
*
|
||||||
|
Loading…
Reference in New Issue
Block a user