Rearrange implementations

This commit is contained in:
Him188 2020-05-25 18:09:20 +08:00
parent 8af7e0b925
commit 594ae1f778
13 changed files with 243 additions and 178 deletions

View File

@ -14,8 +14,8 @@ import kotlinx.coroutines.Job
import kotlinx.io.charsets.Charset
import net.mamoe.mirai.Bot
import net.mamoe.mirai.console.plugin.PluginLoader
import net.mamoe.mirai.console.plugin.builtin.JarPluginLoader
import net.mamoe.mirai.console.plugin.builtin.JvmPlugin
import net.mamoe.mirai.console.plugin.jvm.JarPluginLoader
import net.mamoe.mirai.console.plugin.jvm.JvmPlugin
import net.mamoe.mirai.console.setting.SettingStorage
import net.mamoe.mirai.utils.DefaultLogger
import net.mamoe.mirai.utils.MiraiExperimentalAPI

View File

@ -9,7 +9,7 @@
package net.mamoe.mirai.console.plugin
import net.mamoe.mirai.console.plugin.builtin.JvmPlugin
import net.mamoe.mirai.console.plugin.jvm.JvmPlugin
import java.io.File
/**

View File

@ -11,7 +11,7 @@
package net.mamoe.mirai.console.plugin
import net.mamoe.mirai.console.plugin.builtin.JarPluginLoader
import net.mamoe.mirai.console.plugin.jvm.JarPluginLoader
import java.io.File
/**

View File

@ -1,166 +0,0 @@
/*
* 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:Suppress("INVISIBLE_MEMBER", "INVISIBLE_REFERENCE", "EXPOSED_SUPER_CLASS")
package net.mamoe.mirai.console.plugin.builtin
import kotlinx.atomicfu.locks.withLock
import kotlinx.coroutines.*
import net.mamoe.mirai.console.MiraiConsole
import net.mamoe.mirai.console.plugin.Plugin
import net.mamoe.mirai.console.plugin.PluginLoader
import net.mamoe.mirai.console.plugin.PluginManager
import net.mamoe.mirai.console.setting.*
import net.mamoe.mirai.console.utils.JavaPluginScheduler
import net.mamoe.mirai.utils.MiraiLogger
import java.io.File
import java.util.*
import java.util.concurrent.locks.ReentrantLock
import kotlin.collections.AbstractCollection
import kotlin.coroutines.CoroutineContext
import kotlin.coroutines.EmptyCoroutineContext
import kotlin.reflect.KProperty
/**
* Java Kotlin Jar 插件
*
* @see JavaPlugin Java 插件
* @see KotlinPlugin Kotlin 插件
*/
interface JvmPlugin : Plugin, CoroutineScope {
/** 日志 */
val logger: MiraiLogger
/** 插件描述 */
val description: JvmPluginDescription
/** 所属插件加载器实例 */
override val loader: JarPluginLoader get() = JarPluginLoader
@JvmDefault
fun onLoad() {
}
@JvmDefault
fun onEnable() {
}
@JvmDefault
fun onDisable() {
}
}
/**
* [JavaPlugin] [KotlinPlugin] 的父类
*/
sealed class AbstractJvmPlugin(parentCoroutineContext: CoroutineContext) : JvmPluginImpl(parentCoroutineContext) {
abstract inner class PluginSetting : Setting() {
private val track =
@Suppress("LeakingThis")
loader.settingStorage.trackOn(this)
init {
this@AbstractJvmPlugin.job.invokeOnCompletion {
track.close()
}
}
override fun onElementChanged(value: Value<*>) {
TODO()
}
}
}
/**
* Java 插件的父类
*/
abstract class JavaPlugin @JvmOverloads constructor(
parentCoroutineContext: CoroutineContext = EmptyCoroutineContext
) : JvmPlugin, AbstractJvmPlugin(parentCoroutineContext) {
/**
* Java API Scheduler
*/
val scheduler: JavaPluginScheduler =
JavaPluginScheduler(this.coroutineContext)
}
/**
* Kotlin 插件的父类
*/
abstract class KotlinPlugin @JvmOverloads constructor(
parentCoroutineContext: CoroutineContext = EmptyCoroutineContext
) : JvmPlugin, AbstractJvmPlugin(parentCoroutineContext)
internal val <T> T.job: Job where T : CoroutineScope, T : Plugin get() = this.coroutineContext[Job]!!
internal sealed class JvmPluginImpl(
parentCoroutineContext: CoroutineContext
) : JvmPlugin, CoroutineScope {
// region JvmPlugin
/**
* Initialized immediately after construction of [JvmPluginImpl] instance
*/
@Suppress("PropertyName")
internal lateinit var _description: JvmPluginDescription
override val description: JvmPluginDescription get() = _description
final override val logger: MiraiLogger by lazy { MiraiConsole.newLogger(this._description.name) }
private var firstRun = true
override val dataFolder: File by lazy {
File(PluginManager.pluginsDataFolder, description.name).apply { mkdir() }
}
internal fun internalOnDisable() {
firstRun = false
this.onDisable()
}
internal fun internalOnLoad() {
this.onLoad()
}
internal fun internalOnEnable() {
if (!firstRun) refreshCoroutineContext()
this.onEnable()
}
// endregion
// region CoroutineScope
// for future use
@Suppress("PropertyName")
@JvmField
internal var _intrinsicCoroutineContext: CoroutineContext = EmptyCoroutineContext
@JvmField
internal val coroutineContextInitializer = {
CoroutineExceptionHandler { _, throwable -> logger.error(throwable) }
.plus(parentCoroutineContext)
.plus(SupervisorJob(parentCoroutineContext[Job])) + _intrinsicCoroutineContext
}
private fun refreshCoroutineContext(): CoroutineContext {
return coroutineContextInitializer().also { _coroutineContext = it }
}
private val contextUpdateLock: ReentrantLock = ReentrantLock()
private var _coroutineContext: CoroutineContext? = null
final override val coroutineContext: CoroutineContext
get() = _coroutineContext
?: contextUpdateLock.withLock { _coroutineContext ?: refreshCoroutineContext() }
// endregion
}

