mirror of
https://github.com/mamoe/mirai.git
synced 2025-01-10 18:40:15 +08:00
Move Plugin.enable and Plugin.disable into PluginManager for a better java API.
This commit is contained in:
parent
c5389201e1
commit
7ecffb239d
@ -13,6 +13,7 @@ import kotlinx.coroutines.*
|
||||
import net.mamoe.mirai.console.MiraiConsole
|
||||
import net.mamoe.mirai.console.data.PluginDataStorage
|
||||
import net.mamoe.mirai.console.internal.MiraiConsoleImplementationBridge
|
||||
import net.mamoe.mirai.console.internal.data.createInstanceOrNull
|
||||
import net.mamoe.mirai.console.plugin.AbstractFilePluginLoader
|
||||
import net.mamoe.mirai.console.plugin.PluginLoadException
|
||||
import net.mamoe.mirai.console.plugin.jvm.JarPluginLoader
|
||||
@ -25,7 +26,6 @@ import net.mamoe.yamlkt.Yaml
|
||||
import java.io.File
|
||||
import java.net.URI
|
||||
import kotlin.coroutines.CoroutineContext
|
||||
import kotlin.reflect.full.createInstance
|
||||
|
||||
internal object JarPluginLoaderImpl :
|
||||
AbstractFilePluginLoader<JvmPlugin, JvmPluginDescription>(".jar"),
|
||||
@ -90,14 +90,14 @@ internal object JarPluginLoaderImpl :
|
||||
jarFile = file
|
||||
).kotlin.run {
|
||||
objectInstance
|
||||
?: kotlin.runCatching { createInstance() }.getOrNull()
|
||||
?: createInstanceOrNull()
|
||||
?: (java.constructors + java.declaredConstructors)
|
||||
.firstOrNull { it.parameterCount == 0 }
|
||||
?.apply { kotlin.runCatching { isAccessible = true } }
|
||||
?.newInstance()
|
||||
} ?: error("No Kotlin object or public no-arg constructor found")
|
||||
} ?: error("No Kotlin object or public no-arg constructor found for $mainClassName")
|
||||
|
||||
check(main is JvmPlugin) { "The main class of Jar plugin must extend JvmPlugin, recommending JavaPlugin or KotlinPlugin" }
|
||||
check(main is JvmPlugin) { "The main class of Jar plugin must extend JvmPlugin, recommended JavaPlugin or KotlinPlugin" }
|
||||
|
||||
if (main is JvmPluginInternal) {
|
||||
main._description = description
|
||||
@ -110,6 +110,7 @@ internal object JarPluginLoaderImpl :
|
||||
}
|
||||
|
||||
override fun enable(plugin: JvmPlugin) {
|
||||
if (plugin.isEnabled) throw IllegalStateException("Plugin is already enabled")
|
||||
ensureActive()
|
||||
if (plugin is JvmPluginInternal) {
|
||||
plugin.internalOnEnable()
|
||||
@ -117,6 +118,8 @@ internal object JarPluginLoaderImpl :
|
||||
}
|
||||
|
||||
override fun disable(plugin: JvmPlugin) {
|
||||
if (!plugin.isEnabled) throw IllegalStateException("Plugin is already disabled")
|
||||
|
||||
if (plugin is JvmPluginInternal) {
|
||||
plugin.internalOnDisable()
|
||||
} else plugin.onDisable()
|
||||
|
@ -16,10 +16,10 @@ import net.mamoe.mirai.console.MiraiConsole
|
||||
import net.mamoe.mirai.console.internal.data.mkdir
|
||||
import net.mamoe.mirai.console.plugin.Plugin
|
||||
import net.mamoe.mirai.console.plugin.PluginManager
|
||||
import net.mamoe.mirai.console.plugin.PluginManager.INSTANCE.safeLoader
|
||||
import net.mamoe.mirai.console.plugin.ResourceContainer.Companion.asResourceContainer
|
||||
import net.mamoe.mirai.console.plugin.jvm.JvmPlugin
|
||||
import net.mamoe.mirai.console.plugin.jvm.JvmPluginDescription
|
||||
import net.mamoe.mirai.console.plugin.safeLoader
|
||||
import net.mamoe.mirai.utils.MiraiLogger
|
||||
import java.io.InputStream
|
||||
import java.nio.file.Path
|
||||
|
@ -61,7 +61,7 @@ internal object PluginManagerImpl : PluginManager {
|
||||
|
||||
init {
|
||||
MiraiConsole.coroutineContext[Job]!!.invokeOnCompletion {
|
||||
plugins.forEach(Plugin::disable)
|
||||
plugins.forEach { it.disable() }
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -12,6 +12,8 @@
|
||||
package net.mamoe.mirai.console.plugin
|
||||
|
||||
import net.mamoe.mirai.console.command.CommandOwner
|
||||
import net.mamoe.mirai.console.plugin.PluginManager.INSTANCE.disable
|
||||
import net.mamoe.mirai.console.plugin.PluginManager.INSTANCE.enable
|
||||
import net.mamoe.mirai.console.plugin.dsecription.PluginDescription
|
||||
import net.mamoe.mirai.console.plugin.jvm.JvmPlugin
|
||||
import net.mamoe.mirai.console.util.ConsoleExperimentalAPI
|
||||
@ -21,6 +23,10 @@ import java.nio.file.Path
|
||||
/**
|
||||
* 表示一个 mirai-console 插件.
|
||||
*
|
||||
* @see PluginManager.enable 启用一个插件
|
||||
* @see PluginManager.disable 禁用一个插件
|
||||
* @see PluginManager.description 获取一个插件的 [描述][PluginDescription]
|
||||
*
|
||||
* @see PluginDescription 插件描述, 需由 [PluginLoader] 帮助提供([PluginLoader.description])
|
||||
* @see JvmPlugin Java, Kotlin 或其他 JVM 平台插件
|
||||
* @see PluginFileExtensions 支持文件系统存储的扩展
|
||||
@ -31,8 +37,8 @@ public interface Plugin : CommandOwner {
|
||||
/**
|
||||
* 判断此插件是否已启用
|
||||
*
|
||||
* @see disable 关闭这个插件
|
||||
* @see enable 启用这个插件
|
||||
* @see PluginManager.enable 启用一个插件
|
||||
* @see PluginManager.disable 禁用一个插件
|
||||
*/
|
||||
public val isEnabled: Boolean
|
||||
|
||||
@ -42,33 +48,6 @@ public interface Plugin : CommandOwner {
|
||||
public val loader: PluginLoader<*, *>
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取插件描述
|
||||
*/
|
||||
public val Plugin.description: PluginDescription get() = safeLoader.getDescription(this)
|
||||
|
||||
/**
|
||||
* 禁用这个插件
|
||||
*
|
||||
* @see PluginLoader.disable
|
||||
*/
|
||||
public fun Plugin.disable(): Unit = safeLoader.disable(this)
|
||||
|
||||
/**
|
||||
* 启用这个插件
|
||||
*
|
||||
* @see PluginLoader.enable
|
||||
*/
|
||||
public fun Plugin.enable(): Unit = safeLoader.enable(this)
|
||||
|
||||
/**
|
||||
* 经过泛型类型转换的 [PluginLoader]
|
||||
*/
|
||||
@get:JvmSynthetic
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
public inline val <P : Plugin> P.safeLoader: PluginLoader<P, PluginDescription>
|
||||
get() = this.loader as PluginLoader<P, PluginDescription>
|
||||
|
||||
/**
|
||||
* 支持文件系统存储的扩展.
|
||||
*
|
||||
|
@ -38,7 +38,7 @@ public interface PluginLoader<P : Plugin, D : PluginDescription> {
|
||||
*
|
||||
* 在 console 启动时, [PluginManager] 会获取所有 [PluginDescription], 分析依赖关系, 确认插件加载顺序.
|
||||
*
|
||||
* **实现细节:** 此函数只*应该*在 console 启动时被调用一次. 但取决于前端实现不同, 或可能由于被一些插件需要, 此函数也可能会被多次调用.
|
||||
* **实现细节:** 此函数*只应该*在 console 启动时被调用一次. 但取决于前端实现不同, 或由于被一些插件需要, 此函数也可能会被多次调用.
|
||||
*/
|
||||
public fun listPlugins(): List<D>
|
||||
|
||||
@ -52,6 +52,7 @@ public interface PluginLoader<P : Plugin, D : PluginDescription> {
|
||||
* @throws PluginLoadException 在加载插件遇到意料之中的错误时抛出 (如无法读取插件信息等).
|
||||
*
|
||||
* @see PluginDescription 插件描述
|
||||
* @see getDescription 无 receiver, 接受参数的版本.
|
||||
*/
|
||||
@get:JvmName("getPluginDescription")
|
||||
@get:Throws(PluginLoadException::class)
|
||||
@ -71,17 +72,53 @@ public interface PluginLoader<P : Plugin, D : PluginDescription> {
|
||||
/**
|
||||
* 启用这个插件.
|
||||
*
|
||||
* **实现约定**: 若插件已经启用, 抛出
|
||||
* **实现细节**: 此函数可抛出 [PluginLoadException] 作为正常失败原因, 其他任意异常都属于意外错误.
|
||||
* 当异常发生时, 插件将会直接被放弃加载, 并影响依赖它的其他插件.
|
||||
*
|
||||
* @throws IllegalStateException 当插件已经启用时抛出
|
||||
* @throws PluginLoadException 在加载插件遇到意料之中的错误时抛出 (如找不到主类等).
|
||||
*/
|
||||
@Throws(IllegalStateException::class, PluginLoadException::class)
|
||||
public fun enable(plugin: P)
|
||||
|
||||
/**
|
||||
* 禁用这个插件.
|
||||
*
|
||||
* **实现细节**: 此函数可抛出 [PluginLoadException] 作为正常失败原因, 其他任意异常都属于意外错误.
|
||||
* 当异常发生时, 插件将会直接被放弃加载, 并影响依赖它的其他插件.
|
||||
*
|
||||
* @throws IllegalStateException 当插件已经禁用时抛出
|
||||
* @throws PluginLoadException 在加载插件遇到意料之中的错误时抛出 (如找不到主类等).
|
||||
*/
|
||||
@Throws(IllegalStateException::class, PluginLoadException::class)
|
||||
public fun disable(plugin: P)
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取此插件的描述.
|
||||
*
|
||||
* **实现细节**: 此函数只允许抛出 [PluginLoadException] 作为正常失败原因, 其他任意异常都属于意外错误.
|
||||
*
|
||||
* 若在 console 启动并加载所有插件的过程中, 本函数抛出异常, 则会放弃此插件的加载, 并影响依赖它的其他插件.
|
||||
*
|
||||
* @throws PluginLoadException 在加载插件遇到意料之中的错误时抛出 (如无法读取插件信息等).
|
||||
*
|
||||
* @see PluginDescription 插件描述
|
||||
* @see PluginLoader.description
|
||||
*/
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
@JvmSynthetic
|
||||
public inline fun <D : PluginDescription, P : Plugin> PluginLoader<in P, out D>.getDescription(plugin: P): D =
|
||||
plugin.description
|
||||
|
||||
/**
|
||||
* 在加载插件过程中遇到的意料之中的问题.
|
||||
*
|
||||
* @see PluginLoader.load
|
||||
* @see PluginLoader.enable
|
||||
* @see PluginLoader.disable
|
||||
* @see PluginLoader.description
|
||||
*/
|
||||
public open class PluginLoadException : RuntimeException {
|
||||
public constructor() : super()
|
||||
public constructor(message: String?) : super(message)
|
||||
|
@ -89,11 +89,36 @@ public interface PluginManager {
|
||||
*/
|
||||
public val Plugin.description: PluginDescription
|
||||
|
||||
/**
|
||||
* 禁用这个插件
|
||||
*
|
||||
* @see PluginLoader.disable
|
||||
*/
|
||||
public fun Plugin.disable(): Unit = safeLoader.disable(this)
|
||||
|
||||
/**
|
||||
* 启用这个插件
|
||||
*
|
||||
* @see PluginLoader.enable
|
||||
*/
|
||||
public fun Plugin.enable(): Unit = safeLoader.enable(this)
|
||||
|
||||
/**
|
||||
* 经过泛型类型转换的 [PluginLoader]
|
||||
*/
|
||||
@get:JvmSynthetic
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
public val <P : Plugin> P.safeLoader: PluginLoader<P, PluginDescription>
|
||||
get() = this.loader as PluginLoader<P, PluginDescription>
|
||||
|
||||
public companion object INSTANCE : PluginManager by PluginManagerImpl {
|
||||
// due to Kotlin's bug
|
||||
public override val Plugin.description: PluginDescription get() = PluginManagerImpl.run { description }
|
||||
public override fun PluginLoader<*, *>.register(): Boolean = PluginManagerImpl.run { register() }
|
||||
public override fun PluginLoader<*, *>.unregister(): Boolean = PluginManagerImpl.run { unregister() }
|
||||
public override fun Plugin.disable(): Unit = PluginManagerImpl.run { disable() }
|
||||
public override fun Plugin.enable(): Unit = PluginManagerImpl.run { enable() }
|
||||
public override val <P : Plugin> P.safeLoader: PluginLoader<P, PluginDescription> get() = PluginManagerImpl.run { safeLoader }
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user