From f9ac26b3af8b3a900a00e0ef24fd44fef876bd54 Mon Sep 17 00:00:00 2001 From: Him188 Date: Wed, 26 Aug 2020 22:51:53 +0800 Subject: [PATCH] Update docs --- .../mamoe/mirai/console/data/PluginData.kt | 32 +++++++++++++++++-- .../console/data/java/JAutoSavePluginData.kt | 10 ++---- .../command/CompositeCommandInternal.kt | 5 ++- 3 files changed, 36 insertions(+), 11 deletions(-) diff --git a/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/data/PluginData.kt b/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/data/PluginData.kt index b4e70316d..d15adccfd 100644 --- a/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/data/PluginData.kt +++ b/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/data/PluginData.kt @@ -39,7 +39,7 @@ import kotlin.reflect.full.findAnnotation * * **注意**: [PluginData] 总应该是单例的. * - * ### [JvmPlugin] 的实现方案 + * ## [JvmPlugin] 的实现方案 * * 要修改保存时的名称, 请参考 [ValueName] * @@ -50,10 +50,13 @@ import kotlin.reflect.full.findAnnotation * object PluginMain : KotlinPlugin() * * object MyPluginData : AutoSavePluginData() { - * val list: MutableList by value(mutableListOf("a", "b")) // mutableListOf("a", "b") 是初始值, 可以省略 + * var list: MutableList by value(mutableListOf("a", "b")) // mutableListOf("a", "b") 是初始值, 可以省略 * val custom: Map by value() // 使用 kotlinx-serialization 序列化的类型. (目前还不支持) * var long: Long by value(0) // 允许 var * var int by value(0) // 可以使用类型推断, 但更推荐使用 `var long: Long by value(0)` 这种定义方式. + * + * // 将 MutableMap 映射到 MutableMap. + * val botToLongMap: MutableMap by value>().mapKeys(Bot::getInstance, Bot::id) * } * * @Serializable @@ -64,7 +67,7 @@ import kotlin.reflect.full.findAnnotation * * 使用时, 可以方便地直接调用, 如: * ``` - * val theList = AccountPluginData.list + * val theList: MutableList = AccountPluginData.list * ``` * * 但也注意, 不要存储 `AccountPluginData.list`. 它可能受不到值跟踪. 若必要存储, 请使用 [PluginData.findBackingFieldValue] @@ -73,8 +76,31 @@ import kotlin.reflect.full.findAnnotation * * 参考 [JAutoSavePluginData] * + * ## 非引用赋值 + * + * 由于实现特殊, 赋值时不会写其引用. 即: + * ``` + * val list = ArrayList("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> by value() + * val newList = MyPluginData.map.getOrPut(1, ::mutableListOf) + * newList.add(1) // 不会添加到 MyPluginData.nestedMap 中, 因为 `mutableListOf` 创建的 MutableList 被非引用地添加进了 MyPluginData.nestedMap + * ``` + * + * 一个解决方案是对 [SerializerAwareValue] 做映射或相关修改. 如 [PluginDataExtensions] + * * @see JvmPlugin.reloadPluginData 通过 [JvmPlugin] 获取指定 [PluginData] 实例. * @see PluginDataStorage [PluginData] 存储仓库 + * @see PluginDataExtensions 相关 [SerializerAwareValue] 映射函数 */ public interface PluginData { /** diff --git a/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/data/java/JAutoSavePluginData.kt b/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/data/java/JAutoSavePluginData.kt index 12333c2bd..835522027 100644 --- a/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/data/java/JAutoSavePluginData.kt +++ b/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/data/java/JAutoSavePluginData.kt @@ -31,6 +31,9 @@ import kotlin.reflect.full.createType * public static PluginMain INSTANCE; * public PluginMain() { * INSTANCE = this; + * } + * @Override + * public onLoad() { * this.reloadPluginData(MyPluginData.INSTANCE); // 读取文件等 * } * } @@ -39,11 +42,6 @@ import kotlin.reflect.full.createType * public class MyPluginData extends JAutoSavePluginData { * public static final MyPluginData INSTANCE = new MyPluginData(); * - * private MyPluginData() { - * super(PluginMain.INSTANCE); - * INSTANCE = this; - * } - * * public final Value string = value("test"); // 默认值 "test" * * public final Value> list = typedValue(createKType(List.class, createKType(String.class))); // 无默认值, 自动创建空 List @@ -60,9 +58,7 @@ import kotlin.reflect.full.createType * 使用时, 需要使用 `.get()`, 如: * ``` * Value> theList = MyPluginData.INSTANCE.list; // 获取 Value 实例. Value 代表一个追踪自动保存的值. - * * List actualList = theList.get(); - * * theList.set(); * ``` * diff --git a/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/internal/command/CompositeCommandInternal.kt b/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/internal/command/CompositeCommandInternal.kt index 11fa903e2..e6a96e25c 100644 --- a/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/internal/command/CompositeCommandInternal.kt +++ b/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/internal/command/CompositeCommandInternal.kt @@ -59,7 +59,10 @@ internal abstract class AbstractReflectionCommand @JvmOverloads constructor( internal var _usage: String = "" override val usage: String // initialized by subCommand reflection - get() = _usage + get() { + subCommands // ensure init + return _usage + } abstract suspend fun CommandSender.onDefault(rawArgs: Array)