From 655a6752fda4370a633ebb6f735482c887e0216e Mon Sep 17 00:00:00 2001 From: Him188 Date: Sun, 17 May 2020 13:09:26 +0800 Subject: [PATCH] Rearrange implementations --- .../mamoe/mirai/console/setting/Internal.kt | 133 ++++++++++++++++++ .../mamoe/mirai/console/setting/Setting.kt | 116 ++------------- 2 files changed, 141 insertions(+), 108 deletions(-) create mode 100644 backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/setting/Internal.kt diff --git a/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/setting/Internal.kt b/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/setting/Internal.kt new file mode 100644 index 000000000..5c92111b8 --- /dev/null +++ b/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/setting/Internal.kt @@ -0,0 +1,133 @@ +/* + * 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.* +import net.mamoe.yamlkt.Yaml +import net.mamoe.yamlkt.YamlConfiguration +import kotlin.reflect.KProperty +import kotlin.reflect.full.findAnnotation + +internal abstract class AbstractSetting { + + @JvmField + internal var valueList: MutableList, KProperty<*>>> = mutableListOf() + + @JvmField + internal var built: Boolean = false + + internal val updaterSerializer: KSerializer by lazy { + built = true + SettingUpdaterSerializer(this as Setting) + } + + internal val kotlinSerializer: KSerializer by lazy { + object : KSerializer { + override val descriptor: SerialDescriptor + get() = this@AbstractSetting.updaterSerializer.descriptor + + override fun deserialize(decoder: Decoder): Setting { + this@AbstractSetting.updaterSerializer.deserialize(decoder) + return this@AbstractSetting as Setting + } + + override fun serialize(encoder: Encoder, value: Setting) { + this@AbstractSetting.updaterSerializer.serialize(encoder, SettingSerializerMark) + } + } + } + + internal fun onElementChanged(value: Value<*>) { + println("my value changed!") + } + + companion object { + @JvmStatic + internal val yaml = + 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 { + override val descriptor: SerialDescriptor by lazy { + SerialDescriptor(instance.serialName) { + for ((value, property) in instance.valueList) { + element(property.serialNameOrPropertyName, 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, _) -> + this.decodeSerializableElement( + value.serializer.descriptor, + index, + value.serializer as KSerializer + ) + } + } else { + while (true) { + val index = this.decodeElementIndex(descriptor) + if (index == CompositeDecoder.READ_DONE) return@decodeStructure SettingSerializerMark + val value = instance.valueList[index].first + + this.decodeSerializableElement( + descriptor, + index, + value.serializer + ) + } + } + SettingSerializerMark + } + + override fun serialize(encoder: Encoder, value: SettingSerializerMark) = encoder.encodeStructure(descriptor) { + instance.valueList.forEachIndexed { index, (value, _) -> + @Suppress("UNCHECKED_CAST") // erased, no problem. + this.encodeSerializableElement( + descriptor, + index, + value.serializer as KSerializer, + value.value + ) + } + } + +} + +internal object SettingSerializerMark + +internal val KProperty<*>.serialNameOrPropertyName: String get() = this.findAnnotation()?.value ?: this.name + +internal inline fun KSerializer.bind( + crossinline setter: (E) -> Unit, + crossinline getter: () -> E +): KSerializer { + return object : KSerializer { + override val descriptor: SerialDescriptor get() = this@bind.descriptor + override fun deserialize(decoder: Decoder): E = this@bind.deserialize(decoder).also { setter(it) } + + @Suppress("UNCHECKED_CAST") + override fun serialize(encoder: Encoder, value: E) = + this@bind.serialize(encoder, getter()) + } +} diff --git a/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/setting/Setting.kt b/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/setting/Setting.kt index c03ff53e9..ac36cb8e0 100644 --- a/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/setting/Setting.kt +++ b/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/setting/Setting.kt @@ -11,35 +11,18 @@ package net.mamoe.mirai.console.setting -import kotlinx.serialization.* -import net.mamoe.yamlkt.Yaml -import net.mamoe.yamlkt.YamlConfiguration -import net.mamoe.yamlkt.YamlConfiguration.ListSerialization.FLOW_SEQUENCE -import net.mamoe.yamlkt.YamlConfiguration.MapSerialization.FLOW_MAP +import kotlinx.serialization.KSerializer import kotlin.properties.ReadWriteProperty import kotlin.reflect.KProperty import kotlin.reflect.full.findAnnotation -internal inline fun KSerializer.bind( - crossinline setter: (E) -> Unit, - crossinline getter: () -> E -): KSerializer { - return object : KSerializer { - override val descriptor: SerialDescriptor get() = this@bind.descriptor - override fun deserialize(decoder: Decoder): E = this@bind.deserialize(decoder).also { setter(it) } - - @Suppress("UNCHECKED_CAST") - override fun serialize(encoder: Encoder, value: E) = - this@bind.serialize(encoder, getter()) - } -} - typealias SerialName = kotlinx.serialization.SerialName /** * 配置的基类 */ -abstract class Setting { +@Suppress("EXPOSED_SUPER_CLASS") +abstract class Setting : AbstractSetting() { open val serialName: String get() = this::class.findAnnotation()?.value ?: this::class.qualifiedName @@ -56,40 +39,6 @@ abstract class Setting { return this } - @JvmField - internal var valueList: MutableList, KProperty<*>>> = mutableListOf() - private var built: Boolean = false - - internal val updaterSerializer: KSerializer by lazy { - built = true - SettingUpdaterSerializer(this) - } - - internal val kotlinSerializer: KSerializer by lazy { - object : KSerializer { - override val descriptor: SerialDescriptor - get() = this@Setting.updaterSerializer.descriptor - - override fun deserialize(decoder: Decoder): Setting { - this@Setting.updaterSerializer.deserialize(decoder) - return this@Setting - } - - override fun serialize(encoder: Encoder, value: Setting) { - this@Setting.updaterSerializer.serialize(encoder, SettingSerializerMark) - } - } - } - - internal fun onElementChanged(value: Value<*>) { - println("my value changed!") - } - - companion object { - private val yaml = - Yaml(configuration = YamlConfiguration(classSerialization = FLOW_MAP, listSerialization = FLOW_SEQUENCE)) - } - override fun toString(): String = yaml.stringify(this.serializer, this) } @@ -97,62 +46,13 @@ abstract class Setting { val T.serializer: KSerializer get() = kotlinSerializer as KSerializer -internal class SettingUpdaterSerializer( - private val instance: Setting -) : KSerializer { - override val descriptor: SerialDescriptor by lazy { - SerialDescriptor(instance.serialName) { - for ((value, property) in instance.valueList) { - element(property.serialNameOrPropertyName, value.serializer.descriptor, annotations, true) - } - } + +fun Setting.value(default: T): Value { + require(this::class != default::class) { + "Recursive nesting is prohibited" } - - @Suppress("UNCHECKED_CAST") // erased, no problem. - override fun deserialize(decoder: Decoder): SettingSerializerMark = decoder.decodeStructure(descriptor) { - if (this.decodeSequentially()) { - instance.valueList.forEachIndexed { index, (value, _) -> - this.decodeSerializableElement( - value.serializer.descriptor, - index, - value.serializer as KSerializer - ) - } - } else { - while (true) { - val index = this.decodeElementIndex(descriptor) - if (index == CompositeDecoder.READ_DONE) return@decodeStructure SettingSerializerMark - val value = instance.valueList[index].first - - this.decodeSerializableElement( - descriptor, - index, - value.serializer - ) - } - } - SettingSerializerMark - } - - override fun serialize(encoder: Encoder, value: SettingSerializerMark) = encoder.encodeStructure(descriptor) { - instance.valueList.forEachIndexed { index, (value, _) -> - @Suppress("UNCHECKED_CAST") // erased, no problem. - this.encodeSerializableElement( - descriptor, - index, - value.serializer as KSerializer, - value.value - ) - } - } - + return valueImpl(default) } -internal object SettingSerializerMark - -internal val KProperty<*>.serialNameOrPropertyName: String get() = this.findAnnotation()?.value ?: this.name - - -fun Setting.value(default: T): Value = valueImpl(default) inline fun Setting.value(default: T, crossinline initializer: T.() -> Unit): Value = value(default).also { it.value.apply(initializer) }