mirror of
https://github.com/mamoe/mirai.git
synced 2025-01-05 07:30:09 +08:00
Make MessageChain implement List<SingleMessage>
;
Hide relevant APIs on `Iterable`; Deprecate `__forEachForJava__` in favor of Java 8 API; Add `fun messageChainOf(vararg messages: Message): MessageChain`; Add `fun Array<out Message>.asMessageChain(): MessageChain`; Add `fun Array<out SingleMessage>.asMessageChain(): MessageChain`; Add `fun Array<out Message>.flatten(): Sequence<SingleMessage>`; Add `fun Array<out SingleMessage>.flatten(): Sequence<SingleMessage>`; Close #312
This commit is contained in:
parent
9733490266
commit
b64b1da666
@ -13,11 +13,10 @@
|
||||
package net.mamoe.mirai.message.data
|
||||
|
||||
import net.mamoe.mirai.utils.MiraiExperimentalAPI
|
||||
import net.mamoe.mirai.utils.MiraiInternalAPI
|
||||
import net.mamoe.mirai.utils.PlannedRemoval
|
||||
import kotlin.jvm.JvmField
|
||||
import kotlin.jvm.JvmMultifileClass
|
||||
import kotlin.jvm.JvmName
|
||||
import kotlin.jvm.JvmSynthetic
|
||||
|
||||
/**
|
||||
* 快速链接的两个消息 (避免构造新的 list).
|
||||
@ -33,26 +32,23 @@ internal class CombinedMessage
|
||||
internal constructor(
|
||||
@JvmField internal val left: Message, // 必须已经完成 constrain single
|
||||
@JvmField internal val tail: Message
|
||||
) : Message, MessageChain {
|
||||
) : Message, MessageChain, List<SingleMessage> by (left.flatten() + tail.flatten()).toList() {
|
||||
|
||||
fun asSequence(): Sequence<SingleMessage> = sequence {
|
||||
yieldCombinedOrElementsFlatten(this@CombinedMessage)
|
||||
}
|
||||
|
||||
override fun iterator(): Iterator<SingleMessage> {
|
||||
return asSequence().iterator()
|
||||
}
|
||||
|
||||
override val size: Int
|
||||
get() = kotlin.run {
|
||||
var size = 0
|
||||
size += if (left is MessageChain) left.size else 1
|
||||
size += if (tail is MessageChain) tail.size else 1
|
||||
size
|
||||
}
|
||||
@PlannedRemoval("1.2.0")
|
||||
@Deprecated(
|
||||
"use asSequence from stdlib",
|
||||
ReplaceWith("(this as List<SingleMessage>).asSequence()"),
|
||||
level = DeprecationLevel.HIDDEN
|
||||
)
|
||||
@Suppress("INVISIBLE_REFERENCE", "INVISIBLE_MEMBER")
|
||||
@kotlin.internal.LowPriorityInOverloadResolution // resolve to extension from stdlib
|
||||
fun asSequence(): Sequence<SingleMessage> = (this as List<SingleMessage>).asSequence()
|
||||
|
||||
override fun equals(other: Any?): Boolean {
|
||||
return other is CombinedMessage && other.left == this.left && other.tail == this.tail
|
||||
if (other == null) return false
|
||||
if (other::class != CombinedMessage::class) return false
|
||||
other as CombinedMessage
|
||||
return other.left == this.left && other.tail == this.tail
|
||||
}
|
||||
|
||||
private var toStringCache: String? = null
|
||||
@ -71,6 +67,7 @@ internal constructor(
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@JvmSynthetic
|
||||
// 不要把它用作 local function, 会编译错误
|
||||
@OptIn(MiraiExperimentalAPI::class, MiraiInternalAPI::class)
|
||||
@ -93,3 +90,4 @@ private suspend fun SequenceScope<SingleMessage>.yieldCombinedOrElementsFlatten(
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
@ -196,6 +196,7 @@ fun Iterable<MessageEvent>.toForwardMessage(displayStrategy: DisplayStrategy = D
|
||||
/**
|
||||
* 转换为 [ForwardMessage]
|
||||
*/
|
||||
@JvmOverloads
|
||||
fun Message.toForwardMessage(
|
||||
sender: User,
|
||||
time: Int = currentTimeSeconds.toInt(),
|
||||
|
@ -33,6 +33,10 @@ import kotlin.reflect.KProperty
|
||||
* 要获取更多消息相关的信息, 查看 [Message]
|
||||
*
|
||||
* ### 构造消息链
|
||||
* - [buildMessageChain]: 使用构建器
|
||||
* - [Message.plus]: 将两个消息相连成为一个消息链
|
||||
* - [asMessageChain] 将 [Iterable], 等类型消息
|
||||
* - [messageChainOf] 类似 [listOf], 将多个 [Message] 构造为 [MessageChain]
|
||||
*
|
||||
* ### 消息链如何工作
|
||||
* - [SingleMessageChainImpl] 将 [单个消息][SingleMessage] 委托为一个 [MessageChain]
|
||||
@ -54,7 +58,8 @@ import kotlin.reflect.KProperty
|
||||
* @see getValue 属性委托扩展
|
||||
* @see flatten 扁平化
|
||||
*/
|
||||
interface MessageChain : Message, Iterable<SingleMessage> {
|
||||
@Suppress("FunctionName", "DeprecatedCallableAddReplaceWith", "INVISIBLE_MEMBER", "INVISIBLE_REFERENCE")
|
||||
interface MessageChain : Message, List<SingleMessage>, RandomAccess {
|
||||
/**
|
||||
* 元素数量. [EmptyMessageChain] 不参加计数.
|
||||
*/
|
||||
@ -72,35 +77,22 @@ interface MessageChain : Message, Iterable<SingleMessage> {
|
||||
* 遍历每一个有内容的消息, 即 [At], [AtAll], [PlainText], [Image], [Face] 等
|
||||
* 仅供 `Java` 使用
|
||||
*/
|
||||
@Suppress("FunctionName")
|
||||
@JsName("forEachContent")
|
||||
@JvmName("forEachContent")
|
||||
@JavaFriendlyAPI
|
||||
final fun __forEachContentForJava__(block: (Message) -> Unit) {
|
||||
this.forEachContent(block)
|
||||
}
|
||||
final fun __forEachContentForJava__(block: (Message) -> Unit) = this.forEachContent(block)
|
||||
|
||||
/**
|
||||
* 遍历每一个消息, 即 [MessageSource] [At], [AtAll], [PlainText], [Image], [QuoteReply] 等
|
||||
* 仅供 `Java` 使用
|
||||
*/
|
||||
@Suppress("FunctionName")
|
||||
@JsName("forEach")
|
||||
|
||||
@PlannedRemoval("1.1.0")
|
||||
@Deprecated("use Java 8 API", level = DeprecationLevel.HIDDEN)
|
||||
@JvmName("forEach")
|
||||
@JavaFriendlyAPI
|
||||
final fun __forEachForJava__(block: (Message) -> Unit) {
|
||||
this.forEach(block)
|
||||
}
|
||||
@JvmSynthetic
|
||||
@kotlin.internal.LowPriorityInOverloadResolution
|
||||
final fun __forEachForJava__(block: (Message) -> Unit) = this.forEach(block)
|
||||
|
||||
|
||||
/**
|
||||
* 获取第一个类型为 [key] 的 [Message] 实例, 找不到则返回 `null`
|
||||
*
|
||||
* @param key 由各个类型消息的伴生对象持有. 如 [PlainText.Key]
|
||||
*/
|
||||
@PlannedRemoval("1.2.0")
|
||||
@JvmName("firstOrNull")
|
||||
@Deprecated("use get", ReplaceWith("get(key)"))
|
||||
@Deprecated("use get instead. This is going to be removed in mirai 1.2.0", ReplaceWith("get(key)"))
|
||||
final fun <M : Message> getOrNull(key: Message.Key<M>): M? = get(key)
|
||||
}
|
||||
|
||||
@ -271,6 +263,13 @@ inline fun <reified T : Message?> MessageChain.orElse(
|
||||
|
||||
|
||||
// region asMessageChain
|
||||
|
||||
/**
|
||||
* 返回一个包含 [messages] 所有元素的消息链, 保留顺序.
|
||||
*/
|
||||
@JvmName("newChain")
|
||||
inline fun messageChainOf(vararg messages: Message): MessageChain = messages.asMessageChain()
|
||||
|
||||
/**
|
||||
* 得到包含 [this] 的 [MessageChain].
|
||||
*
|
||||
@ -301,6 +300,18 @@ fun SingleMessage.asMessageChain(): MessageChain = SingleMessageChainImpl(this)
|
||||
fun Collection<SingleMessage>.asMessageChain(): MessageChain =
|
||||
MessageChainImplByCollection(this.constrainSingleMessages())
|
||||
|
||||
/**
|
||||
* 将 [this] [扁平化后][flatten] 委托为一个 [MessageChain]
|
||||
*/
|
||||
@JvmSynthetic
|
||||
@JvmName("newChain1")
|
||||
// @JsName("newChain")
|
||||
fun Array<out Message>.asMessageChain(): MessageChain = MessageChainImplBySequence(this.flatten())
|
||||
|
||||
@JvmSynthetic
|
||||
@JvmName("newChain2")
|
||||
fun Array<out SingleMessage>.asMessageChain(): MessageChain = MessageChainImplBySequence(this.asSequence())
|
||||
|
||||
/**
|
||||
* 将 [this] [扁平化后][flatten] 委托为一个 [MessageChain]
|
||||
*/
|
||||
@ -316,7 +327,7 @@ fun Iterable<SingleMessage>.asMessageChain(): MessageChain =
|
||||
MessageChainImplByCollection(this.constrainSingleMessages())
|
||||
|
||||
@JvmSynthetic
|
||||
fun MessageChain.asMessageChain(): MessageChain = this // 避免套娃
|
||||
inline fun MessageChain.asMessageChain(): MessageChain = this // 避免套娃
|
||||
|
||||
/**
|
||||
* 将 [this] [扁平化后][flatten] 委托为一个 [MessageChain]
|
||||
@ -338,15 +349,6 @@ fun Sequence<SingleMessage>.asMessageChain(): MessageChain = MessageChainImplByS
|
||||
// @JsName("newChain")
|
||||
fun Sequence<Message>.asMessageChain(): MessageChain = MessageChainImplBySequence(this.flatten())
|
||||
|
||||
/**
|
||||
* 构造一个 [MessageChain]
|
||||
* 为提供更好的 Java API.
|
||||
*/
|
||||
@Suppress("FunctionName")
|
||||
@JvmName("newChain")
|
||||
fun _____newChain______(vararg messages: Message): MessageChain {
|
||||
return messages.asIterable().asMessageChain()
|
||||
}
|
||||
|
||||
/**
|
||||
* 构造一个 [MessageChain]
|
||||
@ -396,6 +398,10 @@ inline fun Sequence<Message>.flatten(): Sequence<SingleMessage> = flatMap { it.f
|
||||
@JvmSynthetic
|
||||
inline fun Sequence<SingleMessage>.flatten(): Sequence<SingleMessage> = this // fast path
|
||||
|
||||
inline fun Array<out Message>.flatten(): Sequence<SingleMessage> = this.asSequence().flatten()
|
||||
|
||||
inline fun Array<out SingleMessage>.flatten(): Sequence<SingleMessage> = this.asSequence() // fast path
|
||||
|
||||
/**
|
||||
* 扁平化 [Message]
|
||||
*
|
||||
|
@ -33,7 +33,7 @@ import kotlin.jvm.JvmSynthetic
|
||||
*
|
||||
*
|
||||
* ### 组成
|
||||
* MessageSource 由 metadata (元数据), form & target, content 组成
|
||||
* [MessageSource] 由 metadata (元数据), form & target, content 组成
|
||||
*
|
||||
* #### metadata
|
||||
* - [id] 消息 id (序列号)
|
||||
|
@ -245,8 +245,8 @@ internal fun <M : Message> MessageChain.firstOrNullImpl(key: Message.Key<M>): M?
|
||||
* 使用 [Collection] 作为委托的 [MessageChain]
|
||||
*/
|
||||
internal class MessageChainImplByCollection constructor(
|
||||
internal val delegate: Collection<SingleMessage> // 必须 constrainSingleMessages, 且为 immutable
|
||||
) : Message, Iterable<SingleMessage>, MessageChain {
|
||||
internal val delegate: List<SingleMessage> // 必须 constrainSingleMessages, 且为 immutable
|
||||
) : Message, MessageChain, List<SingleMessage> by delegate {
|
||||
override val size: Int get() = delegate.size
|
||||
override fun iterator(): Iterator<SingleMessage> = delegate.iterator()
|
||||
|
||||
@ -266,15 +266,7 @@ internal class MessageChainImplByCollection constructor(
|
||||
*/
|
||||
internal class MessageChainImplBySequence constructor(
|
||||
delegate: Sequence<SingleMessage> // 可以有重复 ConstrainSingle
|
||||
) : Message, Iterable<SingleMessage>, MessageChain {
|
||||
override val size: Int by lazy { collected.size }
|
||||
|
||||
/**
|
||||
* [Sequence] 可能只能消耗一遍, 因此需要先转为 [List]
|
||||
*/
|
||||
private val collected: List<SingleMessage> by lazy { delegate.constrainSingleMessages() }
|
||||
override fun iterator(): Iterator<SingleMessage> = collected.iterator()
|
||||
|
||||
) : Message, Iterable<SingleMessage>, MessageChain, List<SingleMessage> by delegate.constrainSingleMessages() {
|
||||
private var toStringTemp: String? = null
|
||||
get() = field ?: this.joinToString("") { it.toString() }.also { field = it }
|
||||
|
||||
@ -291,11 +283,9 @@ internal class MessageChainImplBySequence constructor(
|
||||
*/
|
||||
internal class SingleMessageChainImpl constructor(
|
||||
internal val delegate: SingleMessage
|
||||
) : Message, Iterable<SingleMessage>, MessageChain {
|
||||
override val size: Int get() = 1
|
||||
) : Message, MessageChain, List<SingleMessage> by listOf(delegate) {
|
||||
override fun toString(): String = this.delegate.toString()
|
||||
override fun contentToString(): String = this.delegate.contentToString()
|
||||
override fun iterator(): Iterator<SingleMessage> = iterator { yield(delegate) }
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user