Cleanup, remove old settings

This commit is contained in:
Him188 2020-06-17 13:25:36 +08:00
parent 11cb8d5c68
commit 687729df4e
14 changed files with 10 additions and 2544 deletions

View File

@ -16,8 +16,6 @@ import net.mamoe.mirai.Bot
import net.mamoe.mirai.console.plugin.PluginLoader
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.MiraiExperimentalAPI
import net.mamoe.mirai.utils.MiraiLogger
@ -72,14 +70,6 @@ object MiraiConsole : CoroutineScope, IMiraiConsole {
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 {
DefaultLogger = { identity -> this.newLogger(identity) }
this.coroutineContext[Job]!!.invokeOnCompletion {
@ -116,16 +106,6 @@ internal interface IMiraiConsole : CoroutineScope {
* 内建加载器列表, 一般需要包含 [JarPluginLoader]
*/
val builtInPluginLoaders: List<PluginLoader<*, *>>
/**
* 内建的供 [JvmPlugin] 使用的 [SettingStorage]
*/
val jvmSettingStorage: SettingStorage
/**
* 内建的供 [ConsoleBuiltInSetting] 使用的 [SettingStorage]
*/
val consoleBuiltIntSettingStorage: SettingStorage
}
/**

View File

@ -15,7 +15,6 @@ import net.mamoe.mirai.console.plugin.AbstractFilePluginLoader
import net.mamoe.mirai.console.plugin.PluginLoadException
import net.mamoe.mirai.console.plugin.internal.JvmPluginImpl
import net.mamoe.mirai.console.plugin.internal.PluginsLoader
import net.mamoe.mirai.console.setting.SettingStorage
import net.mamoe.mirai.utils.MiraiLogger
import net.mamoe.yamlkt.Yaml
import java.io.File
@ -49,8 +48,6 @@ object JarPluginLoader : AbstractFilePluginLoader<JvmPlugin, JvmPluginDescriptio
}
}
val settingStorage: SettingStorage = MiraiConsole.jvmSettingStorage
override fun getPluginDescription(plugin: JvmPlugin): JvmPluginDescription = plugin.description
override fun Sequence<File>.mapToDescription(): List<JvmPluginDescription> {

View File

@ -12,9 +12,6 @@
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
@ -23,20 +20,4 @@ import kotlin.coroutines.EmptyCoroutineContext
*/
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()
}
}
}
) : JvmPlugin, JvmPluginImpl(parentCoroutineContext)

View File

@ -1,115 +0,0 @@
/*
* Copyright 2020 Mamoe Technologies and contributors.
*
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
* Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
*
* https://github.com/mamoe/mirai/blob/master/LICENSE
*/
@file:Suppress("NOTHING_TO_INLINE", "unused")
package net.mamoe.mirai.console.setting
import kotlinx.serialization.KSerializer
import net.mamoe.mirai.console.setting.internal.SettingImpl
import net.mamoe.mirai.console.setting.internal.serialNameOrPropertyName
import net.mamoe.mirai.utils.MiraiExperimentalAPI
import kotlin.properties.ReadWriteProperty
import kotlin.reflect.KProperty
import kotlin.reflect.KProperty0
import kotlin.reflect.full.findAnnotation
/**
* 在配置文件和图像界面中保存的名称.
*/
typealias SerialName = kotlinx.serialization.SerialName
/**
* 在配置文件和图像界面中显示的说明.
*/
typealias Comment = net.mamoe.yamlkt.Comment
/**
* 配置的基类. 所有配置必须拥有一个无参构造器, 以用于在 [MutableList] [MutableMap] 中动态识别类型
*/
@Suppress("EXPOSED_SUPER_CLASS")
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?
)
/**
* 这个配置的名称, 仅对于顶层配置有效.
*/
@MiraiExperimentalAPI
open val serialName: String
get() = this::class.findAnnotation<SerialName>()?.value
?: this::class.qualifiedName
?: 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>?
}
/**
* 提供属性委托, 并添加这个对象的自动保存跟踪.
*/
@JvmSynthetic
operator fun <T : Any> Value<T>.provideDelegate(
thisRef: Setting,
property: KProperty<*>
): ReadWriteProperty<Setting, T> {
if (built) error("The Setting is already serialized so it's structure is immutable.")
valueList.add(this to PropertyInfo(property.serialNameOrPropertyName, property.annotations, property.name))
return this
}
abstract override fun onElementChanged(value: Value<*>)
override fun toString(): String = yamlForToString.stringify(this.serializer, this)
}
/**
* 用于更新或保存这个 [Value] 的序列化器.
*/
@Suppress("UNCHECKED_CAST")
val <T : Setting> T.serializer: KSerializer<T>
get() = kotlinSerializer as KSerializer<T>

View File

@ -1,65 +0,0 @@
@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

