Merge remote-tracking branch 'origin/reborn' into reborn

# Conflicts:
#	backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/command/Command.kt
This commit is contained in:
jiahua.liu 2020-05-26 17:02:06 +08:00
commit b66142545c
31 changed files with 887 additions and 350 deletions

View File

@ -3,10 +3,10 @@ package net.mamoe.n;
import com.google.gson.JsonObject; import com.google.gson.JsonObject;
import com.google.gson.JsonParser; import com.google.gson.JsonParser;
import net.mamoe.mirai.console.command.*; import net.mamoe.mirai.console.command.*;
import net.mamoe.mirai.console.plugins.Config; import net.mamoe.mirai.console.plugin.Config;
import net.mamoe.mirai.console.plugins.ConfigSection; import net.mamoe.mirai.console.plugin.ConfigSection;
import net.mamoe.mirai.console.plugins.ConfigSectionFactory; import net.mamoe.mirai.console.plugin.ConfigSectionFactory;
import net.mamoe.mirai.console.plugins.PluginBase; import net.mamoe.mirai.console.plugin.PluginBase;
import net.mamoe.mirai.console.utils.Utils; import net.mamoe.mirai.console.utils.Utils;
import net.mamoe.mirai.message.GroupMessage; import net.mamoe.mirai.message.GroupMessage;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;

View File

@ -101,7 +101,11 @@ fun genAllValueUseSite(): String = buildString {
require(this::class != default::class) { require(this::class != default::class) {
"Recursive nesting is prohibited" "Recursive nesting is prohibited"
} }
return valueImpl(default) return valueImpl(default).also {
if (default is Setting.NestedSetting) {
default.attachedValue = it
}
}
} }
inline fun <T : Setting> Setting.value(default: T, crossinline initializer: T.() -> Unit): Value<T> = inline fun <T : Setting> Setting.value(default: T, crossinline initializer: T.() -> Unit): Value<T> =

View File

@ -110,7 +110,7 @@ fun genAllValueImpl(): String = buildString {
): Mutable${number}${collectionName}Value { ): Mutable${number}${collectionName}Value {
var internalValue: Mutable${collectionName}<${number}> = default var internalValue: Mutable${collectionName}<${number}> = default
val delegt = dynamicMutable${collectionName}{ internalValue } val delegt = dynamicMutable${collectionName} { internalValue }
return object : Mutable${number}${collectionName}Value(), Mutable${collectionName}<${number}> by delegt { return object : Mutable${number}${collectionName}Value(), Mutable${collectionName}<${number}> by delegt {
override var value: Mutable${collectionName}<${number}> override var value: Mutable${collectionName}<${number}>
get() = internalValue get() = internalValue
@ -125,10 +125,10 @@ fun genAllValueImpl(): String = buildString {
override val serializer: KSerializer<Mutable${collectionName}<${number}>> = object : KSerializer<Mutable${collectionName}<${number}>> { override val serializer: KSerializer<Mutable${collectionName}<${number}>> = object : KSerializer<Mutable${collectionName}<${number}>> {
private val delegate = ${collectionName}Serializer(${number}.serializer()) private val delegate = ${collectionName}Serializer(${number}.serializer())
override val descriptor: SerialDescriptor = delegate.descriptor override val descriptor: SerialDescriptor get() = delegate.descriptor
override fun deserialize(decoder: Decoder): Mutable${collectionName}<${number}> { override fun deserialize(decoder: Decoder): Mutable${collectionName}<${number}> {
return delegate.deserialize(decoder).toMutable${collectionName}().observable { return delegate.deserialize(decoder).toMutable${collectionName}().observable {
onElementChanged(outerThis) onElementChanged(outerThis)
} }
} }
@ -208,7 +208,7 @@ fun genPrimitiveValueImpl(
""".trim() """.trim()
} }
} }
override val serializer = $serializer override val serializer get() = $serializer
} }
} }
""".trimIndent() + "\n" """.trimIndent() + "\n"
@ -244,7 +244,7 @@ fun genCollectionValueImpl(
""".trim() """.trim()
} }
} }
override val serializer = $serializer override val serializer get() = $serializer
} }
} }
""".trimIndent() + "\n" """.trimIndent() + "\n"

View File

@ -0,0 +1,139 @@
package net.mamoe.mirai.console.command;
import kotlin.NotImplementedError;
import kotlin.coroutines.EmptyCoroutineContext;
import kotlinx.coroutines.BuildersKt;
import kotlinx.coroutines.CoroutineScope;
import kotlinx.coroutines.CoroutineStart;
import kotlinx.coroutines.future.FutureKt;
import net.mamoe.mirai.console.plugin.jvm.JavaPlugin;
import net.mamoe.mirai.message.data.Message;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.CompletableFuture;
/**
* Java 适配的 {@link CommandManagerKt}
*/
@SuppressWarnings("unused")
public final class JCommandManager {
private JCommandManager() {
throw new NotImplementedError();
}
/**
* 获取指令前缀
*
* @return 指令前缀
*/
@NotNull
public static String getCommandPrefix() {
return CommandManagerKt.getCommandPrefix();
}
/**
* 获取一个指令所有者已经注册了的指令列表.
*
* @param owner 指令所有者
* @return 指令列表
*/
@NotNull
public static List<@NotNull Command> getRegisteredCommands(final @NotNull CommandOwner owner) {
return CommandManagerKt.getRegisteredCommands(Objects.requireNonNull(owner, "owner"));
}
/**
* 注册一个指令.
*
* @param command 指令实例
* @param override 是否覆盖重名指令.
* <p>
* 若原有指令 P, {@link Command#getNames()} 'a', 'b', 'c'. <br>
* 新指令 Q, {@link Command#getNames()} 'b', 将会覆盖原指令 A 注册的 'b'.
* <p>
* 即注册完成后, 'a' 'c' 将会解析到指令 P, 'b' 会解析到指令 Q.
* @return 若已有重名指令, <code>override</code> <code>false</code>, 返回 <code>false</code>; <br>
* 若已有重名指令, <code>override</code> <code>true</code>, 覆盖原有指令并返回 <code>true</code>.
*/
public static boolean register(final @NotNull Command command, final boolean override) {
Objects.requireNonNull(command, "command");
return CommandManagerKt.register(command, override);
}
/**
* 注册一个指令, 已有重复名称的指令时返回 <code>false</code>
*
* @param command 指令实例
* @return 若已有重名指令, 返回 <code>false</code>, 否则返回 <code>true</code>.
*/
public static boolean register(final @NotNull Command command) {
Objects.requireNonNull(command, "command");
return register(command, false);
}
/**
* 查找并返回重名的指令. 返回重名指令.
*/
@Nullable
public static Command findDuplicate(final @NotNull Command command) {
Objects.requireNonNull(command, "command");
return CommandManagerKt.findDuplicate(command);
}
/**
* 取消注册这个指令. 若指令未注册, 返回 <code>false</code>.
*/
public static boolean unregister(final @NotNull Command command) {
Objects.requireNonNull(command, "command");
return CommandManagerKt.unregister(command);
}
/**
* 取消注册所有属于 <code>owner</code> 的指令
*
* @param owner 指令所有者
*/
public static void unregisterAllCommands(final @NotNull CommandOwner owner) {
Objects.requireNonNull(owner, "owner");
CommandManagerKt.unregisterAllCommands(owner);
}
/**
* 解析并执行一个指令
*
* @param args 接受 {@link String} {@link Message} , 其他对象将会被 {@link Object#toString()}
* @return 是否成功解析到指令. 返回 `false` 代表无任何指令匹配
* @see #executeCommandAsync(CoroutineScope, CommandSender, Object...)
*/
public static boolean executeCommand(final @NotNull CommandSender sender, final @NotNull Object... args) throws InterruptedException {
Objects.requireNonNull(sender, "sender");
Objects.requireNonNull(args, "args");
for (Object arg : args) {
Objects.requireNonNull(arg, "element of args");
}
return BuildersKt.runBlocking(EmptyCoroutineContext.INSTANCE, (scope, completion) -> CommandManagerKt.executeCommand(sender, args, completion));
}
/**
* 异步 ( Kotlin 协程线程池) 解析并执行一个指令
*
* @param scope 协程作用域 (用于管理协程生命周期). 一般填入 {@link JavaPlugin} 实例.
* @param args 接受 {@link String} {@link Message} , 其他对象将会被 {@link Object#toString()}
* @return 是否成功解析到指令. 返回 `false` 代表无任何指令匹配
* @see #executeCommand(CommandSender, Object...)
*/
public static CompletableFuture<Boolean> executeCommandAsync(final @NotNull CoroutineScope scope, final @NotNull CommandSender sender, final @NotNull Object... args) {
Objects.requireNonNull(sender, "sender");
Objects.requireNonNull(args, "args");
Objects.requireNonNull(scope, "scope");
for (Object arg : args) {
Objects.requireNonNull(arg, "element of args");
}
return FutureKt.future(scope, EmptyCoroutineContext.INSTANCE, CoroutineStart.DEFAULT, (sc, completion) -> CommandManagerKt.executeCommand(sender, args, completion));
}
}

View File

