Rename PluginKind to PluginLoadPriority, revise load phases

This commit is contained in:
Him188 2020-09-10 20:41:09 +08:00
parent d7fe94acbd
commit 829bd6d454
10 changed files with 70 additions and 53 deletions

View File

@ -11,6 +11,7 @@ package net.mamoe.mirai.console.extension
import net.mamoe.mirai.console.extensions.PermissionServiceProvider import net.mamoe.mirai.console.extensions.PermissionServiceProvider
import net.mamoe.mirai.console.extensions.PluginLoaderProvider import net.mamoe.mirai.console.extensions.PluginLoaderProvider
import net.mamoe.mirai.console.extensions.SingletonExtensionSelector
import net.mamoe.mirai.console.util.ConsoleExperimentalAPI import net.mamoe.mirai.console.util.ConsoleExperimentalAPI
/** /**
@ -28,6 +29,8 @@ public interface FunctionExtension : Extension
/** /**
* 为某单例服务注册的 [Extension]. * 为某单例服务注册的 [Extension].
* *
* 若同时有多个实例可用, 将会使用 [SingletonExtensionSelector.selectSingleton] 选择
*
* @see PermissionServiceProvider * @see PermissionServiceProvider
*/ */
@ConsoleExperimentalAPI @ConsoleExperimentalAPI

View File

