From 655a6752fda4370a633ebb6f735482c887e0216e Mon Sep 17 00:00:00 2001 From: Him188 Date: Sun, 17 May 2020 13:09:26 +0800 Subject: [PATCH 1/4] 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) } From e1f2b2e94745172886f4a92e20551a98c58522ad Mon Sep 17 00:00:00 2001 From: Him188 Date: Sun, 17 May 2020 15:44:05 +0800 Subject: [PATCH 2/4] Support lists and sets in Setting --- .../codegen/SettingValueUseSiteCodegen.kt | 20 +- .../mirai/console/codegen/ValueImplCodegen.kt | 83 +- .../mirai/console/codegen/ValuesCodegen.kt | 92 +- .../mamoe/mirai/console/setting/Internal.kt | 5 +- .../mamoe/mirai/console/setting/Setting.kt | 13 +- .../mamoe/mirai/console/setting/ValueImpl.kt | 312 ++++++ .../mamoe/mirai/console/setting/_Setting.kt | 63 ++ .../net/mamoe/mirai/console/setting/_Value.kt | 69 +- .../mamoe/mirai/console/setting/_ValueImpl.kt | 981 ++++++++++++++---- .../net/mamoe/mirai/console/setting/utils.kt | 271 +++++ 10 files changed, 1705 insertions(+), 204 deletions(-) create mode 100644 backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/setting/ValueImpl.kt create mode 100644 backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/setting/utils.kt diff --git a/backend/codegen/src/main/kotlin/net/mamoe/mirai/console/codegen/SettingValueUseSiteCodegen.kt b/backend/codegen/src/main/kotlin/net/mamoe/mirai/console/codegen/SettingValueUseSiteCodegen.kt index 99269419a..adf4ba0ac 100644 --- a/backend/codegen/src/main/kotlin/net/mamoe/mirai/console/codegen/SettingValueUseSiteCodegen.kt +++ b/backend/codegen/src/main/kotlin/net/mamoe/mirai/console/codegen/SettingValueUseSiteCodegen.kt @@ -63,9 +63,23 @@ fun genAllValueUseSite(): String = buildString { appendln(genValueUseSite("Array<${number}>", "Typed${number}Array")) } - // PRIMITIVE LISTS - for (number in NUMBERS + OTHER_PRIMITIVES) { - appendln(genValueUseSite("List<${number}>", "${number}List")) + // PRIMITIVE LISTS / PRIMITIVE SETS + for (collectionName in listOf("List", "Set")) { + for (number in NUMBERS + OTHER_PRIMITIVES) { + appendln(genValueUseSite("${collectionName}<${number}>", "${number}${collectionName}")) + } + } + + // MUTABLE LIST / MUTABLE SET + for (collectionName in listOf("List", "Set")) { + for (number in NUMBERS + OTHER_PRIMITIVES) { + appendln( + """ + @JvmName("valueMutable") + fun Setting.value(default: Mutable${collectionName}<${number}>): Mutable${number}${collectionName}Value = valueImpl(default) + """.trimIndent() + ) + } } } diff --git a/backend/codegen/src/main/kotlin/net/mamoe/mirai/console/codegen/ValueImplCodegen.kt b/backend/codegen/src/main/kotlin/net/mamoe/mirai/console/codegen/ValueImplCodegen.kt index 7d40123f1..1e06ea9e7 100644 --- a/backend/codegen/src/main/kotlin/net/mamoe/mirai/console/codegen/ValueImplCodegen.kt +++ b/backend/codegen/src/main/kotlin/net/mamoe/mirai/console/codegen/ValueImplCodegen.kt @@ -9,6 +9,7 @@ package net.mamoe.mirai.console.codegen +import org.intellij.lang.annotations.Language import java.io.File @@ -44,10 +45,15 @@ package net.mamoe.mirai.console.setting """.trimIndent() private val IMPORTS = """ +import kotlinx.serialization.* import kotlinx.serialization.builtins.* """.trimIndent() fun genAllValueImpl(): String = buildString { + fun appendln(@Language("kt") code: String) { + this.appendln(code.trimIndent()) + } + // PRIMITIVE for (number in NUMBERS + OTHER_PRIMITIVES) { appendln(genValueImpl(number, number, "$number.serializer()", false)) @@ -60,12 +66,76 @@ fun genAllValueImpl(): String = buildString { // TYPED ARRAYS for (number in NUMBERS + OTHER_PRIMITIVES) { - appendln(genValueImpl("Array<${number}>", "Typed${number}Array", "ArraySerializer(${number}.serializer())", true)) + appendln( + genValueImpl( + "Array<${number}>", + "Typed${number}Array", + "ArraySerializer(${number}.serializer())", + true + ) + ) } - // PRIMITIVE LISTS - for (number in NUMBERS + OTHER_PRIMITIVES) { - appendln(genValueImpl("List<${number}>", "${number}List", "ListSerializer(${number}.serializer())", false)) + // PRIMITIVE LISTS / SETS + for (collectionName in listOf("List", "Set")) { + for (number in NUMBERS + OTHER_PRIMITIVES) { + appendln( + genValueImpl( + "${collectionName}<${number}>", + "${number}${collectionName}", + "${collectionName}Serializer(${number}.serializer())", + false + ) + ) + } + } + + appendln() + + // MUTABLE LIST / MUTABLE SET + + for (collectionName in listOf("List", "Set")) { + for (number in NUMBERS + OTHER_PRIMITIVES) { + appendln( + """ + @JvmName("valueImplMutable${number}${collectionName}") + internal fun Setting.valueImpl( + default: Mutable${collectionName}<${number}> + ): Mutable${number}${collectionName}Value { + var internalValue: Mutable${collectionName}<${number}> = default + + return object : Mutable${number}${collectionName}Value(), Mutable${collectionName}<${number}> by dynamicMutable${collectionName}({ internalValue }) { + override var value: Mutable${collectionName}<${number}> + get() = internalValue + set(new) { + if (new != internalValue) { + internalValue = new + onElementChanged(this) + } + } + + private inline val `this` get() = this + + override val serializer: KSerializer> = object : KSerializer> { + private val delegate = ${collectionName}Serializer(${number}.serializer()) + override val descriptor: SerialDescriptor = delegate.descriptor + + override fun deserialize(decoder: Decoder): Mutable${collectionName}<${number}> { + return delegate.deserialize(decoder).toMutable${collectionName}().observable { + onElementChanged(`this`) + } + } + + override fun serialize(encoder: Encoder, value: Mutable${collectionName}<${number}>) { + delegate.serialize(encoder, value) + } + } + } + } + """ + ) + appendln() + } } } @@ -92,10 +162,7 @@ fun genValueImpl(kotlinTypeName: String, miraiValueName: String, serializer: Str """.trim() } } - override val serializer = ${serializer}.bind( - getter = { internalValue }, - setter = { internalValue = it } - ) + override val serializer = $serializer } } """.trimIndent() + "\n" diff --git a/backend/codegen/src/main/kotlin/net/mamoe/mirai/console/codegen/ValuesCodegen.kt b/backend/codegen/src/main/kotlin/net/mamoe/mirai/console/codegen/ValuesCodegen.kt index 7139245b0..ff92d8851 100644 --- a/backend/codegen/src/main/kotlin/net/mamoe/mirai/console/codegen/ValuesCodegen.kt +++ b/backend/codegen/src/main/kotlin/net/mamoe/mirai/console/codegen/ValuesCodegen.kt @@ -7,6 +7,7 @@ * https://github.com/mamoe/mirai/blob/master/LICENSE */ @file:Suppress("ClassName", "unused") + package net.mamoe.mirai.console.codegen import org.intellij.lang.annotations.Language @@ -54,17 +55,20 @@ internal val OTHER_PRIMITIVES = listOf( ) fun genPublicApi() = buildString { - fun appendln(@Language("kt") code: String){ + fun appendln(@Language("kt") code: String) { this.appendln(code.trimIndent()) } - + appendln(COPYRIGHT.trim()) appendln() appendln( """ package net.mamoe.mirai.console.setting + import kotlinx.serialization.Decoder + import kotlinx.serialization.Encoder import kotlinx.serialization.KSerializer + import kotlinx.serialization.SerialDescriptor import kotlin.properties.ReadWriteProperty import kotlin.reflect.KProperty """ @@ -86,11 +90,23 @@ fun genPublicApi() = buildString { sealed class Value : ReadWriteProperty { abstract var value: T + /** + * 用于更新 [value] 的序列化器 + */ abstract val serializer: KSerializer 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() } """ ) @@ -176,25 +192,34 @@ sealed class Value : ReadWriteProperty { appendln() - // TYPED LISTS + // TYPED LISTS / SETS + for (collectionName in listOf("List", "Set")) { - appendln( - """ - sealed class ListValue : Value>(), Iterable{ + appendln( + """ + sealed class ${collectionName}Value : Value<${collectionName}>(), Iterable{ override fun iterator() = this.value.iterator() } """ - ) + ) - for (number in (NUMBERS + OTHER_PRIMITIVES)) { - val template = """ - abstract class ${number}ListValue internal constructor() : ListValue<${number}>() + for (number in (NUMBERS + OTHER_PRIMITIVES)) { + val template = """ + abstract class ${number}${collectionName}Value internal constructor() : ${collectionName}Value<${number}>() """ - appendln(template) - } + appendln(template) + } - appendln() + appendln() + // SETTING + appendln( + """ + abstract class Setting${collectionName}Value internal constructor() : Value<${collectionName}>(), ${collectionName} + """ + ) + appendln() + } // FOR COMPLEX TYPES @@ -236,4 +261,45 @@ sealed class Value : ReadWriteProperty { ) appendln() + + // MUTABLE LIST / MUTABLE SET + for (collectionName in listOf("List", "Set")) { + appendln( + """ + abstract class Mutable${collectionName}Value internal constructor() : Value>>(), Mutable${collectionName} + """ + ) + + appendln() + + for (number in (NUMBERS + OTHER_PRIMITIVES)) { + appendln( + """ + abstract class Mutable${number}${collectionName}Value internal constructor() : Value>(), Mutable${collectionName}<${number}> + """ + ) + } + + appendln() + // SETTING + appendln( + """ + abstract class MutableSetting${collectionName}Value internal constructor() : Value>(), Mutable${collectionName} + """ + ) + appendln() + } + + appendln() + // DYNAMIC + + appendln( + """ + /** + * 只引用这个对象, 而不跟踪其成员. + * 仅适用于基础类型, 用于 mutable list/map 等情况; 或标注了 [Serializable] 的类. + */ + abstract class DynamicReferenceValue internal constructor() : Value() + """ + ) } \ No newline at end of file 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 index 5c92111b8..46a7b73ef 100644 --- 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 @@ -78,10 +78,11 @@ internal class SettingUpdaterSerializer( override fun deserialize(decoder: Decoder): SettingSerializerMark = decoder.decodeStructure(descriptor) { if (this.decodeSequentially()) { instance.valueList.forEachIndexed { index, (value, _) -> - this.decodeSerializableElement( + val v = value as Value + v.value = this.decodeSerializableElement( value.serializer.descriptor, index, - value.serializer as KSerializer + v.serializer ) } } else { 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 ac36cb8e0..44e76ff49 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 @@ -19,7 +19,7 @@ import kotlin.reflect.full.findAnnotation typealias SerialName = kotlinx.serialization.SerialName /** - * 配置的基类 + * 配置的基类. 所有配置必须拥有一个无参构造器, 以用于在 [MutableList] 与 [MutableMap] 中动态识别类型 */ @Suppress("EXPOSED_SUPER_CLASS") abstract class Setting : AbstractSetting() { @@ -56,3 +56,14 @@ fun Setting.value(default: T): Value { inline fun Setting.value(default: T, crossinline initializer: T.() -> Unit): Value = value(default).also { it.value.apply(initializer) } + +inline fun Setting.value(default: List): SettingListValue = valueImpl(default) + +@JvmName("valueMutable") +inline fun Setting.value(default: MutableList): MutableSettingListValue = valueImpl(default) + + +inline fun Setting.value(default: Set): SettingSetValue = valueImpl(default) + +@JvmName("valueMutable") +inline fun Setting.value(default: MutableSet): MutableSettingSetValue = valueImpl(default) diff --git a/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/setting/ValueImpl.kt b/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/setting/ValueImpl.kt new file mode 100644 index 000000000..d384e9b74 --- /dev/null +++ b/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/setting/ValueImpl.kt @@ -0,0 +1,312 @@ +/* + * 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 kotlinx.serialization.builtins.ListSerializer +import kotlinx.serialization.builtins.SetSerializer +import net.mamoe.yamlkt.YamlDynamicSerializer +import kotlin.reflect.KClass +import kotlin.reflect.full.createInstance + +/// region MUTABLE LIST + +@PublishedApi +@JvmName("valueImplSetting") +@Suppress("UNCHECKED_CAST") +internal inline fun Setting.valueImpl( + default: List +): SettingListValue = valueImpl(default, T::class.createInstance().serializer) + +@PublishedApi +@JvmName("valueImplSettingMutable") +@Suppress("UNCHECKED_CAST") +internal inline fun Setting.valueImpl( + default: MutableList +): MutableSettingListValue = valueImpl(default, T::class.createInstance().serializer) + + +@PublishedApi +@JvmName("valueImpl1") +internal fun Setting.valueImpl( + default: MutableList, + valueMapper: (T) -> Value, + elementSerializer: KSerializer +): MutableListValue = valueImpl(default.mapTo(mutableListOf(), valueMapper), valueMapper, elementSerializer) + +internal fun Setting.valueImpl( + default: MutableList>, + valueMapper: (T) -> Value, + elementSerializer: KSerializer +): MutableListValue { + var internalValue: MutableList> = default + + fun updateShadow(): MutableList = + internalValue.shadowMap(transform = { it.value }, transformBack = { valueMapper(it) }) + + var shadowed: MutableList = updateShadow() + return object : MutableListValue(), MutableList by dynamicMutableList({ shadowed }) { + override var value: MutableList> + get() = internalValue + set(new) { + if (new != internalValue) { + internalValue = new + shadowed = updateShadow() + onElementChanged(this) + } + } + override val serializer: KSerializer>> = object : KSerializer>> { + private val delegate = ListSerializer(elementSerializer) + override val descriptor: SerialDescriptor = delegate.descriptor + + override fun deserialize(decoder: Decoder): MutableList> { + return delegate.deserialize(decoder).mapTo(mutableListOf(), valueMapper) + } + + override fun serialize(encoder: Encoder, value: MutableList>) { + delegate.serialize(encoder, value.map { it.value }) + } + + } + } +} + +@PublishedApi +internal fun Setting.valueImpl( + default: MutableList, + elementSerializer: KSerializer +): MutableSettingListValue { + var internalValue: MutableList = default + + return object : MutableSettingListValue(), MutableList by dynamicMutableList({ internalValue }) { + override var value: MutableList + get() = internalValue + set(new) { + if (new != internalValue) { + internalValue = new + onElementChanged(this) + } + } + override val serializer: KSerializer> = object : KSerializer> { + private val delegate = ListSerializer(elementSerializer) + override val descriptor: SerialDescriptor = delegate.descriptor + + override fun deserialize(decoder: Decoder): MutableList { + return delegate.deserialize(decoder).toMutableList() // TODO: 2020/5/17 ATTACH OBSERVER + } + + override fun serialize(encoder: Encoder, value: MutableList) { + delegate.serialize(encoder, value) + } + + } + } +} + +@PublishedApi +internal fun Setting.valueImpl( + default: List, + elementSerializer: KSerializer +): SettingListValue { + var internalValue: List = default + + return object : SettingListValue(), List by dynamicList({ internalValue }) { + override var value: List + get() = internalValue + set(new) { + if (new != internalValue) { + internalValue = new + onElementChanged(this) + } + } + override val serializer: KSerializer> = object : KSerializer> { + private val delegate = ListSerializer(elementSerializer) + override val descriptor: SerialDescriptor = delegate.descriptor + + override fun deserialize(decoder: Decoder): List { + return delegate.deserialize(decoder) // TODO: 2020/5/17 ATTACH OBSERVER + } + + override fun serialize(encoder: Encoder, value: List) { + delegate.serialize(encoder, value) + } + + } + } +} + +@PublishedApi +internal fun Setting.valueImpl( + default: Set, + elementSerializer: KSerializer +): SettingSetValue { + var internalValue: Set = default + + return object : SettingSetValue(), Set by dynamicSet({ internalValue }) { + override var value: Set + get() = internalValue + set(new) { + if (new != internalValue) { + internalValue = new + onElementChanged(this) + } + } + override val serializer: KSerializer> = object : KSerializer> { + private val delegate = SetSerializer(elementSerializer) + override val descriptor: SerialDescriptor = delegate.descriptor + + override fun deserialize(decoder: Decoder): Set { + return delegate.deserialize(decoder) // TODO: 2020/5/17 ATTACH OBSERVER + } + + override fun serialize(encoder: Encoder, value: Set) { + delegate.serialize(encoder, value) + } + + } + } +} + +@PublishedApi +internal fun Setting.valueImpl( + default: MutableSet, + elementSerializer: KSerializer +): MutableSettingSetValue { + var internalValue: MutableSet = default + + return object : MutableSettingSetValue(), MutableSet by dynamicMutableSet({ internalValue }) { + override var value: MutableSet + get() = internalValue + set(new) { + if (new != internalValue) { + internalValue = new + onElementChanged(this) + } + } + override val serializer: KSerializer> = object : KSerializer> { + private val delegate = SetSerializer(elementSerializer) + override val descriptor: SerialDescriptor = delegate.descriptor + + override fun deserialize(decoder: Decoder): MutableSet { + return delegate.deserialize(decoder).toMutableSet() // TODO: 2020/5/17 ATTACH OBSERVER + } + + override fun serialize(encoder: Encoder, value: MutableSet) { + delegate.serialize(encoder, value) + } + + } + } +} + +// endregion + + +// region MUTABLE SET + +@PublishedApi +@JvmName("valueImplSetting") +@Suppress("UNCHECKED_CAST") +internal inline fun Setting.valueImpl( + default: Set +): SettingSetValue = valueImpl(default, T::class.createInstance().serializer) + +@PublishedApi +@JvmName("valueImplSettingMutable") +@Suppress("UNCHECKED_CAST") +internal inline fun Setting.valueImpl( + default: MutableSet +): MutableSettingSetValue = valueImpl(default, T::class.createInstance().serializer) + + +@JvmName("valueImpl1") +@PublishedApi +internal fun Setting.valueImpl( + default: MutableSet, + valueMapper: (T) -> Value, + elementSerializer: KSerializer +): MutableSetValue = valueImpl(default.mapTo(mutableSetOf(), valueMapper), valueMapper, elementSerializer) + +@JvmName("valueImplMutable") +internal fun Setting.valueImpl( + default: MutableSet>, + valueMapper: (T) -> Value, + elementSerializer: KSerializer +): MutableSetValue { + var internalValue: MutableSet> = default + + fun updateShadow(): MutableSet = + internalValue.shadowMap(transform = { it.value }, transformBack = { valueMapper(it) }) + + var shadowed: MutableSet = updateShadow() + return object : MutableSetValue(), MutableSet by dynamicMutableSet({ shadowed }) { + override var value: MutableSet> + get() = internalValue + set(new) { + if (new != internalValue) { + internalValue = new + shadowed = updateShadow() + onElementChanged(this) + } + } + override val serializer: KSerializer>> = object : KSerializer>> { + private val delegate = SetSerializer(elementSerializer) + override val descriptor: SerialDescriptor = delegate.descriptor + + override fun deserialize(decoder: Decoder): MutableSet> { + return delegate.deserialize(decoder).mapTo(mutableSetOf(), valueMapper) + } + + override fun serialize(encoder: Encoder, value: MutableSet>) { + delegate.serialize(encoder, value.mapTo(mutableSetOf()) { it.value }) + } + } + } +} + +// endregion + +// region DYNAMIC PRIMITIVES AND SERIALIZABLE + +/** + * For primitives and serializable only + */ +@PublishedApi +internal inline fun Setting.valueImpl(default: T): Value = + valueImpl(default, T::class) + +@PublishedApi +internal fun Setting.valueImpl(default: T, clazz: KClass): Value { + if (default is Setting) @Suppress("UNCHECKED_CAST") return valueImpl(default as Setting) as Value + + @OptIn(ImplicitReflectionSerializer::class) + requireNotNull(clazz.serializerOrNull()) { + "${clazz.qualifiedName} is not serializable" + } + return object : DynamicReferenceValue() { + override var value: T = default + override val serializer: KSerializer + get() = object : KSerializer { + override val descriptor: SerialDescriptor + get() = YamlDynamicSerializer.descriptor + + override fun deserialize(decoder: Decoder): T { + return YamlDynamicSerializer.deserialize(decoder).smartCastPrimitive(clazz) + } + + @OptIn(ImplicitReflectionSerializer::class) + override fun serialize(encoder: Encoder, value: T) { + YamlDynamicSerializer.serialize(encoder, value) + } + } + } +} + +// endregion \ No newline at end of file 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 83dbe7345..ec6c3e656 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 @@ -52,4 +52,67 @@ fun Setting.value(default: List): DoubleListValue = valueImpl(default) fun Setting.value(default: List): BooleanListValue = valueImpl(default) fun Setting.value(default: List): CharListValue = valueImpl(default) fun Setting.value(default: List): StringListValue = valueImpl(default) +fun Setting.value(default: Set): IntSetValue = valueImpl(default) +fun Setting.value(default: Set): ShortSetValue = valueImpl(default) +fun Setting.value(default: Set): ByteSetValue = valueImpl(default) +fun Setting.value(default: Set): LongSetValue = valueImpl(default) +fun Setting.value(default: Set): FloatSetValue = valueImpl(default) +fun Setting.value(default: Set): DoubleSetValue = valueImpl(default) +fun Setting.value(default: Set): BooleanSetValue = valueImpl(default) +fun Setting.value(default: Set): CharSetValue = valueImpl(default) +fun Setting.value(default: Set): StringSetValue = valueImpl(default) + +@JvmName("valueMutable") +fun Setting.value(default: MutableList): MutableIntListValue = valueImpl(default) + +@JvmName("valueMutable") +fun Setting.value(default: MutableList): MutableShortListValue = valueImpl(default) + +@JvmName("valueMutable") +fun Setting.value(default: MutableList): MutableByteListValue = valueImpl(default) + +@JvmName("valueMutable") +fun Setting.value(default: MutableList): MutableLongListValue = valueImpl(default) + +@JvmName("valueMutable") +fun Setting.value(default: MutableList): MutableFloatListValue = valueImpl(default) + +@JvmName("valueMutable") +fun Setting.value(default: MutableList): MutableDoubleListValue = valueImpl(default) + +@JvmName("valueMutable") +fun Setting.value(default: MutableList): MutableBooleanListValue = valueImpl(default) + +@JvmName("valueMutable") +fun Setting.value(default: MutableList): MutableCharListValue = valueImpl(default) + +@JvmName("valueMutable") +fun Setting.value(default: MutableList): MutableStringListValue = valueImpl(default) + +@JvmName("valueMutable") +fun Setting.value(default: MutableSet): MutableIntSetValue = valueImpl(default) + +@JvmName("valueMutable") +fun Setting.value(default: MutableSet): MutableShortSetValue = valueImpl(default) + +@JvmName("valueMutable") +fun Setting.value(default: MutableSet): MutableByteSetValue = valueImpl(default) + +@JvmName("valueMutable") +fun Setting.value(default: MutableSet): MutableLongSetValue = valueImpl(default) + +@JvmName("valueMutable") +fun Setting.value(default: MutableSet): MutableFloatSetValue = valueImpl(default) + +@JvmName("valueMutable") +fun Setting.value(default: MutableSet): MutableDoubleSetValue = valueImpl(default) + +@JvmName("valueMutable") +fun Setting.value(default: MutableSet): MutableBooleanSetValue = valueImpl(default) + +@JvmName("valueMutable") +fun Setting.value(default: MutableSet): MutableCharSetValue = valueImpl(default) + +@JvmName("valueMutable") +fun Setting.value(default: MutableSet): MutableStringSetValue = valueImpl(default) diff --git a/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/setting/_Value.kt b/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/setting/_Value.kt index 1ffe99de5..257acbbb9 100644 --- a/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/setting/_Value.kt +++ b/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/setting/_Value.kt @@ -17,7 +17,7 @@ import kotlin.properties.ReadWriteProperty import kotlin.reflect.KProperty /** - * !!! These primitive types are auto-generated by backend/codegen/src/main/kotlin/net.mamoe.mirai.console.ValuesCodegen.kt + * !!! These primitive types are auto-generated by backend/codegen/src/main/kotlin/net.mamoe.mirai.console.codegen.ValuesCodegen.kt * !!! for better performance * !!! DO NOT MODIFY THIS FILE MANUALLY */ @@ -25,11 +25,23 @@ import kotlin.reflect.KProperty sealed class Value : ReadWriteProperty { abstract var value: T + /** + * 用于更新 [value] 的序列化器 + */ abstract val serializer: KSerializer 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 : Value() @@ -103,6 +115,24 @@ abstract class BooleanListValue internal constructor() : ListValue() abstract class CharListValue internal constructor() : ListValue() abstract class StringListValue internal constructor() : ListValue() +abstract class SettingListValue internal constructor() : Value>(), List + +sealed class SetValue : Value>(), Iterable { + override fun iterator() = this.value.iterator() +} + +abstract class IntSetValue internal constructor() : SetValue() +abstract class ShortSetValue internal constructor() : SetValue() +abstract class ByteSetValue internal constructor() : SetValue() +abstract class LongSetValue internal constructor() : SetValue() +abstract class FloatSetValue internal constructor() : SetValue() +abstract class DoubleSetValue internal constructor() : SetValue() +abstract class BooleanSetValue internal constructor() : SetValue() +abstract class CharSetValue internal constructor() : SetValue() +abstract class StringSetValue internal constructor() : SetValue() + +abstract class SettingSetValue internal constructor() : Value>(), Set + abstract class SettingValue internal constructor() : Value() internal fun Setting.valueImpl(default: T): Value { @@ -134,4 +164,39 @@ internal fun Setting.valueImpl(default: T): Value { setter = { internalValue = it } ) } -} \ No newline at end of file +} + +abstract class MutableListValue internal constructor() : Value>>(), MutableList + +abstract class MutableIntListValue internal constructor() : Value>(), MutableList +abstract class MutableShortListValue internal constructor() : Value>(), MutableList +abstract class MutableByteListValue internal constructor() : Value>(), MutableList +abstract class MutableLongListValue internal constructor() : Value>(), MutableList +abstract class MutableFloatListValue internal constructor() : Value>(), MutableList +abstract class MutableDoubleListValue internal constructor() : Value>(), MutableList +abstract class MutableBooleanListValue internal constructor() : Value>(), MutableList +abstract class MutableCharListValue internal constructor() : Value>(), MutableList +abstract class MutableStringListValue internal constructor() : Value>(), MutableList + +abstract class MutableSettingListValue internal constructor() : Value>(), MutableList + +abstract class MutableSetValue internal constructor() : Value>>(), MutableSet + +abstract class MutableIntSetValue internal constructor() : Value>(), MutableSet +abstract class MutableShortSetValue internal constructor() : Value>(), MutableSet +abstract class MutableByteSetValue internal constructor() : Value>(), MutableSet +abstract class MutableLongSetValue internal constructor() : Value>(), MutableSet +abstract class MutableFloatSetValue internal constructor() : Value>(), MutableSet +abstract class MutableDoubleSetValue internal constructor() : Value>(), MutableSet +abstract class MutableBooleanSetValue internal constructor() : Value>(), MutableSet +abstract class MutableCharSetValue internal constructor() : Value>(), MutableSet +abstract class MutableStringSetValue internal constructor() : Value>(), MutableSet + +abstract class MutableSettingSetValue internal constructor() : Value>(), MutableSet + + +/** + * 只引用这个对象, 而不跟踪其成员. + * 仅适用于基础类型, 用于 mutable list/map 等情况; 或标注了 [Serializable] 的类. + */ +abstract class DynamicReferenceValue internal constructor() : Value() diff --git a/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/setting/_ValueImpl.kt b/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/setting/_ValueImpl.kt index cc8b445aa..32662bd32 100644 --- a/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/setting/_ValueImpl.kt +++ b/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/setting/_ValueImpl.kt @@ -1,3 +1,4 @@ + /* * Copyright 2020 Mamoe Technologies and contributors. * @@ -10,11 +11,15 @@ package net.mamoe.mirai.console.setting +import kotlinx.serialization.Decoder +import kotlinx.serialization.Encoder +import kotlinx.serialization.KSerializer +import kotlinx.serialization.SerialDescriptor import kotlinx.serialization.builtins.* /** - * !!! This file is auto-generated by test/kotlin/net.mamoe.mirai.console.SettingsCodegen.kt + * !!! This file is auto-generated by backend/codegen/src/kotlin/net.mamoe.mirai.console.codegen.ValueImplCodegen.kt * !!! DO NOT MODIFY THIS FILE MANUALLY */ @@ -30,13 +35,9 @@ internal fun Setting.valueImpl(default: Int): IntValue { onElementChanged(this) } } - override val serializer = Int.serializer().bind( - getter = { internalValue }, - setter = { internalValue = it } - ) + override val serializer = Int.serializer() } } - internal fun Setting.valueImpl(default: Short): ShortValue { return object : ShortValue() { private var internalValue: Short = default @@ -48,13 +49,9 @@ internal fun Setting.valueImpl(default: Short): ShortValue { onElementChanged(this) } } - override val serializer = Short.serializer().bind( - getter = { internalValue }, - setter = { internalValue = it } - ) + override val serializer = Short.serializer() } } - internal fun Setting.valueImpl(default: Byte): ByteValue { return object : ByteValue() { private var internalValue: Byte = default @@ -66,13 +63,9 @@ internal fun Setting.valueImpl(default: Byte): ByteValue { onElementChanged(this) } } - override val serializer = Byte.serializer().bind( - getter = { internalValue }, - setter = { internalValue = it } - ) + override val serializer = Byte.serializer() } } - internal fun Setting.valueImpl(default: Long): LongValue { return object : LongValue() { private var internalValue: Long = default @@ -84,13 +77,9 @@ internal fun Setting.valueImpl(default: Long): LongValue { onElementChanged(this) } } - override val serializer = Long.serializer().bind( - getter = { internalValue }, - setter = { internalValue = it } - ) + override val serializer = Long.serializer() } } - internal fun Setting.valueImpl(default: Float): FloatValue { return object : FloatValue() { private var internalValue: Float = default @@ -102,13 +91,9 @@ internal fun Setting.valueImpl(default: Float): FloatValue { onElementChanged(this) } } - override val serializer = Float.serializer().bind( - getter = { internalValue }, - setter = { internalValue = it } - ) + override val serializer = Float.serializer() } } - internal fun Setting.valueImpl(default: Double): DoubleValue { return object : DoubleValue() { private var internalValue: Double = default @@ -120,13 +105,9 @@ internal fun Setting.valueImpl(default: Double): DoubleValue { onElementChanged(this) } } - override val serializer = Double.serializer().bind( - getter = { internalValue }, - setter = { internalValue = it } - ) + override val serializer = Double.serializer() } } - internal fun Setting.valueImpl(default: Boolean): BooleanValue { return object : BooleanValue() { private var internalValue: Boolean = default @@ -138,13 +119,9 @@ internal fun Setting.valueImpl(default: Boolean): BooleanValue { onElementChanged(this) } } - override val serializer = Boolean.serializer().bind( - getter = { internalValue }, - setter = { internalValue = it } - ) + override val serializer = Boolean.serializer() } } - internal fun Setting.valueImpl(default: Char): CharValue { return object : CharValue() { private var internalValue: Char = default @@ -156,13 +133,9 @@ internal fun Setting.valueImpl(default: Char): CharValue { onElementChanged(this) } } - override val serializer = Char.serializer().bind( - getter = { internalValue }, - setter = { internalValue = it } - ) + override val serializer = Char.serializer() } } - internal fun Setting.valueImpl(default: String): StringValue { return object : StringValue() { private var internalValue: String = default @@ -174,13 +147,9 @@ internal fun Setting.valueImpl(default: String): StringValue { onElementChanged(this) } } - override val serializer = String.serializer().bind( - getter = { internalValue }, - setter = { internalValue = it } - ) + override val serializer = String.serializer() } } - internal fun Setting.valueImpl(default: IntArray): IntArrayValue { return object : IntArrayValue() { private var internalValue: IntArray = default @@ -192,13 +161,9 @@ internal fun Setting.valueImpl(default: IntArray): IntArrayValue { onElementChanged(this) } } - override val serializer = IntArraySerializer().bind( - getter = { internalValue }, - setter = { internalValue = it } - ) + override val serializer = IntArraySerializer() } } - internal fun Setting.valueImpl(default: ShortArray): ShortArrayValue { return object : ShortArrayValue() { private var internalValue: ShortArray = default @@ -210,13 +175,9 @@ internal fun Setting.valueImpl(default: ShortArray): ShortArrayValue { onElementChanged(this) } } - override val serializer = ShortArraySerializer().bind( - getter = { internalValue }, - setter = { internalValue = it } - ) + override val serializer = ShortArraySerializer() } } - internal fun Setting.valueImpl(default: ByteArray): ByteArrayValue { return object : ByteArrayValue() { private var internalValue: ByteArray = default @@ -228,13 +189,9 @@ internal fun Setting.valueImpl(default: ByteArray): ByteArrayValue { onElementChanged(this) } } - override val serializer = ByteArraySerializer().bind( - getter = { internalValue }, - setter = { internalValue = it } - ) + override val serializer = ByteArraySerializer() } } - internal fun Setting.valueImpl(default: LongArray): LongArrayValue { return object : LongArrayValue() { private var internalValue: LongArray = default @@ -246,13 +203,9 @@ internal fun Setting.valueImpl(default: LongArray): LongArrayValue { onElementChanged(this) } } - override val serializer = LongArraySerializer().bind( - getter = { internalValue }, - setter = { internalValue = it } - ) + override val serializer = LongArraySerializer() } } - internal fun Setting.valueImpl(default: FloatArray): FloatArrayValue { return object : FloatArrayValue() { private var internalValue: FloatArray = default @@ -264,13 +217,9 @@ internal fun Setting.valueImpl(default: FloatArray): FloatArrayValue { onElementChanged(this) } } - override val serializer = FloatArraySerializer().bind( - getter = { internalValue }, - setter = { internalValue = it } - ) + override val serializer = FloatArraySerializer() } } - internal fun Setting.valueImpl(default: DoubleArray): DoubleArrayValue { return object : DoubleArrayValue() { private var internalValue: DoubleArray = default @@ -282,13 +231,9 @@ internal fun Setting.valueImpl(default: DoubleArray): DoubleArrayValue { onElementChanged(this) } } - override val serializer = DoubleArraySerializer().bind( - getter = { internalValue }, - setter = { internalValue = it } - ) + override val serializer = DoubleArraySerializer() } } - internal fun Setting.valueImpl(default: BooleanArray): BooleanArrayValue { return object : BooleanArrayValue() { private var internalValue: BooleanArray = default @@ -300,13 +245,9 @@ internal fun Setting.valueImpl(default: BooleanArray): BooleanArrayValue { onElementChanged(this) } } - override val serializer = BooleanArraySerializer().bind( - getter = { internalValue }, - setter = { internalValue = it } - ) + override val serializer = BooleanArraySerializer() } } - internal fun Setting.valueImpl(default: CharArray): CharArrayValue { return object : CharArrayValue() { private var internalValue: CharArray = default @@ -318,13 +259,9 @@ internal fun Setting.valueImpl(default: CharArray): CharArrayValue { onElementChanged(this) } } - override val serializer = CharArraySerializer().bind( - getter = { internalValue }, - setter = { internalValue = it } - ) + override val serializer = CharArraySerializer() } } - internal fun Setting.valueImpl(default: Array): TypedIntArrayValue { return object : TypedIntArrayValue() { private var internalValue: Array = default @@ -336,13 +273,9 @@ internal fun Setting.valueImpl(default: Array): TypedIntArrayValue { onElementChanged(this) } } - override val serializer = ArraySerializer(Int.serializer()).bind( - getter = { internalValue }, - setter = { internalValue = it } - ) + override val serializer = ArraySerializer(Int.serializer()) } } - internal fun Setting.valueImpl(default: Array): TypedShortArrayValue { return object : TypedShortArrayValue() { private var internalValue: Array = default @@ -354,13 +287,9 @@ internal fun Setting.valueImpl(default: Array): TypedShortArrayValue { onElementChanged(this) } } - override val serializer = ArraySerializer(Short.serializer()).bind( - getter = { internalValue }, - setter = { internalValue = it } - ) + override val serializer = ArraySerializer(Short.serializer()) } } - internal fun Setting.valueImpl(default: Array): TypedByteArrayValue { return object : TypedByteArrayValue() { private var internalValue: Array = default @@ -372,13 +301,9 @@ internal fun Setting.valueImpl(default: Array): TypedByteArrayValue { onElementChanged(this) } } - override val serializer = ArraySerializer(Byte.serializer()).bind( - getter = { internalValue }, - setter = { internalValue = it } - ) + override val serializer = ArraySerializer(Byte.serializer()) } } - internal fun Setting.valueImpl(default: Array): TypedLongArrayValue { return object : TypedLongArrayValue() { private var internalValue: Array = default @@ -390,13 +315,9 @@ internal fun Setting.valueImpl(default: Array): TypedLongArrayValue { onElementChanged(this) } } - override val serializer = ArraySerializer(Long.serializer()).bind( - getter = { internalValue }, - setter = { internalValue = it } - ) + override val serializer = ArraySerializer(Long.serializer()) } } - internal fun Setting.valueImpl(default: Array): TypedFloatArrayValue { return object : TypedFloatArrayValue() { private var internalValue: Array = default @@ -408,13 +329,9 @@ internal fun Setting.valueImpl(default: Array): TypedFloatArrayValue { onElementChanged(this) } } - override val serializer = ArraySerializer(Float.serializer()).bind( - getter = { internalValue }, - setter = { internalValue = it } - ) + override val serializer = ArraySerializer(Float.serializer()) } } - internal fun Setting.valueImpl(default: Array): TypedDoubleArrayValue { return object : TypedDoubleArrayValue() { private var internalValue: Array = default @@ -426,13 +343,9 @@ internal fun Setting.valueImpl(default: Array): TypedDoubleArrayValue { onElementChanged(this) } } - override val serializer = ArraySerializer(Double.serializer()).bind( - getter = { internalValue }, - setter = { internalValue = it } - ) + override val serializer = ArraySerializer(Double.serializer()) } } - internal fun Setting.valueImpl(default: Array): TypedBooleanArrayValue { return object : TypedBooleanArrayValue() { private var internalValue: Array = default @@ -444,13 +357,9 @@ internal fun Setting.valueImpl(default: Array): TypedBooleanArrayValue onElementChanged(this) } } - override val serializer = ArraySerializer(Boolean.serializer()).bind( - getter = { internalValue }, - setter = { internalValue = it } - ) + override val serializer = ArraySerializer(Boolean.serializer()) } } - internal fun Setting.valueImpl(default: Array): TypedCharArrayValue { return object : TypedCharArrayValue() { private var internalValue: Array = default @@ -462,13 +371,9 @@ internal fun Setting.valueImpl(default: Array): TypedCharArrayValue { onElementChanged(this) } } - override val serializer = ArraySerializer(Char.serializer()).bind( - getter = { internalValue }, - setter = { internalValue = it } - ) + override val serializer = ArraySerializer(Char.serializer()) } } - internal fun Setting.valueImpl(default: Array): TypedStringArrayValue { return object : TypedStringArrayValue() { private var internalValue: Array = default @@ -480,13 +385,9 @@ internal fun Setting.valueImpl(default: Array): TypedStringArrayValue { onElementChanged(this) } } - override val serializer = ArraySerializer(String.serializer()).bind( - getter = { internalValue }, - setter = { internalValue = it } - ) + override val serializer = ArraySerializer(String.serializer()) } } - internal fun Setting.valueImpl(default: List): IntListValue { return object : IntListValue() { private var internalValue: List = default @@ -498,13 +399,9 @@ internal fun Setting.valueImpl(default: List): IntListValue { onElementChanged(this) } } - override val serializer = ListSerializer(Int.serializer()).bind( - getter = { internalValue }, - setter = { internalValue = it } - ) + override val serializer = ListSerializer(Int.serializer()) } } - internal fun Setting.valueImpl(default: List): ShortListValue { return object : ShortListValue() { private var internalValue: List = default @@ -516,13 +413,9 @@ internal fun Setting.valueImpl(default: List): ShortListValue { onElementChanged(this) } } - override val serializer = ListSerializer(Short.serializer()).bind( - getter = { internalValue }, - setter = { internalValue = it } - ) + override val serializer = ListSerializer(Short.serializer()) } } - internal fun Setting.valueImpl(default: List): ByteListValue { return object : ByteListValue() { private var internalValue: List = default @@ -534,13 +427,9 @@ internal fun Setting.valueImpl(default: List): ByteListValue { onElementChanged(this) } } - override val serializer = ListSerializer(Byte.serializer()).bind( - getter = { internalValue }, - setter = { internalValue = it } - ) + override val serializer = ListSerializer(Byte.serializer()) } } - internal fun Setting.valueImpl(default: List): LongListValue { return object : LongListValue() { private var internalValue: List = default @@ -552,13 +441,9 @@ internal fun Setting.valueImpl(default: List): LongListValue { onElementChanged(this) } } - override val serializer = ListSerializer(Long.serializer()).bind( - getter = { internalValue }, - setter = { internalValue = it } - ) + override val serializer = ListSerializer(Long.serializer()) } } - internal fun Setting.valueImpl(default: List): FloatListValue { return object : FloatListValue() { private var internalValue: List = default @@ -570,13 +455,9 @@ internal fun Setting.valueImpl(default: List): FloatListValue { onElementChanged(this) } } - override val serializer = ListSerializer(Float.serializer()).bind( - getter = { internalValue }, - setter = { internalValue = it } - ) + override val serializer = ListSerializer(Float.serializer()) } } - internal fun Setting.valueImpl(default: List): DoubleListValue { return object : DoubleListValue() { private var internalValue: List = default @@ -588,13 +469,9 @@ internal fun Setting.valueImpl(default: List): DoubleListValue { onElementChanged(this) } } - override val serializer = ListSerializer(Double.serializer()).bind( - getter = { internalValue }, - setter = { internalValue = it } - ) + override val serializer = ListSerializer(Double.serializer()) } } - internal fun Setting.valueImpl(default: List): BooleanListValue { return object : BooleanListValue() { private var internalValue: List = default @@ -606,13 +483,9 @@ internal fun Setting.valueImpl(default: List): BooleanListValue { onElementChanged(this) } } - override val serializer = ListSerializer(Boolean.serializer()).bind( - getter = { internalValue }, - setter = { internalValue = it } - ) + override val serializer = ListSerializer(Boolean.serializer()) } } - internal fun Setting.valueImpl(default: List): CharListValue { return object : CharListValue() { private var internalValue: List = default @@ -624,13 +497,9 @@ internal fun Setting.valueImpl(default: List): CharListValue { onElementChanged(this) } } - override val serializer = ListSerializer(Char.serializer()).bind( - getter = { internalValue }, - setter = { internalValue = it } - ) + override val serializer = ListSerializer(Char.serializer()) } } - internal fun Setting.valueImpl(default: List): StringListValue { return object : StringListValue() { private var internalValue: List = default @@ -642,10 +511,772 @@ internal fun Setting.valueImpl(default: List): StringListValue { onElementChanged(this) } } - override val serializer = ListSerializer(String.serializer()).bind( - getter = { internalValue }, - setter = { internalValue = it } - ) + override val serializer = ListSerializer(String.serializer()) + } +} + +internal fun Setting.valueImpl(default: Set): IntSetValue { + return object : IntSetValue() { + private var internalValue: Set = default + override var value: Set + get() = internalValue + set(new) { + if (new != internalValue) { + internalValue = new + onElementChanged(this) + } + } + override val serializer = SetSerializer(Int.serializer()) + } +} + +internal fun Setting.valueImpl(default: Set): ShortSetValue { + return object : ShortSetValue() { + private var internalValue: Set = default + override var value: Set + get() = internalValue + set(new) { + if (new != internalValue) { + internalValue = new + onElementChanged(this) + } + } + override val serializer = SetSerializer(Short.serializer()) + } +} + +internal fun Setting.valueImpl(default: Set): ByteSetValue { + return object : ByteSetValue() { + private var internalValue: Set = default + override var value: Set + get() = internalValue + set(new) { + if (new != internalValue) { + internalValue = new + onElementChanged(this) + } + } + override val serializer = SetSerializer(Byte.serializer()) + } +} + +internal fun Setting.valueImpl(default: Set): LongSetValue { + return object : LongSetValue() { + private var internalValue: Set = default + override var value: Set + get() = internalValue + set(new) { + if (new != internalValue) { + internalValue = new + onElementChanged(this) + } + } + override val serializer = SetSerializer(Long.serializer()) + } +} + +internal fun Setting.valueImpl(default: Set): FloatSetValue { + return object : FloatSetValue() { + private var internalValue: Set = default + override var value: Set + get() = internalValue + set(new) { + if (new != internalValue) { + internalValue = new + onElementChanged(this) + } + } + override val serializer = SetSerializer(Float.serializer()) + } +} + +internal fun Setting.valueImpl(default: Set): DoubleSetValue { + return object : DoubleSetValue() { + private var internalValue: Set = default + override var value: Set + get() = internalValue + set(new) { + if (new != internalValue) { + internalValue = new + onElementChanged(this) + } + } + override val serializer = SetSerializer(Double.serializer()) + } +} + +internal fun Setting.valueImpl(default: Set): BooleanSetValue { + return object : BooleanSetValue() { + private var internalValue: Set = default + override var value: Set + get() = internalValue + set(new) { + if (new != internalValue) { + internalValue = new + onElementChanged(this) + } + } + override val serializer = SetSerializer(Boolean.serializer()) + } +} + +internal fun Setting.valueImpl(default: Set): CharSetValue { + return object : CharSetValue() { + private var internalValue: Set = default + override var value: Set + get() = internalValue + set(new) { + if (new != internalValue) { + internalValue = new + onElementChanged(this) + } + } + override val serializer = SetSerializer(Char.serializer()) + } +} + +internal fun Setting.valueImpl(default: Set): StringSetValue { + return object : StringSetValue() { + private var internalValue: Set = default + override var value: Set + get() = internalValue + set(new) { + if (new != internalValue) { + internalValue = new + onElementChanged(this) + } + } + override val serializer = SetSerializer(String.serializer()) + } +} + +@JvmName("valueImplMutableIntList") +internal fun Setting.valueImpl( + default: MutableList +): MutableIntListValue { + var internalValue: MutableList = default + + return object : MutableIntListValue(), MutableList by dynamicMutableList({ internalValue }) { + override var value: MutableList + get() = internalValue + set(new) { + if (new != internalValue) { + internalValue = new + onElementChanged(this) + } + } + + private inline val `this` get() = this + + override val serializer: KSerializer> = object : KSerializer> { + private val delegate = ListSerializer(Int.serializer()) + override val descriptor: SerialDescriptor = delegate.descriptor + + override fun deserialize(decoder: Decoder): MutableList { + return delegate.deserialize(decoder).toMutableList().observable { + onElementChanged(`this`) + } + } + + override fun serialize(encoder: Encoder, value: MutableList) { + delegate.serialize(encoder, value) + } + } + } +} + +@JvmName("valueImplMutableShortList") +internal fun Setting.valueImpl( + default: MutableList +): MutableShortListValue { + var internalValue: MutableList = default + + return object : MutableShortListValue(), MutableList by dynamicMutableList({ internalValue }) { + override var value: MutableList + get() = internalValue + set(new) { + if (new != internalValue) { + internalValue = new + onElementChanged(this) + } + } + + private inline val `this` get() = this + + override val serializer: KSerializer> = object : KSerializer> { + private val delegate = ListSerializer(Short.serializer()) + override val descriptor: SerialDescriptor = delegate.descriptor + + override fun deserialize(decoder: Decoder): MutableList { + return delegate.deserialize(decoder).toMutableList().observable { + onElementChanged(`this`) + } + } + + override fun serialize(encoder: Encoder, value: MutableList) { + delegate.serialize(encoder, value) + } + } + } +} + +@JvmName("valueImplMutableByteList") +internal fun Setting.valueImpl( + default: MutableList +): MutableByteListValue { + var internalValue: MutableList = default + + return object : MutableByteListValue(), MutableList by dynamicMutableList({ internalValue }) { + override var value: MutableList + get() = internalValue + set(new) { + if (new != internalValue) { + internalValue = new + onElementChanged(this) + } + } + + private inline val `this` get() = this + + override val serializer: KSerializer> = object : KSerializer> { + private val delegate = ListSerializer(Byte.serializer()) + override val descriptor: SerialDescriptor = delegate.descriptor + + override fun deserialize(decoder: Decoder): MutableList { + return delegate.deserialize(decoder).toMutableList().observable { + onElementChanged(`this`) + } + } + + override fun serialize(encoder: Encoder, value: MutableList) { + delegate.serialize(encoder, value) + } + } + } +} + +@JvmName("valueImplMutableLongList") +internal fun Setting.valueImpl( + default: MutableList +): MutableLongListValue { + var internalValue: MutableList = default + + return object : MutableLongListValue(), MutableList by dynamicMutableList({ internalValue }) { + override var value: MutableList + get() = internalValue + set(new) { + if (new != internalValue) { + internalValue = new + onElementChanged(this) + } + } + + private inline val `this` get() = this + + override val serializer: KSerializer> = object : KSerializer> { + private val delegate = ListSerializer(Long.serializer()) + override val descriptor: SerialDescriptor = delegate.descriptor + + override fun deserialize(decoder: Decoder): MutableList { + return delegate.deserialize(decoder).toMutableList().observable { + onElementChanged(`this`) + } + } + + override fun serialize(encoder: Encoder, value: MutableList) { + delegate.serialize(encoder, value) + } + } + } +} + +@JvmName("valueImplMutableFloatList") +internal fun Setting.valueImpl( + default: MutableList +): MutableFloatListValue { + var internalValue: MutableList = default + + return object : MutableFloatListValue(), MutableList by dynamicMutableList({ internalValue }) { + override var value: MutableList + get() = internalValue + set(new) { + if (new != internalValue) { + internalValue = new + onElementChanged(this) + } + } + + private inline val `this` get() = this + + override val serializer: KSerializer> = object : KSerializer> { + private val delegate = ListSerializer(Float.serializer()) + override val descriptor: SerialDescriptor = delegate.descriptor + + override fun deserialize(decoder: Decoder): MutableList { + return delegate.deserialize(decoder).toMutableList().observable { + onElementChanged(`this`) + } + } + + override fun serialize(encoder: Encoder, value: MutableList) { + delegate.serialize(encoder, value) + } + } + } +} + +@JvmName("valueImplMutableDoubleList") +internal fun Setting.valueImpl( + default: MutableList +): MutableDoubleListValue { + var internalValue: MutableList = default + + return object : MutableDoubleListValue(), MutableList by dynamicMutableList({ internalValue }) { + override var value: MutableList + get() = internalValue + set(new) { + if (new != internalValue) { + internalValue = new + onElementChanged(this) + } + } + + private inline val `this` get() = this + + override val serializer: KSerializer> = object : KSerializer> { + private val delegate = ListSerializer(Double.serializer()) + override val descriptor: SerialDescriptor = delegate.descriptor + + override fun deserialize(decoder: Decoder): MutableList { + return delegate.deserialize(decoder).toMutableList().observable { + onElementChanged(`this`) + } + } + + override fun serialize(encoder: Encoder, value: MutableList) { + delegate.serialize(encoder, value) + } + } + } +} + +@JvmName("valueImplMutableBooleanList") +internal fun Setting.valueImpl( + default: MutableList +): MutableBooleanListValue { + var internalValue: MutableList = default + + return object : MutableBooleanListValue(), MutableList by dynamicMutableList({ internalValue }) { + override var value: MutableList + get() = internalValue + set(new) { + if (new != internalValue) { + internalValue = new + onElementChanged(this) + } + } + + private inline val `this` get() = this + + override val serializer: KSerializer> = object : KSerializer> { + private val delegate = ListSerializer(Boolean.serializer()) + override val descriptor: SerialDescriptor = delegate.descriptor + + override fun deserialize(decoder: Decoder): MutableList { + return delegate.deserialize(decoder).toMutableList().observable { + onElementChanged(`this`) + } + } + + override fun serialize(encoder: Encoder, value: MutableList) { + delegate.serialize(encoder, value) + } + } + } +} + +@JvmName("valueImplMutableCharList") +internal fun Setting.valueImpl( + default: MutableList +): MutableCharListValue { + var internalValue: MutableList = default + + return object : MutableCharListValue(), MutableList by dynamicMutableList({ internalValue }) { + override var value: MutableList + get() = internalValue + set(new) { + if (new != internalValue) { + internalValue = new + onElementChanged(this) + } + } + + private inline val `this` get() = this + + override val serializer: KSerializer> = object : KSerializer> { + private val delegate = ListSerializer(Char.serializer()) + override val descriptor: SerialDescriptor = delegate.descriptor + + override fun deserialize(decoder: Decoder): MutableList { + return delegate.deserialize(decoder).toMutableList().observable { + onElementChanged(`this`) + } + } + + override fun serialize(encoder: Encoder, value: MutableList) { + delegate.serialize(encoder, value) + } + } + } +} + +@JvmName("valueImplMutableStringList") +internal fun Setting.valueImpl( + default: MutableList +): MutableStringListValue { + var internalValue: MutableList = default + + return object : MutableStringListValue(), MutableList by dynamicMutableList({ internalValue }) { + override var value: MutableList + get() = internalValue + set(new) { + if (new != internalValue) { + internalValue = new + onElementChanged(this) + } + } + + private inline val `this` get() = this + + override val serializer: KSerializer> = object : KSerializer> { + private val delegate = ListSerializer(String.serializer()) + override val descriptor: SerialDescriptor = delegate.descriptor + + override fun deserialize(decoder: Decoder): MutableList { + return delegate.deserialize(decoder).toMutableList().observable { + onElementChanged(`this`) + } + } + + override fun serialize(encoder: Encoder, value: MutableList) { + delegate.serialize(encoder, value) + } + } + } +} + +@JvmName("valueImplMutableIntSet") +internal fun Setting.valueImpl( + default: MutableSet +): MutableIntSetValue { + var internalValue: MutableSet = default + + return object : MutableIntSetValue(), MutableSet by dynamicMutableSet({ internalValue }) { + override var value: MutableSet + get() = internalValue + set(new) { + if (new != internalValue) { + internalValue = new + onElementChanged(this) + } + } + + private inline val `this` get() = this + + override val serializer: KSerializer> = object : KSerializer> { + private val delegate = SetSerializer(Int.serializer()) + override val descriptor: SerialDescriptor = delegate.descriptor + + override fun deserialize(decoder: Decoder): MutableSet { + return delegate.deserialize(decoder).toMutableSet().observable { + onElementChanged(`this`) + } + } + + override fun serialize(encoder: Encoder, value: MutableSet) { + delegate.serialize(encoder, value) + } + } + } +} + +@JvmName("valueImplMutableShortSet") +internal fun Setting.valueImpl( + default: MutableSet +): MutableShortSetValue { + var internalValue: MutableSet = default + + return object : MutableShortSetValue(), MutableSet by dynamicMutableSet({ internalValue }) { + override var value: MutableSet + get() = internalValue + set(new) { + if (new != internalValue) { + internalValue = new + onElementChanged(this) + } + } + + private inline val `this` get() = this + + override val serializer: KSerializer> = object : KSerializer> { + private val delegate = SetSerializer(Short.serializer()) + override val descriptor: SerialDescriptor = delegate.descriptor + + override fun deserialize(decoder: Decoder): MutableSet { + return delegate.deserialize(decoder).toMutableSet().observable { + onElementChanged(`this`) + } + } + + override fun serialize(encoder: Encoder, value: MutableSet) { + delegate.serialize(encoder, value) + } + } + } +} + +@JvmName("valueImplMutableByteSet") +internal fun Setting.valueImpl( + default: MutableSet +): MutableByteSetValue { + var internalValue: MutableSet = default + + return object : MutableByteSetValue(), MutableSet by dynamicMutableSet({ internalValue }) { + override var value: MutableSet + get() = internalValue + set(new) { + if (new != internalValue) { + internalValue = new + onElementChanged(this) + } + } + + private inline val `this` get() = this + + override val serializer: KSerializer> = object : KSerializer> { + private val delegate = SetSerializer(Byte.serializer()) + override val descriptor: SerialDescriptor = delegate.descriptor + + override fun deserialize(decoder: Decoder): MutableSet { + return delegate.deserialize(decoder).toMutableSet().observable { + onElementChanged(`this`) + } + } + + override fun serialize(encoder: Encoder, value: MutableSet) { + delegate.serialize(encoder, value) + } + } + } +} + +@JvmName("valueImplMutableLongSet") +internal fun Setting.valueImpl( + default: MutableSet +): MutableLongSetValue { + var internalValue: MutableSet = default + + return object : MutableLongSetValue(), MutableSet by dynamicMutableSet({ internalValue }) { + override var value: MutableSet + get() = internalValue + set(new) { + if (new != internalValue) { + internalValue = new + onElementChanged(this) + } + } + + private inline val `this` get() = this + + override val serializer: KSerializer> = object : KSerializer> { + private val delegate = SetSerializer(Long.serializer()) + override val descriptor: SerialDescriptor = delegate.descriptor + + override fun deserialize(decoder: Decoder): MutableSet { + return delegate.deserialize(decoder).toMutableSet().observable { + onElementChanged(`this`) + } + } + + override fun serialize(encoder: Encoder, value: MutableSet) { + delegate.serialize(encoder, value) + } + } + } +} + +@JvmName("valueImplMutableFloatSet") +internal fun Setting.valueImpl( + default: MutableSet +): MutableFloatSetValue { + var internalValue: MutableSet = default + + return object : MutableFloatSetValue(), MutableSet by dynamicMutableSet({ internalValue }) { + override var value: MutableSet + get() = internalValue + set(new) { + if (new != internalValue) { + internalValue = new + onElementChanged(this) + } + } + + private inline val `this` get() = this + + override val serializer: KSerializer> = object : KSerializer> { + private val delegate = SetSerializer(Float.serializer()) + override val descriptor: SerialDescriptor = delegate.descriptor + + override fun deserialize(decoder: Decoder): MutableSet { + return delegate.deserialize(decoder).toMutableSet().observable { + onElementChanged(`this`) + } + } + + override fun serialize(encoder: Encoder, value: MutableSet) { + delegate.serialize(encoder, value) + } + } + } +} + +@JvmName("valueImplMutableDoubleSet") +internal fun Setting.valueImpl( + default: MutableSet +): MutableDoubleSetValue { + var internalValue: MutableSet = default + + return object : MutableDoubleSetValue(), MutableSet by dynamicMutableSet({ internalValue }) { + override var value: MutableSet + get() = internalValue + set(new) { + if (new != internalValue) { + internalValue = new + onElementChanged(this) + } + } + + private inline val `this` get() = this + + override val serializer: KSerializer> = object : KSerializer> { + private val delegate = SetSerializer(Double.serializer()) + override val descriptor: SerialDescriptor = delegate.descriptor + + override fun deserialize(decoder: Decoder): MutableSet { + return delegate.deserialize(decoder).toMutableSet().observable { + onElementChanged(`this`) + } + } + + override fun serialize(encoder: Encoder, value: MutableSet) { + delegate.serialize(encoder, value) + } + } + } +} + +@JvmName("valueImplMutableBooleanSet") +internal fun Setting.valueImpl( + default: MutableSet +): MutableBooleanSetValue { + var internalValue: MutableSet = default + + return object : MutableBooleanSetValue(), MutableSet by dynamicMutableSet({ internalValue }) { + override var value: MutableSet + get() = internalValue + set(new) { + if (new != internalValue) { + internalValue = new + onElementChanged(this) + } + } + + private inline val `this` get() = this + + override val serializer: KSerializer> = object : KSerializer> { + private val delegate = SetSerializer(Boolean.serializer()) + override val descriptor: SerialDescriptor = delegate.descriptor + + override fun deserialize(decoder: Decoder): MutableSet { + return delegate.deserialize(decoder).toMutableSet().observable { + onElementChanged(`this`) + } + } + + override fun serialize(encoder: Encoder, value: MutableSet) { + delegate.serialize(encoder, value) + } + } + } +} + +@JvmName("valueImplMutableCharSet") +internal fun Setting.valueImpl( + default: MutableSet +): MutableCharSetValue { + var internalValue: MutableSet = default + + return object : MutableCharSetValue(), MutableSet by dynamicMutableSet({ internalValue }) { + override var value: MutableSet + get() = internalValue + set(new) { + if (new != internalValue) { + internalValue = new + onElementChanged(this) + } + } + + private inline val `this` get() = this + + override val serializer: KSerializer> = object : KSerializer> { + private val delegate = SetSerializer(Char.serializer()) + override val descriptor: SerialDescriptor = delegate.descriptor + + override fun deserialize(decoder: Decoder): MutableSet { + return delegate.deserialize(decoder).toMutableSet().observable { + onElementChanged(`this`) + } + } + + override fun serialize(encoder: Encoder, value: MutableSet) { + delegate.serialize(encoder, value) + } + } + } +} + +@JvmName("valueImplMutableStringSet") +internal fun Setting.valueImpl( + default: MutableSet +): MutableStringSetValue { + var internalValue: MutableSet = default + + return object : MutableStringSetValue(), MutableSet by dynamicMutableSet({ internalValue }) { + override var value: MutableSet + get() = internalValue + set(new) { + if (new != internalValue) { + internalValue = new + onElementChanged(this) + } + } + + private inline val `this` get() = this + + override val serializer: KSerializer> = object : KSerializer> { + private val delegate = SetSerializer(String.serializer()) + override val descriptor: SerialDescriptor = delegate.descriptor + + override fun deserialize(decoder: Decoder): MutableSet { + return delegate.deserialize(decoder).toMutableSet().observable { + onElementChanged(`this`) + } + } + + override fun serialize(encoder: Encoder, value: MutableSet) { + delegate.serialize(encoder, value) + } + } } } diff --git a/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/setting/utils.kt b/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/setting/utils.kt new file mode 100644 index 000000000..0f069db89 --- /dev/null +++ b/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/setting/utils.kt @@ -0,0 +1,271 @@ +/* + * 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.ImplicitReflectionSerializer +import kotlinx.serialization.serializer +import net.mamoe.yamlkt.Yaml +import kotlin.reflect.KClass + +internal fun MutableList.shadowMap(transform: (E) -> R, transformBack: (R) -> E): MutableList { + return object : MutableList { + override val size: Int get() = this@shadowMap.size + + override fun contains(element: R): Boolean = this@shadowMap.any { it.let(transform) == element } + override fun containsAll(elements: Collection): Boolean = elements.all(::contains) + override fun get(index: Int): R = this@shadowMap[index].let(transform) + override fun indexOf(element: R): Int = this@shadowMap.indexOfFirst { it.let(transform) == element } + override fun isEmpty(): Boolean = this@shadowMap.isEmpty() + override fun iterator(): MutableIterator = object : MutableIterator { + private val delegate = this@shadowMap.iterator() + override fun hasNext(): Boolean = delegate.hasNext() + override fun next(): R = delegate.next().let(transform) + override fun remove() = delegate.remove() + } + + override fun lastIndexOf(element: R): Int = this@shadowMap.indexOfLast { it.let(transform) == element } + override fun add(element: R): Boolean = this@shadowMap.add(element.let(transformBack)) + override fun add(index: Int, element: R) = this@shadowMap.add(index, element.let(transformBack)) + override fun addAll(index: Int, elements: Collection): Boolean = + this@shadowMap.addAll(index, elements.map(transformBack)) + + override fun addAll(elements: Collection): Boolean = this@shadowMap.addAll(elements.map(transformBack)) + override fun clear() = this@shadowMap.clear() + + override fun listIterator(): MutableListIterator = object : MutableListIterator { + private val delegate = this@shadowMap.listIterator() + override fun hasPrevious(): Boolean = delegate.hasPrevious() + override fun nextIndex(): Int = delegate.nextIndex() + override fun previous(): R = delegate.previous().let(transform) + override fun previousIndex(): Int = delegate.previousIndex() + override fun add(element: R) = delegate.add(element.let(transformBack)) + override fun hasNext(): Boolean = delegate.hasNext() + override fun next(): R = delegate.next().let(transform) + override fun remove() = delegate.remove() + override fun set(element: R) = delegate.set(element.let(transformBack)) + } + + override fun listIterator(index: Int): MutableListIterator = object : MutableListIterator { + private val delegate = this@shadowMap.listIterator(index) + override fun hasPrevious(): Boolean = delegate.hasPrevious() + override fun nextIndex(): Int = delegate.nextIndex() + override fun previous(): R = delegate.previous().let(transform) + override fun previousIndex(): Int = delegate.previousIndex() + override fun add(element: R) = delegate.add(element.let(transformBack)) + override fun hasNext(): Boolean = delegate.hasNext() + override fun next(): R = delegate.next().let(transform) + override fun remove() = delegate.remove() + override fun set(element: R) = delegate.set(element.let(transformBack)) + } + + override fun remove(element: R): Boolean = this@shadowMap.removeIf { it.let(transform) == element } + override fun removeAll(elements: Collection): Boolean = elements.all(::remove) + override fun removeAt(index: Int): R = this@shadowMap.removeAt(index).let(transform) + override fun retainAll(elements: Collection): Boolean = this@shadowMap.retainAll(elements.map(transformBack)) + override fun set(index: Int, element: R): R = + this@shadowMap.set(index, element.let(transformBack)).let(transform) + + override fun subList(fromIndex: Int, toIndex: Int): MutableList = + this@shadowMap.subList(fromIndex, toIndex).map(transform).toMutableList() + } +} + + +internal fun MutableSet.shadowMap(transform: (E) -> R, transformBack: (R) -> E): MutableSet { + return object : MutableSet { + override val size: Int get() = this@shadowMap.size + + override fun contains(element: R): Boolean = this@shadowMap.any { it.let(transform) == element } + override fun containsAll(elements: Collection): Boolean = elements.all(::contains) + override fun isEmpty(): Boolean = this@shadowMap.isEmpty() + override fun iterator(): MutableIterator = object : MutableIterator { + private val delegate = this@shadowMap.iterator() + override fun hasNext(): Boolean = delegate.hasNext() + override fun next(): R = delegate.next().let(transform) + override fun remove() = delegate.remove() + } + + override fun add(element: R): Boolean = this@shadowMap.add(element.let(transformBack)) + override fun addAll(elements: Collection): Boolean = this@shadowMap.addAll(elements.map(transformBack)) + override fun clear() = this@shadowMap.clear() + + override fun remove(element: R): Boolean = this@shadowMap.removeIf { it.let(transform) == element } + override fun removeAll(elements: Collection): Boolean = elements.all(::remove) + override fun retainAll(elements: Collection): Boolean = this@shadowMap.retainAll(elements.map(transformBack)) + } +} + +internal fun dynamicList(supplier: () -> List): List { + return object : List { + override val size: Int get() = supplier().size + override fun contains(element: T): Boolean = supplier().contains(element) + override fun containsAll(elements: Collection): Boolean = supplier().containsAll(elements) + override fun get(index: Int): T = supplier()[index] + override fun indexOf(element: T): Int = supplier().indexOf(element) + override fun isEmpty(): Boolean = supplier().isEmpty() + override fun iterator(): Iterator = supplier().iterator() + override fun lastIndexOf(element: T): Int = supplier().lastIndexOf(element) + override fun listIterator(): ListIterator = supplier().listIterator() + override fun listIterator(index: Int): ListIterator = supplier().listIterator(index) + override fun subList(fromIndex: Int, toIndex: Int): List = supplier().subList(fromIndex, toIndex) + } +} + +internal fun dynamicSet(supplier: () -> Set): Set { + return object : Set { + override val size: Int get() = supplier().size + override fun contains(element: T): Boolean = supplier().contains(element) + override fun containsAll(elements: Collection): Boolean = supplier().containsAll(elements) + override fun isEmpty(): Boolean = supplier().isEmpty() + override fun iterator(): Iterator = supplier().iterator() + } +} + + +internal fun dynamicMutableList(supplier: () -> MutableList): MutableList { + return object : MutableList { + override val size: Int get() = supplier().size + override fun contains(element: T): Boolean = supplier().contains(element) + override fun containsAll(elements: Collection): Boolean = supplier().containsAll(elements) + override fun get(index: Int): T = supplier()[index] + override fun indexOf(element: T): Int = supplier().indexOf(element) + override fun isEmpty(): Boolean = supplier().isEmpty() + override fun iterator(): MutableIterator = supplier().iterator() + override fun lastIndexOf(element: T): Int = supplier().lastIndexOf(element) + override fun add(element: T): Boolean = supplier().add(element) + override fun add(index: Int, element: T) = supplier().add(index, element) + override fun addAll(index: Int, elements: Collection): Boolean = supplier().addAll(index, elements) + override fun addAll(elements: Collection): Boolean = supplier().addAll(elements) + override fun clear() = supplier().clear() + override fun listIterator(): MutableListIterator = supplier().listIterator() + override fun listIterator(index: Int): MutableListIterator = supplier().listIterator(index) + override fun remove(element: T): Boolean = supplier().remove(element) + override fun removeAll(elements: Collection): Boolean = supplier().removeAll(elements) + override fun removeAt(index: Int): T = supplier().removeAt(index) + override fun retainAll(elements: Collection): Boolean = supplier().retainAll(elements) + override fun set(index: Int, element: T): T = supplier().set(index, element) + override fun subList(fromIndex: Int, toIndex: Int): MutableList = supplier().subList(fromIndex, toIndex) + } +} + + +internal fun dynamicMutableSet(supplier: () -> MutableSet): MutableSet { + return object : MutableSet { + override val size: Int get() = supplier().size + override fun contains(element: T): Boolean = supplier().contains(element) + override fun containsAll(elements: Collection): Boolean = supplier().containsAll(elements) + override fun isEmpty(): Boolean = supplier().isEmpty() + override fun iterator(): MutableIterator = supplier().iterator() + override fun add(element: T): Boolean = supplier().add(element) + override fun addAll(elements: Collection): Boolean = supplier().addAll(elements) + override fun clear() = supplier().clear() + override fun remove(element: T): Boolean = supplier().remove(element) + override fun removeAll(elements: Collection): Boolean = supplier().removeAll(elements) + override fun retainAll(elements: Collection): Boolean = supplier().retainAll(elements) + } +} + +internal inline fun MutableList.observable(crossinline onChanged: () -> Unit): MutableList { + return object : MutableList { + override val size: Int get() = this@observable.size + override fun contains(element: T): Boolean = this@observable.contains(element) + override fun containsAll(elements: Collection): Boolean = this@observable.containsAll(elements) + override fun get(index: Int): T = this@observable[index] + override fun indexOf(element: T): Int = this@observable.indexOf(element) + override fun isEmpty(): Boolean = this@observable.isEmpty() + override fun iterator(): MutableIterator = object : MutableIterator { + private val delegate = this@observable.iterator() + override fun hasNext(): Boolean = delegate.hasNext() + override fun next(): T = delegate.next() + override fun remove() = delegate.remove().also { onChanged() } + } + + override fun lastIndexOf(element: T): Int = this@observable.lastIndexOf(element) + override fun add(element: T): Boolean = this@observable.add(element).also { onChanged() } + override fun add(index: Int, element: T) = this@observable.add(index, element).also { onChanged() } + override fun addAll(index: Int, elements: Collection): Boolean = + this@observable.addAll(index, elements).also { onChanged() } + + override fun addAll(elements: Collection): Boolean = this@observable.addAll(elements).also { onChanged() } + override fun clear() = this@observable.clear().also { onChanged() } + override fun listIterator(): MutableListIterator = object : MutableListIterator { + private val delegate = this@observable.listIterator() + override fun hasPrevious(): Boolean = delegate.hasPrevious() + override fun nextIndex(): Int = delegate.nextIndex() + override fun previous(): T = delegate.previous() + override fun previousIndex(): Int = delegate.previousIndex() + override fun add(element: T) = delegate.add(element).also { onChanged() } + override fun hasNext(): Boolean = delegate.hasNext() + override fun next(): T = delegate.next() + override fun remove() = delegate.remove().also { onChanged() } + override fun set(element: T) = delegate.set(element).also { onChanged() } + } + + override fun listIterator(index: Int): MutableListIterator = object : MutableListIterator { + private val delegate = this@observable.listIterator(index) + override fun hasPrevious(): Boolean = delegate.hasPrevious() + override fun nextIndex(): Int = delegate.nextIndex() + override fun previous(): T = delegate.previous() + override fun previousIndex(): Int = delegate.previousIndex() + override fun add(element: T) = delegate.add(element).also { onChanged() } + override fun hasNext(): Boolean = delegate.hasNext() + override fun next(): T = delegate.next() + override fun remove() = delegate.remove().also { onChanged() } + override fun set(element: T) = delegate.set(element).also { onChanged() } + } + + override fun remove(element: T): Boolean = this@observable.remove(element).also { onChanged() } + override fun removeAll(elements: Collection): Boolean = + this@observable.removeAll(elements).also { onChanged() } + + override fun removeAt(index: Int): T = this@observable.removeAt(index).also { onChanged() } + override fun retainAll(elements: Collection): Boolean = + this@observable.retainAll(elements).also { onChanged() } + + override fun set(index: Int, element: T): T = this@observable.set(index, element).also { onChanged() } + override fun subList(fromIndex: Int, toIndex: Int): MutableList = this@observable.subList(fromIndex, toIndex) + } +} + +internal inline fun MutableSet.observable(crossinline onChanged: () -> Unit): MutableSet { + return object : MutableSet { + override val size: Int get() = this@observable.size + override fun contains(element: T): Boolean = this@observable.contains(element) + override fun containsAll(elements: Collection): Boolean = this@observable.containsAll(elements) + override fun isEmpty(): Boolean = this@observable.isEmpty() + override fun iterator(): MutableIterator = object : MutableIterator { + private val delegate = this@observable.iterator() + override fun hasNext(): Boolean = delegate.hasNext() + override fun next(): T = delegate.next() + override fun remove() = delegate.remove().also { onChanged() } + } + + override fun add(element: T): Boolean = this@observable.add(element).also { onChanged() } + override fun addAll(elements: Collection): Boolean = this@observable.addAll(elements).also { onChanged() } + override fun clear() = this@observable.clear().also { onChanged() } + override fun remove(element: T): Boolean = this@observable.remove(element).also { onChanged() } + override fun removeAll(elements: Collection): Boolean = + this@observable.removeAll(elements).also { onChanged() } + + override fun retainAll(elements: Collection): Boolean = + this@observable.retainAll(elements).also { onChanged() } + } +} + + +@OptIn(ImplicitReflectionSerializer::class) +internal fun Any.smartCastPrimitive(clazz: KClass): R { + kotlin.runCatching { + return Yaml.default.parse(clazz.serializer(), this.toString()) + }.getOrElse { + throw IllegalArgumentException("Cannot cast '$this' to ${clazz.qualifiedName}", it) + } +} + From 3c36bb7660b7f112d5163410a00b6d6f2c5fd2ee Mon Sep 17 00:00:00 2001 From: Him188 Date: Sun, 17 May 2020 15:47:41 +0800 Subject: [PATCH 3/4] Improve codegen --- .../mirai/console/codegen/ValueImplCodegen.kt | 38 +++++++++++ .../mirai/console/codegen/ValuesCodegen.kt | 36 +---------- .../net/mamoe/mirai/console/setting/_Value.kt | 45 +++---------- .../mamoe/mirai/console/setting/_ValueImpl.kt | 63 ++++++++++++++++++- 4 files changed, 110 insertions(+), 72 deletions(-) diff --git a/backend/codegen/src/main/kotlin/net/mamoe/mirai/console/codegen/ValueImplCodegen.kt b/backend/codegen/src/main/kotlin/net/mamoe/mirai/console/codegen/ValueImplCodegen.kt index 1e06ea9e7..0401e5093 100644 --- a/backend/codegen/src/main/kotlin/net/mamoe/mirai/console/codegen/ValueImplCodegen.kt +++ b/backend/codegen/src/main/kotlin/net/mamoe/mirai/console/codegen/ValueImplCodegen.kt @@ -57,11 +57,13 @@ fun genAllValueImpl(): String = buildString { // PRIMITIVE for (number in NUMBERS + OTHER_PRIMITIVES) { appendln(genValueImpl(number, number, "$number.serializer()", false)) + appendln() } // PRIMITIVE ARRAYS for (number in NUMBERS + OTHER_PRIMITIVES.filterNot { it == "String" }) { appendln(genValueImpl("${number}Array", "${number}Array", "${number}ArraySerializer()", true)) + appendln() } // TYPED ARRAYS @@ -74,6 +76,7 @@ fun genAllValueImpl(): String = buildString { true ) ) + appendln() } // PRIMITIVE LISTS / SETS @@ -87,6 +90,7 @@ fun genAllValueImpl(): String = buildString { false ) ) + appendln() } } @@ -137,6 +141,40 @@ fun genAllValueImpl(): String = buildString { appendln() } } + + appendln() + + + appendln( + """ + internal fun Setting.valueImpl(default: T): Value { + return object : SettingValue() { + private var internalValue: T = default + override var value: T + get() = internalValue + set(new) { + if (new != internalValue) { + internalValue = new + onElementChanged(this) + } + } + override val serializer = object : KSerializer{ + override val descriptor: SerialDescriptor + get() = internalValue.updaterSerializer.descriptor + + override fun deserialize(decoder: Decoder): T { + internalValue.updaterSerializer.deserialize(decoder) + return internalValue + } + + override fun serialize(encoder: Encoder, value: T) { + internalValue.updaterSerializer.serialize(encoder, SettingSerializerMark) + } + } + } + } + """ + ) } fun genValueImpl(kotlinTypeName: String, miraiValueName: String, serializer: String, isArray: Boolean): String = diff --git a/backend/codegen/src/main/kotlin/net/mamoe/mirai/console/codegen/ValuesCodegen.kt b/backend/codegen/src/main/kotlin/net/mamoe/mirai/console/codegen/ValuesCodegen.kt index ff92d8851..d0d984b07 100644 --- a/backend/codegen/src/main/kotlin/net/mamoe/mirai/console/codegen/ValuesCodegen.kt +++ b/backend/codegen/src/main/kotlin/net/mamoe/mirai/console/codegen/ValuesCodegen.kt @@ -65,10 +65,7 @@ fun genPublicApi() = buildString { """ package net.mamoe.mirai.console.setting - import kotlinx.serialization.Decoder - import kotlinx.serialization.Encoder import kotlinx.serialization.KSerializer - import kotlinx.serialization.SerialDescriptor import kotlin.properties.ReadWriteProperty import kotlin.reflect.KProperty """ @@ -221,42 +218,11 @@ sealed class Value : ReadWriteProperty { appendln() } - // FOR COMPLEX TYPES + // SETTING VALUE appendln( """ abstract class SettingValue internal constructor() : Value() - - internal fun Setting.valueImpl(default: T): Value { - return object : SettingValue() { - private var internalValue: T = default - override var value: T - get() = internalValue - set(new) { - if (new != internalValue) { - internalValue = new - onElementChanged(this) - } - } - override val serializer = object : KSerializer{ - override val descriptor: SerialDescriptor - get() = internalValue.updaterSerializer.descriptor - - override fun deserialize(decoder: Decoder): T { - internalValue.updaterSerializer.deserialize(decoder) - return internalValue - } - - override fun serialize(encoder: Encoder, value: T) { - internalValue.updaterSerializer.serialize(encoder, SettingSerializerMark) - } - - }.bind( - getter = { internalValue }, - setter = { internalValue = it } - ) - } - } """ ) diff --git a/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/setting/_Value.kt b/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/setting/_Value.kt index 257acbbb9..a28b5e9f4 100644 --- a/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/setting/_Value.kt +++ b/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/setting/_Value.kt @@ -9,10 +9,7 @@ package net.mamoe.mirai.console.setting -import kotlinx.serialization.Decoder -import kotlinx.serialization.Encoder import kotlinx.serialization.KSerializer -import kotlinx.serialization.SerialDescriptor import kotlin.properties.ReadWriteProperty import kotlin.reflect.KProperty @@ -65,29 +62,36 @@ sealed class PrimitiveArrayValue : ArrayValue() abstract class IntArrayValue internal constructor() : PrimitiveArrayValue(), Iterable { override fun iterator(): Iterator = this.value.iterator() } + abstract class ShortArrayValue internal constructor() : PrimitiveArrayValue(), Iterable { override fun iterator(): Iterator = this.value.iterator() } + abstract class ByteArrayValue internal constructor() : PrimitiveArrayValue(), Iterable { override fun iterator(): Iterator = this.value.iterator() } + abstract class LongArrayValue internal constructor() : PrimitiveArrayValue(), Iterable { override fun iterator(): Iterator = this.value.iterator() } + abstract class FloatArrayValue internal constructor() : PrimitiveArrayValue(), Iterable { override fun iterator(): Iterator = this.value.iterator() } + abstract class DoubleArrayValue internal constructor() : PrimitiveArrayValue(), Iterable { override fun iterator(): Iterator = this.value.iterator() } + abstract class BooleanArrayValue internal constructor() : PrimitiveArrayValue(), Iterable { override fun iterator(): Iterator = this.value.iterator() } + abstract class CharArrayValue internal constructor() : PrimitiveArrayValue(), Iterable { override fun iterator(): Iterator = this.value.iterator() } -sealed class TypedPrimitiveArrayValue : ArrayValue>() , Iterable{ +sealed class TypedPrimitiveArrayValue : ArrayValue>(), Iterable { override fun iterator() = this.value.iterator() } @@ -101,7 +105,7 @@ abstract class TypedBooleanArrayValue internal constructor() : TypedPrimitiveArr abstract class TypedCharArrayValue internal constructor() : TypedPrimitiveArrayValue() abstract class TypedStringArrayValue internal constructor() : TypedPrimitiveArrayValue() -sealed class ListValue : Value>(), Iterable{ +sealed class ListValue : Value>(), Iterable { override fun iterator() = this.value.iterator() } @@ -135,37 +139,6 @@ abstract class SettingSetValue internal constructor() : Value internal constructor() : Value() -internal fun Setting.valueImpl(default: T): Value { - return object : SettingValue() { - private var internalValue: T = default - override var value: T - get() = internalValue - set(new) { - if (new != internalValue) { - internalValue = new - onElementChanged(this) - } - } - override val serializer = object : KSerializer { - override val descriptor: SerialDescriptor - get() = internalValue.updaterSerializer.descriptor - - override fun deserialize(decoder: Decoder): T { - internalValue.updaterSerializer.deserialize(decoder) - return internalValue - } - - override fun serialize(encoder: Encoder, value: T) { - internalValue.updaterSerializer.serialize(encoder, SettingSerializerMark) - } - - }.bind( - getter = { internalValue }, - setter = { internalValue = it } - ) - } -} - abstract class MutableListValue internal constructor() : Value>>(), MutableList abstract class MutableIntListValue internal constructor() : Value>(), MutableList diff --git a/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/setting/_ValueImpl.kt b/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/setting/_ValueImpl.kt index 32662bd32..17ce4184b 100644 --- a/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/setting/_ValueImpl.kt +++ b/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/setting/_ValueImpl.kt @@ -1,4 +1,3 @@ - /* * Copyright 2020 Mamoe Technologies and contributors. * @@ -38,6 +37,7 @@ internal fun Setting.valueImpl(default: Int): IntValue { override val serializer = Int.serializer() } } + internal fun Setting.valueImpl(default: Short): ShortValue { return object : ShortValue() { private var internalValue: Short = default @@ -52,6 +52,7 @@ internal fun Setting.valueImpl(default: Short): ShortValue { override val serializer = Short.serializer() } } + internal fun Setting.valueImpl(default: Byte): ByteValue { return object : ByteValue() { private var internalValue: Byte = default @@ -66,6 +67,7 @@ internal fun Setting.valueImpl(default: Byte): ByteValue { override val serializer = Byte.serializer() } } + internal fun Setting.valueImpl(default: Long): LongValue { return object : LongValue() { private var internalValue: Long = default @@ -80,6 +82,7 @@ internal fun Setting.valueImpl(default: Long): LongValue { override val serializer = Long.serializer() } } + internal fun Setting.valueImpl(default: Float): FloatValue { return object : FloatValue() { private var internalValue: Float = default @@ -94,6 +97,7 @@ internal fun Setting.valueImpl(default: Float): FloatValue { override val serializer = Float.serializer() } } + internal fun Setting.valueImpl(default: Double): DoubleValue { return object : DoubleValue() { private var internalValue: Double = default @@ -108,6 +112,7 @@ internal fun Setting.valueImpl(default: Double): DoubleValue { override val serializer = Double.serializer() } } + internal fun Setting.valueImpl(default: Boolean): BooleanValue { return object : BooleanValue() { private var internalValue: Boolean = default @@ -122,6 +127,7 @@ internal fun Setting.valueImpl(default: Boolean): BooleanValue { override val serializer = Boolean.serializer() } } + internal fun Setting.valueImpl(default: Char): CharValue { return object : CharValue() { private var internalValue: Char = default @@ -136,6 +142,7 @@ internal fun Setting.valueImpl(default: Char): CharValue { override val serializer = Char.serializer() } } + internal fun Setting.valueImpl(default: String): StringValue { return object : StringValue() { private var internalValue: String = default @@ -150,6 +157,7 @@ internal fun Setting.valueImpl(default: String): StringValue { override val serializer = String.serializer() } } + internal fun Setting.valueImpl(default: IntArray): IntArrayValue { return object : IntArrayValue() { private var internalValue: IntArray = default @@ -164,6 +172,7 @@ internal fun Setting.valueImpl(default: IntArray): IntArrayValue { override val serializer = IntArraySerializer() } } + internal fun Setting.valueImpl(default: ShortArray): ShortArrayValue { return object : ShortArrayValue() { private var internalValue: ShortArray = default @@ -178,6 +187,7 @@ internal fun Setting.valueImpl(default: ShortArray): ShortArrayValue { override val serializer = ShortArraySerializer() } } + internal fun Setting.valueImpl(default: ByteArray): ByteArrayValue { return object : ByteArrayValue() { private var internalValue: ByteArray = default @@ -192,6 +202,7 @@ internal fun Setting.valueImpl(default: ByteArray): ByteArrayValue { override val serializer = ByteArraySerializer() } } + internal fun Setting.valueImpl(default: LongArray): LongArrayValue { return object : LongArrayValue() { private var internalValue: LongArray = default @@ -206,6 +217,7 @@ internal fun Setting.valueImpl(default: LongArray): LongArrayValue { override val serializer = LongArraySerializer() } } + internal fun Setting.valueImpl(default: FloatArray): FloatArrayValue { return object : FloatArrayValue() { private var internalValue: FloatArray = default @@ -220,6 +232,7 @@ internal fun Setting.valueImpl(default: FloatArray): FloatArrayValue { override val serializer = FloatArraySerializer() } } + internal fun Setting.valueImpl(default: DoubleArray): DoubleArrayValue { return object : DoubleArrayValue() { private var internalValue: DoubleArray = default @@ -234,6 +247,7 @@ internal fun Setting.valueImpl(default: DoubleArray): DoubleArrayValue { override val serializer = DoubleArraySerializer() } } + internal fun Setting.valueImpl(default: BooleanArray): BooleanArrayValue { return object : BooleanArrayValue() { private var internalValue: BooleanArray = default @@ -248,6 +262,7 @@ internal fun Setting.valueImpl(default: BooleanArray): BooleanArrayValue { override val serializer = BooleanArraySerializer() } } + internal fun Setting.valueImpl(default: CharArray): CharArrayValue { return object : CharArrayValue() { private var internalValue: CharArray = default @@ -262,6 +277,7 @@ internal fun Setting.valueImpl(default: CharArray): CharArrayValue { override val serializer = CharArraySerializer() } } + internal fun Setting.valueImpl(default: Array): TypedIntArrayValue { return object : TypedIntArrayValue() { private var internalValue: Array = default @@ -276,6 +292,7 @@ internal fun Setting.valueImpl(default: Array): TypedIntArrayValue { override val serializer = ArraySerializer(Int.serializer()) } } + internal fun Setting.valueImpl(default: Array): TypedShortArrayValue { return object : TypedShortArrayValue() { private var internalValue: Array = default @@ -290,6 +307,7 @@ internal fun Setting.valueImpl(default: Array): TypedShortArrayValue { override val serializer = ArraySerializer(Short.serializer()) } } + internal fun Setting.valueImpl(default: Array): TypedByteArrayValue { return object : TypedByteArrayValue() { private var internalValue: Array = default @@ -304,6 +322,7 @@ internal fun Setting.valueImpl(default: Array): TypedByteArrayValue { override val serializer = ArraySerializer(Byte.serializer()) } } + internal fun Setting.valueImpl(default: Array): TypedLongArrayValue { return object : TypedLongArrayValue() { private var internalValue: Array = default @@ -318,6 +337,7 @@ internal fun Setting.valueImpl(default: Array): TypedLongArrayValue { override val serializer = ArraySerializer(Long.serializer()) } } + internal fun Setting.valueImpl(default: Array): TypedFloatArrayValue { return object : TypedFloatArrayValue() { private var internalValue: Array = default @@ -332,6 +352,7 @@ internal fun Setting.valueImpl(default: Array): TypedFloatArrayValue { override val serializer = ArraySerializer(Float.serializer()) } } + internal fun Setting.valueImpl(default: Array): TypedDoubleArrayValue { return object : TypedDoubleArrayValue() { private var internalValue: Array = default @@ -346,6 +367,7 @@ internal fun Setting.valueImpl(default: Array): TypedDoubleArrayValue { override val serializer = ArraySerializer(Double.serializer()) } } + internal fun Setting.valueImpl(default: Array): TypedBooleanArrayValue { return object : TypedBooleanArrayValue() { private var internalValue: Array = default @@ -360,6 +382,7 @@ internal fun Setting.valueImpl(default: Array): TypedBooleanArrayValue override val serializer = ArraySerializer(Boolean.serializer()) } } + internal fun Setting.valueImpl(default: Array): TypedCharArrayValue { return object : TypedCharArrayValue() { private var internalValue: Array = default @@ -374,6 +397,7 @@ internal fun Setting.valueImpl(default: Array): TypedCharArrayValue { override val serializer = ArraySerializer(Char.serializer()) } } + internal fun Setting.valueImpl(default: Array): TypedStringArrayValue { return object : TypedStringArrayValue() { private var internalValue: Array = default @@ -388,6 +412,7 @@ internal fun Setting.valueImpl(default: Array): TypedStringArrayValue { override val serializer = ArraySerializer(String.serializer()) } } + internal fun Setting.valueImpl(default: List): IntListValue { return object : IntListValue() { private var internalValue: List = default @@ -402,6 +427,7 @@ internal fun Setting.valueImpl(default: List): IntListValue { override val serializer = ListSerializer(Int.serializer()) } } + internal fun Setting.valueImpl(default: List): ShortListValue { return object : ShortListValue() { private var internalValue: List = default @@ -416,6 +442,7 @@ internal fun Setting.valueImpl(default: List): ShortListValue { override val serializer = ListSerializer(Short.serializer()) } } + internal fun Setting.valueImpl(default: List): ByteListValue { return object : ByteListValue() { private var internalValue: List = default @@ -430,6 +457,7 @@ internal fun Setting.valueImpl(default: List): ByteListValue { override val serializer = ListSerializer(Byte.serializer()) } } + internal fun Setting.valueImpl(default: List): LongListValue { return object : LongListValue() { private var internalValue: List = default @@ -444,6 +472,7 @@ internal fun Setting.valueImpl(default: List): LongListValue { override val serializer = ListSerializer(Long.serializer()) } } + internal fun Setting.valueImpl(default: List): FloatListValue { return object : FloatListValue() { private var internalValue: List = default @@ -458,6 +487,7 @@ internal fun Setting.valueImpl(default: List): FloatListValue { override val serializer = ListSerializer(Float.serializer()) } } + internal fun Setting.valueImpl(default: List): DoubleListValue { return object : DoubleListValue() { private var internalValue: List = default @@ -472,6 +502,7 @@ internal fun Setting.valueImpl(default: List): DoubleListValue { override val serializer = ListSerializer(Double.serializer()) } } + internal fun Setting.valueImpl(default: List): BooleanListValue { return object : BooleanListValue() { private var internalValue: List = default @@ -486,6 +517,7 @@ internal fun Setting.valueImpl(default: List): BooleanListValue { override val serializer = ListSerializer(Boolean.serializer()) } } + internal fun Setting.valueImpl(default: List): CharListValue { return object : CharListValue() { private var internalValue: List = default @@ -500,6 +532,7 @@ internal fun Setting.valueImpl(default: List): CharListValue { override val serializer = ListSerializer(Char.serializer()) } } + internal fun Setting.valueImpl(default: List): StringListValue { return object : StringListValue() { private var internalValue: List = default @@ -650,6 +683,7 @@ internal fun Setting.valueImpl(default: Set): StringSetValue { } } + @JvmName("valueImplMutableIntList") internal fun Setting.valueImpl( default: MutableList @@ -1281,3 +1315,30 @@ internal fun Setting.valueImpl( } +internal fun Setting.valueImpl(default: T): Value { + return object : SettingValue() { + private var internalValue: T = default + override var value: T + get() = internalValue + set(new) { + if (new != internalValue) { + internalValue = new + onElementChanged(this) + } + } + override val serializer = object : KSerializer { + override val descriptor: SerialDescriptor + get() = internalValue.updaterSerializer.descriptor + + override fun deserialize(decoder: Decoder): T { + internalValue.updaterSerializer.deserialize(decoder) + return internalValue + } + + override fun serialize(encoder: Encoder, value: T) { + internalValue.updaterSerializer.serialize(encoder, SettingSerializerMark) + } + } + } +} + From a7eaf788ac09d7de17ea8464054aa622676ce034 Mon Sep 17 00:00:00 2001 From: Him188 Date: Sun, 17 May 2020 15:55:11 +0800 Subject: [PATCH 4/4] Rearrange implementations --- .../codegen/SettingValueUseSiteCodegen.kt | 32 +++++++++++++++++++ .../mirai/console/codegen/ValuesCodegen.kt | 4 +-- .../mamoe/mirai/console/setting/Setting.kt | 22 ------------- .../mamoe/mirai/console/setting/ValueImpl.kt | 7 ++-- .../mamoe/mirai/console/setting/_Setting.kt | 22 ++++++++++++- .../net/mamoe/mirai/console/setting/_Value.kt | 7 ---- 6 files changed, 59 insertions(+), 35 deletions(-) diff --git a/backend/codegen/src/main/kotlin/net/mamoe/mirai/console/codegen/SettingValueUseSiteCodegen.kt b/backend/codegen/src/main/kotlin/net/mamoe/mirai/console/codegen/SettingValueUseSiteCodegen.kt index adf4ba0ac..00aa5a915 100644 --- a/backend/codegen/src/main/kotlin/net/mamoe/mirai/console/codegen/SettingValueUseSiteCodegen.kt +++ b/backend/codegen/src/main/kotlin/net/mamoe/mirai/console/codegen/SettingValueUseSiteCodegen.kt @@ -9,6 +9,7 @@ package net.mamoe.mirai.console.codegen +import org.intellij.lang.annotations.Language import java.io.File @@ -48,6 +49,9 @@ import kotlinx.serialization.builtins.* """.trimIndent() fun genAllValueUseSite(): String = buildString { + fun appendln(@Language("kt") code: String) { + this.appendln(code.trimIndent()) + } // PRIMITIVE for (number in NUMBERS + OTHER_PRIMITIVES) { appendln(genValueUseSite(number, number)) @@ -73,6 +77,7 @@ fun genAllValueUseSite(): String = buildString { // MUTABLE LIST / MUTABLE SET for (collectionName in listOf("List", "Set")) { for (number in NUMBERS + OTHER_PRIMITIVES) { + appendln() appendln( """ @JvmName("valueMutable") @@ -81,6 +86,33 @@ fun genAllValueUseSite(): String = buildString { ) } } + + // SPECIAL + appendln() + appendln( + """ + fun Setting.value(default: T): Value { + require(this::class != default::class) { + "Recursive nesting is prohibited" + } + return valueImpl(default) + } + + inline fun Setting.value(default: T, crossinline initializer: T.() -> Unit): Value = + value(default).also { it.value.apply(initializer) } + + inline fun Setting.value(default: List): SettingListValue = valueImpl(default) + + @JvmName("valueMutable") + inline fun Setting.value(default: MutableList): MutableSettingListValue = valueImpl(default) + + + inline fun Setting.value(default: Set): SettingSetValue = valueImpl(default) + + @JvmName("valueMutable") + inline fun Setting.value(default: MutableSet): MutableSettingSetValue = valueImpl(default) + """ + ) } fun genValueUseSite(kotlinTypeName: String, miraiValueName: String): String = diff --git a/backend/codegen/src/main/kotlin/net/mamoe/mirai/console/codegen/ValuesCodegen.kt b/backend/codegen/src/main/kotlin/net/mamoe/mirai/console/codegen/ValuesCodegen.kt index d0d984b07..3b3d095c9 100644 --- a/backend/codegen/src/main/kotlin/net/mamoe/mirai/console/codegen/ValuesCodegen.kt +++ b/backend/codegen/src/main/kotlin/net/mamoe/mirai/console/codegen/ValuesCodegen.kt @@ -21,7 +21,7 @@ fun main() { }.writeText(genPublicApi()) } -internal const val COPYRIGHT = """ +internal val COPYRIGHT = """ /* * Copyright 2020 Mamoe Technologies and contributors. * @@ -30,7 +30,7 @@ internal const val COPYRIGHT = """ * * https://github.com/mamoe/mirai/blob/master/LICENSE */ -""" +""".trim() internal val NUMBERS = listOf( "Int", 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 44e76ff49..ed4373690 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 @@ -45,25 +45,3 @@ abstract class Setting : AbstractSetting() { @Suppress("UNCHECKED_CAST") val T.serializer: KSerializer get() = kotlinSerializer as KSerializer - - -fun Setting.value(default: T): Value { - require(this::class != default::class) { - "Recursive nesting is prohibited" - } - return valueImpl(default) -} - -inline fun Setting.value(default: T, crossinline initializer: T.() -> Unit): Value = - value(default).also { it.value.apply(initializer) } - -inline fun Setting.value(default: List): SettingListValue = valueImpl(default) - -@JvmName("valueMutable") -inline fun Setting.value(default: MutableList): MutableSettingListValue = valueImpl(default) - - -inline fun Setting.value(default: Set): SettingSetValue = valueImpl(default) - -@JvmName("valueMutable") -inline fun Setting.value(default: MutableSet): MutableSettingSetValue = valueImpl(default) diff --git a/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/setting/ValueImpl.kt b/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/setting/ValueImpl.kt index d384e9b74..0331ad96e 100644 --- a/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/setting/ValueImpl.kt +++ b/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/setting/ValueImpl.kt @@ -33,6 +33,7 @@ internal inline fun Setting.valueImpl( ): MutableSettingListValue = valueImpl(default, T::class.createInstance().serializer) +/* @PublishedApi @JvmName("valueImpl1") internal fun Setting.valueImpl( @@ -40,7 +41,7 @@ internal fun Setting.valueImpl( valueMapper: (T) -> Value, elementSerializer: KSerializer ): MutableListValue = valueImpl(default.mapTo(mutableListOf(), valueMapper), valueMapper, elementSerializer) - +*/ internal fun Setting.valueImpl( default: MutableList>, valueMapper: (T) -> Value, @@ -225,7 +226,7 @@ internal inline fun Setting.valueImpl( default: MutableSet ): MutableSettingSetValue = valueImpl(default, T::class.createInstance().serializer) - +/* @JvmName("valueImpl1") @PublishedApi internal fun Setting.valueImpl( @@ -233,7 +234,7 @@ internal fun Setting.valueImpl( valueMapper: (T) -> Value, elementSerializer: KSerializer ): MutableSetValue = valueImpl(default.mapTo(mutableSetOf(), valueMapper), valueMapper, elementSerializer) - +*/ @JvmName("valueImplMutable") internal fun Setting.valueImpl( default: MutableSet>, 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 ec6c3e656..2f4b80a48 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 @@ -1,4 +1,3 @@ - /* * Copyright 2020 Mamoe Technologies and contributors. * @@ -116,3 +115,24 @@ fun Setting.value(default: MutableSet): MutableCharSetValue = valueImpl(de @JvmName("valueMutable") fun Setting.value(default: MutableSet): MutableStringSetValue = valueImpl(default) +fun Setting.value(default: T): Value { + require(this::class != default::class) { + "Recursive nesting is prohibited" + } + return valueImpl(default) +} + +inline fun Setting.value(default: T, crossinline initializer: T.() -> Unit): Value = + value(default).also { it.value.apply(initializer) } + +inline fun Setting.value(default: List): SettingListValue = valueImpl(default) + +@JvmName("valueMutable") +inline fun Setting.value(default: MutableList): MutableSettingListValue = valueImpl(default) + + +inline fun Setting.value(default: Set): SettingSetValue = valueImpl(default) + +@JvmName("valueMutable") +inline fun Setting.value(default: MutableSet): MutableSettingSetValue = valueImpl(default) + diff --git a/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/setting/_Value.kt b/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/setting/_Value.kt index a28b5e9f4..1aa6600b5 100644 --- a/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/setting/_Value.kt +++ b/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/setting/_Value.kt @@ -62,31 +62,24 @@ sealed class PrimitiveArrayValue : ArrayValue() abstract class IntArrayValue internal constructor() : PrimitiveArrayValue(), Iterable { override fun iterator(): Iterator = this.value.iterator() } - abstract class ShortArrayValue internal constructor() : PrimitiveArrayValue(), Iterable { override fun iterator(): Iterator = this.value.iterator() } - abstract class ByteArrayValue internal constructor() : PrimitiveArrayValue(), Iterable { override fun iterator(): Iterator = this.value.iterator() } - abstract class LongArrayValue internal constructor() : PrimitiveArrayValue(), Iterable { override fun iterator(): Iterator = this.value.iterator() } - abstract class FloatArrayValue internal constructor() : PrimitiveArrayValue(), Iterable { override fun iterator(): Iterator = this.value.iterator() } - abstract class DoubleArrayValue internal constructor() : PrimitiveArrayValue(), Iterable { override fun iterator(): Iterator = this.value.iterator() } - abstract class BooleanArrayValue internal constructor() : PrimitiveArrayValue(), Iterable { override fun iterator(): Iterator = this.value.iterator() } - abstract class CharArrayValue internal constructor() : PrimitiveArrayValue(), Iterable { override fun iterator(): Iterator = this.value.iterator() }