@ -25,7 +25,7 @@ public class BotManager {
} }
public static List<Long> getManagers(Bot bot) { public static List<Long> getManagers(Bot bot) {
return BotHelperKt.getBotManagers(bot); return BotManagers.getManagers(bot);
} }
public static boolean isManager(Bot bot, long target) { public static boolean isManager(Bot bot, long target) {

View File

@ -13,8 +13,11 @@ import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Job import kotlinx.coroutines.Job
import kotlinx.io.charsets.Charset import kotlinx.io.charsets.Charset
import net.mamoe.mirai.Bot import net.mamoe.mirai.Bot
import net.mamoe.mirai.console.plugins.PluginLoader import net.mamoe.mirai.console.plugin.PluginLoader
import net.mamoe.mirai.console.plugins.builtin.JarPluginLoader 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.console.setting.internal.ConsoleBuiltInSetting
import net.mamoe.mirai.utils.DefaultLogger import net.mamoe.mirai.utils.DefaultLogger
import net.mamoe.mirai.utils.MiraiExperimentalAPI import net.mamoe.mirai.utils.MiraiExperimentalAPI
import net.mamoe.mirai.utils.MiraiLogger import net.mamoe.mirai.utils.MiraiLogger
@ -34,14 +37,48 @@ object MiraiConsole : CoroutineScope, IMiraiConsole {
this.instance = instance this.instance = instance
} }
override val build: String get() = instance.build /**
override val version: String get() = instance.version * `mirai-console` build
*/
@MiraiExperimentalAPI
override val build: String
get() = instance.build
/**
* `mirai-console` 版本
*/
@MiraiExperimentalAPI
override val version: String
get() = instance.version
/**
* Console 运行路径
*/
override val rootDir: File get() = instance.rootDir override val rootDir: File get() = instance.rootDir
/**
* Console 前端接口
*/
override val frontEnd: MiraiConsoleFrontEnd get() = instance.frontEnd override val frontEnd: MiraiConsoleFrontEnd get() = instance.frontEnd
override val mainLogger: MiraiLogger get() = instance.mainLogger
/**
* 与前端交互所使用的 Logger
*/
@MiraiExperimentalAPI
override val mainLogger: MiraiLogger
get() = instance.mainLogger
override val coroutineContext: CoroutineContext get() = instance.coroutineContext override val coroutineContext: CoroutineContext get() = instance.coroutineContext
override val builtInPluginLoaders: List<PluginLoader<*, *>> = instance.builtInPluginLoaders override val builtInPluginLoaders: List<PluginLoader<*, *>> get() = instance.builtInPluginLoaders
@Suppress("CANNOT_WEAKEN_ACCESS_PRIVILEGE")
internal override val jvmSettingStorage: SettingStorage
get() = instance.jvmSettingStorage
@Suppress("CANNOT_WEAKEN_ACCESS_PRIVILEGE")
override val consoleBuiltIntSettingStorage: SettingStorage
get() = instance.consoleBuiltIntSettingStorage
init { init {
DefaultLogger = { identity -> this.newLogger(identity) } DefaultLogger = { identity -> this.newLogger(identity) }
@ -79,6 +116,16 @@ internal interface IMiraiConsole : CoroutineScope {
* 内建加载器列表, 一般需要包含 [JarPluginLoader] * 内建加载器列表, 一般需要包含 [JarPluginLoader]
*/ */
val builtInPluginLoaders: List<PluginLoader<*, *>> val builtInPluginLoaders: List<PluginLoader<*, *>>
/**
* 内建的供 [JvmPlugin] 使用的 [SettingStorage]
*/
val jvmSettingStorage: SettingStorage
/**
* 内建的供 [ConsoleBuiltInSetting] 使用的 [SettingStorage]
*/
val consoleBuiltIntSettingStorage: SettingStorage
} }
/** /**

View File

@ -12,13 +12,8 @@
package net.mamoe.mirai.console.command package net.mamoe.mirai.console.command
import net.mamoe.mirai.console.command.description.* import net.mamoe.mirai.console.command.description.*
import net.mamoe.mirai.console.command.description.CommandParam
import net.mamoe.mirai.console.command.description.CommandParserContext
import net.mamoe.mirai.console.command.description.EmptyCommandParserContext
import net.mamoe.mirai.console.command.description.plus
import net.mamoe.mirai.message.data.PlainText import net.mamoe.mirai.message.data.PlainText
import net.mamoe.mirai.message.data.SingleMessage import net.mamoe.mirai.message.data.SingleMessage
import java.lang.Exception
import kotlin.reflect.KAnnotatedElement import kotlin.reflect.KAnnotatedElement
import kotlin.reflect.KClass import kotlin.reflect.KClass
import kotlin.reflect.full.* import kotlin.reflect.full.*
@ -29,20 +24,37 @@ import kotlin.reflect.full.*
* @see register 注册这个指令 * @see register 注册这个指令
*/ */
interface Command { interface Command {
/**
* 指令名. 需要至少有一个元素. 所有元素都不能带有空格
*/
val names: Array<out String> val names: Array<out String>
fun getPrimaryName():String = names[0]
val usage: String val usage: String
val description: String val description: String
/**
* 指令权限
*/
val permission: CommandPermission val permission: CommandPermission
/**
* `true` 时表示 [指令前缀][CommandPrefix] 可选
*/
val prefixOptional: Boolean val prefixOptional: Boolean
val owner: CommandOwner val owner: CommandOwner
/**
* @param args 指令参数. 可能是 [SingleMessage] [String]. 且已经以 ' ' 分割.
*/
suspend fun onCommand(sender: CommandSender, args: Array<out Any>) suspend fun onCommand(sender: CommandSender, args: Array<out Any>)
} }
/**
* 主要指令名. [Command.names] 的第一个元素.
*/
val Command.primaryName: String get() = names[0]
/** /**
* 功能最集中的Commend * 功能最集中的Commend
* 支持且只支持有sub的指令 * 支持且只支持有sub的指令
@ -55,20 +67,26 @@ interface Command {
abstract class CompositeCommand @JvmOverloads constructor( abstract class CompositeCommand @JvmOverloads constructor(
override val owner: CommandOwner, override val owner: CommandOwner,
vararg names: String, vararg names: String,
override val description: String = "no description available", description: String = "no description available",
override val permission: CommandPermission = CommandPermission.Default, override val permission: CommandPermission = CommandPermission.Default,
override val prefixOptional: Boolean = false, override val prefixOptional: Boolean = false,
overrideContext: CommandParserContext = EmptyCommandParserContext overrideContext: CommandParserContext = EmptyCommandParserContext
) : Command { ) : Command {
override val description = description.trimIndent()
class IllegalParameterException(message:String): Exception(message)
override val names: Array<out String> = override val names: Array<out String> =
names.map(String::trim).filterNot(String::isEmpty).map(String::toLowerCase).toTypedArray() names.map(String::trim).filterNot(String::isEmpty).map(String::toLowerCase).also { list ->
list.firstOrNull { !it.isValidSubName() }?.let {
error("Name is not valid: $it")
}
}.toTypedArray()
/**
* [CommandArgParser] 的环境
*/
val context: CommandParserContext = CommandParserContext.Builtins + overrideContext val context: CommandParserContext = CommandParserContext.Builtins + overrideContext
override lateinit var usage: String override var usage: String = "<command build failed>" // initialized by subCommand reflection
internal set
/** 指定子指令要求的权限 */ /** 指定子指令要求的权限 */
@Retention(AnnotationRetention.RUNTIME) @Retention(AnnotationRetention.RUNTIME)
@ -107,6 +125,9 @@ abstract class CompositeCommand @JvmOverloads constructor(
) )
} }
class IllegalParameterException internal constructor(message: String) : Exception(message)
internal val subCommands: Array<SubCommandDescriptor> by lazy { internal val subCommands: Array<SubCommandDescriptor> by lazy {
val buildUsage = StringBuilder(this.description).append(": \n") val buildUsage = StringBuilder(this.description).append(": \n")
@ -117,7 +138,7 @@ abstract class CompositeCommand @JvmOverloads constructor(
val overridePermission = function.findAnnotation<Permission>()//optional val overridePermission = function.findAnnotation<Permission>()//optional
val subDescription = function.findAnnotation<Description>()?.description?:"no description available" val subDescription = function.findAnnotation<Description>()?.description?:"no description available"
if((function.returnType.classifier as? KClass<*>)?.isSubclassOf(Boolean::class) != true){ if ((function.returnType.classifier as? KClass<*>)?.isSubclassOf(Boolean::class) != true) {
throw IllegalParameterException("Return Type of SubCommand must be Boolean") throw IllegalParameterException("Return Type of SubCommand must be Boolean")
} }
@ -126,7 +147,7 @@ abstract class CompositeCommand @JvmOverloads constructor(
throw IllegalParameterException("First parameter (receiver for kotlin) for sub commend " + function.name + " from " + this.getPrimaryName() + " should be <out CommandSender>") throw IllegalParameterException("First parameter (receiver for kotlin) for sub commend " + function.name + " from " + this.getPrimaryName() + " should be <out CommandSender>")
} }
if(notStatic){ if (notStatic) {
parameter.removeAt(0) parameter.removeAt(0)
} }
@ -136,12 +157,12 @@ abstract class CompositeCommand @JvmOverloads constructor(
((receiver.type.classifier as? KClass<*>).also { print(it) } ((receiver.type.classifier as? KClass<*>).also { print(it) }
?.isSubclassOf(CommandSender::class) != true) ?.isSubclassOf(CommandSender::class) != true)
) { ) {
throw IllegalParameterException("First parameter (receiver for kotlin) for sub commend " + function.name + " from " + this.getPrimaryName() + " should be <out CommandSender>") throw IllegalParameterException("First parameter (receiver for kotlin) for sub commend " + function.name + " from " + this.primaryName + " should be <out CommandSender>")
} }
} }
val commandName = function.findAnnotation<SubCommand>()!!.name.map { val commandName = function.findAnnotation<SubCommand>()!!.name.map {
if(!it.isValidSubName()){ if (!it.isValidSubName()) {
error("SubName $it is not valid") error("SubName $it is not valid")
} }
it it
@ -149,20 +170,22 @@ abstract class CompositeCommand @JvmOverloads constructor(
//map parameter //map parameter
val parms = parameter.map { val parms = parameter.map {
buildUsage.append("/" + getPrimaryName() + " ") buildUsage.append("/$primaryName ")
if(it.isVararg){ if (it.isVararg) {
throw IllegalParameterException("parameter for sub commend " + function.name + " from " + this.getPrimaryName() + " should not be var arg") throw IllegalParameterException("parameter for sub commend " + function.name + " from " + this.primaryName + " should not be var arg")
} }
if(it.isOptional){ if (it.isOptional) {
throw IllegalParameterException("parameter for sub commend " + function.name + " from " + this.getPrimaryName() + " should not be var optional") throw IllegalParameterException("parameter for sub commend " + function.name + " from " + this.primaryName + " should not be var optional")
} }
val argName = it.findAnnotation<Name>()?.name?:it.name?:"unknown" val argName = it.findAnnotation<Name>()?.name ?: it.name ?: "unknown"
buildUsage.append("<").append(argName).append("> ") buildUsage.append("<").append(argName).append("> ").append(" ")
CommandParam( CommandParam(
argName, argName,
(it.type.classifier as? KClass<*>)?: throw IllegalParameterException("unsolved type reference from param " + it.name + " in " + function.name + " from " + this.getPrimaryName())) (it.type.classifier as? KClass<*>)
?: throw IllegalParameterException("unsolved type reference from param " + it.name + " in " + function.name + " from " + this.primaryName)
)
}.toTypedArray() }.toTypedArray()
buildUsage.append(subDescription).append("\n") buildUsage.append(subDescription).append("\n")
@ -173,9 +196,9 @@ abstract class CompositeCommand @JvmOverloads constructor(
subDescription, subDescription,
overridePermission?.permission?.getInstance() ?: permission, overridePermission?.permission?.getInstance() ?: permission,
onCommand = block { sender: CommandSender, args: Array<out Any> -> onCommand = block { sender: CommandSender, args: Array<out Any> ->
if(notStatic) { if (notStatic) {
function.callSuspend(this,sender, *args) as Boolean function.callSuspend(this, sender, *args) as Boolean
}else{ } else {
function.callSuspend(sender, *args) as Boolean function.callSuspend(sender, *args) as Boolean
} }
} }
@ -306,7 +329,7 @@ internal fun Any.flattenCommandComponents(): ArrayList<Any> {
internal inline fun <reified T : Annotation> KAnnotatedElement.hasAnnotation(): Boolean = internal inline fun <reified T : Annotation> KAnnotatedElement.hasAnnotation(): Boolean =
findAnnotation<T>() != null findAnnotation<T>() != null
internal inline fun <T:Any> KClass<out T>.getInstance():T { internal inline fun <T : Any> KClass<out T>.getInstance(): T {
return this.objectInstance ?: this.createInstance() return this.objectInstance ?: this.createInstance()
} }

View File

@ -8,34 +8,66 @@
*/ */
@file:Suppress("NOTHING_TO_INLINE", "unused") @file:Suppress("NOTHING_TO_INLINE", "unused")
@file:JvmName("CommandManager") @file:JvmName("CommandManagerKt")
package net.mamoe.mirai.console.command package net.mamoe.mirai.console.command
import kotlinx.atomicfu.locks.withLock import kotlinx.atomicfu.locks.withLock
import net.mamoe.mirai.console.plugins.Plugin import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Job
import net.mamoe.mirai.console.plugin.Plugin
import net.mamoe.mirai.message.data.Message import net.mamoe.mirai.message.data.Message
import net.mamoe.mirai.message.data.MessageChain import net.mamoe.mirai.message.data.MessageChain
import net.mamoe.mirai.message.data.SingleMessage import net.mamoe.mirai.message.data.SingleMessage
import net.mamoe.mirai.utils.MiraiInternalAPI
/**
* 指令的所有者.
* @see PluginCommandOwner
*/
sealed class CommandOwner sealed class CommandOwner
@MiraiInternalAPI
object TestCommandOwner : CommandOwner() object TestCommandOwner : CommandOwner()
abstract class PluginCommandOwner(val plugin: Plugin) : CommandOwner() /**
* 插件指令所有者. 插件只能通过 [PluginCommandOwner] 管理指令.
*/
abstract class PluginCommandOwner(val plugin: Plugin) : CommandOwner() {
init {
if (plugin is CoroutineScope) { // JVM Plugin
plugin.coroutineContext[Job]?.invokeOnCompletion {
this.unregisterAllCommands()
}
}
}
}
// 由前端实现 /**
* 代表控制台所有者. 所有的 mirai-console 内建的指令都属于 [ConsoleCommandOwner].
*
* 由前端实现
*/
internal abstract class ConsoleCommandOwner : CommandOwner() internal abstract class ConsoleCommandOwner : CommandOwner()
/** /**
* 获取已经注册了的指令列表 * 获取已经注册了的属于这个 [CommandOwner] 的指令列表.
* @see JCommandManager.getRegisteredCommands Java 方法
*/ */
val CommandOwner.registeredCommands: List<Command> get() = InternalCommandManager.registeredCommands.filter { it.owner == this } val CommandOwner.registeredCommands: List<Command> get() = InternalCommandManager.registeredCommands.filter { it.owner == this }
/**
* 指令前缀, '/'
* @see JCommandManager.getCommandPrefix Java 方法
*/
@get:JvmName("getCommandPrefix") @get:JvmName("getCommandPrefix")
val CommandPrefix: String val CommandPrefix: String
get() = InternalCommandManager.COMMAND_PREFIX get() = InternalCommandManager.COMMAND_PREFIX
/**
* 取消注册所有属于 [this] 的指令
* @see JCommandManager.unregisterAllCommands Java 方法
*/
fun CommandOwner.unregisterAllCommands() { fun CommandOwner.unregisterAllCommands() {
for (registeredCommand in registeredCommands) { for (registeredCommand in registeredCommands) {
registeredCommand.unregister() registeredCommand.unregister()
@ -43,10 +75,26 @@ fun CommandOwner.unregisterAllCommands() {
} }
/** /**
* 注册一个指令. 若此指令已经注册或有已经注册的指令与 [SubCommandDescriptor] 重名, 返回 `false` * 注册一个指令.
*
* @param override 是否覆盖重名指令.
*
* 若原有指令 P, [Command.names] 'a', 'b', 'c'.
* 新指令 Q, [Command.names] 'b', 将会覆盖原指令 A 注册的 'b'.
*
* 即注册完成后, 'a' 'c' 将会解析到指令 P, 'b' 会解析到指令 Q.
*
* @return
* 若已有重名指令, [override] `false`, 返回 `false`;
* 若已有重名指令, [override] `true`, 覆盖原有指令并返回 `true`.
*
* @see JCommandManager.register Java 方法
*/ */
fun Command.register(): Boolean = InternalCommandManager.modifyLock.withLock { @JvmOverloads
if (findDuplicate() != null) return false fun Command.register(override: Boolean = false): Boolean = InternalCommandManager.modifyLock.withLock {
if (!override) {
if (findDuplicate() != null) return false
}
InternalCommandManager.registeredCommands.add(this@register) InternalCommandManager.registeredCommands.add(this@register)
if (this.prefixOptional) { if (this.prefixOptional) {
for (name in this.names) { for (name in this.names) {
@ -54,6 +102,7 @@ fun Command.register(): Boolean = InternalCommandManager.modifyLock.withLock {
} }
} else { } else {
for (name in this.names) { for (name in this.names) {
InternalCommandManager.optionalPrefixCommandMap.remove(name) // ensure resolution consistency
InternalCommandManager.requiredPrefixCommandMap[name] = this InternalCommandManager.requiredPrefixCommandMap[name] = this
} }
} }
@ -61,13 +110,17 @@ fun Command.register(): Boolean = InternalCommandManager.modifyLock.withLock {
} }
/** /**
* 查找是否有重名的指令. 返回重名的指令. * 查找并返回重名的指令. 返回重名指令.
*
* @see JCommandManager.findDuplicate Java 方法
*/ */
fun Command.findDuplicate(): Command? = fun Command.findDuplicate(): Command? =
InternalCommandManager.registeredCommands.firstOrNull { it.names intersects this.names } InternalCommandManager.registeredCommands.firstOrNull { it.names intersects this.names }
/** /**
* 取消注册这个指令. 若指令未注册, 返回 `false` * 取消注册这个指令. 若指令未注册, 返回 `false`.
*
* @see JCommandManager.unregister Java 方法
*/ */
fun Command.unregister(): Boolean = InternalCommandManager.modifyLock.withLock { fun Command.unregister(): Boolean = InternalCommandManager.modifyLock.withLock {
InternalCommandManager.registeredCommands.remove(this) InternalCommandManager.registeredCommands.remove(this)
@ -78,8 +131,12 @@ fun Command.unregister(): Boolean = InternalCommandManager.modifyLock.withLock {
/** /**
* 解析并执行一个指令 * 解析并执行一个指令
* *
* Java 调用方式: `<static> CommandManager.executeCommand(Command)`
*
* @param messages 接受 [String] [Message], 其他对象将会被 [Any.toString] * @param messages 接受 [String] [Message], 其他对象将会被 [Any.toString]
* @return 是否成功解析到指令. 返回 `false` 代表无任何指令匹配 * @return 是否成功解析到指令. 返回 `false` 代表无任何指令匹配
*
* @see JCommandManager.executeCommand Java 方法
*/ */
suspend fun CommandSender.executeCommand(vararg messages: Any): Boolean { suspend fun CommandSender.executeCommand(vararg messages: Any): Boolean {
if (messages.isEmpty()) return false if (messages.isEmpty()) return false
@ -88,17 +145,21 @@ suspend fun CommandSender.executeCommand(vararg messages: Any): Boolean {
messages[0].let { if (it is SingleMessage) it.toString() else it.toString().substringBefore(' ') }) messages[0].let { if (it is SingleMessage) it.toString() else it.toString().substringBefore(' ') })
} }
@JvmSynthetic
internal inline fun <reified T> List<T>.dropToTypedArray(n: Int): Array<T> = Array(size - n) { this[n + it] } internal inline fun <reified T> List<T>.dropToTypedArray(n: Int): Array<T> = Array(size - n) { this[n + it] }
/** /**
* 解析并执行一个指令 * 解析并执行一个指令
* @return 是否成功解析到指令. 返回 `false` 代表无任何指令匹配 * @return 是否成功解析到指令. 返回 `false` 代表无任何指令匹配
*
* @see JCommandManager.executeCommand Java 方法
*/ */
suspend fun CommandSender.executeCommand(message: MessageChain): Boolean { suspend fun CommandSender.executeCommand(message: MessageChain): Boolean {
if (message.isEmpty()) return false if (message.isEmpty()) return false
return executeCommandInternal(message, message[0].toString()) return executeCommandInternal(message, message[0].toString())
} }
@JvmSynthetic
internal suspend inline fun CommandSender.executeCommandInternal( internal suspend inline fun CommandSender.executeCommandInternal(
messages: Any, messages: Any,
commandName: String commandName: String

View File

@ -7,22 +7,26 @@
* https://github.com/mamoe/mirai/blob/master/LICENSE * https://github.com/mamoe/mirai/blob/master/LICENSE
*/ */
@file:Suppress("NOTHING_TO_INLINE") @file:Suppress("NOTHING_TO_INLINE", "INAPPLICABLE_JVM_NAME")
package net.mamoe.mirai.console.command package net.mamoe.mirai.console.command
import kotlinx.coroutines.runBlocking import kotlinx.coroutines.runBlocking
import net.mamoe.mirai.Bot import net.mamoe.mirai.Bot
import net.mamoe.mirai.console.MiraiConsole
import net.mamoe.mirai.console.utils.JavaFriendlyAPI
import net.mamoe.mirai.contact.* import net.mamoe.mirai.contact.*
import net.mamoe.mirai.message.MessageEvent import net.mamoe.mirai.message.MessageEvent
import net.mamoe.mirai.message.data.Message import net.mamoe.mirai.message.data.Message
import net.mamoe.mirai.message.data.PlainText import net.mamoe.mirai.message.data.PlainText
import org.jetbrains.annotations.Contract
/** /**
* 指令发送者 * 指令发送者
* *
* @see AbstractCommandSender 请继承于该抽象类 * @see AbstractCommandSender 请继承于该抽象类
*/ */
@Suppress("FunctionName")
interface CommandSender { interface CommandSender {
/** /**
* 与这个 [CommandSender] 相关的 [Bot]. 当通过控制台执行时为 null. * 与这个 [CommandSender] 相关的 [Bot]. 当通过控制台执行时为 null.
@ -32,15 +36,18 @@ interface CommandSender {
/** /**
* 立刻发送一条消息 * 立刻发送一条消息
*/ */
@JvmSynthetic
suspend fun sendMessage(message: Message) suspend fun sendMessage(message: Message)
/** @JvmDefault
* 写入要发送的内容 所有内容最后会被以一条发出 @JavaFriendlyAPI
*/ @JvmName("sendMessage")
fun appendMessage(message: String) fun __sendMessageBlocking(messageChain: Message) = runBlocking { sendMessage(messageChain) }
fun sendMessageBlocking(messageChain: Message) = runBlocking { sendMessage(messageChain) } @JvmDefault
fun sendMessageBlocking(message: String) = runBlocking { sendMessage(message) } @JavaFriendlyAPI
@JvmName("sendMessage")
fun __sendMessageBlocking(message: String) = runBlocking { sendMessage(message) }
} }
/** /**
@ -52,42 +59,19 @@ interface BotAwareCommandSender : CommandSender {
suspend inline fun CommandSender.sendMessage(message: String) = sendMessage(PlainText(message)) suspend inline fun CommandSender.sendMessage(message: String) = sendMessage(PlainText(message))
abstract class AbstractCommandSender : CommandSender {
internal val builder = StringBuilder()
override fun appendMessage(message: String) {
builder.appendln(message)
}
internal open suspend fun flushMessage() {
if (builder.isNotEmpty()) {
sendMessage(builder.toString().removeSuffix("\n"))
}
}
}
/** /**
* 控制台指令执行者. 代表由控制台执行指令 * 控制台指令执行者. 代表由控制台执行指令
*/ */
object ConsoleCommandSender : AbstractCommandSender() { // 前端实现
override val bot: Nothing? get() = null abstract class ConsoleCommandSender internal constructor() : CommandSender {
final override val bot: Nothing? get() = null
override suspend fun sendMessage(message: Message) {
TODO()
// MiraiConsole.logger("[Command]", 0, messageChain.toString())
}
override suspend fun flushMessage() {
super.flushMessage()
builder.clear()
}
} }
inline fun Friend.asCommandSender(): FriendCommandSender = FriendCommandSender(this) fun Friend.asCommandSender(): FriendCommandSender = FriendCommandSender(this)
inline fun Member.asCommandSender(): MemberCommandSender = MemberCommandSender(this) fun Member.asCommandSender(): MemberCommandSender = MemberCommandSender(this)
inline fun User.asCommandSender(): UserCommandSender { fun User.asCommandSender(): UserCommandSender {
return when (this) { return when (this) {
is Friend -> this.asCommandSender() is Friend -> this.asCommandSender()
is Member -> this.asCommandSender() is Member -> this.asCommandSender()
@ -100,7 +84,10 @@ inline fun User.asCommandSender(): UserCommandSender {
* 代表一个用户私聊机器人执行指令 * 代表一个用户私聊机器人执行指令
* @see User.asCommandSender * @see User.asCommandSender
*/ */
sealed class UserCommandSender : AbstractCommandSender(), BotAwareCommandSender { sealed class UserCommandSender : CommandSender, BotAwareCommandSender {
/**
* @see MessageEvent.sender
*/
abstract val user: User abstract val user: User
/** /**

View File

@ -7,9 +7,10 @@
* https://github.com/mamoe/mirai/blob/master/LICENSE * https://github.com/mamoe/mirai/blob/master/LICENSE
*/ */
package net.mamoe.mirai.console.plugins package net.mamoe.mirai.console.plugin
import net.mamoe.mirai.console.plugins.builtin.JvmPlugin import net.mamoe.mirai.console.plugin.jvm.JvmPlugin
import java.io.File
/** /**
* 表示一个 mirai-console 插件. * 表示一个 mirai-console 插件.
@ -22,4 +23,9 @@ interface Plugin {
* 所属插件加载器实例 * 所属插件加载器实例
*/ */
val loader: PluginLoader<*, *> val loader: PluginLoader<*, *>
/**
* 插件数据目录
*/
val dataFolder: File
} }

View File

@ -9,8 +9,9 @@
@file:Suppress("unused") @file:Suppress("unused")
package net.mamoe.mirai.console.plugins package net.mamoe.mirai.console.plugin
import net.mamoe.mirai.console.plugin.jvm.JarPluginLoader
import java.io.File import java.io.File
/** /**
@ -59,7 +60,7 @@ open class PluginLoadException : RuntimeException {
*/ */
interface FilePluginLoader<P : Plugin, D : PluginDescription> : PluginLoader<P, D> { interface FilePluginLoader<P : Plugin, D : PluginDescription> : PluginLoader<P, D> {
/** /**
* 所支持的插件文件后缀, '.'. [JarPluginLoader] "jar" * 所支持的插件文件后缀, '.'. [JarPluginLoader] ".jar"
*/ */
val fileSuffix: String val fileSuffix: String
} }
@ -70,6 +71,9 @@ abstract class AbstractFilePluginLoader<P : Plugin, D : PluginDescription>(
private fun pluginsFilesSequence(): Sequence<File> = private fun pluginsFilesSequence(): Sequence<File> =
PluginManager.pluginsDir.walk().filter { it.isFile && it.name.endsWith(fileSuffix, ignoreCase = true) } PluginManager.pluginsDir.walk().filter { it.isFile && it.name.endsWith(fileSuffix, ignoreCase = true) }
/**
* 读取扫描到的后缀与 [fileSuffix] 相同的文件中的 [PluginDescription]
*/
protected abstract fun Sequence<File>.mapToDescription(): List<D> protected abstract fun Sequence<File>.mapToDescription(): List<D>
final override fun listPlugins(): List<D> = pluginsFilesSequence().mapToDescription() final override fun listPlugins(): List<D> = pluginsFilesSequence().mapToDescription()

View File

@ -9,7 +9,7 @@
@file:Suppress("NOTHING_TO_INLINE") @file:Suppress("NOTHING_TO_INLINE")
package net.mamoe.mirai.console.plugins package net.mamoe.mirai.console.plugin
import kotlinx.atomicfu.locks.withLock import kotlinx.atomicfu.locks.withLock
import net.mamoe.mirai.console.MiraiConsole import net.mamoe.mirai.console.MiraiConsole
@ -24,6 +24,7 @@ inline fun PluginLoader<*, *>.unregister() = PluginManager.unregisterPluginLoade
object PluginManager { object PluginManager {
val pluginsDir = File(MiraiConsole.rootDir, "plugins").apply { mkdir() } val pluginsDir = File(MiraiConsole.rootDir, "plugins").apply { mkdir() }
val pluginsDataFolder = File(MiraiConsole.rootDir, "data").apply { mkdir() }
private val _pluginLoaders: MutableList<PluginLoader<*, *>> = mutableListOf() private val _pluginLoaders: MutableList<PluginLoader<*, *>> = mutableListOf()
private val loadersLock: ReentrantLock = ReentrantLock() private val loadersLock: ReentrantLock = ReentrantLock()

View File

@ -7,7 +7,7 @@
* https://github.com/mamoe/mirai/blob/master/LICENSE * https://github.com/mamoe/mirai/blob/master/LICENSE
*/ */
package net.mamoe.mirai.console.plugins package net.mamoe.mirai.console.plugin
import kotlinx.serialization.* import kotlinx.serialization.*
import kotlinx.serialization.builtins.serializer import kotlinx.serialization.builtins.serializer

View File

@ -7,9 +7,7 @@
* https://github.com/mamoe/mirai/blob/master/LICENSE * https://github.com/mamoe/mirai/blob/master/LICENSE
*/ */
@file:Suppress("INVISIBLE_MEMBER", "INVISIBLE_REFERENCE", "EXPOSED_SUPER_CLASS") package net.mamoe.mirai.console.plugin.internal
package net.mamoe.mirai.console.plugins.builtin
import kotlinx.atomicfu.locks.withLock import kotlinx.atomicfu.locks.withLock
import kotlinx.coroutines.CoroutineExceptionHandler import kotlinx.coroutines.CoroutineExceptionHandler
@ -17,91 +15,47 @@ import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Job import kotlinx.coroutines.Job
import kotlinx.coroutines.SupervisorJob import kotlinx.coroutines.SupervisorJob
import net.mamoe.mirai.console.MiraiConsole import net.mamoe.mirai.console.MiraiConsole
import net.mamoe.mirai.console.plugins.Plugin import net.mamoe.mirai.console.plugin.Plugin
import net.mamoe.mirai.console.plugins.PluginLoader import net.mamoe.mirai.console.plugin.PluginManager
import net.mamoe.mirai.console.utils.JavaPluginScheduler import net.mamoe.mirai.console.plugin.jvm.JvmPlugin
import net.mamoe.mirai.console.plugin.jvm.JvmPluginDescription
import net.mamoe.mirai.utils.MiraiLogger import net.mamoe.mirai.utils.MiraiLogger
import java.io.File
import java.util.concurrent.locks.ReentrantLock import java.util.concurrent.locks.ReentrantLock
import kotlin.coroutines.CoroutineContext import kotlin.coroutines.CoroutineContext
import kotlin.coroutines.EmptyCoroutineContext import kotlin.coroutines.EmptyCoroutineContext
internal val <T> T.job: Job where T : CoroutineScope, T : Plugin get() = this.coroutineContext[Job]!!
/** @PublishedApi
* Java Kotlin Jar 插件 internal abstract class JvmPluginImpl(
*
* @see JavaPlugin Java 插件
* @see KotlinPlugin Kotlin 插件
*/
interface JvmPlugin : Plugin, CoroutineScope {
/** 日志 */
val logger: MiraiLogger
/** 插件描述 */
val description: JvmPluginDescription
/** 所属插件加载器实例 */
override val loader: PluginLoader<*, *> get() = JarPluginLoader
@JvmDefault
fun onLoad() {
}
@JvmDefault
fun onEnable() {
}
@JvmDefault
fun onDisable() {
}
}
/**
* Java 插件的父类
*/
abstract class JavaPlugin @JvmOverloads constructor(
parentCoroutineContext: CoroutineContext = EmptyCoroutineContext
) : JvmPlugin, JvmPluginImpl(parentCoroutineContext) {
/**
* Java API Scheduler
*/
val scheduler: JavaPluginScheduler =
JavaPluginScheduler(this.coroutineContext)
}
abstract class KotlinPlugin @JvmOverloads constructor(
parentCoroutineContext: CoroutineContext = EmptyCoroutineContext
) : JvmPlugin, JvmPluginImpl(parentCoroutineContext) {
// that's it
}
internal sealed class JvmPluginImpl(
parentCoroutineContext: CoroutineContext parentCoroutineContext: CoroutineContext
) : JvmPlugin, CoroutineScope { ) : JvmPlugin,
CoroutineScope {
// region JvmPlugin
/** /**
* Initialized immediately after construction of [JvmPluginImpl] instance * Initialized immediately after construction of [JvmPluginImpl] instance
*/ */
@Suppress("PropertyName") @Suppress("PropertyName")
internal lateinit var _description: JvmPluginDescription internal lateinit var _description: JvmPluginDescription
// for future use
@Suppress("PropertyName")
@JvmField
internal var _intrinsicCoroutineContext: CoroutineContext = EmptyCoroutineContext
override val description: JvmPluginDescription get() = _description override val description: JvmPluginDescription get() = _description
final override val logger: MiraiLogger by lazy { MiraiConsole.newLogger(this._description.name) } final override val logger: MiraiLogger by lazy {
MiraiConsole.newLogger(
@JvmField this._description.name
internal val coroutineContextInitializer = { )
CoroutineExceptionHandler { _, throwable -> logger.error(throwable) }
.plus(parentCoroutineContext)
.plus(SupervisorJob(parentCoroutineContext[Job])) + _intrinsicCoroutineContext
} }
private var firstRun = true private var firstRun = true
override val dataFolder: File by lazy {
File(
PluginManager.pluginsDataFolder,
description.name
).apply { mkdir() }
}
internal fun internalOnDisable() { internal fun internalOnDisable() {
firstRun = false firstRun = false
this.onDisable() this.onDisable()
@ -116,14 +70,33 @@ internal sealed class JvmPluginImpl(
this.onEnable() 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 { private fun refreshCoroutineContext(): CoroutineContext {
return coroutineContextInitializer().also { _coroutineContext = it } return coroutineContextInitializer().also { _coroutineContext = it }
} }
private val contextUpdateLock: ReentrantLock = ReentrantLock() private val contextUpdateLock: ReentrantLock =
ReentrantLock()
private var _coroutineContext: CoroutineContext? = null private var _coroutineContext: CoroutineContext? = null
final override val coroutineContext: CoroutineContext final override val coroutineContext: CoroutineContext
get() = _coroutineContext get() = _coroutineContext
?: contextUpdateLock.withLock { _coroutineContext ?: refreshCoroutineContext() } ?: contextUpdateLock.withLock { _coroutineContext ?: refreshCoroutineContext() }
// endregion
} }

View File

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

View File

@ -7,15 +7,16 @@
* https://github.com/mamoe/mirai/blob/master/LICENSE * https://github.com/mamoe/mirai/blob/master/LICENSE
*/ */
package net.mamoe.mirai.console.plugins.builtin package net.mamoe.mirai.console.plugin.jvm
import kotlinx.coroutines.* import kotlinx.coroutines.*
import net.mamoe.mirai.console.MiraiConsole import net.mamoe.mirai.console.MiraiConsole
import net.mamoe.mirai.console.plugins.AbstractFilePluginLoader import net.mamoe.mirai.console.plugin.AbstractFilePluginLoader
import net.mamoe.mirai.console.plugins.PluginLoadException import net.mamoe.mirai.console.plugin.PluginLoadException
import net.mamoe.mirai.console.plugins.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.mirai.utils.MiraiLogger
import net.mamoe.mirai.utils.error
import net.mamoe.yamlkt.Yaml import net.mamoe.yamlkt.Yaml
import java.io.File import java.io.File
import java.net.URL import java.net.URL
@ -25,7 +26,7 @@ import kotlin.reflect.full.createInstance
/** /**
* 内建的 Jar (JVM) 插件加载器 * 内建的 Jar (JVM) 插件加载器
*/ */
object JarPluginLoader : AbstractFilePluginLoader<JvmPlugin, JvmPluginDescription>("jar"), CoroutineScope { object JarPluginLoader : AbstractFilePluginLoader<JvmPlugin, JvmPluginDescription>(".jar"), CoroutineScope {
private val logger: MiraiLogger by lazy { private val logger: MiraiLogger by lazy {
MiraiConsole.newLogger(JarPluginLoader::class.simpleName!!) MiraiConsole.newLogger(JarPluginLoader::class.simpleName!!)
} }
@ -39,7 +40,8 @@ object JarPluginLoader : AbstractFilePluginLoader<JvmPlugin, JvmPluginDescriptio
} }
private val supervisor: Job = coroutineContext[Job]!! private val supervisor: Job = coroutineContext[Job]!!
private val classLoader: PluginsLoader = PluginsLoader(this.javaClass.classLoader) private val classLoader: PluginsLoader =
PluginsLoader(this.javaClass.classLoader)
init { init {
supervisor.invokeOnCompletion { supervisor.invokeOnCompletion {
@ -47,6 +49,8 @@ object JarPluginLoader : AbstractFilePluginLoader<JvmPlugin, JvmPluginDescriptio
} }
} }
val settingStorage: SettingStorage = MiraiConsole.jvmSettingStorage
override fun getPluginDescription(plugin: JvmPlugin): JvmPluginDescription = plugin.description override fun getPluginDescription(plugin: JvmPlugin): JvmPluginDescription = plugin.description
override fun Sequence<File>.mapToDescription(): List<JvmPluginDescription> { override fun Sequence<File>.mapToDescription(): List<JvmPluginDescription> {

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,15 +7,15 @@
* https://github.com/mamoe/mirai/blob/master/LICENSE * https://github.com/mamoe/mirai/blob/master/LICENSE
*/ */
package net.mamoe.mirai.console.plugins.builtin package net.mamoe.mirai.console.plugin.jvm
import kotlinx.serialization.SerialName import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable import kotlinx.serialization.Serializable
import kotlinx.serialization.Transient import kotlinx.serialization.Transient
import net.mamoe.mirai.console.plugins.FilePluginDescription import net.mamoe.mirai.console.plugin.FilePluginDescription
import net.mamoe.mirai.console.plugins.PluginDependency import net.mamoe.mirai.console.plugin.PluginDependency
import net.mamoe.mirai.console.plugins.PluginDescription import net.mamoe.mirai.console.plugin.PluginDescription
import net.mamoe.mirai.console.plugins.PluginKind import net.mamoe.mirai.console.plugin.PluginKind
import java.io.File import java.io.File
@Serializable @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

@ -7,15 +7,17 @@
* https://github.com/mamoe/mirai/blob/master/LICENSE * https://github.com/mamoe/mirai/blob/master/LICENSE
*/ */
@file:Suppress("NOTHING_TO_INLINE") @file:Suppress("NOTHING_TO_INLINE", "unused")
package net.mamoe.mirai.console.setting package net.mamoe.mirai.console.setting
import kotlinx.serialization.KSerializer import kotlinx.serialization.KSerializer
import net.mamoe.mirai.console.setting.internal.SettingImpl import net.mamoe.mirai.console.setting.internal.SettingImpl
import net.mamoe.mirai.console.setting.internal.serialNameOrPropertyName
import net.mamoe.mirai.utils.MiraiExperimentalAPI import net.mamoe.mirai.utils.MiraiExperimentalAPI
import kotlin.properties.ReadWriteProperty import kotlin.properties.ReadWriteProperty
import kotlin.reflect.KProperty import kotlin.reflect.KProperty
import kotlin.reflect.KProperty0
import kotlin.reflect.full.findAnnotation import kotlin.reflect.full.findAnnotation
/** /**
@ -33,6 +35,23 @@ typealias Comment = net.mamoe.yamlkt.Comment
*/ */
@Suppress("EXPOSED_SUPER_CLASS") @Suppress("EXPOSED_SUPER_CLASS")
abstract class Setting : SettingImpl() { abstract class Setting : SettingImpl() {
/**
* 表示这个配置的嵌套对象, 自动绑定数据更新.
*/
abstract inner class Inner : Setting() {
internal lateinit var attachedValue: Value<*>
override fun onElementChanged(value: Value<*>) {
this@Setting.onElementChanged(attachedValue)
}
}
data class PropertyInfo(
val serialName: String,
val annotations: List<Annotation>,
val propertyOriginalName: String?
)
/** /**
* 这个配置的名称, 仅对于顶层配置有效. * 这个配置的名称, 仅对于顶层配置有效.
*/ */
@ -43,6 +62,33 @@ abstract class Setting : SettingImpl() {
?: error("Names should be assigned to anonymous classes manually by overriding serialName") ?: error("Names should be assigned to anonymous classes manually by overriding serialName")
// for Java only
fun <T : Any> addProperty(
propertyInfo: PropertyInfo,
value: Value<*>
): Value<*> {
if (built) error("The Setting is already serialized so it's structure is immutable.")
valueList.add(value to propertyInfo)
return value
}
/**
* 获取这个属性的真实 [Value] 委托
*/
@get:JvmSynthetic
val <R : Any> KProperty0<R>.correspondingValue: Value<R>
@Suppress("UNCHECKED_CAST")
get() = findCorrespondingValue(this)
?: throw NoSuchElementException("No corresponding Value found for property $this")
/**
* 获取这个属性的真实 [Value] 委托
*/
fun <R : Any> findCorrespondingValue(property: KProperty0<R>): Value<R>? {
@Suppress("UNCHECKED_CAST")
return this@Setting.valueList.firstOrNull { it.second.propertyOriginalName == property.name }?.first as Value<R>?
}
/** /**
* 提供属性委托, 并添加这个对象的自动保存跟踪. * 提供属性委托, 并添加这个对象的自动保存跟踪.
*/ */
@ -52,10 +98,12 @@ abstract class Setting : SettingImpl() {
property: KProperty<*> property: KProperty<*>
): ReadWriteProperty<Setting, T> { ): ReadWriteProperty<Setting, T> {
if (built) error("The Setting is already serialized so it's structure is immutable.") if (built) error("The Setting is already serialized so it's structure is immutable.")
valueList.add(this to property) valueList.add(this to PropertyInfo(property.serialNameOrPropertyName, property.annotations, property.name))
return this return this
} }
abstract override fun onElementChanged(value: Value<*>)
override fun toString(): String = yamlForToString.stringify(this.serializer, this) override fun toString(): String = yamlForToString.stringify(this.serializer, this)
} }

View File

@ -0,0 +1,65 @@
@file:Suppress("INVISIBLE_REFERENCE", "INVISIBLE_MEMBER")
package net.mamoe.mirai.console.setting
import kotlinx.atomicfu.locks.withLock
import kotlinx.serialization.*
import kotlinx.serialization.internal.getChecked
import net.mamoe.mirai.console.setting.internal.SettingSerializerMark
import java.io.Closeable
import java.io.File
import java.util.concurrent.locks.ReentrantLock
/**
* [Setting] 存储方式
*/
interface SettingStorage {
interface TrackedSetting : Closeable {
fun save()
fun update()
override fun close()
}
fun trackOn(setting: Setting): TrackedSetting
fun saveAll()
fun updateAll()
}
class SingleFileSettingStorage(
val file: File
) : SettingStorage {
private val descriptor: MutableList<Setting> = ArrayList()
private val updaterSerializer: KSerializer<SettingSerializerMark> = object : KSerializer<SettingSerializerMark> {
override val descriptor: SerialDescriptor = SerialDescriptor("SingleFileSettingStorage") {
TODO()
}
override fun deserialize(decoder: Decoder): SettingSerializerMark {
TODO("Not yet implemented")
}
override fun serialize(encoder: Encoder, value: SettingSerializerMark) {
TODO("Not yet implemented")
}
}
init {
require(file.isFile) { "file $file is not a file" }
require(file.canRead()) { "file $file is not readable" }
}
override fun trackOn(setting: Setting): SettingStorage.TrackedSetting {
TODO("Not yet implemented")
}
override fun saveAll() {
TODO("Not yet implemented")
}
override fun updateAll() {
TODO("Not yet implemented")
}
}

View File

@ -124,7 +124,11 @@ fun <T : Setting> Setting.value(default: T): Value<T> {
require(this::class != default::class) { require(this::class != default::class) {
"Recursive nesting is prohibited" "Recursive nesting is prohibited"
} }
return valueImpl(default) return valueImpl(default).also {
if (default is Setting.Inner) {
default.attachedValue = it
}
}
} }
inline fun <T : Setting> Setting.value(default: T, crossinline initializer: T.() -> Unit): Value<T> = inline fun <T : Setting> Setting.value(default: T, crossinline initializer: T.() -> Unit): Value<T> =

View File

@ -0,0 +1,32 @@
/*
* 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.setting.internal
import kotlinx.coroutines.Job
import net.mamoe.mirai.console.MiraiConsole
import net.mamoe.mirai.console.setting.Setting
import net.mamoe.mirai.console.setting.Value
internal abstract class ConsoleBuiltInSetting : Setting() {
private val track =
@Suppress("LeakingThis")
MiraiConsole.jvmSettingStorage.trackOn(this)
init {
MiraiConsole.coroutineContext[Job]!!.invokeOnCompletion {
track.close()
}
}
override fun onElementChanged(value: Value<*>) {
TODO()
}
}

View File

@ -9,7 +9,10 @@
package net.mamoe.mirai.console.setting.internal package net.mamoe.mirai.console.setting.internal
import kotlinx.serialization.* import kotlinx.serialization.Decoder
import kotlinx.serialization.Encoder
import kotlinx.serialization.KSerializer
import kotlinx.serialization.SerialDescriptor
import kotlinx.serialization.builtins.* import kotlinx.serialization.builtins.*
import net.mamoe.mirai.console.setting.* import net.mamoe.mirai.console.setting.*
@ -31,7 +34,7 @@ internal fun Setting.valueImpl(default: Int): IntValue {
onElementChanged(this) onElementChanged(this)
} }
} }
override val serializer = Int.serializer() override val serializer get() = Int.serializer()
} }
} }
@ -46,7 +49,7 @@ internal fun Setting.valueImpl(default: Short): ShortValue {
onElementChanged(this) onElementChanged(this)
} }
} }
override val serializer = Short.serializer() override val serializer get() = Short.serializer()
} }
} }
@ -61,7 +64,7 @@ internal fun Setting.valueImpl(default: Byte): ByteValue {
onElementChanged(this) onElementChanged(this)
} }
} }
override val serializer = Byte.serializer() override val serializer get() = Byte.serializer()
} }
} }
@ -76,7 +79,7 @@ internal fun Setting.valueImpl(default: Long): LongValue {
onElementChanged(this) onElementChanged(this)
} }
} }
override val serializer = Long.serializer() override val serializer get() = Long.serializer()
} }
} }
@ -91,7 +94,7 @@ internal fun Setting.valueImpl(default: Float): FloatValue {
onElementChanged(this) onElementChanged(this)
} }
} }
override val serializer = Float.serializer() override val serializer get() = Float.serializer()
} }
} }
@ -106,7 +109,7 @@ internal fun Setting.valueImpl(default: Double): DoubleValue {
onElementChanged(this) onElementChanged(this)
} }
} }
override val serializer = Double.serializer() override val serializer get() = Double.serializer()
} }
} }
@ -121,7 +124,7 @@ internal fun Setting.valueImpl(default: Boolean): BooleanValue {
onElementChanged(this) onElementChanged(this)
} }
} }
override val serializer = Boolean.serializer() override val serializer get() = Boolean.serializer()
} }
} }
@ -136,7 +139,7 @@ internal fun Setting.valueImpl(default: Char): CharValue {
onElementChanged(this) onElementChanged(this)
} }
} }
override val serializer = Char.serializer() override val serializer get() = Char.serializer()
} }
} }
@ -151,7 +154,7 @@ internal fun Setting.valueImpl(default: String): StringValue {
onElementChanged(this) onElementChanged(this)
} }
} }
override val serializer = String.serializer() override val serializer get() = String.serializer()
} }
} }
@ -166,7 +169,7 @@ internal fun Setting.valueImpl(default: IntArray): IntArrayValue {
onElementChanged(this) onElementChanged(this)
} }
} }
override val serializer = IntArraySerializer() override val serializer get() = IntArraySerializer()
} }
} }
@ -181,7 +184,7 @@ internal fun Setting.valueImpl(default: ShortArray): ShortArrayValue {
onElementChanged(this) onElementChanged(this)
} }
} }
override val serializer = ShortArraySerializer() override val serializer get() = ShortArraySerializer()
} }
} }
@ -196,7 +199,7 @@ internal fun Setting.valueImpl(default: ByteArray): ByteArrayValue {
onElementChanged(this) onElementChanged(this)
} }
} }
override val serializer = ByteArraySerializer() override val serializer get() = ByteArraySerializer()
} }
} }
@ -211,7 +214,7 @@ internal fun Setting.valueImpl(default: LongArray): LongArrayValue {
onElementChanged(this) onElementChanged(this)
} }
} }
override val serializer = LongArraySerializer() override val serializer get() = LongArraySerializer()
} }
} }
@ -226,7 +229,7 @@ internal fun Setting.valueImpl(default: FloatArray): FloatArrayValue {
onElementChanged(this) onElementChanged(this)
} }
} }
override val serializer = FloatArraySerializer() override val serializer get() = FloatArraySerializer()
} }
} }
@ -241,7 +244,7 @@ internal fun Setting.valueImpl(default: DoubleArray): DoubleArrayValue {
onElementChanged(this) onElementChanged(this)
} }
} }
override val serializer = DoubleArraySerializer() override val serializer get() = DoubleArraySerializer()
} }
} }
@ -256,7 +259,7 @@ internal fun Setting.valueImpl(default: BooleanArray): BooleanArrayValue {
onElementChanged(this) onElementChanged(this)
} }
} }
override val serializer = BooleanArraySerializer() override val serializer get() = BooleanArraySerializer()
} }
} }
@ -271,7 +274,7 @@ internal fun Setting.valueImpl(default: CharArray): CharArrayValue {
onElementChanged(this) onElementChanged(this)
} }
} }
override val serializer = CharArraySerializer() override val serializer get() = CharArraySerializer()
} }
} }
@ -286,7 +289,7 @@ internal fun Setting.valueImpl(default: Array<Int>): TypedIntArrayValue {
onElementChanged(this) onElementChanged(this)
} }
} }
override val serializer = ArraySerializer(Int.serializer()) override val serializer get() = ArraySerializer(Int.serializer())
} }
} }
@ -301,7 +304,7 @@ internal fun Setting.valueImpl(default: Array<Short>): TypedShortArrayValue {
onElementChanged(this) onElementChanged(this)
} }
} }
override val serializer = ArraySerializer(Short.serializer()) override val serializer get() = ArraySerializer(Short.serializer())
} }
} }
@ -316,7 +319,7 @@ internal fun Setting.valueImpl(default: Array<Byte>): TypedByteArrayValue {
onElementChanged(this) onElementChanged(this)
} }
} }
override val serializer = ArraySerializer(Byte.serializer()) override val serializer get() = ArraySerializer(Byte.serializer())
} }
} }
@ -331,7 +334,7 @@ internal fun Setting.valueImpl(default: Array<Long>): TypedLongArrayValue {
onElementChanged(this) onElementChanged(this)
} }
} }
override val serializer = ArraySerializer(Long.serializer()) override val serializer get() = ArraySerializer(Long.serializer())
} }
} }
@ -346,7 +349,7 @@ internal fun Setting.valueImpl(default: Array<Float>): TypedFloatArrayValue {
onElementChanged(this) onElementChanged(this)
} }
} }
override val serializer = ArraySerializer(Float.serializer()) override val serializer get() = ArraySerializer(Float.serializer())
} }
} }
@ -361,7 +364,7 @@ internal fun Setting.valueImpl(default: Array<Double>): TypedDoubleArrayValue {
onElementChanged(this) onElementChanged(this)
} }
} }
override val serializer = ArraySerializer(Double.serializer()) override val serializer get() = ArraySerializer(Double.serializer())
} }
} }
@ -376,7 +379,7 @@ internal fun Setting.valueImpl(default: Array<Boolean>): TypedBooleanArrayValue
onElementChanged(this) onElementChanged(this)
} }
} }
override val serializer = ArraySerializer(Boolean.serializer()) override val serializer get() = ArraySerializer(Boolean.serializer())
} }
} }
@ -391,7 +394,7 @@ internal fun Setting.valueImpl(default: Array<Char>): TypedCharArrayValue {
onElementChanged(this) onElementChanged(this)
} }
} }
override val serializer = ArraySerializer(Char.serializer()) override val serializer get() = ArraySerializer(Char.serializer())
} }
} }
@ -406,7 +409,7 @@ internal fun Setting.valueImpl(default: Array<String>): TypedStringArrayValue {
onElementChanged(this) onElementChanged(this)
} }
} }
override val serializer = ArraySerializer(String.serializer()) override val serializer get() = ArraySerializer(String.serializer())
} }
} }
@ -422,7 +425,7 @@ internal fun Setting.valueImpl(default: List<Int>): IntListValue {
onElementChanged(this) onElementChanged(this)
} }
} }
override val serializer = ListSerializer(Int.serializer()) override val serializer get() = ListSerializer(Int.serializer())
} }
} }
@ -438,7 +441,7 @@ internal fun Setting.valueImpl(default: List<Short>): ShortListValue {
onElementChanged(this) onElementChanged(this)
} }
} }
override val serializer = ListSerializer(Short.serializer()) override val serializer get() = ListSerializer(Short.serializer())
} }
} }
@ -454,7 +457,7 @@ internal fun Setting.valueImpl(default: List<Byte>): ByteListValue {
onElementChanged(this) onElementChanged(this)
} }
} }
override val serializer = ListSerializer(Byte.serializer()) override val serializer get() = ListSerializer(Byte.serializer())
} }
} }
@ -470,7 +473,7 @@ internal fun Setting.valueImpl(default: List<Long>): LongListValue {
onElementChanged(this) onElementChanged(this)
} }
} }
override val serializer = ListSerializer(Long.serializer()) override val serializer get() = ListSerializer(Long.serializer())
} }
} }
@ -486,7 +489,7 @@ internal fun Setting.valueImpl(default: List<Float>): FloatListValue {
onElementChanged(this) onElementChanged(this)
} }
} }
override val serializer = ListSerializer(Float.serializer()) override val serializer get() = ListSerializer(Float.serializer())
} }
} }
@ -502,7 +505,7 @@ internal fun Setting.valueImpl(default: List<Double>): DoubleListValue {
onElementChanged(this) onElementChanged(this)
} }
} }
override val serializer = ListSerializer(Double.serializer()) override val serializer get() = ListSerializer(Double.serializer())
} }
} }
@ -518,7 +521,7 @@ internal fun Setting.valueImpl(default: List<Boolean>): BooleanListValue {
onElementChanged(this) onElementChanged(this)
} }
} }
override val serializer = ListSerializer(Boolean.serializer()) override val serializer get() = ListSerializer(Boolean.serializer())
} }
} }
@ -534,7 +537,7 @@ internal fun Setting.valueImpl(default: List<Char>): CharListValue {
onElementChanged(this) onElementChanged(this)
} }
} }
override val serializer = ListSerializer(Char.serializer()) override val serializer get() = ListSerializer(Char.serializer())
} }
} }
@ -550,7 +553,7 @@ internal fun Setting.valueImpl(default: List<String>): StringListValue {
onElementChanged(this) onElementChanged(this)
} }
} }
override val serializer = ListSerializer(String.serializer()) override val serializer get() = ListSerializer(String.serializer())
} }
} }
@ -566,7 +569,7 @@ internal fun Setting.valueImpl(default: Set<Int>): IntSetValue {
onElementChanged(this) onElementChanged(this)
} }
} }
override val serializer = SetSerializer(Int.serializer()) override val serializer get() = SetSerializer(Int.serializer())
} }
} }
@ -582,7 +585,7 @@ internal fun Setting.valueImpl(default: Set<Short>): ShortSetValue {
onElementChanged(this) onElementChanged(this)
} }
} }
override val serializer = SetSerializer(Short.serializer()) override val serializer get() = SetSerializer(Short.serializer())
} }
} }
@ -598,7 +601,7 @@ internal fun Setting.valueImpl(default: Set<Byte>): ByteSetValue {
onElementChanged(this) onElementChanged(this)
} }
} }
override val serializer = SetSerializer(Byte.serializer()) override val serializer get() = SetSerializer(Byte.serializer())
} }
} }
@ -614,7 +617,7 @@ internal fun Setting.valueImpl(default: Set<Long>): LongSetValue {
onElementChanged(this) onElementChanged(this)
} }
} }
override val serializer = SetSerializer(Long.serializer()) override val serializer get() = SetSerializer(Long.serializer())
} }
} }
@ -630,7 +633,7 @@ internal fun Setting.valueImpl(default: Set<Float>): FloatSetValue {
onElementChanged(this) onElementChanged(this)
} }
} }
override val serializer = SetSerializer(Float.serializer()) override val serializer get() = SetSerializer(Float.serializer())
} }
} }
@ -646,7 +649,7 @@ internal fun Setting.valueImpl(default: Set<Double>): DoubleSetValue {
onElementChanged(this) onElementChanged(this)
} }
} }
override val serializer = SetSerializer(Double.serializer()) override val serializer get() = SetSerializer(Double.serializer())
} }
} }
@ -662,7 +665,7 @@ internal fun Setting.valueImpl(default: Set<Boolean>): BooleanSetValue {
onElementChanged(this) onElementChanged(this)
} }
} }
override val serializer = SetSerializer(Boolean.serializer()) override val serializer get() = SetSerializer(Boolean.serializer())
} }
} }
@ -678,7 +681,7 @@ internal fun Setting.valueImpl(default: Set<Char>): CharSetValue {
onElementChanged(this) onElementChanged(this)
} }
} }
override val serializer = SetSerializer(Char.serializer()) override val serializer get() = SetSerializer(Char.serializer())
} }
} }
@ -694,7 +697,7 @@ internal fun Setting.valueImpl(default: Set<String>): StringSetValue {
onElementChanged(this) onElementChanged(this)
} }
} }
override val serializer = SetSerializer(String.serializer()) override val serializer get() = SetSerializer(String.serializer())
} }
} }
@ -705,7 +708,7 @@ internal fun Setting.valueImpl(
): MutableIntListValue { ): MutableIntListValue {
var internalValue: MutableList<Int> = default var internalValue: MutableList<Int> = default
val delegt = dynamicMutableList{ internalValue } val delegt = dynamicMutableList { internalValue }
return object : MutableIntListValue(), MutableList<Int> by delegt { return object : MutableIntListValue(), MutableList<Int> by delegt {
override var value: MutableList<Int> override var value: MutableList<Int>
get() = internalValue get() = internalValue
@ -715,15 +718,15 @@ internal fun Setting.valueImpl(
onElementChanged(this) onElementChanged(this)
} }
} }
private val outerThis get() = this private val outerThis get() = this
override val serializer: KSerializer<MutableList<Int>> = object : KSerializer<MutableList<Int>> { override val serializer: KSerializer<MutableList<Int>> = object : KSerializer<MutableList<Int>> {
private val delegate = ListSerializer(Int.serializer()) private val delegate = ListSerializer(Int.serializer())
override val descriptor: SerialDescriptor = delegate.descriptor override val descriptor: SerialDescriptor get() = delegate.descriptor
override fun deserialize(decoder: Decoder): MutableList<Int> { override fun deserialize(decoder: Decoder): MutableList<Int> {
return delegate.deserialize(decoder).toMutableList().observable { return delegate.deserialize(decoder).toMutableList().observable {
onElementChanged(outerThis) onElementChanged(outerThis)
} }
} }
@ -741,7 +744,7 @@ internal fun Setting.valueImpl(
): MutableShortListValue { ): MutableShortListValue {
var internalValue: MutableList<Short> = default var internalValue: MutableList<Short> = default
val delegt = dynamicMutableList{ internalValue } val delegt = dynamicMutableList { internalValue }
return object : MutableShortListValue(), MutableList<Short> by delegt { return object : MutableShortListValue(), MutableList<Short> by delegt {
override var value: MutableList<Short> override var value: MutableList<Short>
get() = internalValue get() = internalValue
@ -751,15 +754,15 @@ internal fun Setting.valueImpl(
onElementChanged(this) onElementChanged(this)
} }
} }
private val outerThis get() = this private val outerThis get() = this
override val serializer: KSerializer<MutableList<Short>> = object : KSerializer<MutableList<Short>> { override val serializer: KSerializer<MutableList<Short>> = object : KSerializer<MutableList<Short>> {
private val delegate = ListSerializer(Short.serializer()) private val delegate = ListSerializer(Short.serializer())
override val descriptor: SerialDescriptor = delegate.descriptor override val descriptor: SerialDescriptor get() = delegate.descriptor
override fun deserialize(decoder: Decoder): MutableList<Short> { override fun deserialize(decoder: Decoder): MutableList<Short> {
return delegate.deserialize(decoder).toMutableList().observable { return delegate.deserialize(decoder).toMutableList().observable {
onElementChanged(outerThis) onElementChanged(outerThis)
} }
} }
@ -777,7 +780,7 @@ internal fun Setting.valueImpl(
): MutableByteListValue { ): MutableByteListValue {
var internalValue: MutableList<Byte> = default var internalValue: MutableList<Byte> = default
val delegt = dynamicMutableList{ internalValue } val delegt = dynamicMutableList { internalValue }
return object : MutableByteListValue(), MutableList<Byte> by delegt { return object : MutableByteListValue(), MutableList<Byte> by delegt {
override var value: MutableList<Byte> override var value: MutableList<Byte>
get() = internalValue get() = internalValue
@ -787,15 +790,15 @@ internal fun Setting.valueImpl(
onElementChanged(this) onElementChanged(this)
} }
} }
private val outerThis get() = this private val outerThis get() = this
override val serializer: KSerializer<MutableList<Byte>> = object : KSerializer<MutableList<Byte>> { override val serializer: KSerializer<MutableList<Byte>> = object : KSerializer<MutableList<Byte>> {
private val delegate = ListSerializer(Byte.serializer()) private val delegate = ListSerializer(Byte.serializer())
override val descriptor: SerialDescriptor = delegate.descriptor override val descriptor: SerialDescriptor get() = delegate.descriptor
override fun deserialize(decoder: Decoder): MutableList<Byte> { override fun deserialize(decoder: Decoder): MutableList<Byte> {
return delegate.deserialize(decoder).toMutableList().observable { return delegate.deserialize(decoder).toMutableList().observable {
onElementChanged(outerThis) onElementChanged(outerThis)
} }
} }
@ -813,7 +816,7 @@ internal fun Setting.valueImpl(
): MutableLongListValue { ): MutableLongListValue {
var internalValue: MutableList<Long> = default var internalValue: MutableList<Long> = default
val delegt = dynamicMutableList{ internalValue } val delegt = dynamicMutableList { internalValue }
return object : MutableLongListValue(), MutableList<Long> by delegt { return object : MutableLongListValue(), MutableList<Long> by delegt {
override var value: MutableList<Long> override var value: MutableList<Long>
get() = internalValue get() = internalValue
@ -823,15 +826,15 @@ internal fun Setting.valueImpl(
onElementChanged(this) onElementChanged(this)
} }
} }
private val outerThis get() = this private val outerThis get() = this
override val serializer: KSerializer<MutableList<Long>> = object : KSerializer<MutableList<Long>> { override val serializer: KSerializer<MutableList<Long>> = object : KSerializer<MutableList<Long>> {
private val delegate = ListSerializer(Long.serializer()) private val delegate = ListSerializer(Long.serializer())
override val descriptor: SerialDescriptor = delegate.descriptor override val descriptor: SerialDescriptor get() = delegate.descriptor
override fun deserialize(decoder: Decoder): MutableList<Long> { override fun deserialize(decoder: Decoder): MutableList<Long> {
return delegate.deserialize(decoder).toMutableList().observable { return delegate.deserialize(decoder).toMutableList().observable {
onElementChanged(outerThis) onElementChanged(outerThis)
} }
} }
@ -849,7 +852,7 @@ internal fun Setting.valueImpl(
): MutableFloatListValue { ): MutableFloatListValue {
var internalValue: MutableList<Float> = default var internalValue: MutableList<Float> = default
val delegt = dynamicMutableList{ internalValue } val delegt = dynamicMutableList { internalValue }
return object : MutableFloatListValue(), MutableList<Float> by delegt { return object : MutableFloatListValue(), MutableList<Float> by delegt {
override var value: MutableList<Float> override var value: MutableList<Float>
get() = internalValue get() = internalValue
@ -859,15 +862,15 @@ internal fun Setting.valueImpl(
onElementChanged(this) onElementChanged(this)
} }
} }
private val outerThis get() = this private val outerThis get() = this
override val serializer: KSerializer<MutableList<Float>> = object : KSerializer<MutableList<Float>> { override val serializer: KSerializer<MutableList<Float>> = object : KSerializer<MutableList<Float>> {
private val delegate = ListSerializer(Float.serializer()) private val delegate = ListSerializer(Float.serializer())
override val descriptor: SerialDescriptor = delegate.descriptor override val descriptor: SerialDescriptor get() = delegate.descriptor
override fun deserialize(decoder: Decoder): MutableList<Float> { override fun deserialize(decoder: Decoder): MutableList<Float> {
return delegate.deserialize(decoder).toMutableList().observable { return delegate.deserialize(decoder).toMutableList().observable {
onElementChanged(outerThis) onElementChanged(outerThis)
} }
} }
@ -885,7 +888,7 @@ internal fun Setting.valueImpl(
): MutableDoubleListValue { ): MutableDoubleListValue {
var internalValue: MutableList<Double> = default var internalValue: MutableList<Double> = default
val delegt = dynamicMutableList{ internalValue } val delegt = dynamicMutableList { internalValue }
return object : MutableDoubleListValue(), MutableList<Double> by delegt { return object : MutableDoubleListValue(), MutableList<Double> by delegt {
override var value: MutableList<Double> override var value: MutableList<Double>
get() = internalValue get() = internalValue
@ -895,15 +898,15 @@ internal fun Setting.valueImpl(
onElementChanged(this) onElementChanged(this)
} }
} }
private val outerThis get() = this private val outerThis get() = this
override val serializer: KSerializer<MutableList<Double>> = object : KSerializer<MutableList<Double>> { override val serializer: KSerializer<MutableList<Double>> = object : KSerializer<MutableList<Double>> {
private val delegate = ListSerializer(Double.serializer()) private val delegate = ListSerializer(Double.serializer())
override val descriptor: SerialDescriptor = delegate.descriptor override val descriptor: SerialDescriptor get() = delegate.descriptor
override fun deserialize(decoder: Decoder): MutableList<Double> { override fun deserialize(decoder: Decoder): MutableList<Double> {
return delegate.deserialize(decoder).toMutableList().observable { return delegate.deserialize(decoder).toMutableList().observable {
onElementChanged(outerThis) onElementChanged(outerThis)
} }
} }
@ -921,7 +924,7 @@ internal fun Setting.valueImpl(
): MutableBooleanListValue { ): MutableBooleanListValue {
var internalValue: MutableList<Boolean> = default var internalValue: MutableList<Boolean> = default
val delegt = dynamicMutableList{ internalValue } val delegt = dynamicMutableList { internalValue }
return object : MutableBooleanListValue(), MutableList<Boolean> by delegt { return object : MutableBooleanListValue(), MutableList<Boolean> by delegt {
override var value: MutableList<Boolean> override var value: MutableList<Boolean>
get() = internalValue get() = internalValue
@ -931,15 +934,15 @@ internal fun Setting.valueImpl(
onElementChanged(this) onElementChanged(this)
} }
} }
private val outerThis get() = this private val outerThis get() = this
override val serializer: KSerializer<MutableList<Boolean>> = object : KSerializer<MutableList<Boolean>> { override val serializer: KSerializer<MutableList<Boolean>> = object : KSerializer<MutableList<Boolean>> {
private val delegate = ListSerializer(Boolean.serializer()) private val delegate = ListSerializer(Boolean.serializer())
override val descriptor: SerialDescriptor = delegate.descriptor override val descriptor: SerialDescriptor get() = delegate.descriptor
override fun deserialize(decoder: Decoder): MutableList<Boolean> { override fun deserialize(decoder: Decoder): MutableList<Boolean> {
return delegate.deserialize(decoder).toMutableList().observable { return delegate.deserialize(decoder).toMutableList().observable {
onElementChanged(outerThis) onElementChanged(outerThis)
} }
} }
@ -957,7 +960,7 @@ internal fun Setting.valueImpl(
): MutableCharListValue { ): MutableCharListValue {
var internalValue: MutableList<Char> = default var internalValue: MutableList<Char> = default
val delegt = dynamicMutableList{ internalValue } val delegt = dynamicMutableList { internalValue }
return object : MutableCharListValue(), MutableList<Char> by delegt { return object : MutableCharListValue(), MutableList<Char> by delegt {
override var value: MutableList<Char> override var value: MutableList<Char>
get() = internalValue get() = internalValue
@ -967,15 +970,15 @@ internal fun Setting.valueImpl(
onElementChanged(this) onElementChanged(this)
} }
} }
private val outerThis get() = this private val outerThis get() = this
override val serializer: KSerializer<MutableList<Char>> = object : KSerializer<MutableList<Char>> { override val serializer: KSerializer<MutableList<Char>> = object : KSerializer<MutableList<Char>> {
private val delegate = ListSerializer(Char.serializer()) private val delegate = ListSerializer(Char.serializer())
override val descriptor: SerialDescriptor = delegate.descriptor override val descriptor: SerialDescriptor get() = delegate.descriptor
override fun deserialize(decoder: Decoder): MutableList<Char> { override fun deserialize(decoder: Decoder): MutableList<Char> {
return delegate.deserialize(decoder).toMutableList().observable { return delegate.deserialize(decoder).toMutableList().observable {
onElementChanged(outerThis) onElementChanged(outerThis)
} }
} }
@ -993,7 +996,7 @@ internal fun Setting.valueImpl(
): MutableStringListValue { ): MutableStringListValue {
var internalValue: MutableList<String> = default var internalValue: MutableList<String> = default
val delegt = dynamicMutableList{ internalValue } val delegt = dynamicMutableList { internalValue }
return object : MutableStringListValue(), MutableList<String> by delegt { return object : MutableStringListValue(), MutableList<String> by delegt {
override var value: MutableList<String> override var value: MutableList<String>
get() = internalValue get() = internalValue
@ -1003,15 +1006,15 @@ internal fun Setting.valueImpl(
onElementChanged(this) onElementChanged(this)
} }
} }
private val outerThis get() = this private val outerThis get() = this
override val serializer: KSerializer<MutableList<String>> = object : KSerializer<MutableList<String>> { override val serializer: KSerializer<MutableList<String>> = object : KSerializer<MutableList<String>> {
private val delegate = ListSerializer(String.serializer()) private val delegate = ListSerializer(String.serializer())
override val descriptor: SerialDescriptor = delegate.descriptor override val descriptor: SerialDescriptor get() = delegate.descriptor
override fun deserialize(decoder: Decoder): MutableList<String> { override fun deserialize(decoder: Decoder): MutableList<String> {
return delegate.deserialize(decoder).toMutableList().observable { return delegate.deserialize(decoder).toMutableList().observable {
onElementChanged(outerThis) onElementChanged(outerThis)
} }
} }
@ -1029,7 +1032,7 @@ internal fun Setting.valueImpl(
): MutableIntSetValue { ): MutableIntSetValue {
var internalValue: MutableSet<Int> = default var internalValue: MutableSet<Int> = default
val delegt = dynamicMutableSet{ internalValue } val delegt = dynamicMutableSet { internalValue }
return object : MutableIntSetValue(), MutableSet<Int> by delegt { return object : MutableIntSetValue(), MutableSet<Int> by delegt {
override var value: MutableSet<Int> override var value: MutableSet<Int>
get() = internalValue get() = internalValue
@ -1039,15 +1042,15 @@ internal fun Setting.valueImpl(
onElementChanged(this) onElementChanged(this)
} }
} }
private val outerThis get() = this private val outerThis get() = this
override val serializer: KSerializer<MutableSet<Int>> = object : KSerializer<MutableSet<Int>> { override val serializer: KSerializer<MutableSet<Int>> = object : KSerializer<MutableSet<Int>> {
private val delegate = SetSerializer(Int.serializer()) private val delegate = SetSerializer(Int.serializer())
override val descriptor: SerialDescriptor = delegate.descriptor override val descriptor: SerialDescriptor get() = delegate.descriptor
override fun deserialize(decoder: Decoder): MutableSet<Int> { override fun deserialize(decoder: Decoder): MutableSet<Int> {
return delegate.deserialize(decoder).toMutableSet().observable { return delegate.deserialize(decoder).toMutableSet().observable {
onElementChanged(outerThis) onElementChanged(outerThis)
} }
} }
@ -1065,7 +1068,7 @@ internal fun Setting.valueImpl(
): MutableShortSetValue { ): MutableShortSetValue {
var internalValue: MutableSet<Short> = default var internalValue: MutableSet<Short> = default
val delegt = dynamicMutableSet{ internalValue } val delegt = dynamicMutableSet { internalValue }
return object : MutableShortSetValue(), MutableSet<Short> by delegt { return object : MutableShortSetValue(), MutableSet<Short> by delegt {
override var value: MutableSet<Short> override var value: MutableSet<Short>
get() = internalValue get() = internalValue
@ -1075,15 +1078,15 @@ internal fun Setting.valueImpl(
onElementChanged(this) onElementChanged(this)
} }
} }
private val outerThis get() = this private val outerThis get() = this
override val serializer: KSerializer<MutableSet<Short>> = object : KSerializer<MutableSet<Short>> { override val serializer: KSerializer<MutableSet<Short>> = object : KSerializer<MutableSet<Short>> {
private val delegate = SetSerializer(Short.serializer()) private val delegate = SetSerializer(Short.serializer())
override val descriptor: SerialDescriptor = delegate.descriptor override val descriptor: SerialDescriptor get() = delegate.descriptor
override fun deserialize(decoder: Decoder): MutableSet<Short> { override fun deserialize(decoder: Decoder): MutableSet<Short> {
return delegate.deserialize(decoder).toMutableSet().observable { return delegate.deserialize(decoder).toMutableSet().observable {
onElementChanged(outerThis) onElementChanged(outerThis)
} }
} }
@ -1101,7 +1104,7 @@ internal fun Setting.valueImpl(
): MutableByteSetValue { ): MutableByteSetValue {
var internalValue: MutableSet<Byte> = default var internalValue: MutableSet<Byte> = default
val delegt = dynamicMutableSet{ internalValue } val delegt = dynamicMutableSet { internalValue }
return object : MutableByteSetValue(), MutableSet<Byte> by delegt { return object : MutableByteSetValue(), MutableSet<Byte> by delegt {
override var value: MutableSet<Byte> override var value: MutableSet<Byte>
get() = internalValue get() = internalValue
@ -1111,15 +1114,15 @@ internal fun Setting.valueImpl(
onElementChanged(this) onElementChanged(this)
} }
} }
private val outerThis get() = this private val outerThis get() = this
override val serializer: KSerializer<MutableSet<Byte>> = object : KSerializer<MutableSet<Byte>> { override val serializer: KSerializer<MutableSet<Byte>> = object : KSerializer<MutableSet<Byte>> {
private val delegate = SetSerializer(Byte.serializer()) private val delegate = SetSerializer(Byte.serializer())
override val descriptor: SerialDescriptor = delegate.descriptor override val descriptor: SerialDescriptor get() = delegate.descriptor
override fun deserialize(decoder: Decoder): MutableSet<Byte> { override fun deserialize(decoder: Decoder): MutableSet<Byte> {
return delegate.deserialize(decoder).toMutableSet().observable { return delegate.deserialize(decoder).toMutableSet().observable {
onElementChanged(outerThis) onElementChanged(outerThis)
} }
} }
@ -1137,7 +1140,7 @@ internal fun Setting.valueImpl(
): MutableLongSetValue { ): MutableLongSetValue {
var internalValue: MutableSet<Long> = default var internalValue: MutableSet<Long> = default
val delegt = dynamicMutableSet{ internalValue } val delegt = dynamicMutableSet { internalValue }
return object : MutableLongSetValue(), MutableSet<Long> by delegt { return object : MutableLongSetValue(), MutableSet<Long> by delegt {
override var value: MutableSet<Long> override var value: MutableSet<Long>
get() = internalValue get() = internalValue
@ -1147,15 +1150,15 @@ internal fun Setting.valueImpl(
onElementChanged(this) onElementChanged(this)
} }
} }
private val outerThis get() = this private val outerThis get() = this
override val serializer: KSerializer<MutableSet<Long>> = object : KSerializer<MutableSet<Long>> { override val serializer: KSerializer<MutableSet<Long>> = object : KSerializer<MutableSet<Long>> {
private val delegate = SetSerializer(Long.serializer()) private val delegate = SetSerializer(Long.serializer())
override val descriptor: SerialDescriptor = delegate.descriptor override val descriptor: SerialDescriptor get() = delegate.descriptor
override fun deserialize(decoder: Decoder): MutableSet<Long> { override fun deserialize(decoder: Decoder): MutableSet<Long> {
return delegate.deserialize(decoder).toMutableSet().observable { return delegate.deserialize(decoder).toMutableSet().observable {
onElementChanged(outerThis) onElementChanged(outerThis)
} }
} }
@ -1173,7 +1176,7 @@ internal fun Setting.valueImpl(
): MutableFloatSetValue { ): MutableFloatSetValue {
var internalValue: MutableSet<Float> = default var internalValue: MutableSet<Float> = default
val delegt = dynamicMutableSet{ internalValue } val delegt = dynamicMutableSet { internalValue }
return object : MutableFloatSetValue(), MutableSet<Float> by delegt { return object : MutableFloatSetValue(), MutableSet<Float> by delegt {
override var value: MutableSet<Float> override var value: MutableSet<Float>
get() = internalValue get() = internalValue
@ -1183,15 +1186,15 @@ internal fun Setting.valueImpl(
onElementChanged(this) onElementChanged(this)
} }
} }
private val outerThis get() = this private val outerThis get() = this
override val serializer: KSerializer<MutableSet<Float>> = object : KSerializer<MutableSet<Float>> { override val serializer: KSerializer<MutableSet<Float>> = object : KSerializer<MutableSet<Float>> {
private val delegate = SetSerializer(Float.serializer()) private val delegate = SetSerializer(Float.serializer())
override val descriptor: SerialDescriptor = delegate.descriptor override val descriptor: SerialDescriptor get() = delegate.descriptor
override fun deserialize(decoder: Decoder): MutableSet<Float> { override fun deserialize(decoder: Decoder): MutableSet<Float> {
return delegate.deserialize(decoder).toMutableSet().observable { return delegate.deserialize(decoder).toMutableSet().observable {
onElementChanged(outerThis) onElementChanged(outerThis)
} }
} }
@ -1209,7 +1212,7 @@ internal fun Setting.valueImpl(
): MutableDoubleSetValue { ): MutableDoubleSetValue {
var internalValue: MutableSet<Double> = default var internalValue: MutableSet<Double> = default
val delegt = dynamicMutableSet{ internalValue } val delegt = dynamicMutableSet { internalValue }
return object : MutableDoubleSetValue(), MutableSet<Double> by delegt { return object : MutableDoubleSetValue(), MutableSet<Double> by delegt {
override var value: MutableSet<Double> override var value: MutableSet<Double>
get() = internalValue get() = internalValue
@ -1219,15 +1222,15 @@ internal fun Setting.valueImpl(
onElementChanged(this) onElementChanged(this)
} }
} }
private val outerThis get() = this private val outerThis get() = this
override val serializer: KSerializer<MutableSet<Double>> = object : KSerializer<MutableSet<Double>> { override val serializer: KSerializer<MutableSet<Double>> = object : KSerializer<MutableSet<Double>> {
private val delegate = SetSerializer(Double.serializer()) private val delegate = SetSerializer(Double.serializer())
override val descriptor: SerialDescriptor = delegate.descriptor override val descriptor: SerialDescriptor get() = delegate.descriptor
override fun deserialize(decoder: Decoder): MutableSet<Double> { override fun deserialize(decoder: Decoder): MutableSet<Double> {
return delegate.deserialize(decoder).toMutableSet().observable { return delegate.deserialize(decoder).toMutableSet().observable {
onElementChanged(outerThis) onElementChanged(outerThis)
} }
} }
@ -1245,7 +1248,7 @@ internal fun Setting.valueImpl(
): MutableBooleanSetValue { ): MutableBooleanSetValue {
var internalValue: MutableSet<Boolean> = default var internalValue: MutableSet<Boolean> = default
val delegt = dynamicMutableSet{ internalValue } val delegt = dynamicMutableSet { internalValue }
return object : MutableBooleanSetValue(), MutableSet<Boolean> by delegt { return object : MutableBooleanSetValue(), MutableSet<Boolean> by delegt {
override var value: MutableSet<Boolean> override var value: MutableSet<Boolean>
get() = internalValue get() = internalValue
@ -1255,15 +1258,15 @@ internal fun Setting.valueImpl(
onElementChanged(this) onElementChanged(this)
} }
} }
private val outerThis get() = this private val outerThis get() = this
override val serializer: KSerializer<MutableSet<Boolean>> = object : KSerializer<MutableSet<Boolean>> { override val serializer: KSerializer<MutableSet<Boolean>> = object : KSerializer<MutableSet<Boolean>> {
private val delegate = SetSerializer(Boolean.serializer()) private val delegate = SetSerializer(Boolean.serializer())
override val descriptor: SerialDescriptor = delegate.descriptor override val descriptor: SerialDescriptor get() = delegate.descriptor
override fun deserialize(decoder: Decoder): MutableSet<Boolean> { override fun deserialize(decoder: Decoder): MutableSet<Boolean> {
return delegate.deserialize(decoder).toMutableSet().observable { return delegate.deserialize(decoder).toMutableSet().observable {
onElementChanged(outerThis) onElementChanged(outerThis)
} }
} }
@ -1281,7 +1284,7 @@ internal fun Setting.valueImpl(
): MutableCharSetValue { ): MutableCharSetValue {
var internalValue: MutableSet<Char> = default var internalValue: MutableSet<Char> = default
val delegt = dynamicMutableSet{ internalValue } val delegt = dynamicMutableSet { internalValue }
return object : MutableCharSetValue(), MutableSet<Char> by delegt { return object : MutableCharSetValue(), MutableSet<Char> by delegt {
override var value: MutableSet<Char> override var value: MutableSet<Char>
get() = internalValue get() = internalValue
@ -1291,15 +1294,15 @@ internal fun Setting.valueImpl(
onElementChanged(this) onElementChanged(this)
} }
} }
private val outerThis get() = this private val outerThis get() = this
override val serializer: KSerializer<MutableSet<Char>> = object : KSerializer<MutableSet<Char>> { override val serializer: KSerializer<MutableSet<Char>> = object : KSerializer<MutableSet<Char>> {
private val delegate = SetSerializer(Char.serializer()) private val delegate = SetSerializer(Char.serializer())
override val descriptor: SerialDescriptor = delegate.descriptor override val descriptor: SerialDescriptor get() = delegate.descriptor
override fun deserialize(decoder: Decoder): MutableSet<Char> { override fun deserialize(decoder: Decoder): MutableSet<Char> {
return delegate.deserialize(decoder).toMutableSet().observable { return delegate.deserialize(decoder).toMutableSet().observable {
onElementChanged(outerThis) onElementChanged(outerThis)
} }
} }
@ -1317,7 +1320,7 @@ internal fun Setting.valueImpl(
): MutableStringSetValue { ): MutableStringSetValue {
var internalValue: MutableSet<String> = default var internalValue: MutableSet<String> = default
val delegt = dynamicMutableSet{ internalValue } val delegt = dynamicMutableSet { internalValue }
return object : MutableStringSetValue(), MutableSet<String> by delegt { return object : MutableStringSetValue(), MutableSet<String> by delegt {
override var value: MutableSet<String> override var value: MutableSet<String>
get() = internalValue get() = internalValue
@ -1327,15 +1330,15 @@ internal fun Setting.valueImpl(
onElementChanged(this) onElementChanged(this)
} }
} }
private val outerThis get() = this private val outerThis get() = this
override val serializer: KSerializer<MutableSet<String>> = object : KSerializer<MutableSet<String>> { override val serializer: KSerializer<MutableSet<String>> = object : KSerializer<MutableSet<String>> {
private val delegate = SetSerializer(String.serializer()) private val delegate = SetSerializer(String.serializer())
override val descriptor: SerialDescriptor = delegate.descriptor override val descriptor: SerialDescriptor get() = delegate.descriptor
override fun deserialize(decoder: Decoder): MutableSet<String> { override fun deserialize(decoder: Decoder): MutableSet<String> {
return delegate.deserialize(decoder).toMutableSet().observable { return delegate.deserialize(decoder).toMutableSet().observable {
onElementChanged(outerThis) onElementChanged(outerThis)
} }
} }
@ -1359,7 +1362,7 @@ internal fun <T : Setting> Setting.valueImpl(default: T): Value<T> {
onElementChanged(this) onElementChanged(this)
} }
} }
override val serializer = object : KSerializer<T>{ override val serializer = object : KSerializer<T> {
override val descriptor: SerialDescriptor override val descriptor: SerialDescriptor
get() = internalValue.updaterSerializer.descriptor get() = internalValue.updaterSerializer.descriptor

View File

@ -24,7 +24,7 @@ import kotlin.reflect.full.findAnnotation
internal abstract class SettingImpl { internal abstract class SettingImpl {
@JvmField @JvmField
internal var valueList: MutableList<Pair<Value<*>, KProperty<*>>> = mutableListOf() internal var valueList: MutableList<Pair<Value<*>, Setting.PropertyInfo>> = mutableListOf()
@JvmField @JvmField
internal var built: Boolean = false internal var built: Boolean = false
@ -53,9 +53,7 @@ internal abstract class SettingImpl {
} }
} }
internal fun onElementChanged(value: Value<*>) { abstract fun onElementChanged(value: Value<*>)
println("my value changed!")
}
companion object { companion object {
@JvmStatic @JvmStatic
@ -78,8 +76,9 @@ internal class SettingUpdaterSerializer(
override val descriptor: SerialDescriptor by lazy { override val descriptor: SerialDescriptor by lazy {
@OptIn(MiraiExperimentalAPI::class) @OptIn(MiraiExperimentalAPI::class)
SerialDescriptor(instance.serialName) { SerialDescriptor(instance.serialName) {
for ((value, property) in instance.valueList) { for ((value, prop) in instance.valueList) {
element(property.serialNameOrPropertyName, value.serializer.descriptor, annotations, true) val (serialName, annotations) = prop
element(serialName, value.serializer.descriptor, annotations, true)
} }
} }
} }

View File

@ -17,7 +17,9 @@ import net.mamoe.mirai.console.setting.*
import net.mamoe.yamlkt.YamlDynamicSerializer import net.mamoe.yamlkt.YamlDynamicSerializer
import kotlin.internal.LowPriorityInOverloadResolution import kotlin.internal.LowPriorityInOverloadResolution
import kotlin.reflect.KClass import kotlin.reflect.KClass
import kotlin.reflect.KType
import kotlin.reflect.full.createInstance import kotlin.reflect.full.createInstance
import kotlin.reflect.typeOf
/// region MUTABLE LIST /// region MUTABLE LIST
@ -291,6 +293,7 @@ internal fun <T : Any> Setting.valueImpl(
/** /**
* For primitives and serializable only * For primitives and serializable only
*/ */
@OptIn(ExperimentalStdlibApi::class)
@PublishedApi @PublishedApi
@LowPriorityInOverloadResolution @LowPriorityInOverloadResolution
internal inline fun <reified T : Any> Setting.valueImpl(default: T): Value<T> = internal inline fun <reified T : Any> Setting.valueImpl(default: T): Value<T> =

View File

@ -6,14 +6,21 @@
* *
* https://github.com/mamoe/mirai/blob/master/LICENSE * https://github.com/mamoe/mirai/blob/master/LICENSE
*/ */
@file:JvmName("BotManagers")
package net.mamoe.mirai.console.utils package net.mamoe.mirai.console.utils
import kotlinx.atomicfu.locks.withLock
import net.mamoe.mirai.Bot import net.mamoe.mirai.Bot
import net.mamoe.mirai.console.MiraiConsole import net.mamoe.mirai.console.setting.Value
import net.mamoe.mirai.console.plugins.* import net.mamoe.mirai.console.setting.internal.ConsoleBuiltInSetting
import net.mamoe.mirai.console.setting.value
import net.mamoe.mirai.contact.User import net.mamoe.mirai.contact.User
import java.io.File import java.util.concurrent.TimeUnit
import java.util.concurrent.locks.Condition
import java.util.concurrent.locks.Lock
import java.util.concurrent.locks.ReentrantLock
import kotlin.properties.ReadWriteProperty
/** /**
@ -32,15 +39,4 @@ fun Bot.removeManager(long: Long) {
} }
val Bot.managers: List<Long> val Bot.managers: List<Long>
get() { get() = TODO()
TODO()
}
fun Bot.checkManager(long: Long): Boolean {
return this.managers.contains(long)
}
fun getBotManagers(bot: Bot): List<Long> {
return bot.managers
}

View File

@ -0,0 +1,8 @@
package net.mamoe.mirai.console.utils
/**
* 表明这个 API 是为了让 Java 使用者调用更方便. Kotlin 使用者不应该使用这些 API.
*/
@RequiresOptIn(level = RequiresOptIn.Level.ERROR)
@Target(AnnotationTarget.PROPERTY, AnnotationTarget.FUNCTION, AnnotationTarget.TYPE, AnnotationTarget.CLASS)
internal annotation class JavaFriendlyAPI

View File

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

View File

@ -12,14 +12,20 @@
package net.mamoe.mirai.console.command package net.mamoe.mirai.console.command
import net.mamoe.mirai.Bot import net.mamoe.mirai.Bot
import net.mamoe.mirai.console.plugins.builtin.KotlinPlugin import net.mamoe.mirai.console.plugin.jvm.KotlinPlugin
import net.mamoe.mirai.console.setting.value
import net.mamoe.mirai.message.data.* import net.mamoe.mirai.message.data.*
import org.junit.jupiter.api.Test import org.junit.jupiter.api.Test
import kotlin.test.assertEquals import kotlin.test.assertEquals
val plugin: KotlinPlugin = object : KotlinPlugin() { val plugin = MyPlugin()
class MyPlugin : KotlinPlugin() {
inner class MySetting : PluginSetting() {
val int by value(1)
}
} }
/* /*
@ -94,9 +100,6 @@ internal inline fun withSender(block: CommandSender.() -> Unit): MessageChain {
result.add(message) result.add(message)
} }
override fun appendMessage(message: String) {
result.add(message)
}
} }
sender.let(block) sender.let(block)
return result.asMessageChain() return result.asMessageChain()