mirror of
https://github.com/mamoe/mirai.git
synced 2025-01-25 15:40:28 +08:00
Rearrange implementations
This commit is contained in:
parent
e4e1e684e3
commit
655a6752fd
@ -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<Pair<Value<*>, KProperty<*>>> = 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@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<SettingSerializerMark> {
|
||||
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<Any>
|
||||
)
|
||||
}
|
||||
} 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<Any>,
|
||||
value.value
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
internal object SettingSerializerMark
|
||||
|
||||
internal val KProperty<*>.serialNameOrPropertyName: String get() = this.findAnnotation<SerialName>()?.value ?: this.name
|
||||
|
||||
internal inline fun <E> KSerializer<E>.bind(
|
||||
crossinline setter: (E) -> Unit,
|
||||
crossinline getter: () -> E
|
||||
): KSerializer<E> {
|
||||
return object : KSerializer<E> {
|
||||
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())
|
||||
}
|
||||
}
|
@ -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 <E> KSerializer<E>.bind(
|
||||
crossinline setter: (E) -> Unit,
|
||||
crossinline getter: () -> E
|
||||
): KSerializer<E> {
|
||||
return object : KSerializer<E> {
|
||||
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<SerialName>()?.value
|
||||
?: this::class.qualifiedName
|
||||
@ -56,40 +39,6 @@ abstract class Setting {
|
||||
return this
|
||||
}
|
||||
|
||||
@JvmField
|
||||
internal var valueList: MutableList<Pair<Value<*>, KProperty<*>>> = mutableListOf()
|
||||
private var built: Boolean = false
|
||||
|
||||
internal val updaterSerializer: KSerializer<SettingSerializerMark> by lazy {
|
||||
built = true
|
||||
SettingUpdaterSerializer(this)
|
||||
}
|
||||
|
||||
internal val kotlinSerializer: KSerializer<Setting> by lazy {
|
||||
object : KSerializer<Setting> {
|
||||
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 : Setting> T.serializer: KSerializer<T>
|
||||
get() = kotlinSerializer as KSerializer<T>
|
||||
|
||||
internal class SettingUpdaterSerializer(
|
||||
private val instance: Setting
|
||||
) : KSerializer<SettingSerializerMark> {
|
||||
override val descriptor: SerialDescriptor by lazy {
|
||||
SerialDescriptor(instance.serialName) {
|
||||
for ((value, property) in instance.valueList) {
|
||||
element(property.serialNameOrPropertyName, value.serializer.descriptor, annotations, true)
|
||||
}
|
||||
}
|
||||
|
||||
fun <T : Setting> Setting.value(default: T): Value<T> {
|
||||
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<Any>
|
||||
)
|
||||
}
|
||||
} 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<Any>,
|
||||
value.value
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
return valueImpl(default)
|
||||
}
|
||||
|
||||
internal object SettingSerializerMark
|
||||
|
||||
internal val KProperty<*>.serialNameOrPropertyName: String get() = this.findAnnotation<SerialName>()?.value ?: this.name
|
||||
|
||||
|
||||
fun <T : Setting> Setting.value(default: T): Value<T> = valueImpl(default)
|
||||
inline fun <T : Setting> Setting.value(default: T, crossinline initializer: T.() -> Unit): Value<T> =
|
||||
value(default).also { it.value.apply(initializer) }
|
||||
|
Loading…
Reference in New Issue
Block a user