View File

@ -0,0 +1,102 @@
/*
* 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.plugin.internal
import kotlinx.atomicfu.locks.withLock
import kotlinx.coroutines.CoroutineExceptionHandler
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Job
import kotlinx.coroutines.SupervisorJob
import net.mamoe.mirai.console.MiraiConsole
import net.mamoe.mirai.console.plugin.Plugin
import net.mamoe.mirai.console.plugin.PluginManager
import net.mamoe.mirai.console.plugin.jvm.JvmPlugin
import net.mamoe.mirai.console.plugin.jvm.JvmPluginDescription
import net.mamoe.mirai.utils.MiraiLogger
import java.io.File
import java.util.concurrent.locks.ReentrantLock
import kotlin.coroutines.CoroutineContext
import kotlin.coroutines.EmptyCoroutineContext
internal val <T> T.job: Job where T : CoroutineScope, T : Plugin get() = this.coroutineContext[Job]!!
@PublishedApi
internal abstract class JvmPluginImpl(
parentCoroutineContext: CoroutineContext
) : JvmPlugin,
CoroutineScope {
// region JvmPlugin
/**
* Initialized immediately after construction of [JvmPluginImpl] instance
*/
@Suppress("PropertyName")
internal lateinit var _description: JvmPluginDescription
override val description: JvmPluginDescription get() = _description
final override val logger: MiraiLogger by lazy {
MiraiConsole.newLogger(
this._description.name
)
}
private var firstRun = true
override val dataFolder: File by lazy {
File(
PluginManager.pluginsDataFolder,
description.name
).apply { mkdir() }
}
internal fun internalOnDisable() {
firstRun = false
this.onDisable()
}
internal fun internalOnLoad() {
this.onLoad()
}
internal fun internalOnEnable() {
if (!firstRun) refreshCoroutineContext()
this.onEnable()
}
// endregion
// region CoroutineScope
// for future use
@Suppress("PropertyName")
@JvmField
internal var _intrinsicCoroutineContext: CoroutineContext =
EmptyCoroutineContext
@JvmField
internal val coroutineContextInitializer = {
CoroutineExceptionHandler { _, throwable -> logger.error(throwable) }
.plus(parentCoroutineContext)
.plus(SupervisorJob(parentCoroutineContext[Job])) + _intrinsicCoroutineContext
}
private fun refreshCoroutineContext(): CoroutineContext {
return coroutineContextInitializer().also { _coroutineContext = it }
}
private val contextUpdateLock: ReentrantLock =
ReentrantLock()
private var _coroutineContext: CoroutineContext? = null
final override val coroutineContext: CoroutineContext
get() = _coroutineContext
?: contextUpdateLock.withLock { _coroutineContext ?: refreshCoroutineContext() }
// endregion
}

View File