@ -5,12 +5,14 @@ import net.mamoe.mirai.console.extension.SingletonExtension
import net.mamoe.mirai.console.extension.SingletonExtensionPoint import net.mamoe.mirai.console.extension.SingletonExtensionPoint
import net.mamoe.mirai.console.permission.ExperimentalPermission import net.mamoe.mirai.console.permission.ExperimentalPermission
import net.mamoe.mirai.console.permission.PermissionService import net.mamoe.mirai.console.permission.PermissionService
import net.mamoe.mirai.console.plugin.description.PluginKind import net.mamoe.mirai.console.plugin.description.PluginLoadPriority
/** /**
* [权限服务][PermissionService] 提供器. * [权限服务][PermissionService] 提供器.
* *
* 此扩展可由 [PluginKind.LOADER] [PluginKind.HIGH_PRIORITY_EXTENSIONS] 插件提供 * 当插件注册 [PermissionService] , 默认会使用插件的 [PermissionService].
*
* 此扩展可由 [PluginLoadPriority.BEFORE_EXTENSIONS] [PluginLoadPriority.ON_EXTENSIONS] 插件提供
*/ */
@ExperimentalPermission @ExperimentalPermission
public interface PermissionServiceProvider : SingletonExtension<PermissionService<*>> { public interface PermissionServiceProvider : SingletonExtension<PermissionService<*>> {

View File

@ -3,12 +3,12 @@ package net.mamoe.mirai.console.extensions
import net.mamoe.mirai.console.extension.AbstractExtensionPoint import net.mamoe.mirai.console.extension.AbstractExtensionPoint
import net.mamoe.mirai.console.extension.InstanceExtension import net.mamoe.mirai.console.extension.InstanceExtension
import net.mamoe.mirai.console.plugin.PluginLoader import net.mamoe.mirai.console.plugin.PluginLoader
import net.mamoe.mirai.console.plugin.description.PluginKind import net.mamoe.mirai.console.plugin.description.PluginLoadPriority
/** /**
* 提供扩展 [PluginLoader] * 提供扩展 [PluginLoader]
* *
* 此扩展可由 [PluginKind.LOADER] 插件提供 * 此扩展可由 [PluginLoadPriority.BEFORE_EXTENSIONS] 插件提供
*/ */
public interface PluginLoaderProvider : InstanceExtension<PluginLoader<*, *>> { public interface PluginLoaderProvider : InstanceExtension<PluginLoader<*, *>> {
public companion object ExtensionPoint : AbstractExtensionPoint<PluginLoaderProvider>(PluginLoaderProvider::class) public companion object ExtensionPoint : AbstractExtensionPoint<PluginLoaderProvider>(PluginLoaderProvider::class)

View File

@ -12,7 +12,7 @@ package net.mamoe.mirai.console.extensions
import net.mamoe.mirai.console.MiraiConsole import net.mamoe.mirai.console.MiraiConsole
import net.mamoe.mirai.console.extension.* import net.mamoe.mirai.console.extension.*
import net.mamoe.mirai.console.internal.extensions.BuiltInSingletonExtensionSelector import net.mamoe.mirai.console.internal.extensions.BuiltInSingletonExtensionSelector
import net.mamoe.mirai.console.plugin.description.PluginKind import net.mamoe.mirai.console.plugin.description.PluginLoadPriority
import net.mamoe.mirai.console.plugin.name import net.mamoe.mirai.console.plugin.name
import net.mamoe.mirai.utils.info import net.mamoe.mirai.utils.info
import kotlin.reflect.KClass import kotlin.reflect.KClass
@ -22,7 +22,7 @@ import kotlin.reflect.KClass
* *
* 如有多个 [SingletonExtensionSelector] 注册, 将会停止服务器. * 如有多个 [SingletonExtensionSelector] 注册, 将会停止服务器.
* *
* 此扩展可由 [PluginKind.LOADER] [PluginKind.HIGH_PRIORITY_EXTENSIONS] 插件提供 * 此扩展可由 [PluginLoadPriority.BEFORE_EXTENSIONS] 插件提供
*/ */
public interface SingletonExtensionSelector : FunctionExtension { public interface SingletonExtensionSelector : FunctionExtension {

View File

@ -126,20 +126,12 @@ internal object MiraiConsoleImplementationBridge : CoroutineScope, MiraiConsoleI
val pluginLoadSession: PluginManagerImpl.PluginLoadSession val pluginLoadSession: PluginManagerImpl.PluginLoadSession
phase `load plugin provider plugins and high priority extension plugins`@{ phase `load BEFORE_EXTENSIONS plugins`@{
PluginManager // init PluginManager // init
mainLogger.verbose { "Loading PluginLoader provider plugins..." } mainLogger.verbose { "Loading PluginLoader provider plugins..." }
PluginManagerImpl.loadEnablePluginProviderPlugins() PluginManagerImpl.loadEnablePluginProviderPlugins()
mainLogger.verbose { "${PluginManager.plugins.size} such plugin(s) loaded." } mainLogger.verbose { "${PluginManager.plugins.size} such plugin(s) loaded." }
mainLogger.verbose { "Scanning high-priority extension and normal plugins..." }
pluginLoadSession = PluginManagerImpl.scanPluginsUsingPluginLoadersIncludingThoseFromPluginLoaderProvider()
mainLogger.verbose { "${pluginLoadSession.allKindsOfPlugins.size} plugin(s) found." }
mainLogger.verbose { "Loading Extension provider plugins..." }
PluginManagerImpl.loadEnableHighPriorityExtensionPlugins(pluginLoadSession)
mainLogger.verbose { "${PluginManager.plugins.size} such plugin(s) loaded." }
} }
phase `load SingletonExtensionSelector`@{ phase `load SingletonExtensionSelector`@{
@ -149,6 +141,16 @@ internal object MiraiConsoleImplementationBridge : CoroutineScope, MiraiConsoleI
} }
} }
phase `load ON_EXTENSIONS plugins`@{
mainLogger.verbose { "Scanning high-priority extension and normal plugins..." }
pluginLoadSession = PluginManagerImpl.scanPluginsUsingPluginLoadersIncludingThoseFromPluginLoaderProvider()
mainLogger.verbose { "${pluginLoadSession.allKindsOfPlugins.size} plugin(s) found." }
mainLogger.verbose { "Loading Extension provider plugins..." }
PluginManagerImpl.loadEnableHighPriorityExtensionPlugins(pluginLoadSession)
mainLogger.verbose { "${PluginManager.plugins.size} such plugin(s) loaded." }
}
phase `load PermissionService`@{ phase `load PermissionService`@{
mainLogger.verbose { "Loading PermissionService..." } mainLogger.verbose { "Loading PermissionService..." }
PermissionService.INSTANCE.let { ps -> PermissionService.INSTANCE.let { ps ->
@ -169,7 +171,7 @@ internal object MiraiConsoleImplementationBridge : CoroutineScope, MiraiConsoleI
CommandManagerImpl.commandListener // start CommandManagerImpl.commandListener // start
} }
phase `load normal plugins`@{ phase `load AFTER_EXTENSION plugins`@{
mainLogger.verbose { "Loading normal plugins..." } mainLogger.verbose { "Loading normal plugins..." }
val count = PluginManagerImpl.loadEnableNormalPlugins(pluginLoadSession) val count = PluginManagerImpl.loadEnableNormalPlugins(pluginLoadSession)
mainLogger.verbose { "$count normal plugin(s) loaded." } mainLogger.verbose { "$count normal plugin(s) loaded." }

View File

@ -22,7 +22,7 @@ import net.mamoe.mirai.console.internal.data.mkdir
import net.mamoe.mirai.console.plugin.* import net.mamoe.mirai.console.plugin.*
import net.mamoe.mirai.console.plugin.description.PluginDependency import net.mamoe.mirai.console.plugin.description.PluginDependency
import net.mamoe.mirai.console.plugin.description.PluginDescription import net.mamoe.mirai.console.plugin.description.PluginDescription
import net.mamoe.mirai.console.plugin.description.PluginKind import net.mamoe.mirai.console.plugin.description.PluginLoadPriority
import net.mamoe.mirai.console.plugin.jvm.JvmPlugin import net.mamoe.mirai.console.plugin.jvm.JvmPlugin
import net.mamoe.mirai.console.util.CoroutineScopeUtils.childScope import net.mamoe.mirai.console.util.CoroutineScopeUtils.childScope
import net.mamoe.mirai.utils.info import net.mamoe.mirai.utils.info
@ -131,7 +131,7 @@ internal object PluginManagerImpl : PluginManager, CoroutineScope by MiraiConsol
internal fun loadEnableHighPriorityExtensionPlugins(session: PluginLoadSession): Int { internal fun loadEnableHighPriorityExtensionPlugins(session: PluginLoadSession): Int {
loadersLock.withLock { loadersLock.withLock {
session.allKindsOfPlugins.flatMap { it.second } session.allKindsOfPlugins.flatMap { it.second }
.filter { it.kind == PluginKind.HIGH_PRIORITY_EXTENSIONS } .filter { it.loadPriority == PluginLoadPriority.ON_EXTENSIONS }
.sortByDependencies() .sortByDependencies()
.also { it.loadAndEnableAllInOrder() } .also { it.loadAndEnableAllInOrder() }
.let { return it.size } .let { return it.size }
@ -142,7 +142,7 @@ internal object PluginManagerImpl : PluginManager, CoroutineScope by MiraiConsol
internal fun loadEnableNormalPlugins(session: PluginLoadSession): Int { internal fun loadEnableNormalPlugins(session: PluginLoadSession): Int {
loadersLock.withLock { loadersLock.withLock {
session.allKindsOfPlugins.flatMap { it.second } session.allKindsOfPlugins.flatMap { it.second }
.filter { it.kind == PluginKind.NORMAL } .filter { it.loadPriority == PluginLoadPriority.AFTER_EXTENSIONS }
.sortByDependencies() .sortByDependencies()
.also { it.loadAndEnableAllInOrder() } .also { it.loadAndEnableAllInOrder() }
.let { return it.size } .let { return it.size }
@ -191,7 +191,8 @@ internal object PluginManagerImpl : PluginManager, CoroutineScope by MiraiConsol
loader as PluginLoader<Plugin, PluginDescription> loader as PluginLoader<Plugin, PluginDescription>
descriptions.forEach(PluginManagerImpl::checkPluginDescription) descriptions.forEach(PluginManagerImpl::checkPluginDescription)
descriptions.filter { it.kind == PluginKind.LOADER }.sortByDependencies().loadAndEnableAllInOrder() descriptions.filter { it.loadPriority == PluginLoadPriority.BEFORE_EXTENSIONS }.sortByDependencies()
.loadAndEnableAllInOrder()
} }
.flatMap { it.second.asSequence() } .flatMap { it.second.asSequence() }

View File

@ -18,7 +18,7 @@ import net.mamoe.mirai.console.plugin.PluginManager.INSTANCE.enable
import net.mamoe.mirai.console.plugin.PluginManager.INSTANCE.safeLoader import net.mamoe.mirai.console.plugin.PluginManager.INSTANCE.safeLoader
import net.mamoe.mirai.console.plugin.description.PluginDependency import net.mamoe.mirai.console.plugin.description.PluginDependency
import net.mamoe.mirai.console.plugin.description.PluginDescription import net.mamoe.mirai.console.plugin.description.PluginDescription
import net.mamoe.mirai.console.plugin.description.PluginKind import net.mamoe.mirai.console.plugin.description.PluginLoadPriority
import net.mamoe.mirai.console.plugin.jvm.JvmPlugin import net.mamoe.mirai.console.plugin.jvm.JvmPlugin
/** /**
@ -65,9 +65,9 @@ public inline val Plugin.name: String get() = this.description.name
public inline val Plugin.version: Semver get() = this.description.version public inline val Plugin.version: Semver get() = this.description.version
/** /**
* 获取 [PluginDescription.kind] * 获取 [PluginDescription.loadPriority]
*/ */
public inline val Plugin.kind: PluginKind get() = this.description.kind public inline val Plugin.loadPriority: PluginLoadPriority get() = this.description.loadPriority
/** /**
* 获取 [PluginDescription.info] * 获取 [PluginDescription.info]

View File

@ -23,9 +23,9 @@ public interface PluginDescription {
/** /**
* 插件类型. 将会决定加载顺序 * 插件类型. 将会决定加载顺序
* *
* @see PluginKind * @see PluginLoadPriority
*/ */
public val kind: PluginKind public val loadPriority: PluginLoadPriority
/** /**
* 插件 ID, 必须全英文, 仅允许英文字母, '-', '_', '.'. * 插件 ID, 必须全英文, 仅允许英文字母, '-', '_', '.'.

View File

@ -14,39 +14,46 @@ import kotlinx.serialization.builtins.serializer
import net.mamoe.mirai.console.extension.Extension import net.mamoe.mirai.console.extension.Extension
import net.mamoe.mirai.console.extensions.BotConfigurationAlterer import net.mamoe.mirai.console.extensions.BotConfigurationAlterer
import net.mamoe.mirai.console.extensions.PermissionServiceProvider import net.mamoe.mirai.console.extensions.PermissionServiceProvider
import net.mamoe.mirai.console.extensions.PluginLoaderProvider
import net.mamoe.mirai.console.extensions.SingletonExtensionSelector
import net.mamoe.mirai.console.internal.data.map import net.mamoe.mirai.console.internal.data.map
import net.mamoe.mirai.console.plugin.PluginLoader import net.mamoe.mirai.console.plugin.description.PluginLoadPriority.*
import net.mamoe.mirai.console.plugin.description.PluginKind.*
/** /**
* 插件类型. * 插件类型.
* *
* 插件类型将影响加载顺序: [LOADER] -> [HIGH_PRIORITY_EXTENSIONS] -> [NORMAL]. * 插件类型将影响加载顺序: [BEFORE_EXTENSIONS] -> [ON_EXTENSIONS] -> [AFTER_EXTENSIONS].
* *
* 依赖解决过程与插件类型有很大关联. 在一个较早的阶段, 只会解决在此阶段加载的插件. 意味着 [LOADER] 不允许依赖一个 [NORMAL] 类型的插件. * 依赖解决过程与插件类型有很大关联. 在一个较早的阶段, 只会解决在此阶段加载的插件. 意味着 [BEFORE_EXTENSIONS] 不允许依赖一个 [AFTER_EXTENSIONS] 类型的插件.
*/ */
public enum class PluginKind { public enum class PluginLoadPriority {
/** 表示此插件提供一个 [PluginLoader], 也可以同时提供其他 [Extension] 应最早被加载 */ /**
LOADER, * 表示此插件最早被加载. Console 启动时的第一初始化阶段就会加载这些插件.
*
* 一般只有提供 [PluginLoaderProvider] [SingletonExtensionSelector] 的插件才需要在此阶段加载.
*/
BEFORE_EXTENSIONS,
/** /**
* 表示此插件提供一些高优先级的 [Extension], 应在加载其他 [NORMAL] 类型插件前加载 * 表示此插件提供一些高优先级的 [Extension], 应在加载其他 [AFTER_EXTENSIONS] 类型插件前加载
* *
* 高优先级的 [Extension] 通常是覆盖 Console 内置的部分服务的扩展. [PermissionServiceProvider]. * 高优先级的 [Extension] 通常是覆盖 Console 内置的部分服务的扩展. [PermissionServiceProvider].
* *
* 一些普通的 [Extension], [BotConfigurationAlterer], 也可以使用 [NORMAL] 类型插件注册. * 一些普通的 [Extension], [BotConfigurationAlterer], 也可以使用 [AFTER_EXTENSIONS] 类型插件注册.
*/ */
HIGH_PRIORITY_EXTENSIONS, ON_EXTENSIONS,
/** 表示此插件为一个通常的插件, 按照正常的依赖关系加载. */ /**
NORMAL; * 表示此插件为一个通常的插件, 在扩展处理完毕后加载.
*/
AFTER_EXTENSIONS;
public object AsStringSerializer : KSerializer<PluginKind> by String.serializer().map( public object AsStringSerializer : KSerializer<PluginLoadPriority> by String.serializer().map(
serializer = { it.name }, serializer = { it.name },
deserializer = { str -> deserializer = { str ->
values().firstOrNull { values().firstOrNull {
it.name.equals(str, ignoreCase = true) it.name.equals(str, ignoreCase = true)
} ?: NORMAL } ?: AFTER_EXTENSIONS
} }
) )
} }

View File

@ -14,7 +14,7 @@ package net.mamoe.mirai.console.plugin.jvm
import com.vdurmont.semver4j.Semver import com.vdurmont.semver4j.Semver
import net.mamoe.mirai.console.plugin.description.PluginDependency import net.mamoe.mirai.console.plugin.description.PluginDependency
import net.mamoe.mirai.console.plugin.description.PluginDescription import net.mamoe.mirai.console.plugin.description.PluginDescription
import net.mamoe.mirai.console.plugin.description.PluginKind import net.mamoe.mirai.console.plugin.description.PluginLoadPriority
import kotlin.internal.LowPriorityInOverloadResolution import kotlin.internal.LowPriorityInOverloadResolution
/** /**
@ -82,7 +82,7 @@ public class JvmPluginDescriptionBuilder(
private var author: String = "" private var author: String = ""
private var info: String = "" private var info: String = ""
private var dependencies: MutableSet<PluginDependency> = mutableSetOf() private var dependencies: MutableSet<PluginDependency> = mutableSetOf()
private var kind: PluginKind = PluginKind.NORMAL private var loadPriority: PluginLoadPriority = PluginLoadPriority.AFTER_EXTENSIONS
@ILoveKuriyamaMiraiForever @ILoveKuriyamaMiraiForever
public fun name(value: String): JvmPluginDescriptionBuilder = apply { this.name = value.trim() } public fun name(value: String): JvmPluginDescriptionBuilder = apply { this.name = value.trim() }
@ -104,17 +104,19 @@ public class JvmPluginDescriptionBuilder(
public fun info(value: String): JvmPluginDescriptionBuilder = apply { this.info = value.trimIndent() } public fun info(value: String): JvmPluginDescriptionBuilder = apply { this.info = value.trimIndent() }
@ILoveKuriyamaMiraiForever @ILoveKuriyamaMiraiForever
public fun kind(value: PluginKind): JvmPluginDescriptionBuilder = apply { this.kind = value } public fun kind(value: PluginLoadPriority): JvmPluginDescriptionBuilder = apply { this.loadPriority = value }
@ILoveKuriyamaMiraiForever @ILoveKuriyamaMiraiForever
public fun normalPlugin(): JvmPluginDescriptionBuilder = apply { this.kind = PluginKind.NORMAL } public fun normalPlugin(): JvmPluginDescriptionBuilder =
apply { this.loadPriority = PluginLoadPriority.AFTER_EXTENSIONS }
@ILoveKuriyamaMiraiForever @ILoveKuriyamaMiraiForever
public fun loaderProviderPlugin(): JvmPluginDescriptionBuilder = apply { this.kind = PluginKind.LOADER } public fun loaderProviderPlugin(): JvmPluginDescriptionBuilder =
apply { this.loadPriority = PluginLoadPriority.BEFORE_EXTENSIONS }
@ILoveKuriyamaMiraiForever @ILoveKuriyamaMiraiForever
public fun highPriorityExtensionsPlugin(): JvmPluginDescriptionBuilder = public fun highPriorityExtensionsPlugin(): JvmPluginDescriptionBuilder =
apply { this.kind = PluginKind.HIGH_PRIORITY_EXTENSIONS } apply { this.loadPriority = PluginLoadPriority.ON_EXTENSIONS }
@ILoveKuriyamaMiraiForever @ILoveKuriyamaMiraiForever
public fun dependsOn( public fun dependsOn(
@ -152,7 +154,7 @@ public class JvmPluginDescriptionBuilder(
@Suppress("DEPRECATION_ERROR") @Suppress("DEPRECATION_ERROR")
public fun build(): JvmPluginDescription = public fun build(): JvmPluginDescription =
SimpleJvmPluginDescription(name, version, id, author, info, dependencies, kind) SimpleJvmPluginDescription(name, version, id, author, info, dependencies, loadPriority)
@Retention(AnnotationRetention.SOURCE) @Retention(AnnotationRetention.SOURCE)
@DslMarker @DslMarker
@ -192,7 +194,7 @@ public data class SimpleJvmPluginDescription
public override val author: String = "", public override val author: String = "",
public override val info: String = "", public override val info: String = "",
public override val dependencies: Set<PluginDependency> = setOf(), public override val dependencies: Set<PluginDependency> = setOf(),
public override val kind: PluginKind = PluginKind.NORMAL, public override val loadPriority: PluginLoadPriority = PluginLoadPriority.AFTER_EXTENSIONS,
) : JvmPluginDescription { ) : JvmPluginDescription {
@Deprecated( @Deprecated(
@ -214,8 +216,8 @@ public data class SimpleJvmPluginDescription
author: String = "", author: String = "",
info: String = "", info: String = "",
dependencies: Set<PluginDependency> = setOf(), dependencies: Set<PluginDependency> = setOf(),
kind: PluginKind = PluginKind.NORMAL, loadPriority: PluginLoadPriority = PluginLoadPriority.AFTER_EXTENSIONS,
) : this(name, Semver(version, Semver.SemverType.LOOSE), id, author, info, dependencies, kind) ) : this(name, Semver(version, Semver.SemverType.LOOSE), id, author, info, dependencies, loadPriority)
init { init {
require(!name.contains(':')) { "':' is forbidden in plugin name" } require(!name.contains(':')) { "':' is forbidden in plugin name" }
@ -240,8 +242,8 @@ public fun JvmPluginDescription(
author: String = "", author: String = "",
info: String = "", info: String = "",
dependencies: Set<PluginDependency> = setOf(), dependencies: Set<PluginDependency> = setOf(),
kind: PluginKind = PluginKind.NORMAL loadPriority: PluginLoadPriority = PluginLoadPriority.AFTER_EXTENSIONS
): JvmPluginDescription = SimpleJvmPluginDescription(name, version, id, author, info, dependencies, kind) ): JvmPluginDescription = SimpleJvmPluginDescription(name, version, id, author, info, dependencies, loadPriority)
@Deprecated( @Deprecated(
"JvmPluginDescription 没有构造器. 请使用 SimpleJvmPluginDescription.", "JvmPluginDescription 没有构造器. 请使用 SimpleJvmPluginDescription.",
@ -260,5 +262,5 @@ public fun JvmPluginDescription(
author: String = "", author: String = "",
info: String = "", info: String = "",
dependencies: Set<PluginDependency> = setOf(), dependencies: Set<PluginDependency> = setOf(),
kind: PluginKind = PluginKind.NORMAL loadPriority: PluginLoadPriority = PluginLoadPriority.AFTER_EXTENSIONS
): JvmPluginDescription = SimpleJvmPluginDescription(name, version, id, author, info, dependencies, kind) ): JvmPluginDescription = SimpleJvmPluginDescription(name, version, id, author, info, dependencies, loadPriority)