Add derived types codegen & value impl

This commit is contained in:
Him188 2020-05-16 13:07:23 +08:00
parent ef17e23a03
commit 0e25b1f46f
3 changed files with 118 additions and 7 deletions

View File

@ -6,8 +6,7 @@
*
* https://github.com/mamoe/mirai/blob/master/LICENSE
*/
@file:Suppress("ClassName")
@file:Suppress("ClassName", "unused")
package net.mamoe.mirai.console.codegen
import org.intellij.lang.annotations.Language
@ -196,4 +195,45 @@ sealed class Value<T : Any> : ReadWriteProperty<Setting, T> {
}
appendln()
// FOR COMPLEX TYPES
appendln(
"""
abstract class SettingValue<T : Setting> internal constructor() : Value<T>()
internal fun <T : Setting> Setting.valueImpl(default: T): Value<T> {
return object : SettingValue<T>() {
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<T>{
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 }
)
}
}
"""
)
appendln()
}

View File

@ -13,6 +13,9 @@ 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 kotlin.properties.ReadWriteProperty
import kotlin.reflect.KProperty
import kotlin.reflect.full.findAnnotation
@ -57,17 +60,44 @@ abstract class Setting {
internal var valueList: MutableList<Pair<Value<*>, KProperty<*>>> = mutableListOf()
private var built: Boolean = false
internal val serializer: KSerializer<SettingSerializerMark> by lazy {
internal val updaterSerializer: KSerializer<SettingSerializerMark> by lazy {
built = true
SettingSerializer(this)
SettingUpdaterSerializer(this)
}
internal val kotlinSerializer: KSerializer<Setting> by lazy {
object : KSerializer<Setting> {
override val descriptor: SerialDescriptor
get() = this@Setting.updaterSerializer.descriptor
override fun deserialize(decoder: Decoder): Setting {
this@Setting.updaterSerializer.deserialize(decoder)
return this@Setting
}
override fun serialize(encoder: Encoder, value: Setting) {
this@Setting.updaterSerializer.serialize(encoder, SettingSerializerMark)
}
}
}
internal fun onElementChanged(value: Value<*>) {
println("my value changed!")
}
companion object {
private val yaml =
Yaml(configuration = YamlConfiguration(classSerialization = FLOW_MAP, listSerialization = FLOW_SEQUENCE))
}
override fun toString(): String = yaml.stringify(this.serializer, this)
}
internal class SettingSerializer(
@Suppress("UNCHECKED_CAST")
val <T : Setting> T.serializer: KSerializer<T>
get() = kotlinSerializer as KSerializer<T>
internal class SettingUpdaterSerializer(
private val instance: Setting
) : KSerializer<SettingSerializerMark> {
override val descriptor: SerialDescriptor by lazy {
@ -120,4 +150,9 @@ internal class SettingSerializer(
internal object SettingSerializerMark
internal val KProperty<*>.serialNameOrPropertyName: String get() = this.findAnnotation<SerialName>()?.value ?: this.name
internal val KProperty<*>.serialNameOrPropertyName: String get() = this.findAnnotation<SerialName>()?.value ?: this.name
fun <T : Setting> Setting.value(default: T): Value<T> = valueImpl(default)
inline fun <T : Setting> Setting.value(default: T, crossinline initializer: T.() -> Unit): Value<T> =
value(default).also { it.value.apply(initializer) }

View File

@ -9,12 +9,15 @@
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
/**
* !!! 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.ValuesCodegen.kt
* !!! for better performance
* !!! DO NOT MODIFY THIS FILE MANUALLY
*/
@ -89,6 +92,7 @@ abstract class TypedStringArrayValue internal constructor() : TypedPrimitiveArra
sealed class ListValue<E> : Value<List<E>>(), Iterable<E>{
override fun iterator() = this.value.iterator()
}
abstract class IntListValue internal constructor() : ListValue<Int>()
abstract class ShortListValue internal constructor() : ListValue<Short>()
abstract class ByteListValue internal constructor() : ListValue<Byte>()
@ -99,3 +103,35 @@ abstract class BooleanListValue internal constructor() : ListValue<Boolean>()
abstract class CharListValue internal constructor() : ListValue<Char>()
abstract class StringListValue internal constructor() : ListValue<String>()
abstract class SettingValue<T : Setting> internal constructor() : Value<T>()
internal fun <T : Setting> Setting.valueImpl(default: T): Value<T> {
return object : SettingValue<T>() {
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<T> {
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 }
)
}
}