diff --git a/mirai-console/backend/codegen/src/ValuePluginDataCodegen.kt b/mirai-console/backend/codegen/src/ValuePluginDataCodegen.kt index 22aa9bcab..dd36532cb 100644 --- a/mirai-console/backend/codegen/src/ValuePluginDataCodegen.kt +++ b/mirai-console/backend/codegen/src/ValuePluginDataCodegen.kt @@ -1,5 +1,5 @@ /* - * Copyright 2019-2021 Mamoe Technologies and contributors. + * Copyright 2019-2022 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. @@ -160,7 +160,7 @@ internal fun PluginData.${ktType.lowerCaseName}ValueImpl(): SerializerAwareValue } - object JPluginData_value_primitivesCodegen : RegionCodegen("JPluginData.kt"), DefaultInvoke { + object JPluginData_value_primitivesCodegen : RegionCodegen("JAutoSavePluginData.kt"), DefaultInvoke { @JvmStatic fun main(args: Array) = super.startIndependently() override val defaultInvokeArgs: List = KtPrimitives + KtString @@ -172,7 +172,7 @@ internal fun PluginData.${ktType.lowerCaseName}ValueImpl(): SerializerAwareValue /** * 创建一个 [${ktType.standardName}] 类型的 [Value], 并设置初始值为 [default] */ - public fun value(default: ${ktType.standardName}): SerializerAwareValue<${ktType.standardName}> = delegate.valueImpl(default) + public fun value(default: ${ktType.standardName}): SerializerAwareValue<${ktType.standardName}> = valueImpl(default) """ ) appendLine() @@ -180,6 +180,30 @@ internal fun PluginData.${ktType.lowerCaseName}ValueImpl(): SerializerAwareValue } + /** + * @since 2.11 + */ + object JavaAutoSavePluginData_value_primitivesCodegen : RegionCodegen("JavaAutoSavePluginData.kt"), DefaultInvoke { + @JvmStatic + fun main(args: Array) = super.startIndependently() + override val defaultInvokeArgs: List = KtPrimitives + KtString + + override fun StringBuilder.apply(ktType: KtType) { + @Suppress("unused") + appendKCode( + """ + /** + * 创建一个名称为 [name], 类型为 [${ktType.standardName}] 的 [Value], 并设置初始值为 [default]. + */ + public fun value(name: String, default: ${ktType.standardName}): SerializerAwareValue<${ktType.standardName}> = valueImpl(default).apply { track(this, name, emptyList()) } + """ + ) + appendLine() + } + + } + + /** * 运行本 object 中所有嵌套 object Codegen */ diff --git a/mirai-console/backend/mirai-console/compatibility-validation/jvm/api/jvm.api b/mirai-console/backend/mirai-console/compatibility-validation/jvm/api/jvm.api index 11f086ea8..81d45fb5e 100644 --- a/mirai-console/backend/mirai-console/compatibility-validation/jvm/api/jvm.api +++ b/mirai-console/backend/mirai-console/compatibility-validation/jvm/api/jvm.api @@ -1416,6 +1416,34 @@ public final class net/mamoe/mirai/console/data/java/JAutoSavePluginData$Compani public final fun createKType (Ljava/lang/Class;[Lkotlin/reflect/KType;)Lkotlin/reflect/KType; } +public abstract class net/mamoe/mirai/console/data/java/JavaAutoSavePluginConfig : net/mamoe/mirai/console/data/java/JavaAutoSavePluginData, net/mamoe/mirai/console/data/PluginConfig { + public fun (Ljava/lang/String;)V +} + +public abstract class net/mamoe/mirai/console/data/java/JavaAutoSavePluginData : net/mamoe/mirai/console/data/AutoSavePluginData, net/mamoe/mirai/console/data/PluginConfig { + public static final field Companion Lnet/mamoe/mirai/console/data/java/JavaAutoSavePluginData$Companion; + public fun (Ljava/lang/String;)V + public static final fun createKType (Ljava/lang/Class;Z[Lkotlin/reflect/KType;)Lkotlin/reflect/KType; + public static final fun createKType (Ljava/lang/Class;[Lkotlin/reflect/KType;)Lkotlin/reflect/KType; + public final fun typedValue (Ljava/lang/String;Lkotlin/reflect/KType;)Lnet/mamoe/mirai/console/data/SerializerAwareValue; + public final fun typedValue (Ljava/lang/String;Lkotlin/reflect/KType;Ljava/lang/Object;)Lnet/mamoe/mirai/console/data/SerializerAwareValue; + public static synthetic fun typedValue$default (Lnet/mamoe/mirai/console/data/java/JavaAutoSavePluginData;Ljava/lang/String;Lkotlin/reflect/KType;Ljava/lang/Object;ILjava/lang/Object;)Lnet/mamoe/mirai/console/data/SerializerAwareValue; + public final fun value (Ljava/lang/String;B)Lnet/mamoe/mirai/console/data/SerializerAwareValue; + public final fun value (Ljava/lang/String;C)Lnet/mamoe/mirai/console/data/SerializerAwareValue; + public final fun value (Ljava/lang/String;D)Lnet/mamoe/mirai/console/data/SerializerAwareValue; + public final fun value (Ljava/lang/String;F)Lnet/mamoe/mirai/console/data/SerializerAwareValue; + public final fun value (Ljava/lang/String;I)Lnet/mamoe/mirai/console/data/SerializerAwareValue; + public final fun value (Ljava/lang/String;J)Lnet/mamoe/mirai/console/data/SerializerAwareValue; + public final fun value (Ljava/lang/String;Ljava/lang/String;)Lnet/mamoe/mirai/console/data/SerializerAwareValue; + public final fun value (Ljava/lang/String;S)Lnet/mamoe/mirai/console/data/SerializerAwareValue; + public final fun value (Ljava/lang/String;Z)Lnet/mamoe/mirai/console/data/SerializerAwareValue; +} + +public final class net/mamoe/mirai/console/data/java/JavaAutoSavePluginData$Companion { + public final fun createKType (Ljava/lang/Class;Z[Lkotlin/reflect/KType;)Lkotlin/reflect/KType; + public final fun createKType (Ljava/lang/Class;[Lkotlin/reflect/KType;)Lkotlin/reflect/KType; +} + public abstract interface class net/mamoe/mirai/console/events/ConsoleEvent : net/mamoe/mirai/event/Event { } diff --git a/mirai-console/backend/mirai-console/src/data/java/JAutoSavePluginConfig.kt b/mirai-console/backend/mirai-console/src/data/java/JAutoSavePluginConfig.kt index 06f2c1614..acb670a3f 100644 --- a/mirai-console/backend/mirai-console/src/data/java/JAutoSavePluginConfig.kt +++ b/mirai-console/backend/mirai-console/src/data/java/JAutoSavePluginConfig.kt @@ -1,5 +1,5 @@ /* - * Copyright 2019-2021 Mamoe Technologies and contributors. + * Copyright 2019-2022 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. @@ -14,6 +14,7 @@ package net.mamoe.mirai.console.data.java import net.mamoe.mirai.console.data.AutoSavePluginConfig import net.mamoe.mirai.console.data.PluginConfig import net.mamoe.mirai.console.data.PluginData +import net.mamoe.mirai.utils.DeprecatedSinceMirai /** * 一个插件的配置数据, 用于和用户交互. @@ -37,5 +38,11 @@ import net.mamoe.mirai.console.data.PluginData * @see JAutoSavePluginData * @see PluginConfig */ +@Deprecated( + "请使用 JavaAutoSavePluginConfig", + replaceWith = ReplaceWith("JavaAutoSavePluginConfig", "net.mamoe.mirai.console.data.java.JavaAutoSavePluginConfig"), + level = DeprecationLevel.WARNING +) +@DeprecatedSinceMirai(warningSince = "2.11") public abstract class JAutoSavePluginConfig public constructor(saveName: String) : AutoSavePluginConfig(saveName), PluginConfig \ No newline at end of file diff --git a/mirai-console/backend/mirai-console/src/data/java/JAutoSavePluginData.kt b/mirai-console/backend/mirai-console/src/data/java/JAutoSavePluginData.kt index 5c04dbc46..c512c1331 100644 --- a/mirai-console/backend/mirai-console/src/data/java/JAutoSavePluginData.kt +++ b/mirai-console/backend/mirai-console/src/data/java/JAutoSavePluginData.kt @@ -1,10 +1,10 @@ /* - * Copyright 2019-2021 Mamoe Technologies and contributors. + * Copyright 2019-2022 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. + * 此源代码的使用受 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 + * https://github.com/mamoe/mirai/blob/dev/LICENSE */ @file:Suppress("unused", "EXPOSED_SUPER_CLASS") @@ -16,6 +16,7 @@ import net.mamoe.mirai.console.internal.data.cast import net.mamoe.mirai.console.internal.data.setValueBySerializer import net.mamoe.mirai.console.internal.data.valueImpl import net.mamoe.mirai.console.plugin.jvm.JvmPlugin +import net.mamoe.mirai.utils.DeprecatedSinceMirai import java.util.concurrent.ConcurrentHashMap import java.util.concurrent.ConcurrentMap import kotlin.reflect.KClass @@ -69,10 +70,16 @@ import kotlin.reflect.full.createType * * @see PluginData */ +@Deprecated( + "请使用 JavaAutoSavePluginData", + replaceWith = ReplaceWith("JavaAutoSavePluginData", "net.mamoe.mirai.console.data.java.JavaAutoSavePluginData"), + level = DeprecationLevel.WARNING +) +@DeprecatedSinceMirai(warningSince = "2.11") public abstract class JAutoSavePluginData public constructor(saveName: String) : AutoSavePluginData(saveName), PluginConfig { - //// region JPluginData_value_primitives CODEGEN //// + //// region JAutoSavePluginData_value_primitives CODEGEN //// /** * 创建一个 [Byte] 类型的 [Value], 并设置初始值为 [default] @@ -119,7 +126,7 @@ public abstract class JAutoSavePluginData public constructor(saveName: String) : */ public fun value(default: String): SerializerAwareValue = valueImpl(default) - //// endregion JPluginData_value_primitives CODEGEN //// + //// endregion JAutoSavePluginData_value_primitives CODEGEN //// /** * 构造一个支持泛型的 [Value]. diff --git a/mirai-console/backend/mirai-console/src/data/java/JavaAutoSavePluginConfig.kt b/mirai-console/backend/mirai-console/src/data/java/JavaAutoSavePluginConfig.kt new file mode 100644 index 000000000..ec7ac6ae3 --- /dev/null +++ b/mirai-console/backend/mirai-console/src/data/java/JavaAutoSavePluginConfig.kt @@ -0,0 +1,45 @@ +/* + * Copyright 2019-2022 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/dev/LICENSE + */ + +@file:Suppress("unused", "EXPOSED_SUPER_CLASS") + +package net.mamoe.mirai.console.data.java + +import net.mamoe.mirai.console.data.PluginConfig +import net.mamoe.mirai.console.data.PluginData +import net.mamoe.mirai.console.util.JavaFriendlyApi + +/** + * 一个插件的配置数据, 用于和用户交互. + * + * 用户可通过 mirai-console 前端 (如在 Android 中可视化实现) 修改这些配置, 修改会自动写入这个对象中. + * + * **提示**: + * 插件内部的数据应用 [PluginData] 存储, 而不能使用 [PluginConfig]. + * + * ### 实现 + * + * 在 [JavaAutoSavePluginData] 的示例基础上, 修改类定义 + * ```java + * // 原 + * public class AccountPluginData extends JavaAutoSavePluginData { + * // 修改为 + * public class AccountPluginConfig extends JavaAutoSavePluginConfig { + * ``` + * 即可将一个 [PluginData] 变更为 [PluginConfig]. + * + * @see JavaAutoSavePluginData + * @see PluginConfig + * + * @since 2.11 + */ +@JavaFriendlyApi +public abstract class JavaAutoSavePluginConfig public constructor(saveName: String) : + JavaAutoSavePluginData(saveName), + PluginConfig \ No newline at end of file diff --git a/mirai-console/backend/mirai-console/src/data/java/JavaAutoSavePluginData.kt b/mirai-console/backend/mirai-console/src/data/java/JavaAutoSavePluginData.kt new file mode 100644 index 000000000..8b9cd0e7e --- /dev/null +++ b/mirai-console/backend/mirai-console/src/data/java/JavaAutoSavePluginData.kt @@ -0,0 +1,191 @@ +/* + * Copyright 2019-2022 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/dev/LICENSE + */ + +@file:Suppress("unused", "EXPOSED_SUPER_CLASS") + +package net.mamoe.mirai.console.data.java + +import net.mamoe.mirai.console.data.* +import net.mamoe.mirai.console.internal.data.cast +import net.mamoe.mirai.console.internal.data.setValueBySerializer +import net.mamoe.mirai.console.internal.data.valueImpl +import net.mamoe.mirai.console.plugin.jvm.JvmPlugin +import net.mamoe.mirai.console.util.JavaFriendlyApi +import java.util.concurrent.ConcurrentHashMap +import java.util.concurrent.ConcurrentMap +import kotlin.reflect.KClass +import kotlin.reflect.KType +import kotlin.reflect.KTypeProjection +import kotlin.reflect.KVariance +import kotlin.reflect.full.createType + +/** + * 供 Java 用户使用的 [PluginData]. 参考 [PluginData] 以获取更多信息. + * + * 仍然更推荐在项目中混用 Java 和 Kotlin, 使用 Kotlin 编写 [PluginData]. + * 也可以使用其他持久化库替代 [PluginData]. + * + * 在 [JvmPlugin] 的典型实现方式: + * ``` + * // PluginMain.java + * public final class PluginMain extends JavaPlugin { + * public static PluginMain INSTANCE; + * public PluginMain() { + * INSTANCE = this; + * } + * @Override + * public onLoad() { + * this.reloadPluginData(MyPluginData.INSTANCE); // 读取文件等 + * } + * } + * + * // MyPluginData.java + * public class MyPluginData extends JavaAutoSavePluginData { + * public static final MyPluginData INSTANCE = new MyPluginData(); + * + * public final Value string = value("test"); // 默认值 "test" + * + * public final Value> list = typedValue(createKType(List.class, createKType(String.class))); // 无默认值, 自动创建空 List + * + * public final Value> custom = typedValue( + * createKType(Map.class, createKType(Long.class), createKType(Object.class)), + * new HashMap() {{ // 带默认值 + * put(123L, "ok"); + * }} + * ); + * } + * ``` + * + * 使用时, 需要使用 `.get()`, 如: + * ``` + * Value> theList = MyPluginData.INSTANCE.list; // 获取 Value 实例. Value 代表一个追踪自动保存的值. + * List actualList = theList.get(); + * theList.set(); + * ``` + * + * **注意**: 由于实现特殊, 请不要在初始化 Value 时就使用 `.get()`. 这可能会导致自动保存追踪失效. 必须在使用时才调用 `.get()` 获取真实数据对象. + * + * @see PluginData + * @since 2.11 + */ +@JavaFriendlyApi +public abstract class JavaAutoSavePluginData public constructor(saveName: String) : AutoSavePluginData(saveName), + PluginConfig { + + //// region JavaAutoSavePluginData_value_primitives CODEGEN //// + + /** + * 创建一个名称为 [name], 类型为 [Byte] 的 [Value], 并设置初始值为 [default]. + */ + public fun value(name: String, default: Byte): SerializerAwareValue = + valueImpl(default).apply { track(this, name, emptyList()) } + + /** + * 创建一个名称为 [name], 类型为 [Short] 的 [Value], 并设置初始值为 [default]. + */ + public fun value(name: String, default: Short): SerializerAwareValue = + valueImpl(default).apply { track(this, name, emptyList()) } + + /** + * 创建一个名称为 [name], 类型为 [Int] 的 [Value], 并设置初始值为 [default]. + */ + public fun value(name: String, default: Int): SerializerAwareValue = + valueImpl(default).apply { track(this, name, emptyList()) } + + /** + * 创建一个名称为 [name], 类型为 [Long] 的 [Value], 并设置初始值为 [default]. + */ + public fun value(name: String, default: Long): SerializerAwareValue = + valueImpl(default).apply { track(this, name, emptyList()) } + + /** + * 创建一个名称为 [name], 类型为 [Float] 的 [Value], 并设置初始值为 [default]. + */ + public fun value(name: String, default: Float): SerializerAwareValue = + valueImpl(default).apply { track(this, name, emptyList()) } + + /** + * 创建一个名称为 [name], 类型为 [Double] 的 [Value], 并设置初始值为 [default]. + */ + public fun value(name: String, default: Double): SerializerAwareValue = + valueImpl(default).apply { track(this, name, emptyList()) } + + /** + * 创建一个名称为 [name], 类型为 [Char] 的 [Value], 并设置初始值为 [default]. + */ + public fun value(name: String, default: Char): SerializerAwareValue = + valueImpl(default).apply { track(this, name, emptyList()) } + + /** + * 创建一个名称为 [name], 类型为 [Boolean] 的 [Value], 并设置初始值为 [default]. + */ + public fun value(name: String, default: Boolean): SerializerAwareValue = + valueImpl(default).apply { track(this, name, emptyList()) } + + /** + * 创建一个名称为 [name], 类型为 [String] 的 [Value], 并设置初始值为 [default]. + */ + public fun value(name: String, default: String): SerializerAwareValue = + valueImpl(default).apply { track(this, name, emptyList()) } + + //// endregion JavaAutoSavePluginData_value_primitives CODEGEN //// + + /** + * 创建一个支持泛型的 [Value]. + * + * 对于 [Map], [Set], [List], [ConcurrentMap] 等标准库类型, 这个函数会尝试构造 [LinkedHashMap], [LinkedHashSet], [ArrayList], [ConcurrentHashMap] 等相关类型. + * 而对于自定义数据类型, 本函数只会反射获取 [objectInstance][KClass.objectInstance] 或使用*无参构造器*构造实例. + * + * @param type Kotlin 类型. 可通过 [createKType] 获得 + * + * @param T 类型 T. 仅支持: + * - 基础数据类型, [String] + * - 标准库集合类型 ([List], [Map], [Set], [ConcurrentMap]) + * - 标准库数据类型 ([Map.Entry], [Pair], [Triple]) + * - 使用 [kotlinx.serialization](https://github.com/Kotlin/kotlinx.serialization) 的 [Serializable] 标记的 **Kotlin** 类 + */ + @JvmOverloads + public fun typedValue(name: String, type: KType, default: T? = null): SerializerAwareValue { + val value = valueImpl(type, type.classifier!!.cast()) + if (default != null) value.setValueBySerializer(default) + track(value, name, emptyList()) + return value + } + + /** + * @since 2.11 + */ + @JavaFriendlyApi + public companion object { + /** + * 根据 [Class] 及泛型参数获得一个类型 + * + * 如要获得一个 `Map` 的类型, + * ```java + * KType type = JPluginDataHelper.createKType(Map.java, createKType(String.java), createKType(Long.java)) + * ``` + * + * @param genericArguments 带有顺序的泛型参数 + */ + @JvmStatic + public fun createKType(clazz: Class, nullable: Boolean, vararg genericArguments: KType): KType { + return clazz.kotlin.createType(genericArguments.map { KTypeProjection(KVariance.INVARIANT, it) }, nullable) + } + + /** + * 根据 [Class] 及泛型参数获得一个不可为 `null` 的类型 + * + * @see createKType + */ + @JvmStatic + public fun createKType(clazz: Class, vararg genericArguments: KType): KType { + return createKType(clazz, false, *genericArguments) + } + } +} \ No newline at end of file diff --git a/mirai-console/backend/mirai-console/src/internal/data/_PrimitiveValueDeclarations.kt b/mirai-console/backend/mirai-console/src/internal/data/_PrimitiveValueDeclarations.kt index a7ec22f46..beb4a58c2 100644 --- a/mirai-console/backend/mirai-console/src/internal/data/_PrimitiveValueDeclarations.kt +++ b/mirai-console/backend/mirai-console/src/internal/data/_PrimitiveValueDeclarations.kt @@ -1,5 +1,5 @@ /* - * Copyright 2019-2021 Mamoe Technologies and contributors. + * Copyright 2019-2022 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. @@ -25,8 +25,12 @@ internal abstract class AbstractValueImpl : Value { } } -internal fun Value.setValueBySerializer(value: T) = - (this.castOrInternalError>()).setValueBySerializer(value) +internal fun Value.setValueBySerializer(value: T) { + if (this is SerializableValue) { + return this.delegate.setValueBySerializer(value) + } + this.castOrInternalError>().setValueBySerializer(value) +} //// region PrimitiveValuesImpl CODEGEN //// diff --git a/mirai-console/backend/mirai-console/test/data/JAutoSavePluginDataTest.kt b/mirai-console/backend/mirai-console/test/data/JAutoSavePluginDataTest.kt new file mode 100644 index 000000000..ed46bfdf3 --- /dev/null +++ b/mirai-console/backend/mirai-console/test/data/JAutoSavePluginDataTest.kt @@ -0,0 +1,55 @@ +/* + * Copyright 2019-2022 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/dev/LICENSE + */ + +package net.mamoe.mirai.console.data + +import net.mamoe.mirai.console.data.java.JavaAutoSavePluginData +import net.mamoe.mirai.console.plugin.jvm.reloadPluginData +import net.mamoe.mirai.console.testFramework.AbstractConsoleInstanceTest +import net.mamoe.mirai.console.util.JavaFriendlyApi +import org.junit.jupiter.api.Test +import kotlin.test.assertEquals + + +class JAutoSavePluginDataTest : AbstractConsoleInstanceTest() { + @OptIn(JavaFriendlyApi::class) + class MyData : JavaAutoSavePluginData("testSaveName") { + val strMember: Value = value("strMember", "str") + val intMember: Value = value("intMember", 1) + + val typed: Value> = typedValue( + "typed", + createKType( + List::class.java, + false, + createKType(String::class.java, false) + ), + listOf("aa", "bb") + ) + } + + @Test + fun `can reload`() { + val instance = MyData() + mockPlugin.reloadPluginData(instance) + assertEquals("str", instance.strMember.value) + assertEquals(Integer.valueOf(1), instance.intMember.value) + assertEquals(listOf("aa", "bb"), instance.typed.value) + + assertEquals( + """ + strMember: str + intMember: 1 + typed: + - aa + - bb + """.trimIndent(), mockPlugin.dataFolder.resolve("testSaveName.yml").readText() + ) + } +} \ No newline at end of file diff --git a/mirai-console/backend/mirai-console/test/data/PluginMovingTests.kt b/mirai-console/backend/mirai-console/test/data/PluginMovingTests.kt index b14f85e87..8878ef214 100644 --- a/mirai-console/backend/mirai-console/test/data/PluginMovingTests.kt +++ b/mirai-console/backend/mirai-console/test/data/PluginMovingTests.kt @@ -1,5 +1,5 @@ /* - * Copyright 2019-2021 Mamoe Technologies and contributors. + * Copyright 2019-2022 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. @@ -34,7 +34,6 @@ class PluginMovingTests : AbstractConsoleInstanceTest() { fun movingPluginPath() { // Normal move mkdir(mockPlugin.name) - mockPlugin.load() assert(!MiraiConsole.job.isCancelled) // when id == name mkdir(mockPluginWithName.name) diff --git a/mirai-console/backend/mirai-console/test/testFramework/AbstractConsoleInstanceTest.kt b/mirai-console/backend/mirai-console/test/testFramework/AbstractConsoleInstanceTest.kt index f11a01be9..73570ae6c 100644 --- a/mirai-console/backend/mirai-console/test/testFramework/AbstractConsoleInstanceTest.kt +++ b/mirai-console/backend/mirai-console/test/testFramework/AbstractConsoleInstanceTest.kt @@ -30,11 +30,19 @@ abstract class AbstractConsoleInstanceTest { protected open fun initializeConsole() { this.implementation = MockConsoleImplementation().apply { start() } CommandManager + consoleImplementation.jvmPluginLoader.load(mockPlugin) + consoleImplementation.jvmPluginLoader.enable(mockPlugin) } @AfterEach protected open fun stopConsole() { if (MiraiConsoleImplementation.instanceInitialized) { + try { + consoleImplementation.jvmPluginLoader.disable(mockPlugin) + } catch (e: Exception) { + e.printStackTrace() + } + try { runBlocking { MiraiConsole.job.cancelAndJoin() } } catch (e: CancellationException) { diff --git a/mirai-console/backend/mirai-console/test/testFramework/MockConsoleImplementation.kt b/mirai-console/backend/mirai-console/test/testFramework/MockConsoleImplementation.kt index 558c9fcd2..d4534cb35 100644 --- a/mirai-console/backend/mirai-console/test/testFramework/MockConsoleImplementation.kt +++ b/mirai-console/backend/mirai-console/test/testFramework/MockConsoleImplementation.kt @@ -1,5 +1,5 @@ /* - * Copyright 2019-2021 Mamoe Technologies and contributors. + * Copyright 2019-2022 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. @@ -17,8 +17,8 @@ import net.mamoe.mirai.console.MiraiConsoleFrontEndDescription import net.mamoe.mirai.console.MiraiConsoleImplementation import net.mamoe.mirai.console.MiraiConsoleImplementation.Companion.start import net.mamoe.mirai.console.command.CommandManager -import net.mamoe.mirai.console.data.MemoryPluginDataStorage import net.mamoe.mirai.console.data.PluginDataStorage +import net.mamoe.mirai.console.internal.data.MultiFilePluginDataStorageImpl import net.mamoe.mirai.console.plugin.jvm.JvmPluginLoader import net.mamoe.mirai.console.plugin.loader.PluginLoader import net.mamoe.mirai.console.util.ConsoleInput @@ -35,7 +35,7 @@ import kotlin.coroutines.CoroutineContext import kotlin.io.path.createTempDirectory open class MockConsoleImplementation : MiraiConsoleImplementation { - override val rootPath: Path = createTempDirectory() + final override val rootPath: Path = createTempDirectory() override val frontEndDescription: MiraiConsoleFrontEndDescription get() = object : MiraiConsoleFrontEndDescription { @@ -58,10 +58,13 @@ open class MockConsoleImplementation : MiraiConsoleImplementation { } } override val commandManager: CommandManager by lazy { backendAccess.createDefaultCommandManager(coroutineContext) } - override val dataStorageForJvmPluginLoader: PluginDataStorage = MemoryPluginDataStorage() - override val configStorageForJvmPluginLoader: PluginDataStorage = MemoryPluginDataStorage() - override val dataStorageForBuiltIns: PluginDataStorage = MemoryPluginDataStorage() - override val configStorageForBuiltIns: PluginDataStorage = MemoryPluginDataStorage() + override val dataStorageForJvmPluginLoader: PluginDataStorage = + MultiFilePluginDataStorageImpl(rootPath.resolve("data")) + override val configStorageForJvmPluginLoader: PluginDataStorage = + MultiFilePluginDataStorageImpl(rootPath.resolve("config")) + override val dataStorageForBuiltIns: PluginDataStorage = MultiFilePluginDataStorageImpl(rootPath.resolve("data")) + override val configStorageForBuiltIns: PluginDataStorage = + MultiFilePluginDataStorageImpl(rootPath.resolve("config")) override val consoleInput: ConsoleInput = object : ConsoleInput { override suspend fun requestInput(hint: String): String {