FrontEnd callbacks; Accessors for FrontEnd

This commit is contained in:
Karlatemp 2021-02-18 01:09:28 +08:00
parent bc009263b5
commit 11e7d9f454
No known key found for this signature in database
GPG Key ID: 21FBDDF664FF06F8
2 changed files with 72 additions and 15 deletions

View File

@ -17,9 +17,13 @@ import net.mamoe.mirai.Bot
import net.mamoe.mirai.console.MiraiConsoleImplementation.Companion.start import net.mamoe.mirai.console.MiraiConsoleImplementation.Companion.start
import net.mamoe.mirai.console.command.ConsoleCommandSender import net.mamoe.mirai.console.command.ConsoleCommandSender
import net.mamoe.mirai.console.data.PluginDataStorage 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.MiraiConsoleImplementationBridge
import net.mamoe.mirai.console.internal.extension.GlobalComponentStorage
import net.mamoe.mirai.console.internal.logging.LoggerControllerImpl import net.mamoe.mirai.console.internal.logging.LoggerControllerImpl
import net.mamoe.mirai.console.internal.plugin.PluginManagerImpl
import net.mamoe.mirai.console.logging.LoggerController import net.mamoe.mirai.console.logging.LoggerController
import net.mamoe.mirai.console.plugin.Plugin
import net.mamoe.mirai.console.plugin.jvm.JvmPluginLoader import net.mamoe.mirai.console.plugin.jvm.JvmPluginLoader
import net.mamoe.mirai.console.plugin.loader.PluginLoader import net.mamoe.mirai.console.plugin.loader.PluginLoader
import net.mamoe.mirai.console.util.ConsoleInput import net.mamoe.mirai.console.util.ConsoleInput
@ -185,7 +189,42 @@ public interface MiraiConsoleImplementation : CoroutineScope {
public val loggerController: LoggerController get() = LoggerControllerImpl public val loggerController: LoggerController get() = LoggerControllerImpl
/// Hooks & Backend Access
/**
* 后端 [phase] 阶段执行前会调用此方法, 如果此方法抛出了一个错误会直接中断 console 初始化
*/
public fun prePhase(phase: String) {}
/**
* 后端 [phase] 阶段执行后会调用此方法, 如果此方法抛出了一个错误会直接中断 console 初始化
*/
public fun postPhase(phase: String) {}
/** 后端在 [start] 前会调用此方法 */
public fun preStart() {}
/** 后端在 [start] 后会调用此方法 */
public fun postStart() {}
/**
* 用于提供前端访问后端内部实现
*/
@ConsoleFrontEndImplementation
public interface BackendAccess {
// GlobalComponentStorage
public val globalComponentStorage: ComponentStorage
// PluginManagerImpl.resolvedPlugins
public val resolvedPlugins: MutableList<Plugin>
}
public val backendAccess: BackendAccess get() = backendAccessInstance
public companion object { public companion object {
private val backendAccessInstance = object : BackendAccess {
override val globalComponentStorage: ComponentStorage get() = GlobalComponentStorage
override val resolvedPlugins: MutableList<Plugin> get() = PluginManagerImpl.resolvedPlugins
}
internal lateinit var instance: MiraiConsoleImplementation internal lateinit var instance: MiraiConsoleImplementation
private val initLock = ReentrantLock() private val initLock = ReentrantLock()

View File

@ -16,7 +16,10 @@ import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Job import kotlinx.coroutines.Job
import kotlinx.coroutines.runBlocking import kotlinx.coroutines.runBlocking
import net.mamoe.mirai.Bot import net.mamoe.mirai.Bot
import net.mamoe.mirai.console.* import net.mamoe.mirai.console.MalformedMiraiConsoleImplementationError
import net.mamoe.mirai.console.MiraiConsole
import net.mamoe.mirai.console.MiraiConsoleFrontEndDescription
import net.mamoe.mirai.console.MiraiConsoleImplementation
import net.mamoe.mirai.console.command.BuiltInCommands import net.mamoe.mirai.console.command.BuiltInCommands
import net.mamoe.mirai.console.command.CommandManager import net.mamoe.mirai.console.command.CommandManager
import net.mamoe.mirai.console.command.ConsoleCommandSender import net.mamoe.mirai.console.command.ConsoleCommandSender
@ -104,8 +107,9 @@ internal object MiraiConsoleImplementationBridge : CoroutineScope, MiraiConsoleI
@Suppress("RemoveRedundantBackticks") @Suppress("RemoveRedundantBackticks")
internal fun doStart() { internal fun doStart() {
instance.preStart()
phase `setup logger controller`@{ phase("setup logger controller") {
if (loggerController === LoggerControllerImpl) { if (loggerController === LoggerControllerImpl) {
// Reload LoggerConfig. // Reload LoggerConfig.
ConsoleDataScope.addAndReloadConfig(LoggerConfig) ConsoleDataScope.addAndReloadConfig(LoggerConfig)
@ -113,7 +117,7 @@ internal object MiraiConsoleImplementationBridge : CoroutineScope, MiraiConsoleI
} }
} }
phase `greeting`@{ phase("greeting") {
val buildDateFormatted = val buildDateFormatted =
buildDate.atZone(ZoneId.systemDefault()).format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")) buildDate.atZone(ZoneId.systemDefault()).format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"))
@ -122,7 +126,7 @@ internal object MiraiConsoleImplementationBridge : CoroutineScope, MiraiConsoleI
mainLogger.info { frontEndDescription.render() } mainLogger.info { frontEndDescription.render() }
} }
phase `check coroutineContext`@{ phase("check coroutineContext") {
if (coroutineContext[Job] == null) { if (coroutineContext[Job] == null) {
throw MalformedMiraiConsoleImplementationError("The coroutineContext given to MiraiConsole must have a Job in it.") throw MalformedMiraiConsoleImplementationError("The coroutineContext given to MiraiConsole must have a Job in it.")
} }
@ -139,13 +143,13 @@ internal object MiraiConsoleImplementationBridge : CoroutineScope, MiraiConsoleI
// start // start
phase `load configurations`@{ phase("load configurations") {
mainLogger.verbose { "Loading configurations..." } mainLogger.verbose { "Loading configurations..." }
ConsoleDataScope.addAndReloadConfig(CommandConfig) ConsoleDataScope.addAndReloadConfig(CommandConfig)
ConsoleDataScope.reloadAll() ConsoleDataScope.reloadAll()
} }
phase `initialize all plugins`@{ phase("initialize all plugins") {
PluginManager // init PluginManager // init
mainLogger.verbose { "Loading JVM plugins..." } mainLogger.verbose { "Loading JVM plugins..." }
@ -158,13 +162,13 @@ internal object MiraiConsoleImplementationBridge : CoroutineScope, MiraiConsoleI
} }
} }
phase `load all plugins`@{ phase("load all plugins") {
PluginManagerImpl.loadPlugins(PluginManagerImpl.scanPluginsUsingPluginLoadersIncludingThoseFromPluginLoaderProvider()) PluginManagerImpl.loadPlugins(PluginManagerImpl.scanPluginsUsingPluginLoadersIncludingThoseFromPluginLoaderProvider())
mainLogger.verbose { "${PluginManager.plugins.size} plugin(s) loaded." } mainLogger.verbose { "${PluginManager.plugins.size} plugin(s) loaded." }
} }
phase `load SingletonExtensionSelector`@{ phase("load SingletonExtensionSelector") {
SingletonExtensionSelector.init() SingletonExtensionSelector.init()
val instance = SingletonExtensionSelector.instance val instance = SingletonExtensionSelector.instance
if (instance is BuiltInSingletonExtensionSelector) { if (instance is BuiltInSingletonExtensionSelector) {
@ -173,7 +177,7 @@ internal object MiraiConsoleImplementationBridge : CoroutineScope, MiraiConsoleI
} }
phase `load PermissionService`@{ phase("load PermissionService") {
mainLogger.verbose { "Loading PermissionService..." } mainLogger.verbose { "Loading PermissionService..." }
PermissionService.INSTANCE.let { ps -> PermissionService.INSTANCE.let { ps ->
@ -188,7 +192,7 @@ internal object MiraiConsoleImplementationBridge : CoroutineScope, MiraiConsoleI
runIgnoreException<UnsupportedOperationException> { ConsoleCommandSender.permit(RootPermission) } runIgnoreException<UnsupportedOperationException> { ConsoleCommandSender.permit(RootPermission) }
} }
phase `prepare commands`@{ phase("prepare commands") {
mainLogger.verbose { "Loading built-in commands..." } mainLogger.verbose { "Loading built-in commands..." }
BuiltInCommands.registerAll() BuiltInCommands.registerAll()
mainLogger.info { "Prepared built-in commands: ${BuiltInCommands.all.joinToString { it.primaryName }}" } mainLogger.info { "Prepared built-in commands: ${BuiltInCommands.all.joinToString { it.primaryName }}" }
@ -196,7 +200,7 @@ internal object MiraiConsoleImplementationBridge : CoroutineScope, MiraiConsoleI
// CommandManagerImpl.commandListener // start // CommandManagerImpl.commandListener // start
} }
phase `enable plugins`@{ phase("enable plugins") {
mainLogger.verbose { "Enabling plugins..." } mainLogger.verbose { "Enabling plugins..." }
PluginManagerImpl.enableAllLoadedPlugins() PluginManagerImpl.enableAllLoadedPlugins()
@ -208,7 +212,7 @@ internal object MiraiConsoleImplementationBridge : CoroutineScope, MiraiConsoleI
mainLogger.info { "${PluginManagerImpl.plugins.size} plugin(s) enabled." } mainLogger.info { "${PluginManagerImpl.plugins.size} plugin(s) enabled." }
} }
phase `auto-login bots`@{ phase("auto-login bots") {
runBlocking { runBlocking {
val accounts = AutoLoginConfig.accounts.toList() val accounts = AutoLoginConfig.accounts.toList()
for (account in accounts) { for (account in accounts) {
@ -259,9 +263,13 @@ internal object MiraiConsoleImplementationBridge : CoroutineScope, MiraiConsoleI
} }
} }
phase("finally post") {
GlobalComponentStorage.run { GlobalComponentStorage.run {
PostStartupExtension.useExtensions { it() } // exceptions thrown will be caught by caller of `doStart`. PostStartupExtension.useExtensions { it() } // exceptions thrown will be caught by caller of `doStart`.
} }
}
instance.postStart()
mainLogger.info { "mirai-console started successfully." } mainLogger.info { "mirai-console started successfully." }
} }
@ -275,10 +283,20 @@ internal object MiraiConsoleImplementationBridge : CoroutineScope, MiraiConsoleI
* 表示一个初始化阶段, 无实际作用. * 表示一个初始化阶段, 无实际作用.
*/ */
@ILoveOmaeKumikoForever @ILoveOmaeKumikoForever
private inline fun phase(block: () -> Unit) { private inline fun phase(phase: String, block: () -> Unit) {
contract { contract {
callsInPlace(block, InvocationKind.EXACTLY_ONCE) callsInPlace(block, InvocationKind.EXACTLY_ONCE)
} }
prePhase(phase)
block() block()
postPhase(phase)
}
override fun prePhase(phase: String) {
instance.prePhase(phase)
}
override fun postPhase(phase: String) {
instance.postPhase(phase)
} }
} }