mirror of
https://github.com/mamoe/mirai.git
synced 2025-03-12 14:00:12 +08:00
Fix syncFromEvent
, add Tests
This commit is contained in:
parent
422e8a9b4b
commit
ca216bc492
@ -15,7 +15,6 @@ import kotlinx.coroutines.*
|
|||||||
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.jvm.JvmSynthetic
|
||||||
import kotlin.reflect.KClass
|
import kotlin.reflect.KClass
|
||||||
|
|
||||||
@ -37,7 +36,16 @@ suspend inline fun <reified E : Event, R : Any> syncFromEvent(
|
|||||||
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 syncFromEventOrNull(timeoutMillis, mapper) ?: error("timeout $timeoutMillis ms asyncFromEvent")
|
|
||||||
|
return if (timeoutMillis == -1L) {
|
||||||
|
coroutineScope {
|
||||||
|
syncFromEventImpl<E, R>(E::class, this, mapper)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
withTimeout(timeoutMillis) {
|
||||||
|
syncFromEventImpl<E, R>(E::class, this, mapper)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -54,19 +62,13 @@ suspend inline fun <reified E : Event, R : Any> syncFromEvent(
|
|||||||
@JvmSynthetic
|
@JvmSynthetic
|
||||||
@SinceMirai("0.38.0")
|
@SinceMirai("0.38.0")
|
||||||
suspend inline fun <reified E : Event, R : Any> syncFromEventOrNull(
|
suspend inline fun <reified E : Event, R : Any> syncFromEventOrNull(
|
||||||
timeoutMillis: Long = -1,
|
timeoutMillis: Long,
|
||||||
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 > 0) { "timeoutMillis must be > 0" }
|
||||||
|
|
||||||
return if (timeoutMillis == -1L) {
|
return withTimeoutOrNull(timeoutMillis) {
|
||||||
coroutineScope {
|
syncFromEventImpl<E, R>(E::class, this, mapper)
|
||||||
syncFromEventOrNullImpl<E, R>(E::class, this, mapper)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
withTimeoutOrNull(timeoutMillis) {
|
|
||||||
syncFromEventOrNullImpl<E, R>(E::class, this, mapper)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -83,7 +85,7 @@ suspend inline fun <reified E : Event, R : Any> syncFromEventOrNull(
|
|||||||
@Suppress("DeferredIsResult")
|
@Suppress("DeferredIsResult")
|
||||||
@SinceMirai("0.38.0")
|
@SinceMirai("0.38.0")
|
||||||
inline fun <reified E : Event, R : Any> CoroutineScope.asyncFromEventOrNull(
|
inline fun <reified E : Event, R : Any> CoroutineScope.asyncFromEventOrNull(
|
||||||
timeoutMillis: Long = -1,
|
timeoutMillis: Long,
|
||||||
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?> {
|
): Deferred<R?> {
|
||||||
@ -123,11 +125,11 @@ inline fun <reified E : Event, R : Any> CoroutineScope.asyncFromEvent(
|
|||||||
//////////////
|
//////////////
|
||||||
|
|
||||||
@PublishedApi
|
@PublishedApi
|
||||||
internal suspend fun <E : Event, R> syncFromEventOrNullImpl(
|
internal suspend fun <E : Event, R> syncFromEventImpl(
|
||||||
eventClass: KClass<E>,
|
eventClass: KClass<E>,
|
||||||
coroutineScope: CoroutineScope,
|
coroutineScope: CoroutineScope,
|
||||||
mapper: suspend E.(E) -> R?
|
mapper: suspend E.(E) -> R?
|
||||||
): R? = suspendCoroutine { cont ->
|
): R = suspendCancellableCoroutine { cont ->
|
||||||
coroutineScope.subscribe(eventClass) {
|
coroutineScope.subscribe(eventClass) {
|
||||||
cont.resumeWith(kotlin.runCatching {
|
cont.resumeWith(kotlin.runCatching {
|
||||||
mapper.invoke(this, it) ?: return@subscribe ListeningStatus.LISTENING
|
mapper.invoke(this, it) ?: return@subscribe ListeningStatus.LISTENING
|
||||||
|
@ -0,0 +1,61 @@
|
|||||||
|
/*
|
||||||
|
* 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.message
|
||||||
|
|
||||||
|
import kotlinx.coroutines.CoroutineScope
|
||||||
|
import kotlinx.coroutines.TimeoutCancellationException
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
|
import kotlinx.coroutines.withTimeout
|
||||||
|
import net.mamoe.mirai.event.TestEvent
|
||||||
|
import net.mamoe.mirai.event.broadcast
|
||||||
|
import net.mamoe.mirai.event.syncFromEvent
|
||||||
|
import net.mamoe.mirai.test.runBlocking
|
||||||
|
import kotlin.coroutines.CoroutineContext
|
||||||
|
import kotlin.coroutines.EmptyCoroutineContext
|
||||||
|
import kotlin.coroutines.resume
|
||||||
|
import kotlin.coroutines.suspendCoroutine
|
||||||
|
import kotlin.test.Test
|
||||||
|
import kotlin.test.assertFailsWith
|
||||||
|
|
||||||
|
internal class SubscribingGetTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun testSyncFromEvent(): Unit = runBlocking {
|
||||||
|
withTimeout(500) {
|
||||||
|
suspendCoroutine<Unit> { cont ->
|
||||||
|
launch {
|
||||||
|
syncFromEvent(5000) { _: TestEvent ->
|
||||||
|
cont.resume(Unit)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
launch {
|
||||||
|
TestEvent().broadcast()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun testSyncFromEventTimeout() {
|
||||||
|
runBlockingWithTimeout(500) {
|
||||||
|
assertFailsWith<TimeoutCancellationException> {
|
||||||
|
syncFromEvent(100) { _: TestEvent -> }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal fun <R> runBlockingWithTimeout(
|
||||||
|
millis: Long,
|
||||||
|
context: CoroutineContext = EmptyCoroutineContext,
|
||||||
|
block: suspend CoroutineScope.() -> R
|
||||||
|
): R = runBlocking(context) {
|
||||||
|
withTimeout(millis, block)
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user