Introduce AsyncRecallResult for getting result of recallIn

This commit is contained in:
Him188 2021-01-11 18:36:04 +08:00
parent 84ecb1df11
commit 93fcb566fd
5 changed files with 109 additions and 10 deletions

View File

@ -45,6 +45,7 @@ fun ktor(id: String, version: String = Versions.ktor) = "io.ktor:ktor-$id:$versi
val `kotlinx-coroutines-core` = kotlinx("coroutines-core", Versions.coroutines)
val `kotlinx-coroutines-jdk8` = kotlinx("coroutines-jdk8", Versions.coroutines)
val `kotlinx-serialization-core` = kotlinx("serialization-core", Versions.serialization)
val `kotlinx-serialization-json` = kotlinx("serialization-json", Versions.serialization)
val `kotlinx-serialization-protobuf` = kotlinx("serialization-protobuf", Versions.serialization)

View File

@ -1,5 +1,5 @@
/*
* Copyright 2019-2020 Mamoe Technologies and contributors.
* Copyright 2019-2021 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.
@ -78,6 +78,7 @@ kotlin {
api1(`kotlinx-io-jvm`)
api1(`kotlinx-coroutines-io-jvm`)
api(`kotlinx-coroutines-core`)
// api(`kotlinx-coroutines-jdk8`)
implementation1(`kotlinx-atomicfu`)

View File

@ -1,5 +1,5 @@
/*
* Copyright 2019-2020 Mamoe Technologies and contributors.
* Copyright 2019-2021 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.
@ -11,12 +11,12 @@
package net.mamoe.mirai.message
import kotlinx.coroutines.Deferred
import net.mamoe.kjbb.JvmBlockingBridge
import net.mamoe.mirai.Bot
import net.mamoe.mirai.IMirai
import net.mamoe.mirai.Mirai
import net.mamoe.mirai.contact.*
import net.mamoe.mirai.message.action.AsyncRecallResult
import net.mamoe.mirai.message.data.*
import net.mamoe.mirai.message.data.MessageSource.Key.quote
import net.mamoe.mirai.message.data.MessageSource.Key.recallIn
@ -70,7 +70,7 @@ public open class MessageReceipt<out C : Contact> @MiraiInternalApi constructor(
* @see IMirai.recallMessage
*/
@Suppress("DeferredIsResult")
public fun recallIn(millis: Long): Deferred<Unit> = this.source.recallIn(millis)
public fun recallIn(millis: Long): AsyncRecallResult = this.source.recallIn(millis)
/**
* 引用这条消息.

View File

@ -0,0 +1,90 @@
/*
* 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
*/
@file:Suppress("MemberVisibilityCanBePrivate", "unused")
package net.mamoe.mirai.message.action
import kotlinx.coroutines.*
import net.mamoe.kjbb.JvmBlockingBridge
import net.mamoe.mirai.message.data.MessageSource
import net.mamoe.mirai.message.data.MessageSource.Key.recallIn
import java.util.concurrent.CompletableFuture
/**
* [MessageSource.recallIn] 的结果.
*
* @see MessageSource.recallIn
*/
public class AsyncRecallResult internal constructor(
/**
* 撤回时产生的异常. Kotlin [Deferred] API.
*/
public val exception: Deferred<Throwable?>,
) {
/**
* 撤回时产生的异常. Java [CompletableFuture] API.
*/
public val exceptionFuture: CompletableFuture<Throwable?> by lazy { exception.asCompletableFuture() }
/**
* 撤回是否成功. Kotlin [Deferred] API.
*/
public val isSuccess: Deferred<Boolean> by lazy {
GlobalScope.async {
kotlin.runCatching { exception.await() == null }.getOrElse { false }
}
}
/**
* 撤回是否成功. Java [CompletableFuture] API.
*/
public val isSuccessFuture: CompletableFuture<Boolean> by lazy { isSuccess.asCompletableFuture() }
/**
* 等待撤回完成, 返回撤回时产生的异常.
*/
@JvmBlockingBridge
public suspend fun awaitException(): Throwable? {
return exception.await()
}
/**
* 等待撤回完成, 返回撤回的结果.
*/
@JvmBlockingBridge
public suspend fun awaitIsSuccess(): Boolean {
return isSuccess.await()
}
}
// copied from kotlinx-coroutines-jdk8
private fun <T> Deferred<T>.asCompletableFuture(): CompletableFuture<T> {
val future = CompletableFuture<T>()
setupCancellation(future)
invokeOnCompletion {
@OptIn(ExperimentalCoroutinesApi::class)
try {
future.complete(getCompleted())
} catch (t: Throwable) {
future.completeExceptionally(t)
}
}
return future
}
// copied from kotlinx-coroutines-jdk8
private fun Job.setupCancellation(future: CompletableFuture<*>) {
future.whenComplete { _, exception ->
cancel(exception?.let {
it as? CancellationException ?: CancellationException("CompletableFuture was completed exceptionally", it)
})
}
}

View File

@ -25,6 +25,7 @@ import net.mamoe.mirai.contact.*
import net.mamoe.mirai.event.events.MessageEvent
import net.mamoe.mirai.internal.message.MessageSourceSerializerImpl
import net.mamoe.mirai.message.MessageReceipt
import net.mamoe.mirai.message.action.AsyncRecallResult
import net.mamoe.mirai.message.data.MessageSource.Key.quote
import net.mamoe.mirai.message.data.MessageSource.Key.recall
import net.mamoe.mirai.utils.LazyProperty
@ -199,20 +200,26 @@ public sealed class MessageSource : Message, MessageMetadata, ConstrainSingle {
*/
@JvmStatic
@Suppress("DeferredIsResult")
public fun MessageChain.recallIn(millis: Long): Deferred<Unit> = this.source.recallIn(millis)
public fun MessageChain.recallIn(millis: Long): AsyncRecallResult = this.source.recallIn(millis)
/**
* 在一段时间后撤回这条消息.
*
* @return 返回撤回的结果 [Deferred]. [Deferred.await] 返回 `null` 表示成功执行
* @see IMirai.recallMessage
*/
@JvmStatic
@Suppress("DeferredIsResult")
public fun MessageSource.recallIn(millis: Long): Deferred<Unit> {
return bot.async {
delay(millis)
Mirai.recallMessage(bot, this@recallIn)
}
public fun MessageSource.recallIn(millis: Long): AsyncRecallResult {
return AsyncRecallResult(bot.async {
try {
delay(millis)
Mirai.recallMessage(bot, this@recallIn)
null
} catch (e: Throwable) {
e
}
})
}
/**