From f8674d68756441048b289370eb1d6500b14ec2ac Mon Sep 17 00:00:00 2001 From: Him188 Date: Mon, 27 Dec 2021 16:50:33 +0000 Subject: [PATCH] Change CommandManager from singleton to instance object --- .../src/MiraiConsoleImplementation.kt | 19 +++++++++++++++++++ .../src/command/BuiltInCommands.kt | 5 ++--- .../src/command/CommandManager.kt | 11 ++++++++--- .../internal/command/CommandManagerImpl.kt | 8 ++++++-- .../test/command/InstanceTestCommand.kt | 11 +++++++---- .../MockConsoleImplementation.kt | 2 ++ .../src/MiraiConsoleImplementationTerminal.kt | 3 ++- 7 files changed, 46 insertions(+), 13 deletions(-) diff --git a/mirai-console/backend/mirai-console/src/MiraiConsoleImplementation.kt b/mirai-console/backend/mirai-console/src/MiraiConsoleImplementation.kt index 82abf278a..7269bb20b 100644 --- a/mirai-console/backend/mirai-console/src/MiraiConsoleImplementation.kt +++ b/mirai-console/backend/mirai-console/src/MiraiConsoleImplementation.kt @@ -15,6 +15,7 @@ import kotlinx.atomicfu.locks.withLock import kotlinx.coroutines.* import net.mamoe.mirai.Bot import net.mamoe.mirai.console.MiraiConsoleImplementation.Companion.start +import net.mamoe.mirai.console.command.CommandManager import net.mamoe.mirai.console.command.ConsoleCommandSender import net.mamoe.mirai.console.data.AutoSavePluginDataHolder import net.mamoe.mirai.console.data.PluginConfig @@ -22,6 +23,7 @@ import net.mamoe.mirai.console.data.PluginData import net.mamoe.mirai.console.data.PluginDataStorage import net.mamoe.mirai.console.extension.ComponentStorage import net.mamoe.mirai.console.internal.MiraiConsoleImplementationBridge +import net.mamoe.mirai.console.internal.command.CommandManagerImpl import net.mamoe.mirai.console.internal.data.builtins.ConsoleDataScopeImpl import net.mamoe.mirai.console.internal.extension.GlobalComponentStorage import net.mamoe.mirai.console.internal.logging.LoggerControllerImpl @@ -144,6 +146,17 @@ public interface MiraiConsoleImplementation : CoroutineScope { */ public val consoleCommandSender: ConsoleCommandSenderImpl + /** + * [CommandManager] 实现, 建议实现为 lazy: + * ``` + * override val commandManager: CommandManager by lazy { backendAccess.createDefaultCommandManager(coroutineContext) } + * ``` + * + * @since 2.10.0-RC + * @see BackendAccess.createDefaultCommandManager + */ + public val commandManager: CommandManager + public val dataStorageForJvmPluginLoader: PluginDataStorage public val configStorageForJvmPluginLoader: PluginDataStorage public val dataStorageForBuiltIns: PluginDataStorage @@ -301,6 +314,12 @@ public interface MiraiConsoleImplementation : CoroutineScope { */ public fun createDefaultJvmPluginLoader(coroutineContext: CoroutineContext): JvmPluginLoader = BuiltInJvmPluginLoaderImpl(coroutineContext) + + /** + * @since 2.10.0-RC + */ + public fun createDefaultCommandManager(coroutineContext: CoroutineContext): CommandManager = + CommandManagerImpl(coroutineContext) } /** diff --git a/mirai-console/backend/mirai-console/src/command/BuiltInCommands.kt b/mirai-console/backend/mirai-console/src/command/BuiltInCommands.kt index 9e074c859..b6895b429 100644 --- a/mirai-console/backend/mirai-console/src/command/BuiltInCommands.kt +++ b/mirai-console/backend/mirai-console/src/command/BuiltInCommands.kt @@ -14,6 +14,7 @@ import kotlinx.coroutines.sync.Mutex import kotlinx.coroutines.sync.withLock import net.mamoe.mirai.Bot import net.mamoe.mirai.console.MiraiConsole +import net.mamoe.mirai.console.command.CommandManager.INSTANCE.allRegisteredCommands import net.mamoe.mirai.console.command.CommandManager.INSTANCE.register import net.mamoe.mirai.console.command.descriptor.CommandArgumentParserException import net.mamoe.mirai.console.command.descriptor.CommandValueArgumentParser.Companion.map @@ -23,8 +24,6 @@ import net.mamoe.mirai.console.command.descriptor.buildCommandArgumentContext import net.mamoe.mirai.console.extensions.PermissionServiceProvider import net.mamoe.mirai.console.internal.MiraiConsoleBuildConstants import net.mamoe.mirai.console.internal.MiraiConsoleImplementationBridge -import net.mamoe.mirai.console.internal.command.CommandManagerImpl -import net.mamoe.mirai.console.internal.command.CommandManagerImpl.allRegisteredCommands import net.mamoe.mirai.console.internal.data.builtins.AutoLoginConfig import net.mamoe.mirai.console.internal.data.builtins.AutoLoginConfig.Account.* import net.mamoe.mirai.console.internal.data.builtins.AutoLoginConfig.Account.PasswordKind.MD5 @@ -232,7 +231,7 @@ public object BuiltInCommands { scopeWith(ConsoleCommandSender).sendMessage( "Login failed: ${throwable.localizedMessage ?: throwable.message ?: throwable.toString()}" + if (this is CommandSenderOnMessage<*>) { - CommandManagerImpl.launch(CoroutineName("stacktrace delayer from Login")) { + MiraiConsole.launch(CoroutineName("stacktrace delayer from Login")) { fromEvent.nextMessageOrNull(60.secondsToMillis) { it.message.contentEquals("stacktrace") } } "\n 1 分钟内发送 stacktrace 以获取堆栈信息" diff --git a/mirai-console/backend/mirai-console/src/command/CommandManager.kt b/mirai-console/backend/mirai-console/src/command/CommandManager.kt index 47d22ef14..515e3b1f4 100644 --- a/mirai-console/backend/mirai-console/src/command/CommandManager.kt +++ b/mirai-console/backend/mirai-console/src/command/CommandManager.kt @@ -15,15 +15,16 @@ package net.mamoe.mirai.console.command +import me.him188.kotlin.dynamic.delegation.dynamicDelegation import me.him188.kotlin.jvm.blocking.bridge.JvmBlockingBridge +import net.mamoe.mirai.console.MiraiConsoleImplementation import net.mamoe.mirai.console.command.CommandManager.INSTANCE.executeCommand import net.mamoe.mirai.console.command.descriptor.ExperimentalCommandDescriptors import net.mamoe.mirai.console.command.parse.CommandCall import net.mamoe.mirai.console.command.parse.CommandCallParser import net.mamoe.mirai.console.command.resolve.CommandCallResolver import net.mamoe.mirai.console.command.resolve.ResolvedCommandCall -import net.mamoe.mirai.console.internal.command.CommandManagerImpl -import net.mamoe.mirai.console.internal.command.CommandManagerImpl.executeCommand +import net.mamoe.mirai.console.internal.MiraiConsoleImplementationBridge import net.mamoe.mirai.console.internal.command.executeCommandImpl import net.mamoe.mirai.console.util.ConsoleExperimentalApi import net.mamoe.mirai.message.data.* @@ -170,7 +171,11 @@ public interface CommandManager { */ public fun matchCommand(commandName: String): Command? - public companion object INSTANCE : CommandManager by CommandManagerImpl { + /** + * [CommandManager] 实例. 转发所有调用到 [MiraiConsoleImplementation.commandManager]. + */ + public companion object INSTANCE : + CommandManager by (dynamicDelegation { MiraiConsoleImplementationBridge.commandManager }) { /** * @see CommandManager.getRegisteredCommands diff --git a/mirai-console/backend/mirai-console/src/internal/command/CommandManagerImpl.kt b/mirai-console/backend/mirai-console/src/internal/command/CommandManagerImpl.kt index b14d9b939..ba1d8cd93 100644 --- a/mirai-console/backend/mirai-console/src/internal/command/CommandManagerImpl.kt +++ b/mirai-console/backend/mirai-console/src/internal/command/CommandManagerImpl.kt @@ -23,14 +23,18 @@ import net.mamoe.mirai.console.command.resolve.CommandCallResolver.Companion.res import net.mamoe.mirai.console.command.resolve.getOrElse import net.mamoe.mirai.console.internal.util.ifNull import net.mamoe.mirai.console.permission.PermissionService.Companion.testPermission -import net.mamoe.mirai.utils.childScope import net.mamoe.mirai.message.data.Message import net.mamoe.mirai.message.data.toMessageChain import net.mamoe.mirai.utils.MiraiLogger +import net.mamoe.mirai.utils.castOrNull +import net.mamoe.mirai.utils.childScope import java.util.concurrent.locks.ReentrantLock +import kotlin.coroutines.CoroutineContext @OptIn(ExperimentalCommandDescriptors::class) -internal object CommandManagerImpl : CommandManager, CoroutineScope by MiraiConsole.childScope("CommandManagerImpl") { +internal class CommandManagerImpl( + parentCoroutineContext: CoroutineContext +) : CommandManager, CoroutineScope by parentCoroutineContext.childScope("CommandManagerImpl") { private val logger: MiraiLogger by lazy { MiraiConsole.createLogger("command") } diff --git a/mirai-console/backend/mirai-console/test/command/InstanceTestCommand.kt b/mirai-console/backend/mirai-console/test/command/InstanceTestCommand.kt index 3c933f4d6..463f416e0 100644 --- a/mirai-console/backend/mirai-console/test/command/InstanceTestCommand.kt +++ b/mirai-console/backend/mirai-console/test/command/InstanceTestCommand.kt @@ -22,9 +22,10 @@ import net.mamoe.mirai.console.command.CommandManager.INSTANCE.unregisterCommand import net.mamoe.mirai.console.command.descriptor.CommandValueArgumentParser import net.mamoe.mirai.console.command.descriptor.ExperimentalCommandDescriptors import net.mamoe.mirai.console.command.descriptor.buildCommandArgumentContext -import net.mamoe.mirai.console.testFramework.AbstractConsoleInstanceTest +import net.mamoe.mirai.console.internal.MiraiConsoleImplementationBridge import net.mamoe.mirai.console.internal.command.CommandManagerImpl import net.mamoe.mirai.console.internal.command.flattenCommandComponents +import net.mamoe.mirai.console.testFramework.AbstractConsoleInstanceTest import net.mamoe.mirai.message.data.* import org.junit.jupiter.api.Test import kotlin.test.* @@ -99,6 +100,8 @@ internal val owner by lazy { TestUnitCommandOwner } @OptIn(ExperimentalCommandDescriptors::class) internal class InstanceTestCommand : AbstractConsoleInstanceTest() { + private val manager by lazy { MiraiConsoleImplementationBridge.commandManager as CommandManagerImpl } + @Test fun testRegister() { try { @@ -111,10 +114,10 @@ internal class InstanceTestCommand : AbstractConsoleInstanceTest() { assertEquals(1, getRegisteredCommands(owner).size) - assertEquals(1, CommandManagerImpl._registeredCommands.size) + assertEquals(1, manager._registeredCommands.size) assertEquals(2, - CommandManagerImpl.requiredPrefixCommandMap.size, - CommandManagerImpl.requiredPrefixCommandMap.entries.joinToString { it.toString() }) + manager.requiredPrefixCommandMap.size, + manager.requiredPrefixCommandMap.entries.joinToString { it.toString() }) } finally { unregisterCommand(TestCompositeCommand) } diff --git a/mirai-console/backend/mirai-console/test/testFramework/MockConsoleImplementation.kt b/mirai-console/backend/mirai-console/test/testFramework/MockConsoleImplementation.kt index 9ba8d2822..558c9fcd2 100644 --- a/mirai-console/backend/mirai-console/test/testFramework/MockConsoleImplementation.kt +++ b/mirai-console/backend/mirai-console/test/testFramework/MockConsoleImplementation.kt @@ -16,6 +16,7 @@ import kotlinx.coroutines.cancel 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.plugin.jvm.JvmPluginLoader @@ -56,6 +57,7 @@ open class MockConsoleImplementation : MiraiConsoleImplementation { println(message) } } + override val commandManager: CommandManager by lazy { backendAccess.createDefaultCommandManager(coroutineContext) } override val dataStorageForJvmPluginLoader: PluginDataStorage = MemoryPluginDataStorage() override val configStorageForJvmPluginLoader: PluginDataStorage = MemoryPluginDataStorage() override val dataStorageForBuiltIns: PluginDataStorage = MemoryPluginDataStorage() diff --git a/mirai-console/frontend/mirai-console-terminal/src/MiraiConsoleImplementationTerminal.kt b/mirai-console/frontend/mirai-console-terminal/src/MiraiConsoleImplementationTerminal.kt index f4a04142b..a0a2443dc 100644 --- a/mirai-console/frontend/mirai-console-terminal/src/MiraiConsoleImplementationTerminal.kt +++ b/mirai-console/frontend/mirai-console-terminal/src/MiraiConsoleImplementationTerminal.kt @@ -27,6 +27,7 @@ import net.mamoe.mirai.console.ConsoleFrontEndImplementation import net.mamoe.mirai.console.MiraiConsole import net.mamoe.mirai.console.MiraiConsoleFrontEndDescription import net.mamoe.mirai.console.MiraiConsoleImplementation +import net.mamoe.mirai.console.command.CommandManager import net.mamoe.mirai.console.data.MultiFilePluginDataStorage import net.mamoe.mirai.console.data.PluginDataStorage import net.mamoe.mirai.console.plugin.jvm.JvmPluginLoader @@ -75,7 +76,7 @@ open class MiraiConsoleImplementationTerminal MiraiConsole.mainLogger.error("Exception in coroutine $coroutineName", throwable) }) { override val jvmPluginLoader: JvmPluginLoader by lazy { backendAccess.createDefaultJvmPluginLoader(coroutineContext) } - + override val commandManager: CommandManager by lazy { backendAccess.createDefaultCommandManager(coroutineContext) } override val consoleInput: ConsoleInput get() = ConsoleInputImpl override val isAnsiSupported: Boolean get() = true override val consoleDataScope: MiraiConsoleImplementation.ConsoleDataScope by lazy {