mirror of
https://github.com/mamoe/mirai.git
synced 2025-01-11 02:50:15 +08:00
Support loading PluginLoaders by ServiceLoader for each plugin;
Rearrange implementations
This commit is contained in:
parent
dee8e44110
commit
5a5d45778a
@ -19,7 +19,7 @@ import net.mamoe.mirai.Bot
|
|||||||
import net.mamoe.mirai.console.MiraiConsole.INSTANCE
|
import net.mamoe.mirai.console.MiraiConsole.INSTANCE
|
||||||
import net.mamoe.mirai.console.MiraiConsoleImplementation.Companion.start
|
import net.mamoe.mirai.console.MiraiConsoleImplementation.Companion.start
|
||||||
import net.mamoe.mirai.console.internal.MiraiConsoleImplementationBridge
|
import net.mamoe.mirai.console.internal.MiraiConsoleImplementationBridge
|
||||||
import net.mamoe.mirai.console.internal.util.childScopeContext
|
import net.mamoe.mirai.console.internal.data.builtin.childScopeContext
|
||||||
import net.mamoe.mirai.console.plugin.PluginLoader
|
import net.mamoe.mirai.console.plugin.PluginLoader
|
||||||
import net.mamoe.mirai.console.plugin.PluginManager
|
import net.mamoe.mirai.console.plugin.PluginManager
|
||||||
import net.mamoe.mirai.console.plugin.center.PluginCenter
|
import net.mamoe.mirai.console.plugin.center.PluginCenter
|
||||||
|
@ -24,9 +24,9 @@ import net.mamoe.mirai.console.command.Command.Companion.primaryName
|
|||||||
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.internal.command.CommandManagerImpl
|
import net.mamoe.mirai.console.internal.command.CommandManagerImpl
|
||||||
|
import net.mamoe.mirai.console.internal.data.builtin.ConsoleDataScope
|
||||||
import net.mamoe.mirai.console.internal.plugin.CuiPluginCenter
|
import net.mamoe.mirai.console.internal.plugin.CuiPluginCenter
|
||||||
import net.mamoe.mirai.console.internal.plugin.PluginManagerImpl
|
import net.mamoe.mirai.console.internal.plugin.PluginManagerImpl
|
||||||
import net.mamoe.mirai.console.internal.util.ConsoleDataScope
|
|
||||||
import net.mamoe.mirai.console.plugin.PluginLoader
|
import net.mamoe.mirai.console.plugin.PluginLoader
|
||||||
import net.mamoe.mirai.console.plugin.PluginManager
|
import net.mamoe.mirai.console.plugin.PluginManager
|
||||||
import net.mamoe.mirai.console.plugin.center.PluginCenter
|
import net.mamoe.mirai.console.plugin.center.PluginCenter
|
||||||
|
@ -0,0 +1,46 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2019-2020 Mamoe Technologies and contributors.
|
||||||
|
*
|
||||||
|
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
|
||||||
|
* Use of this source code is governed by the GNU AFFERO GENERAL PUBLIC LICENSE version 3 license that can be found via the following link.
|
||||||
|
*
|
||||||
|
* https://github.com/mamoe/mirai/blob/master/LICENSE
|
||||||
|
*/
|
||||||
|
|
||||||
|
@file:Suppress("MemberVisibilityCanBePrivate")
|
||||||
|
|
||||||
|
package net.mamoe.mirai.console.internal.data.builtin
|
||||||
|
|
||||||
|
import net.mamoe.mirai.Bot
|
||||||
|
import net.mamoe.mirai.console.data.AutoSavePluginConfig
|
||||||
|
import net.mamoe.mirai.console.data.PluginDataExtensions.mapKeys
|
||||||
|
import net.mamoe.mirai.console.data.PluginDataExtensions.withEmptyDefault
|
||||||
|
import net.mamoe.mirai.console.data.getValue
|
||||||
|
import net.mamoe.mirai.console.data.value
|
||||||
|
import net.mamoe.mirai.console.util.BotManager
|
||||||
|
import net.mamoe.mirai.contact.User
|
||||||
|
|
||||||
|
internal object BotManagerImpl : BotManager {
|
||||||
|
override val User.isManager: Boolean get() = this.id in ManagersConfig[this.bot]
|
||||||
|
|
||||||
|
override fun Bot.removeManager(id: Long): Boolean {
|
||||||
|
return ManagersConfig[this].remove(id)
|
||||||
|
}
|
||||||
|
|
||||||
|
override val Bot.managers: List<Long>
|
||||||
|
get() = ManagersConfig[this].toList()
|
||||||
|
|
||||||
|
override fun Bot.addManager(id: Long): Boolean {
|
||||||
|
return ManagersConfig[this].add(id)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal object ManagersConfig : AutoSavePluginConfig() {
|
||||||
|
override val saveName: String
|
||||||
|
get() = "Managers"
|
||||||
|
|
||||||
|
private val managers by value<MutableMap<Long, MutableSet<Long>>>().withEmptyDefault()
|
||||||
|
.mapKeys(Bot::getInstance, Bot::id)
|
||||||
|
|
||||||
|
internal operator fun get(bot: Bot): MutableSet<Long> = managers[bot]!!
|
||||||
|
}
|
@ -0,0 +1,52 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2020 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/master/LICENSE
|
||||||
|
*/
|
||||||
|
|
||||||
|
package net.mamoe.mirai.console.internal.data.builtin
|
||||||
|
|
||||||
|
import kotlinx.coroutines.CoroutineScope
|
||||||
|
import net.mamoe.mirai.console.MiraiConsole
|
||||||
|
import net.mamoe.mirai.console.data.AutoSavePluginDataHolder
|
||||||
|
import net.mamoe.mirai.console.data.PluginConfig
|
||||||
|
import net.mamoe.mirai.console.data.PluginData
|
||||||
|
import net.mamoe.mirai.console.data.PluginDataStorage
|
||||||
|
import net.mamoe.mirai.console.internal.MiraiConsoleImplementationBridge
|
||||||
|
import net.mamoe.mirai.utils.minutesToMillis
|
||||||
|
|
||||||
|
|
||||||
|
internal object ConsoleDataScope : CoroutineScope by MiraiConsole.childScope("ConsoleDataScope") {
|
||||||
|
private val data: Array<out PluginData> = arrayOf()
|
||||||
|
private val configs: Array<out PluginConfig> = arrayOf(ManagersConfig)
|
||||||
|
|
||||||
|
fun reloadAll() {
|
||||||
|
data.forEach { dt ->
|
||||||
|
ConsoleBuiltInPluginDataStorage.load(ConsoleBuiltInPluginDataHolder, dt)
|
||||||
|
}
|
||||||
|
configs.forEach { config ->
|
||||||
|
ConsoleBuiltInPluginConfigStorage.load(ConsoleBuiltInPluginConfigHolder, config)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal object ConsoleBuiltInPluginDataHolder : AutoSavePluginDataHolder,
|
||||||
|
CoroutineScope by ConsoleDataScope.childScope("ConsoleBuiltInPluginDataHolder") {
|
||||||
|
override val autoSaveIntervalMillis: LongRange = 1.minutesToMillis..10.minutesToMillis
|
||||||
|
override val name: String get() = "ConsoleBuiltIns"
|
||||||
|
}
|
||||||
|
|
||||||
|
internal object ConsoleBuiltInPluginConfigHolder : AutoSavePluginDataHolder,
|
||||||
|
CoroutineScope by ConsoleDataScope.childScope("ConsoleBuiltInPluginConfigHolder") {
|
||||||
|
override val autoSaveIntervalMillis: LongRange = 1.minutesToMillis..10.minutesToMillis
|
||||||
|
override val name: String get() = "ConsoleBuiltIns"
|
||||||
|
}
|
||||||
|
|
||||||
|
internal object ConsoleBuiltInPluginDataStorage :
|
||||||
|
PluginDataStorage by MiraiConsoleImplementationBridge.dataStorageForBuiltIns
|
||||||
|
|
||||||
|
internal object ConsoleBuiltInPluginConfigStorage :
|
||||||
|
PluginDataStorage by MiraiConsoleImplementationBridge.configStorageForBuiltIns
|
@ -18,11 +18,11 @@ import net.mamoe.mirai.console.data.PluginDataStorage
|
|||||||
import net.mamoe.mirai.console.internal.MiraiConsoleImplementationBridge
|
import net.mamoe.mirai.console.internal.MiraiConsoleImplementationBridge
|
||||||
import net.mamoe.mirai.console.internal.command.qualifiedNameOrTip
|
import net.mamoe.mirai.console.internal.command.qualifiedNameOrTip
|
||||||
import net.mamoe.mirai.console.internal.data.createInstanceOrNull
|
import net.mamoe.mirai.console.internal.data.createInstanceOrNull
|
||||||
import net.mamoe.mirai.console.internal.util.childScopeContext
|
|
||||||
import net.mamoe.mirai.console.plugin.AbstractFilePluginLoader
|
import net.mamoe.mirai.console.plugin.AbstractFilePluginLoader
|
||||||
import net.mamoe.mirai.console.plugin.PluginLoadException
|
import net.mamoe.mirai.console.plugin.PluginLoadException
|
||||||
import net.mamoe.mirai.console.plugin.jvm.*
|
import net.mamoe.mirai.console.plugin.jvm.*
|
||||||
import net.mamoe.mirai.console.util.ConsoleExperimentalAPI
|
import net.mamoe.mirai.console.util.ConsoleExperimentalAPI
|
||||||
|
import net.mamoe.mirai.console.util.childScopeContext
|
||||||
import net.mamoe.mirai.utils.MiraiLogger
|
import net.mamoe.mirai.utils.MiraiLogger
|
||||||
import net.mamoe.yamlkt.Yaml
|
import net.mamoe.yamlkt.Yaml
|
||||||
import java.io.File
|
import java.io.File
|
||||||
@ -48,7 +48,7 @@ internal object JarPluginLoaderImpl :
|
|||||||
logger.error("Unhandled Jar plugin exception: ${throwable.message}", throwable)
|
logger.error("Unhandled Jar plugin exception: ${throwable.message}", throwable)
|
||||||
})
|
})
|
||||||
|
|
||||||
private val classLoader: PluginsLoader = PluginsLoader(this.javaClass.classLoader)
|
internal val classLoader: PluginsLoader = PluginsLoader(this.javaClass.classLoader)
|
||||||
|
|
||||||
init { // delayed
|
init { // delayed
|
||||||
coroutineContext[Job]!!.invokeOnCompletion {
|
coroutineContext[Job]!!.invokeOnCompletion {
|
||||||
|
@ -15,18 +15,23 @@ import kotlinx.atomicfu.locks.withLock
|
|||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.CoroutineScope
|
||||||
import kotlinx.coroutines.Job
|
import kotlinx.coroutines.Job
|
||||||
import net.mamoe.mirai.console.MiraiConsole
|
import net.mamoe.mirai.console.MiraiConsole
|
||||||
|
import net.mamoe.mirai.console.internal.command.qualifiedNameOrTip
|
||||||
import net.mamoe.mirai.console.internal.data.cast
|
import net.mamoe.mirai.console.internal.data.cast
|
||||||
import net.mamoe.mirai.console.internal.data.mkdir
|
import net.mamoe.mirai.console.internal.data.mkdir
|
||||||
import net.mamoe.mirai.console.internal.util.childScope
|
|
||||||
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.PluginKind
|
||||||
import net.mamoe.mirai.console.plugin.jvm.JvmPlugin
|
import net.mamoe.mirai.console.plugin.jvm.JvmPlugin
|
||||||
|
import net.mamoe.mirai.console.util.childScope
|
||||||
|
import net.mamoe.mirai.utils.error
|
||||||
import net.mamoe.mirai.utils.info
|
import net.mamoe.mirai.utils.info
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import java.nio.file.Path
|
import java.nio.file.Path
|
||||||
|
import java.util.*
|
||||||
import java.util.concurrent.locks.ReentrantLock
|
import java.util.concurrent.locks.ReentrantLock
|
||||||
|
import kotlin.collections.ArrayList
|
||||||
|
import kotlin.streams.asSequence
|
||||||
|
|
||||||
internal object PluginManagerImpl : PluginManager, CoroutineScope by MiraiConsole.childScope("PluginManager") {
|
internal object PluginManagerImpl : PluginManager, CoroutineScope by MiraiConsole.childScope("PluginManager") {
|
||||||
|
|
||||||
@ -123,9 +128,38 @@ internal object PluginManagerImpl : PluginManager, CoroutineScope by MiraiConsol
|
|||||||
@Suppress("UNCHECKED_CAST")
|
@Suppress("UNCHECKED_CAST")
|
||||||
@Throws(PluginMissingDependencyException::class)
|
@Throws(PluginMissingDependencyException::class)
|
||||||
internal fun loadEnablePlugins() {
|
internal fun loadEnablePlugins() {
|
||||||
(loadAndEnableLoaderProviders() + _pluginLoaders.listAllPlugins().flatMap { it.second })
|
loadAndEnableLoaderProviders()
|
||||||
|
loadPluginLoaderProvidedByPlugins()
|
||||||
|
loadersLock.withLock {
|
||||||
|
_pluginLoaders.listAllPlugins().flatMap { it.second }
|
||||||
.sortByDependencies().loadAndEnableAllInOrder()
|
.sortByDependencies().loadAndEnableAllInOrder()
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun loadPluginLoaderProvidedByPlugins() {
|
||||||
|
loadersLock.withLock {
|
||||||
|
JarPluginLoaderImpl.classLoader.pluginLoaders.asSequence()
|
||||||
|
.flatMap { (name, pluginClassLoader) ->
|
||||||
|
ServiceLoader.load(PluginLoader::class.java, pluginClassLoader)
|
||||||
|
.stream().asSequence()
|
||||||
|
.associateBy { name }
|
||||||
|
.asSequence()
|
||||||
|
}
|
||||||
|
.forEach { (name, provider) ->
|
||||||
|
val pluginLoader = kotlin.runCatching {
|
||||||
|
provider.get()
|
||||||
|
}.getOrElse {
|
||||||
|
logger.error(
|
||||||
|
{ "Could not load PluginLoader ${it::class.qualifiedNameOrTip} from plugin $name" },
|
||||||
|
it
|
||||||
|
)
|
||||||
|
return@forEach
|
||||||
|
}
|
||||||
|
_pluginLoaders.add(pluginLoader)
|
||||||
|
logger.info { "Successfully loaded PluginLoader ${pluginLoader::class.qualifiedNameOrTip} from plugin $name" }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private fun List<PluginDescriptionWithLoader>.loadAndEnableAllInOrder() {
|
private fun List<PluginDescriptionWithLoader>.loadAndEnableAllInOrder() {
|
||||||
return this.map { (loader, desc) ->
|
return this.map { (loader, desc) ->
|
||||||
|
@ -15,7 +15,7 @@ import java.net.URLClassLoader
|
|||||||
|
|
||||||
internal class PluginsLoader(private val parentClassLoader: ClassLoader) {
|
internal class PluginsLoader(private val parentClassLoader: ClassLoader) {
|
||||||
private val loggerName = "PluginsLoader"
|
private val loggerName = "PluginsLoader"
|
||||||
private val pluginLoaders = linkedMapOf<String, PluginClassLoader>()
|
internal val pluginLoaders = linkedMapOf<String, PluginClassLoader>()
|
||||||
private val classesCache = mutableMapOf<String, Class<*>>()
|
private val classesCache = mutableMapOf<String, Class<*>>()
|
||||||
private val logger = MiraiConsole.newLogger(loggerName)
|
private val logger = MiraiConsole.newLogger(loggerName)
|
||||||
|
|
||||||
|
@ -1,107 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2019-2020 Mamoe Technologies and contributors.
|
|
||||||
*
|
|
||||||
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
|
|
||||||
* Use of this source code is governed by the GNU AFFERO GENERAL PUBLIC LICENSE version 3 license that can be found via the following link.
|
|
||||||
*
|
|
||||||
* https://github.com/mamoe/mirai/blob/master/LICENSE
|
|
||||||
*/
|
|
||||||
|
|
||||||
@file:Suppress("MemberVisibilityCanBePrivate")
|
|
||||||
|
|
||||||
package net.mamoe.mirai.console.internal.util
|
|
||||||
|
|
||||||
import kotlinx.coroutines.CoroutineName
|
|
||||||
import kotlinx.coroutines.CoroutineScope
|
|
||||||
import kotlinx.coroutines.Job
|
|
||||||
import net.mamoe.mirai.Bot
|
|
||||||
import net.mamoe.mirai.console.MiraiConsole
|
|
||||||
import net.mamoe.mirai.console.data.*
|
|
||||||
import net.mamoe.mirai.console.data.PluginDataExtensions.mapKeys
|
|
||||||
import net.mamoe.mirai.console.data.PluginDataExtensions.withEmptyDefault
|
|
||||||
import net.mamoe.mirai.console.internal.MiraiConsoleImplementationBridge
|
|
||||||
import net.mamoe.mirai.console.internal.plugin.NamedSupervisorJob
|
|
||||||
import net.mamoe.mirai.console.util.BotManager
|
|
||||||
import net.mamoe.mirai.contact.User
|
|
||||||
import net.mamoe.mirai.utils.minutesToMillis
|
|
||||||
import kotlin.coroutines.CoroutineContext
|
|
||||||
import kotlin.coroutines.EmptyCoroutineContext
|
|
||||||
|
|
||||||
internal object BotManagerImpl : BotManager {
|
|
||||||
/**
|
|
||||||
* 判断此用户是否为 console 管理员
|
|
||||||
*/
|
|
||||||
override val User.isManager: Boolean get() = this.id in ManagersConfig[this.bot]
|
|
||||||
|
|
||||||
override fun Bot.removeManager(id: Long): Boolean {
|
|
||||||
return ManagersConfig[this].remove(id)
|
|
||||||
}
|
|
||||||
|
|
||||||
override val Bot.managers: List<Long>
|
|
||||||
get() = ManagersConfig[this].toList()
|
|
||||||
|
|
||||||
override fun Bot.addManager(id: Long): Boolean {
|
|
||||||
return ManagersConfig[this].add(id)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@ValueName("Managers")
|
|
||||||
internal object ManagersConfig : AutoSavePluginConfig() {
|
|
||||||
override val saveName: String
|
|
||||||
get() = "Managers"
|
|
||||||
private val managers by value<MutableMap<Long, MutableSet<Long>>>().withEmptyDefault()
|
|
||||||
.mapKeys(Bot::getInstance, Bot::id)
|
|
||||||
|
|
||||||
internal operator fun get(bot: Bot): MutableSet<Long> = managers[bot]!!
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
internal fun CoroutineContext.overrideWithSupervisorJob(name: String? = null): CoroutineContext =
|
|
||||||
this + NamedSupervisorJob(name ?: "<unnamed>", this[Job])
|
|
||||||
|
|
||||||
internal fun CoroutineScope.childScope(
|
|
||||||
name: String? = null,
|
|
||||||
context: CoroutineContext = EmptyCoroutineContext
|
|
||||||
): CoroutineScope =
|
|
||||||
CoroutineScope(this.childScopeContext(name, context))
|
|
||||||
|
|
||||||
internal fun CoroutineScope.childScopeContext(
|
|
||||||
name: String? = null,
|
|
||||||
context: CoroutineContext = EmptyCoroutineContext
|
|
||||||
): CoroutineContext =
|
|
||||||
this.coroutineContext.overrideWithSupervisorJob(name) + context.let {
|
|
||||||
if (name != null) it + CoroutineName(name)
|
|
||||||
else it
|
|
||||||
}
|
|
||||||
|
|
||||||
internal object ConsoleDataScope : CoroutineScope by MiraiConsole.childScope("ConsoleDataScope") {
|
|
||||||
private val data: Array<out PluginData> = arrayOf()
|
|
||||||
private val configs: Array<out PluginConfig> = arrayOf(ManagersConfig)
|
|
||||||
|
|
||||||
fun reloadAll() {
|
|
||||||
data.forEach { dt ->
|
|
||||||
ConsoleBuiltInPluginDataStorage.load(ConsoleBuiltInPluginDataHolder, dt)
|
|
||||||
}
|
|
||||||
configs.forEach { config ->
|
|
||||||
ConsoleBuiltInPluginConfigStorage.load(ConsoleBuiltInPluginConfigHolder, config)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
internal object ConsoleBuiltInPluginDataHolder : AutoSavePluginDataHolder,
|
|
||||||
CoroutineScope by ConsoleDataScope.childScope("ConsoleBuiltInPluginDataHolder") {
|
|
||||||
override val autoSaveIntervalMillis: LongRange = 1.minutesToMillis..10.minutesToMillis
|
|
||||||
override val name: String get() = "ConsoleBuiltIns"
|
|
||||||
}
|
|
||||||
|
|
||||||
internal object ConsoleBuiltInPluginConfigHolder : AutoSavePluginDataHolder,
|
|
||||||
CoroutineScope by ConsoleDataScope.childScope("ConsoleBuiltInPluginConfigHolder") {
|
|
||||||
override val autoSaveIntervalMillis: LongRange = 1.minutesToMillis..10.minutesToMillis
|
|
||||||
override val name: String get() = "ConsoleBuiltIns"
|
|
||||||
}
|
|
||||||
|
|
||||||
internal object ConsoleBuiltInPluginDataStorage :
|
|
||||||
PluginDataStorage by MiraiConsoleImplementationBridge.dataStorageForBuiltIns
|
|
||||||
|
|
||||||
internal object ConsoleBuiltInPluginConfigStorage :
|
|
||||||
PluginDataStorage by MiraiConsoleImplementationBridge.configStorageForBuiltIns
|
|
@ -17,6 +17,7 @@ import net.mamoe.mirai.console.plugin.PluginManager.INSTANCE.register
|
|||||||
import net.mamoe.mirai.console.plugin.description.PluginDescription
|
import net.mamoe.mirai.console.plugin.description.PluginDescription
|
||||||
import net.mamoe.mirai.console.plugin.jvm.JarPluginLoader
|
import net.mamoe.mirai.console.plugin.jvm.JarPluginLoader
|
||||||
import java.io.File
|
import java.io.File
|
||||||
|
import java.util.*
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 插件加载器.
|
* 插件加载器.
|
||||||
@ -25,11 +26,16 @@ import java.io.File
|
|||||||
*
|
*
|
||||||
* 有关插件的依赖和已加载的插件列表由 [PluginManager] 维护.
|
* 有关插件的依赖和已加载的插件列表由 [PluginManager] 维护.
|
||||||
*
|
*
|
||||||
* ### 内建加载器
|
* ## 内建加载器
|
||||||
* - [JarPluginLoader] Jar 插件加载器
|
* - [JarPluginLoader] Jar 插件加载器
|
||||||
*
|
*
|
||||||
* ### 扩展加载器
|
* ## 扩展加载器
|
||||||
* 插件被允许扩展一个加载器。 可通过 [PluginManager.register]
|
* 插件被允许扩展一个加载器.
|
||||||
|
* Console 使用 [ServiceLoader] 加载 [PluginLoader] 的实例.
|
||||||
|
* 插件也可通过 [PluginManager.register] 手动注册, 然而这是不推荐的.
|
||||||
|
*
|
||||||
|
* ### 实现扩展加载器
|
||||||
|
* 直接实现接口 [PluginLoader] 或 [FilePluginLoader], 并添加 [ServiceLoader] 相关资源文件即可.
|
||||||
*
|
*
|
||||||
* @see JarPluginLoader Jar 插件加载器
|
* @see JarPluginLoader Jar 插件加载器
|
||||||
* @see PluginManager.register 注册一个扩展的插件加载器
|
* @see PluginManager.register 注册一个扩展的插件加载器
|
||||||
|
@ -14,8 +14,10 @@ package net.mamoe.mirai.console.plugin
|
|||||||
import net.mamoe.mirai.console.MiraiConsole
|
import net.mamoe.mirai.console.MiraiConsole
|
||||||
import net.mamoe.mirai.console.internal.plugin.PluginManagerImpl
|
import net.mamoe.mirai.console.internal.plugin.PluginManagerImpl
|
||||||
import net.mamoe.mirai.console.plugin.description.PluginDescription
|
import net.mamoe.mirai.console.plugin.description.PluginDescription
|
||||||
|
import net.mamoe.mirai.console.util.ConsoleExperimentalAPI
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import java.nio.file.Path
|
import java.nio.file.Path
|
||||||
|
import java.util.*
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 插件管理器.
|
* 插件管理器.
|
||||||
@ -102,10 +104,11 @@ public interface PluginManager {
|
|||||||
public val pluginLoaders: List<PluginLoader<*, *>>
|
public val pluginLoaders: List<PluginLoader<*, *>>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 注册一个扩展的插件加载器
|
* 手动注册一个扩展的插件加载器. 在启动时会通过 [ServiceLoader] 加载, 但也可以手动注册.
|
||||||
*
|
*
|
||||||
* @see PluginLoader 插件加载器
|
* @see PluginLoader 插件加载器
|
||||||
*/
|
*/
|
||||||
|
@ConsoleExperimentalAPI
|
||||||
public fun PluginLoader<*, *>.register(): Boolean
|
public fun PluginLoader<*, *>.register(): Boolean
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -113,6 +116,7 @@ public interface PluginManager {
|
|||||||
*
|
*
|
||||||
* @see PluginLoader 插件加载器
|
* @see PluginLoader 插件加载器
|
||||||
*/
|
*/
|
||||||
|
@ConsoleExperimentalAPI
|
||||||
public fun PluginLoader<*, *>.unregister(): Boolean
|
public fun PluginLoader<*, *>.unregister(): Boolean
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -11,7 +11,6 @@
|
|||||||
|
|
||||||
package net.mamoe.mirai.console.plugin.jvm
|
package net.mamoe.mirai.console.plugin.jvm
|
||||||
|
|
||||||
import net.mamoe.mirai.console.util.ConsoleExperimentalAPI
|
|
||||||
import kotlin.coroutines.CoroutineContext
|
import kotlin.coroutines.CoroutineContext
|
||||||
import kotlin.coroutines.EmptyCoroutineContext
|
import kotlin.coroutines.EmptyCoroutineContext
|
||||||
|
|
||||||
@ -27,7 +26,6 @@ public abstract class KotlinPlugin @JvmOverloads constructor(
|
|||||||
/**
|
/**
|
||||||
* 在内存动态加载的插件. 此为预览版本 API.
|
* 在内存动态加载的插件. 此为预览版本 API.
|
||||||
*/
|
*/
|
||||||
@ConsoleExperimentalAPI
|
|
||||||
public abstract class KotlinMemoryPlugin @JvmOverloads constructor(
|
public abstract class KotlinMemoryPlugin @JvmOverloads constructor(
|
||||||
description: JvmPluginDescription,
|
description: JvmPluginDescription,
|
||||||
parentCoroutineContext: CoroutineContext = EmptyCoroutineContext
|
parentCoroutineContext: CoroutineContext = EmptyCoroutineContext
|
||||||
|
@ -0,0 +1,37 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2020 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/master/LICENSE
|
||||||
|
*/
|
||||||
|
|
||||||
|
@file:JvmName("CoroutineScopeUtils")
|
||||||
|
|
||||||
|
package net.mamoe.mirai.console.util
|
||||||
|
|
||||||
|
import kotlinx.coroutines.CoroutineName
|
||||||
|
import kotlinx.coroutines.CoroutineScope
|
||||||
|
import kotlinx.coroutines.Job
|
||||||
|
import net.mamoe.mirai.console.internal.plugin.NamedSupervisorJob
|
||||||
|
import kotlin.coroutines.CoroutineContext
|
||||||
|
import kotlin.coroutines.EmptyCoroutineContext
|
||||||
|
|
||||||
|
internal fun CoroutineContext.overrideWithSupervisorJob(name: String? = null): CoroutineContext =
|
||||||
|
this + NamedSupervisorJob(name ?: "<unnamed>", this[Job])
|
||||||
|
|
||||||
|
internal fun CoroutineScope.childScope(
|
||||||
|
name: String? = null,
|
||||||
|
context: CoroutineContext = EmptyCoroutineContext
|
||||||
|
): CoroutineScope =
|
||||||
|
CoroutineScope(this.childScopeContext(name, context))
|
||||||
|
|
||||||
|
internal fun CoroutineScope.childScopeContext(
|
||||||
|
name: String? = null,
|
||||||
|
context: CoroutineContext = EmptyCoroutineContext
|
||||||
|
): CoroutineContext =
|
||||||
|
this.coroutineContext.overrideWithSupervisorJob(name) + context.let {
|
||||||
|
if (name != null) it + CoroutineName(name)
|
||||||
|
else it
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user