@ -7,7 +7,7 @@
* https://github.com/mamoe/mirai/blob/master/LICENSE
*/
package net.mamoe.mirai.console.plugin
package net.mamoe.mirai.console.plugin.internal
import net.mamoe.mirai.console.MiraiConsole
import java.io.File
@ -50,7 +50,13 @@ internal class PluginsLoader(private val parentClassLoader: ClassLoader) {
fun loadPluginMainClassByJarFile(pluginName: String, mainClass: String, jarFile: File): Class<*> {
try {
if (!pluginLoaders.containsKey(pluginName)) {
pluginLoaders[pluginName] = PluginClassLoader(pluginName, jarFile, this, parentClassLoader)
pluginLoaders[pluginName] =
PluginClassLoader(
pluginName,
jarFile,
this,
parentClassLoader
)
}
return pluginLoaders[pluginName]!!.loadClass(mainClass)
} catch (e: ClassNotFoundException) {

View File

@ -7,13 +7,14 @@
* https://github.com/mamoe/mirai/blob/master/LICENSE
*/
package net.mamoe.mirai.console.plugin.builtin
package net.mamoe.mirai.console.plugin.jvm
import kotlinx.coroutines.*
import net.mamoe.mirai.console.MiraiConsole
import net.mamoe.mirai.console.plugin.AbstractFilePluginLoader
import net.mamoe.mirai.console.plugin.PluginLoadException
import net.mamoe.mirai.console.plugin.PluginsLoader
import net.mamoe.mirai.console.plugin.internal.JvmPluginImpl
import net.mamoe.mirai.console.plugin.internal.PluginsLoader
import net.mamoe.mirai.console.setting.SettingStorage
import net.mamoe.mirai.utils.MiraiLogger
import net.mamoe.yamlkt.Yaml
@ -39,7 +40,8 @@ object JarPluginLoader : AbstractFilePluginLoader<JvmPlugin, JvmPluginDescriptio
}
private val supervisor: Job = coroutineContext[Job]!!
private val classLoader: PluginsLoader = PluginsLoader(this.javaClass.classLoader)
private val classLoader: PluginsLoader =
PluginsLoader(this.javaClass.classLoader)
init {
supervisor.invokeOnCompletion {

View File

@ -0,0 +1,31 @@
/*
* 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:Suppress("INVISIBLE_MEMBER", "INVISIBLE_REFERENCE", "EXPOSED_SUPER_CLASS")
package net.mamoe.mirai.console.plugin.jvm
import net.mamoe.mirai.console.plugin.internal.JvmPluginImpl
import net.mamoe.mirai.console.utils.JavaPluginScheduler
import kotlin.coroutines.CoroutineContext
import kotlin.coroutines.EmptyCoroutineContext
/**
* Java 插件的父类
*/
abstract class JavaPlugin @JvmOverloads constructor(
parentCoroutineContext: CoroutineContext = EmptyCoroutineContext
) : JvmPlugin, JvmPluginImpl(parentCoroutineContext) {
/**
* Java API Scheduler
*/
val scheduler: JavaPluginScheduler =
JavaPluginScheduler(this.coroutineContext)
}

View File

@ -0,0 +1,48 @@
/*
* 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:Suppress("INVISIBLE_MEMBER", "INVISIBLE_REFERENCE", "EXPOSED_SUPER_CLASS")
package net.mamoe.mirai.console.plugin.jvm
import kotlinx.coroutines.CoroutineScope
import net.mamoe.mirai.console.plugin.Plugin
import net.mamoe.mirai.utils.MiraiLogger
/**
* Java Kotlin Jar 插件
*
* @see JavaPlugin Java 插件
* @see KotlinPlugin Kotlin 插件
*/
interface JvmPlugin : Plugin, CoroutineScope {
/** 日志 */
val logger: MiraiLogger
/** 插件描述 */
val description: JvmPluginDescription
/** 所属插件加载器实例 */
override val loader: JarPluginLoader get() = JarPluginLoader
@JvmDefault
fun onLoad() {
}
@JvmDefault
fun onEnable() {
}
@JvmDefault
fun onDisable() {
}
}

View File

@ -7,7 +7,7 @@
* https://github.com/mamoe/mirai/blob/master/LICENSE
*/
package net.mamoe.mirai.console.plugin.builtin
package net.mamoe.mirai.console.plugin.jvm
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable

View File

@ -0,0 +1,42 @@
/*
* 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:Suppress("INVISIBLE_MEMBER", "INVISIBLE_REFERENCE", "EXPOSED_SUPER_CLASS")
package net.mamoe.mirai.console.plugin.jvm
import net.mamoe.mirai.console.plugin.internal.JvmPluginImpl
import net.mamoe.mirai.console.plugin.internal.job
import net.mamoe.mirai.console.setting.Setting
import net.mamoe.mirai.console.setting.Value
import kotlin.coroutines.CoroutineContext
import kotlin.coroutines.EmptyCoroutineContext
/**
* Kotlin 插件的父类
*/
abstract class KotlinPlugin @JvmOverloads constructor(
parentCoroutineContext: CoroutineContext = EmptyCoroutineContext
) : JvmPlugin, JvmPluginImpl(parentCoroutineContext) {
abstract inner class PluginSetting : Setting() {
private val track =
@Suppress("LeakingThis")
JarPluginLoader.settingStorage.trackOn(this)
init {
this@KotlinPlugin.job.invokeOnCompletion {
track.close()
}
}
override fun onElementChanged(value: Value<*>) {
TODO()
}
}
}

View File

@ -11,7 +11,7 @@ package net.mamoe.mirai.console.utils
import kotlinx.coroutines.*
import kotlinx.coroutines.future.future
import net.mamoe.mirai.console.plugin.builtin.JavaPlugin
import net.mamoe.mirai.console.plugin.jvm.JavaPlugin
import java.util.concurrent.Callable
import java.util.concurrent.CompletableFuture
import java.util.concurrent.Future

View File

@ -12,7 +12,7 @@
package net.mamoe.mirai.console.command
import net.mamoe.mirai.Bot
import net.mamoe.mirai.console.plugin.builtin.KotlinPlugin
import net.mamoe.mirai.console.plugin.jvm.KotlinPlugin
import net.mamoe.mirai.console.setting.value
import net.mamoe.mirai.message.data.*
import org.junit.jupiter.api.Test