@ -1,167 +0,0 @@
/*
* Copyright 2020 Mamoe Technologies and contributors.
*
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
* Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
*
* https://github.com/mamoe/mirai/blob/master/LICENSE
*/
@file:Suppress("INVISIBLE_REFERENCE", "INVISIBLE_MEMBER", "unused")
package net.mamoe.mirai.console.setting
import net.mamoe.mirai.console.setting.internal.valueImpl
import kotlin.internal.LowPriorityInOverloadResolution
/**
* !!! This file is auto-generated by backend/codegen/src/kotlin/net.mamoe.mirai.console.codegen.SettingValueUseSiteCodegen.kt
* !!! DO NOT MODIFY THIS FILE MANUALLY
*/
fun Setting.value(default: Int): IntValue = valueImpl(default)
fun Setting.value(default: Short): ShortValue = valueImpl(default)
fun Setting.value(default: Byte): ByteValue = valueImpl(default)
fun Setting.value(default: Long): LongValue = valueImpl(default)
fun Setting.value(default: Float): FloatValue = valueImpl(default)
fun Setting.value(default: Double): DoubleValue = valueImpl(default)
fun Setting.value(default: Boolean): BooleanValue = valueImpl(default)
fun Setting.value(default: Char): CharValue = valueImpl(default)
fun Setting.value(default: String): StringValue = valueImpl(default)
fun Setting.value(default: IntArray): IntArrayValue = valueImpl(default)
fun Setting.value(default: ShortArray): ShortArrayValue = valueImpl(default)
fun Setting.value(default: ByteArray): ByteArrayValue = valueImpl(default)
fun Setting.value(default: LongArray): LongArrayValue = valueImpl(default)
fun Setting.value(default: FloatArray): FloatArrayValue = valueImpl(default)
fun Setting.value(default: DoubleArray): DoubleArrayValue = valueImpl(default)
fun Setting.value(default: BooleanArray): BooleanArrayValue = valueImpl(default)
fun Setting.value(default: CharArray): CharArrayValue = valueImpl(default)
fun Setting.value(default: Array<Int>): TypedIntArrayValue = valueImpl(default)
fun Setting.value(default: Array<Short>): TypedShortArrayValue = valueImpl(default)
fun Setting.value(default: Array<Byte>): TypedByteArrayValue = valueImpl(default)
fun Setting.value(default: Array<Long>): TypedLongArrayValue = valueImpl(default)
fun Setting.value(default: Array<Float>): TypedFloatArrayValue = valueImpl(default)
fun Setting.value(default: Array<Double>): TypedDoubleArrayValue = valueImpl(default)
fun Setting.value(default: Array<Boolean>): TypedBooleanArrayValue = valueImpl(default)
fun Setting.value(default: Array<Char>): TypedCharArrayValue = valueImpl(default)
fun Setting.value(default: Array<String>): TypedStringArrayValue = valueImpl(default)
fun Setting.value(default: List<Int>): IntListValue = valueImpl(default)
fun Setting.value(default: List<Short>): ShortListValue = valueImpl(default)
fun Setting.value(default: List<Byte>): ByteListValue = valueImpl(default)
fun Setting.value(default: List<Long>): LongListValue = valueImpl(default)
fun Setting.value(default: List<Float>): FloatListValue = valueImpl(default)
fun Setting.value(default: List<Double>): DoubleListValue = valueImpl(default)
fun Setting.value(default: List<Boolean>): BooleanListValue = valueImpl(default)
fun Setting.value(default: List<Char>): CharListValue = valueImpl(default)
fun Setting.value(default: List<String>): StringListValue = valueImpl(default)
fun Setting.value(default: Set<Int>): IntSetValue = valueImpl(default)
fun Setting.value(default: Set<Short>): ShortSetValue = valueImpl(default)
fun Setting.value(default: Set<Byte>): ByteSetValue = valueImpl(default)
fun Setting.value(default: Set<Long>): LongSetValue = valueImpl(default)
fun Setting.value(default: Set<Float>): FloatSetValue = valueImpl(default)
fun Setting.value(default: Set<Double>): DoubleSetValue = valueImpl(default)
fun Setting.value(default: Set<Boolean>): BooleanSetValue = valueImpl(default)
fun Setting.value(default: Set<Char>): CharSetValue = valueImpl(default)
fun Setting.value(default: Set<String>): StringSetValue = valueImpl(default)
@JvmName("valueMutable")
fun Setting.value(default: MutableList<Int>): MutableIntListValue = valueImpl(default)
@JvmName("valueMutable")
fun Setting.value(default: MutableList<Short>): MutableShortListValue = valueImpl(default)
@JvmName("valueMutable")
fun Setting.value(default: MutableList<Byte>): MutableByteListValue = valueImpl(default)
@JvmName("valueMutable")
fun Setting.value(default: MutableList<Long>): MutableLongListValue = valueImpl(default)
@JvmName("valueMutable")
fun Setting.value(default: MutableList<Float>): MutableFloatListValue = valueImpl(default)
@JvmName("valueMutable")
fun Setting.value(default: MutableList<Double>): MutableDoubleListValue = valueImpl(default)
@JvmName("valueMutable")
fun Setting.value(default: MutableList<Boolean>): MutableBooleanListValue = valueImpl(default)
@JvmName("valueMutable")
fun Setting.value(default: MutableList<Char>): MutableCharListValue = valueImpl(default)
@JvmName("valueMutable")
fun Setting.value(default: MutableList<String>): MutableStringListValue = valueImpl(default)
@JvmName("valueMutable")
fun Setting.value(default: MutableSet<Int>): MutableIntSetValue = valueImpl(default)
@JvmName("valueMutable")
fun Setting.value(default: MutableSet<Short>): MutableShortSetValue = valueImpl(default)
@JvmName("valueMutable")
fun Setting.value(default: MutableSet<Byte>): MutableByteSetValue = valueImpl(default)
@JvmName("valueMutable")
fun Setting.value(default: MutableSet<Long>): MutableLongSetValue = valueImpl(default)
@JvmName("valueMutable")
fun Setting.value(default: MutableSet<Float>): MutableFloatSetValue = valueImpl(default)
@JvmName("valueMutable")
fun Setting.value(default: MutableSet<Double>): MutableDoubleSetValue = valueImpl(default)
@JvmName("valueMutable")
fun Setting.value(default: MutableSet<Boolean>): MutableBooleanSetValue = valueImpl(default)
@JvmName("valueMutable")
fun Setting.value(default: MutableSet<Char>): MutableCharSetValue = valueImpl(default)
@JvmName("valueMutable")
fun Setting.value(default: MutableSet<String>): MutableStringSetValue = valueImpl(default)
fun <T : Setting> Setting.value(default: T): Value<T> {
require(this::class != default::class) {
"Recursive nesting is prohibited"
}
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> =
value(default).also { it.value.apply(initializer) }
inline fun <reified T : Setting> Setting.value(default: List<T>): SettingListValue<T> = valueImpl(default)
@JvmName("valueMutable")
inline fun <reified T : Setting> Setting.value(default: MutableList<T>): MutableSettingListValue<T> = valueImpl(default)
inline fun <reified T : Setting> Setting.value(default: Set<T>): SettingSetValue<T> = valueImpl(default)
@JvmName("valueMutable")
inline fun <reified T : Setting> Setting.value(default: MutableSet<T>): MutableSettingSetValue<T> = valueImpl(default)
/**
* 创建一个只引用对象而不跟踪其属性的值.
*
* @param T 类型. 必须拥有 [kotlinx.serialization.Serializable] 注解 (因此编译器会自动生成序列化器)
*/
@DangerousReferenceOnlyValue
@JvmName("valueDynamic")
@LowPriorityInOverloadResolution
inline fun <reified T : Any> Setting.value(default: T): Value<T> = valueImpl(default)
@RequiresOptIn(
"""
这种只保存引用的 Value 可能会导致意料之外的结果, 在使用时须保持谨慎.
对值的改变不会触发自动保存, 也不会同步到 UI . UI 中只能编辑序列化之后的值.
""", level = RequiresOptIn.Level.WARNING
)
@Retention(AnnotationRetention.BINARY)
@Target(AnnotationTarget.FUNCTION)
annotation class DangerousReferenceOnlyValue

View File

@ -1,170 +0,0 @@
/*
* Copyright 2020 Mamoe Technologies and contributors.
*
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
* Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
*
* https://github.com/mamoe/mirai/blob/master/LICENSE
*/
package net.mamoe.mirai.console.setting
import kotlinx.serialization.KSerializer
import kotlin.properties.ReadWriteProperty
import kotlin.reflect.KProperty
/**
* !!! This file is auto-generated by backend/codegen/src/main/kotlin/net.mamoe.mirai.console.codegen.ValuesCodegen.kt
* !!! for better performance
* !!! DO NOT MODIFY THIS FILE MANUALLY
*/
sealed class Value<T : Any> : ReadWriteProperty<Setting, T> {
abstract var value: T
/**
* 用于更新 [value] 的序列化器
*/
abstract val serializer: KSerializer<T>
override fun getValue(thisRef: Setting, property: KProperty<*>): T = value
override fun setValue(thisRef: Setting, property: KProperty<*>, value: T) {
this.value = value
}
override fun equals(other: Any?): Boolean {
if (other == null) return false
if (other::class != this::class) return false
other as Value<*>
return other.value == this.value
}
override fun hashCode(): Int = value.hashCode()
}
sealed class PrimitiveValue<T : Any> : Value<T>()
sealed class NumberValue<T : Number> : Value<T>()
abstract class IntValue internal constructor() : NumberValue<Int>()
abstract class ShortValue internal constructor() : NumberValue<Short>()
abstract class ByteValue internal constructor() : NumberValue<Byte>()
abstract class LongValue internal constructor() : NumberValue<Long>()
abstract class FloatValue internal constructor() : NumberValue<Float>()
abstract class DoubleValue internal constructor() : NumberValue<Double>()
abstract class BooleanValue internal constructor() : PrimitiveValue<Boolean>()
abstract class CharValue internal constructor() : PrimitiveValue<Char>()
abstract class StringValue internal constructor() : PrimitiveValue<String>()
// T can be primitive array or typed Array
sealed class ArrayValue<T : Any> : Value<T>()
sealed class PrimitiveArrayValue<T : Any> : ArrayValue<T>()
abstract class IntArrayValue internal constructor() : PrimitiveArrayValue<IntArray>(), Iterable<Int> {
override fun iterator(): Iterator<Int> = this.value.iterator()
}
abstract class ShortArrayValue internal constructor() : PrimitiveArrayValue<ShortArray>(), Iterable<Short> {
override fun iterator(): Iterator<Short> = this.value.iterator()
}
abstract class ByteArrayValue internal constructor() : PrimitiveArrayValue<ByteArray>(), Iterable<Byte> {
override fun iterator(): Iterator<Byte> = this.value.iterator()
}
abstract class LongArrayValue internal constructor() : PrimitiveArrayValue<LongArray>(), Iterable<Long> {
override fun iterator(): Iterator<Long> = this.value.iterator()
}
abstract class FloatArrayValue internal constructor() : PrimitiveArrayValue<FloatArray>(), Iterable<Float> {
override fun iterator(): Iterator<Float> = this.value.iterator()
}
abstract class DoubleArrayValue internal constructor() : PrimitiveArrayValue<DoubleArray>(), Iterable<Double> {
override fun iterator(): Iterator<Double> = this.value.iterator()
}
abstract class BooleanArrayValue internal constructor() : PrimitiveArrayValue<BooleanArray>(), Iterable<Boolean> {
override fun iterator(): Iterator<Boolean> = this.value.iterator()
}
abstract class CharArrayValue internal constructor() : PrimitiveArrayValue<CharArray>(), Iterable<Char> {
override fun iterator(): Iterator<Char> = this.value.iterator()
}
sealed class TypedPrimitiveArrayValue<E> : ArrayValue<Array<E>>(), Iterable<E> {
override fun iterator() = this.value.iterator()
}
abstract class TypedIntArrayValue internal constructor() : TypedPrimitiveArrayValue<Int>()
abstract class TypedShortArrayValue internal constructor() : TypedPrimitiveArrayValue<Short>()
abstract class TypedByteArrayValue internal constructor() : TypedPrimitiveArrayValue<Byte>()
abstract class TypedLongArrayValue internal constructor() : TypedPrimitiveArrayValue<Long>()
abstract class TypedFloatArrayValue internal constructor() : TypedPrimitiveArrayValue<Float>()
abstract class TypedDoubleArrayValue internal constructor() : TypedPrimitiveArrayValue<Double>()
abstract class TypedBooleanArrayValue internal constructor() : TypedPrimitiveArrayValue<Boolean>()
abstract class TypedCharArrayValue internal constructor() : TypedPrimitiveArrayValue<Char>()
abstract class TypedStringArrayValue internal constructor() : TypedPrimitiveArrayValue<String>()
sealed class ListValue<E> : Value<List<E>>(), List<E>
abstract class IntListValue internal constructor() : ListValue<Int>()
abstract class ShortListValue internal constructor() : ListValue<Short>()
abstract class ByteListValue internal constructor() : ListValue<Byte>()
abstract class LongListValue internal constructor() : ListValue<Long>()
abstract class FloatListValue internal constructor() : ListValue<Float>()
abstract class DoubleListValue internal constructor() : ListValue<Double>()
abstract class BooleanListValue internal constructor() : ListValue<Boolean>()
abstract class CharListValue internal constructor() : ListValue<Char>()
abstract class StringListValue internal constructor() : ListValue<String>()
abstract class SettingListValue<T : Setting> internal constructor() : Value<List<T>>(), List<T>
sealed class SetValue<E> : Value<Set<E>>(), Set<E>
abstract class IntSetValue internal constructor() : SetValue<Int>()
abstract class ShortSetValue internal constructor() : SetValue<Short>()
abstract class ByteSetValue internal constructor() : SetValue<Byte>()
abstract class LongSetValue internal constructor() : SetValue<Long>()
abstract class FloatSetValue internal constructor() : SetValue<Float>()
abstract class DoubleSetValue internal constructor() : SetValue<Double>()
abstract class BooleanSetValue internal constructor() : SetValue<Boolean>()
abstract class CharSetValue internal constructor() : SetValue<Char>()
abstract class StringSetValue internal constructor() : SetValue<String>()
abstract class SettingSetValue<T : Setting> internal constructor() : Value<Set<T>>(), Set<T>
abstract class SettingValue<T : Setting> internal constructor() : Value<T>()
abstract class MutableListValue<T : Any> internal constructor() : Value<MutableList<Value<T>>>(), MutableList<T>
abstract class MutableIntListValue internal constructor() : Value<MutableList<Int>>(), MutableList<Int>
abstract class MutableShortListValue internal constructor() : Value<MutableList<Short>>(), MutableList<Short>
abstract class MutableByteListValue internal constructor() : Value<MutableList<Byte>>(), MutableList<Byte>
abstract class MutableLongListValue internal constructor() : Value<MutableList<Long>>(), MutableList<Long>
abstract class MutableFloatListValue internal constructor() : Value<MutableList<Float>>(), MutableList<Float>
abstract class MutableDoubleListValue internal constructor() : Value<MutableList<Double>>(), MutableList<Double>
abstract class MutableBooleanListValue internal constructor() : Value<MutableList<Boolean>>(), MutableList<Boolean>
abstract class MutableCharListValue internal constructor() : Value<MutableList<Char>>(), MutableList<Char>
abstract class MutableStringListValue internal constructor() : Value<MutableList<String>>(), MutableList<String>
abstract class MutableSettingListValue<T : Setting> internal constructor() : Value<MutableList<T>>(), MutableList<T>
abstract class MutableSetValue<T : Any> internal constructor() : Value<MutableSet<Value<T>>>(), MutableSet<T>
abstract class MutableIntSetValue internal constructor() : Value<MutableSet<Int>>(), MutableSet<Int>
abstract class MutableShortSetValue internal constructor() : Value<MutableSet<Short>>(), MutableSet<Short>
abstract class MutableByteSetValue internal constructor() : Value<MutableSet<Byte>>(), MutableSet<Byte>
abstract class MutableLongSetValue internal constructor() : Value<MutableSet<Long>>(), MutableSet<Long>
abstract class MutableFloatSetValue internal constructor() : Value<MutableSet<Float>>(), MutableSet<Float>
abstract class MutableDoubleSetValue internal constructor() : Value<MutableSet<Double>>(), MutableSet<Double>
abstract class MutableBooleanSetValue internal constructor() : Value<MutableSet<Boolean>>(), MutableSet<Boolean>
abstract class MutableCharSetValue internal constructor() : Value<MutableSet<Char>>(), MutableSet<Char>
abstract class MutableStringSetValue internal constructor() : Value<MutableSet<String>>(), MutableSet<String>
abstract class MutableSettingSetValue<T : Setting> internal constructor() : Value<MutableSet<T>>(), MutableSet<T>
/**
* 只引用这个对象, 而不跟踪其成员.
* 仅适用于基础类型, 用于 mutable list/map 等情况; 或标注了 [Serializable] 的类.
*/
abstract class DynamicReferenceValue<T : Any> internal constructor() : Value<T>()

View File

@ -1,32 +0,0 @@
/*
* Copyright 2020 Mamoe Technologies and contributors.
*
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
* Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
*
* https://github.com/mamoe/mirai/blob/master/LICENSE
*/
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

@ -12,140 +12,12 @@ package net.mamoe.mirai.console.setting.internal
import kotlinx.serialization.*
import kotlinx.serialization.builtins.ListSerializer
import kotlinx.serialization.builtins.serializer
import net.mamoe.mirai.console.setting.SerialName
import net.mamoe.mirai.console.setting.Setting
import net.mamoe.mirai.console.setting.Value
import net.mamoe.mirai.utils.MiraiExperimentalAPI
import net.mamoe.yamlkt.Yaml
import net.mamoe.yamlkt.YamlConfiguration
import kotlin.reflect.KProperty
import kotlin.reflect.full.findAnnotation
internal abstract class SettingImpl {
@JvmField
internal var valueList: MutableList<Pair<Value<*>, Setting.PropertyInfo>> = mutableListOf()
@JvmField
internal var built: Boolean = false
internal val updaterSerializer: KSerializer<SettingSerializerMark> by lazy {
built = true
SettingUpdaterSerializer(this as Setting)
}
internal val kotlinSerializer: KSerializer<Setting> by lazy {
object : KSerializer<Setting> {
override val descriptor: SerialDescriptor
get() = this@SettingImpl.updaterSerializer.descriptor
override fun deserialize(decoder: Decoder): Setting {
this@SettingImpl.updaterSerializer.deserialize(decoder)
return this@SettingImpl as Setting
}
override fun serialize(encoder: Encoder, value: Setting) {
this@SettingImpl.updaterSerializer.serialize(
encoder,
SettingSerializerMark
)
}
}
}
abstract fun onElementChanged(value: Value<*>)
companion object {
@JvmStatic
internal val yamlForToString =
Yaml(
configuration = YamlConfiguration(
nonStrictNullability = true,
nonStrictNumber = true,
stringSerialization = YamlConfiguration.StringSerialization.NONE,
classSerialization = YamlConfiguration.MapSerialization.FLOW_MAP,
listSerialization = YamlConfiguration.ListSerialization.FLOW_SEQUENCE
)
)
}
}
internal class SettingUpdaterSerializer(
private val instance: Setting
) : KSerializer<SettingSerializerMark> {
override val descriptor: SerialDescriptor by lazy {
@OptIn(MiraiExperimentalAPI::class)
SerialDescriptor(instance.serialName) {
for ((value, prop) in instance.valueList) {
val (serialName, annotations) = prop
element(serialName, value.serializer.descriptor, annotations, true)
}
}
}
@Suppress("UNCHECKED_CAST") // erased, no problem.
override fun deserialize(decoder: Decoder): SettingSerializerMark = decoder.decodeStructure(descriptor) {
if (this.decodeSequentially()) {
instance.valueList.forEachIndexed { index, (value, _) ->
val v = value as Value<Any>
v.value = this.decodeSerializableElement(
value.serializer.descriptor,
index,
v.serializer
)
}
} else {
while (true) {
val index = this.decodeElementIndex(descriptor)
if (index == CompositeDecoder.READ_DONE) return@decodeStructure SettingSerializerMark
val value = instance.valueList[index].first as Value<Any>
value.value = this.decodeSerializableElement(
descriptor,
index,
value.serializer
)
}
}
SettingSerializerMark
}
private val emptyList = emptyList<String>()
private val emptyListSerializer = ListSerializer(String.serializer())
override fun serialize(encoder: Encoder, value: SettingSerializerMark) {
if (instance.valueList.isEmpty()) {
emptyListSerializer.serialize(encoder, emptyList)
} else encoder.encodeStructure(descriptor) {
instance.valueList.forEachIndexed { index, (value, _) ->
@Suppress("UNCHECKED_CAST") // erased, no problem.
this.encodeElementSmart(descriptor, index, value)
}
}
}
}
// until https://github.com/Him188/yamlkt/issues/2 fixed
internal fun <T : Any> CompositeEncoder.encodeElementSmart(
descriptor: SerialDescriptor,
index: Int,
value: Value<T>
) {
when (value.value::class) {
String::class -> this.encodeStringElement(descriptor, index, value.value as String)
Int::class -> this.encodeIntElement(descriptor, index, value.value as Int)
Byte::class -> this.encodeByteElement(descriptor, index, value.value as Byte)
Char::class -> this.encodeCharElement(descriptor, index, value.value as Char)
Long::class -> this.encodeLongElement(descriptor, index, value.value as Long)
Float::class -> this.encodeFloatElement(descriptor, index, value.value as Float)
Double::class -> this.encodeDoubleElement(descriptor, index, value.value as Double)
Boolean::class -> this.encodeBooleanElement(descriptor, index, value.value as Boolean)
else ->
@Suppress("UNCHECKED_CAST")
this.encodeSerializableElement(descriptor, index, value.serializer as KSerializer<Any>, value.value)
}
}
internal object SettingSerializerMark
internal val KProperty<*>.serialNameOrPropertyName: String get() = this.findAnnotation<SerialName>()?.value ?: this.name

View File

@ -1,324 +0,0 @@
/*
* Copyright 2020 Mamoe Technologies and contributors.
*
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
* Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
*
* https://github.com/mamoe/mirai/blob/master/LICENSE
*/
@file:Suppress("INVISIBLE_REFERENCE", "INVISIBLE_MEMBER")
package net.mamoe.mirai.console.setting.internal
import kotlinx.serialization.*
import kotlinx.serialization.builtins.ListSerializer
import kotlinx.serialization.builtins.SetSerializer
import net.mamoe.mirai.console.setting.*
import net.mamoe.yamlkt.YamlDynamicSerializer
import kotlin.internal.LowPriorityInOverloadResolution
import kotlin.reflect.KClass
import kotlin.reflect.KType
import kotlin.reflect.full.createInstance
import kotlin.reflect.typeOf
/// region MUTABLE LIST
@PublishedApi
@JvmName("valueImplSetting")
@Suppress("UNCHECKED_CAST")
internal inline fun <reified T : Setting> Setting.valueImpl(
default: List<T>
): SettingListValue<T> = valueImpl(default, T::class.createInstance().serializer)
@PublishedApi
@JvmName("valueImplSettingMutable")
@Suppress("UNCHECKED_CAST")
internal inline fun <reified T : Setting> Setting.valueImpl(
default: MutableList<T>
): MutableSettingListValue<T> = valueImpl(default, T::class.createInstance().serializer)
/*
@PublishedApi
@JvmName("valueImpl1")
internal fun <T : Any> Setting.valueImpl(
default: MutableList<T>,
valueMapper: (T) -> Value<T>,
elementSerializer: KSerializer<T>
): MutableListValue<T> = valueImpl(default.mapTo(mutableListOf(), valueMapper), valueMapper, elementSerializer)
*/
internal fun <T : Any> Setting.valueImpl(
default: MutableList<Value<T>>,
valueMapper: (T) -> Value<T>,
elementSerializer: KSerializer<T>
): MutableListValue<T> {
var internalValue: MutableList<Value<T>> = default
fun updateShadow(): MutableList<T> =
internalValue.shadowMap(transform = { it.value }, transformBack = { valueMapper(it) })
var shadowed: MutableList<T> = updateShadow()
val delegt = dynamicMutableList { shadowed }
return object : MutableListValue<T>(), MutableList<T> by delegt {
override var value: MutableList<Value<T>>
get() = internalValue
set(new) {
if (new != internalValue) {
internalValue = new
shadowed = updateShadow()
onElementChanged(this)
}
}
override val serializer: KSerializer<MutableList<Value<T>>> = object : KSerializer<MutableList<Value<T>>> {
private val delegate = ListSerializer(elementSerializer)
override val descriptor: SerialDescriptor = delegate.descriptor
override fun deserialize(decoder: Decoder): MutableList<Value<T>> {
return delegate.deserialize(decoder).mapTo(mutableListOf(), valueMapper)
}
override fun serialize(encoder: Encoder, value: MutableList<Value<T>>) {
delegate.serialize(encoder, value.map { it.value })
}
}
}
}
@PublishedApi
internal fun <T : Setting> Setting.valueImpl(
default: MutableList<T>,
elementSerializer: KSerializer<T>
): MutableSettingListValue<T> {
var internalValue: MutableList<T> = default
val delegt = dynamicMutableList { internalValue }
return object : MutableSettingListValue<T>(), MutableList<T> by delegt {
override var value: MutableList<T>
get() = internalValue
set(new) {
if (new != internalValue) {
internalValue = new
onElementChanged(this)
}
}
override val serializer: KSerializer<MutableList<T>> = object : KSerializer<MutableList<T>> {
private val delegate = ListSerializer(elementSerializer)
override val descriptor: SerialDescriptor = delegate.descriptor
override fun deserialize(decoder: Decoder): MutableList<T> {
return delegate.deserialize(decoder).toMutableList() // TODO: 2020/5/17 ATTACH OBSERVER
}
override fun serialize(encoder: Encoder, value: MutableList<T>) {
delegate.serialize(encoder, value)
}
}
}
}
@PublishedApi
internal fun <T : Setting> Setting.valueImpl(
default: List<T>,
elementSerializer: KSerializer<T>
): SettingListValue<T> {
var internalValue: List<T> = default
val delegt = dynamicList { internalValue }
return object : SettingListValue<T>(), List<T> by delegt {
override var value: List<T>
get() = internalValue
set(new) {
if (new != internalValue) {
internalValue = new
onElementChanged(this)
}
}
override val serializer: KSerializer<List<T>> = object : KSerializer<List<T>> {
private val delegate = ListSerializer(elementSerializer)
override val descriptor: SerialDescriptor = delegate.descriptor
override fun deserialize(decoder: Decoder): List<T> {
return delegate.deserialize(decoder) // TODO: 2020/5/17 ATTACH OBSERVER
}
override fun serialize(encoder: Encoder, value: List<T>) {
delegate.serialize(encoder, value)
}
}
}
}
@PublishedApi
internal fun <T : Setting> Setting.valueImpl(
default: Set<T>,
elementSerializer: KSerializer<T>
): SettingSetValue<T> {
var internalValue: Set<T> = default
val delegt = dynamicSet { internalValue }
return object : SettingSetValue<T>(), Set<T> by delegt {
override var value: Set<T>
get() = internalValue
set(new) {
if (new != internalValue) {
internalValue = new
onElementChanged(this)
}
}
override val serializer: KSerializer<Set<T>> = object : KSerializer<Set<T>> {
private val delegate = SetSerializer(elementSerializer)
override val descriptor: SerialDescriptor = delegate.descriptor
override fun deserialize(decoder: Decoder): Set<T> {
return delegate.deserialize(decoder) // TODO: 2020/5/17 ATTACH OBSERVER
}
override fun serialize(encoder: Encoder, value: Set<T>) {
delegate.serialize(encoder, value)
}
}
}
}
@PublishedApi
internal fun <T : Setting> Setting.valueImpl(
default: MutableSet<T>,
elementSerializer: KSerializer<T>
): MutableSettingSetValue<T> {
var internalValue: MutableSet<T> = default
val delegt = dynamicMutableSet { internalValue }
return object : MutableSettingSetValue<T>(), MutableSet<T> by delegt {
override var value: MutableSet<T>
get() = internalValue
set(new) {
if (new != internalValue) {
internalValue = new
onElementChanged(this)
}
}
override val serializer: KSerializer<MutableSet<T>> = object : KSerializer<MutableSet<T>> {
private val delegate = SetSerializer(elementSerializer)
override val descriptor: SerialDescriptor = delegate.descriptor
override fun deserialize(decoder: Decoder): MutableSet<T> {
return delegate.deserialize(decoder).toMutableSet() // TODO: 2020/5/17 ATTACH OBSERVER
}
override fun serialize(encoder: Encoder, value: MutableSet<T>) {
delegate.serialize(encoder, value)
}
}
}
}
// endregion
// region MUTABLE SET
@PublishedApi
@JvmName("valueImplSetting")
@Suppress("UNCHECKED_CAST")
internal inline fun <reified T : Setting> Setting.valueImpl(
default: Set<T>
): SettingSetValue<T> = valueImpl(default, T::class.createInstance().serializer)
@PublishedApi
@JvmName("valueImplSettingMutable")
@Suppress("UNCHECKED_CAST")
internal inline fun <reified T : Setting> Setting.valueImpl(
default: MutableSet<T>
): MutableSettingSetValue<T> = valueImpl(default, T::class.createInstance().serializer)
/*
@JvmName("valueImpl1")
@PublishedApi
internal fun <T : Any> Setting.valueImpl(
default: MutableSet<T>,
valueMapper: (T) -> Value<T>,
elementSerializer: KSerializer<T>
): MutableSetValue<T> = valueImpl(default.mapTo(mutableSetOf(), valueMapper), valueMapper, elementSerializer)
*/
@JvmName("valueImplMutable")
internal fun <T : Any> Setting.valueImpl(
default: MutableSet<Value<T>>,
valueMapper: (T) -> Value<T>,
elementSerializer: KSerializer<T>
): MutableSetValue<T> {
var internalValue: MutableSet<Value<T>> = default
fun updateShadow(): MutableSet<T> =
internalValue.shadowMap(transform = { it.value }, transformBack = { valueMapper(it) })
var shadowed: MutableSet<T> = updateShadow()
val delegt = dynamicMutableSet { shadowed }
return object : MutableSetValue<T>(), MutableSet<T> by delegt {
override var value: MutableSet<Value<T>>
get() = internalValue
set(new) {
if (new != internalValue) {
internalValue = new
shadowed = updateShadow()
onElementChanged(this)
}
}
override val serializer: KSerializer<MutableSet<Value<T>>> = object : KSerializer<MutableSet<Value<T>>> {
private val delegate = SetSerializer(elementSerializer)
override val descriptor: SerialDescriptor = delegate.descriptor
override fun deserialize(decoder: Decoder): MutableSet<Value<T>> {
return delegate.deserialize(decoder).mapTo(mutableSetOf(), valueMapper)
}
override fun serialize(encoder: Encoder, value: MutableSet<Value<T>>) {
delegate.serialize(encoder, value.mapTo(mutableSetOf()) { it.value })
}
}
}
}
// endregion
// region DYNAMIC PRIMITIVES AND SERIALIZABLE
/**
* For primitives and serializable only
*/
@OptIn(ExperimentalStdlibApi::class)
@PublishedApi
@LowPriorityInOverloadResolution
internal inline fun <reified T : Any> Setting.valueImpl(default: T): Value<T> =
valueImpl(default, T::class)
@PublishedApi
internal fun <T : Any> Setting.valueImpl(default: T, clazz: KClass<out T>): Value<T> {
if (default is Setting) @Suppress("UNCHECKED_CAST") return valueImpl(default as Setting) as Value<T>
@OptIn(ImplicitReflectionSerializer::class)
requireNotNull(clazz.serializerOrNull()) {
"${clazz.qualifiedName} is not serializable"
}
return object : DynamicReferenceValue<T>() {
override var value: T = default
override val serializer: KSerializer<T> = object : KSerializer<T> {
override val descriptor: SerialDescriptor
get() = YamlDynamicSerializer.descriptor
override fun deserialize(decoder: Decoder): T =
YamlDynamicSerializer.deserialize(decoder).smartCastPrimitive(clazz)
override fun serialize(encoder: Encoder, value: T) = YamlDynamicSerializer.serialize(encoder, value)
}
}
}
// endregion

View File

@ -10,17 +10,8 @@
package net.mamoe.mirai.console.utils
import kotlinx.atomicfu.locks.withLock
import net.mamoe.mirai.Bot
import net.mamoe.mirai.console.setting.Value
import net.mamoe.mirai.console.setting.internal.ConsoleBuiltInSetting
import net.mamoe.mirai.console.setting.value
import net.mamoe.mirai.contact.User
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
/**

View File

@ -1,106 +0,0 @@
/*
* Copyright 2020 Mamoe Technologies and contributors.
*
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
* Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
*
* https://github.com/mamoe/mirai/blob/master/LICENSE
*/
@file:Suppress("INVISIBLE_MEMBER", "INVISIBLE_REFERENCE")
package net.mamoe.mirai.console.command
import net.mamoe.mirai.Bot
import net.mamoe.mirai.console.plugin.jvm.KotlinPlugin
import net.mamoe.mirai.console.setting.value
import net.mamoe.mirai.message.data.*
import org.junit.jupiter.api.Test
import kotlin.test.assertEquals
val plugin = MyPlugin()
class MyPlugin : KotlinPlugin() {
inner class MySetting : PluginSetting() {
val int by value(1)
}
}
/*
internal object TestCommand : PluginCommand(
plugin,
CommandDescriptor("test") {
param<String>()
}
) {
override suspend fun CommandSender.onCommand(args: CommandArgs): Boolean {
val s = args.getReified<String>()
sendMessage(s)
return true
}
}*/
internal class TestCommands {
@Test
fun testFlatten() {
assertEquals(listOf("test", "v1"), "test v1".flattenCommandComponents().toList())
assertEquals(listOf("test", "v1"), PlainText("test v1").flattenCommandComponents().toList())
assertEquals(listOf("test", "v1"), arrayOf("test ", "v1", " ").flattenCommandComponents().toList())
assertEquals(
listOf("test", "v1"),
messageChainOf("test v1".toMessage(), " ".toMessage()).flattenCommandComponents().toList()
)
}
/*
@Test
fun testRegister() {
assertTrue(TestCommand.register())
assertEquals(listOf("test"), TestCommand.allNames.single().toList())
assertFalse(TestCommand.register())
assertFalse(
object : PluginCommand(
plugin,
CommandDescriptor("test") {
param<String>()
}
) {
override suspend fun CommandSender.onCommand(args: CommandArgs): Boolean {
val s = args.getReified<String>()
sendMessage(s)
return true
}
}.register()
)
}
@Test
fun testExecute() = runBlocking {
TestCommand.register()
assertEquals(
"ok",
withSender {
execute("test", "arg")
}.contentToString()
)
}*/
}
internal inline fun withSender(block: CommandSender.() -> Unit): MessageChain {
val result = MessageChainBuilder()
val sender: CommandSender = object : CommandSender {
override val bot: Bot?
get() = null
override suspend fun sendMessage(message: Message) {
result.add(message)
}
}
sender.let(block)
return result.asMessageChain()
}

View File

@ -9,15 +9,19 @@
package net.mamoe.mirai.console.command
import net.mamoe.mirai.contact.Member
import net.mamoe.mirai.message.data.Image
import org.junit.jupiter.api.Test
object TestCompositeCommand : CompositeCommand(
TestCommandOwner,
"name1", "name2",
description = """
desc
""".trimIndent()
)
"groupManagement", "grpMgn"
) {
@SubCommand
suspend fun CommandSender.mute(image: Image, target: Member, seconds: Int) {
target.mute(seconds)
}
}
internal class TestComposite {