Change CommandManager from singleton to instance object

This commit is contained in:
Him188 2021-12-27 16:50:33 +00:00
parent 6db81a50ac
commit f8674d6875
7 changed files with 46 additions and 13 deletions

View File

@ -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)
}
/**

View File

@ -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 以获取堆栈信息"

View File

@ -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

View File

@ -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")
}

View File

@ -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)
}

View File

@ -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()

View File

@ -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 {