PluginData
一个插件内部的, 对用户隐藏的数据对象. 可包含对多个 Value 的值变更的跟踪. 典型的实现为 AbstractPluginData.
AbstractPluginData 不涉及有关数据的存储, 而是只维护数据结构: 属性节点列表.
有关存储方案, 请查看 PluginDataStorage.
注意: PluginData 总应该是单例的.
JvmPlugin 的实现方案
要修改保存时的名称, 请参考 ValueName
使用 Kotlin
在 JvmPlugin 的典型实现方式:
object PluginMain : KotlinPlugin()
object MyPluginData : AutoSavePluginData() {
var list: MutableList<String> by value(mutableListOf("a", "b")) // mutableListOf("a", "b") 是初始值, 可以省略
val custom: Map<Long, CustomData> by value() // 使用 kotlinx-serialization 序列化的类型.
var long: Long by value(0) // 允许 var
var int by value(0) // 可以使用类型推断, 但更推荐使用 `var long: Long by value(0)` 这种定义方式.
// 将 MutableMap<Long, Long> 映射到 MutableMap<Bot, Long>.
val botToLongMap: MutableMap<Bot, Long> by value<MutableMap<Long, Long>>().mapKeys(Bot::getInstance, Bot::id)
}
@Serializable // kotlinx.serialization: https://github.com/Kotlin/kotlinx.serialization
data class CustomData(
// ...
)
使用时, 可以方便地直接调用, 如:
val theList: MutableList<String> = AccountPluginData.list
但也注意, 不要存储 AccountPluginData.list
. 它可能受不到值跟踪. 若必要存储, 请使用 AbstractPluginData.findBackingFieldValue
使用 Java
非引用赋值
由于实现特殊, 赋值时不会写其引用. 即:
val list = ArrayList<String>("A")
MyPluginData.list = list // 赋值给 PluginData 的委托属性是非引用的
println(MyPluginData.list) // "[A]"
list.add("B")
println(list) // "[A, B]"
println(MyPluginData.list) // "[A]" // !! 由于 `list` 的引用并未赋值给 `MyPluginData.list`.
另一个更容易出错的示例:
// MyPluginData.nestedMap: MutableMap<Long, List<Long>> by value()
val newList = MyPluginData.map.getOrPut(1, ::mutableListOf)
newList.add(1) // 不会添加到 MyPluginData.nestedMap 中, 因为 `mutableListOf` 创建的 MutableList 被非引用 (浅拷贝) 地添加进了 MyPluginData.nestedMap
一个解决方案是对 SerializerAwareValue 做映射或相关修改. 如 PluginDataExtensions.
要查看详细的解释,请查看 /mirai-console/docs/PluginData.md
实现注意
此类型处于实验性阶段. 使用其中定义的属性和函数是安全的, 但将来可能会新增成员抽象函数.
继承 AbstractPluginData 比继承 PluginData 更安全, 尽管 AbstractPluginData 也不稳定.
See also
Functions
当这个 PluginData 被放入一个 PluginDataStorage 时调用
当所属于这个 PluginData 的 Value 的 值 被修改时被调用. 调用者为 Value 的实现.
Properties
这个 PluginData 保存时使用的名称.
序列化本对象数据时使用的 SerializersModule. 用于支持多态序列化等. 在序列化时会先使用 PluginData.serializersModule, 再对无法找到 serializer 的类型使用 MessageSerializers.serializersModule.
Inheritors
Extensions
通过具体化类型创建一个 SerializerAwareValue, 并设置初始值.
通过具体化类型创建一个 SerializerAwareValue.