Merge remote-tracking branch 'origin/reborn' into reborn

This commit is contained in:
jiahua.liu 2020-05-19 14:52:14 +08:00
commit 88afbb47d8
10 changed files with 1944 additions and 348 deletions

View File

@ -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))
@ -63,12 +67,54 @@ fun genAllValueUseSite(): String = buildString {
appendln(genValueUseSite("Array<${number}>", "Typed${number}Array"))
}
// PRIMITIVE LISTS
// PRIMITIVE LISTS / PRIMITIVE SETS
for (collectionName in listOf("List", "Set")) {
for (number in NUMBERS + OTHER_PRIMITIVES) {
appendln(genValueUseSite("List<${number}>", "${number}List"))
appendln(genValueUseSite("${collectionName}<${number}>", "${number}${collectionName}"))
}
}
// MUTABLE LIST / MUTABLE SET
for (collectionName in listOf("List", "Set")) {
for (number in NUMBERS + OTHER_PRIMITIVES) {
appendln()
appendln(
"""
@JvmName("valueMutable")
fun Setting.value(default: Mutable${collectionName}<${number}>): Mutable${number}${collectionName}Value = valueImpl(default)
""".trimIndent()
)
}
}
// SPECIAL
appendln()
appendln(
"""
fun <T : Setting> Setting.value(default: T): Value<T> {
require(this::class != default::class) {
"Recursive nesting is prohibited"
}
return valueImpl(default)
}
inline fun <T : Setting> Setting.value(default: T, crossinline initializer: T.() -> Unit): Value<T> =
value(default).also { it.value.apply(initializer) }
inline fun <reified T : Setting> Setting.value(default: List<T>): SettingListValue<T> = valueImpl(default)
@JvmName("valueMutable")
inline fun <reified T : Setting> Setting.value(default: MutableList<T>): MutableSettingListValue<T> = valueImpl(default)
inline fun <reified T : Setting> Setting.value(default: Set<T>): SettingSetValue<T> = valueImpl(default)
@JvmName("valueMutable")
inline fun <reified T : Setting> Setting.value(default: MutableSet<T>): MutableSettingSetValue<T> = valueImpl(default)
"""
)
}
fun genValueUseSite(kotlinTypeName: String, miraiValueName: String): String =
"""
fun Setting.value(default: $kotlinTypeName): ${miraiValueName}Value = valueImpl(default)

View File

@ -9,6 +9,7 @@
package net.mamoe.mirai.console.codegen
import org.intellij.lang.annotations.Language
import java.io.File
@ -44,31 +45,138 @@ 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))
appendln()
}
// PRIMITIVE ARRAYS
for (number in NUMBERS + OTHER_PRIMITIVES.filterNot { it == "String" }) {
appendln(genValueImpl("${number}Array", "${number}Array", "${number}ArraySerializer()", true))
appendln()
}
// 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
)
)
appendln()
}
// PRIMITIVE LISTS
// PRIMITIVE LISTS / SETS
for (collectionName in listOf("List", "Set")) {
for (number in NUMBERS + OTHER_PRIMITIVES) {
appendln(genValueImpl("List<${number}>", "${number}List", "ListSerializer(${number}.serializer())", false))
appendln(
genValueImpl(
"${collectionName}<${number}>",
"${number}${collectionName}",
"${collectionName}Serializer(${number}.serializer())",
false
)
)
appendln()
}
}
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<Mutable${collectionName}<${number}>> = object : KSerializer<Mutable${collectionName}<${number}>> {
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()
}
}
appendln()
appendln(
"""
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)
}
}
}
}
"""
)
}
fun genValueImpl(kotlinTypeName: String, miraiValueName: String, serializer: String, isArray: Boolean): String =
"""
internal fun Setting.valueImpl(default: ${kotlinTypeName}): ${miraiValueName}Value {
@ -92,10 +200,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"

View File

@ -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
@ -20,7 +21,7 @@ fun main() {
}.writeText(genPublicApi())
}
internal const val COPYRIGHT = """
internal val COPYRIGHT = """
/*
* Copyright 2020 Mamoe Technologies and contributors.
*
@ -29,7 +30,7 @@ internal const val COPYRIGHT = """
*
* https://github.com/mamoe/mirai/blob/master/LICENSE
*/
"""
""".trim()
internal val NUMBERS = listOf(
"Int",
@ -86,11 +87,23 @@ fun genPublicApi() = buildString {
sealed class Value<T : Any> : ReadWriteProperty<Setting, T> {
abstract var value: T
/**
* 用于更新 [value] 的序列化器
*/
abstract val serializer: KSerializer<T>
override fun getValue(thisRef: Setting, property: KProperty<*>): T = value
override fun setValue(thisRef: Setting, property: KProperty<*>, value: T) {
this.value = value
}
override fun equals(other: Any?): Boolean {
if (other==null)return false
if (other::class != this::class) return false
other as Value<*>
return other.value == this.value
}
override fun hashCode(): Int = value.hashCode()
}
"""
)
@ -176,11 +189,12 @@ sealed class Value<T : Any> : ReadWriteProperty<Setting, T> {
appendln()
// TYPED LISTS
// TYPED LISTS / SETS
for (collectionName in listOf("List", "Set")) {
appendln(
"""
sealed class ListValue<E> : Value<List<E>>(), Iterable<E>{
sealed class ${collectionName}Value<E> : Value<${collectionName}<E>>(), Iterable<E>{
override fun iterator() = this.value.iterator()
}
"""
@ -188,52 +202,70 @@ sealed class Value<T : Any> : ReadWriteProperty<Setting, T> {
for (number in (NUMBERS + OTHER_PRIMITIVES)) {
val template = """
abstract class ${number}ListValue internal constructor() : ListValue<${number}>()
abstract class ${number}${collectionName}Value internal constructor() : ${collectionName}Value<${number}>()
"""
appendln(template)
}
appendln()
// SETTING
appendln(
"""
abstract class Setting${collectionName}Value<T: Setting> internal constructor() : Value<${collectionName}<T>>(), ${collectionName}<T>
"""
)
appendln()
}
// FOR COMPLEX TYPES
// SETTING VALUE
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()
// MUTABLE LIST / MUTABLE SET
for (collectionName in listOf("List", "Set")) {
appendln(
"""
abstract class Mutable${collectionName}Value<T : Any> internal constructor() : Value<Mutable${collectionName}<Value<T>>>(), Mutable${collectionName}<T>
"""
)
appendln()
for (number in (NUMBERS + OTHER_PRIMITIVES)) {
appendln(
"""
abstract class Mutable${number}${collectionName}Value internal constructor() : Value<Mutable${collectionName}<${number}>>(), Mutable${collectionName}<${number}>
"""
)
}
appendln()
// SETTING
appendln(
"""
abstract class MutableSetting${collectionName}Value<T: Setting> internal constructor() : Value<Mutable${collectionName}<T>>(), Mutable${collectionName}<T>
"""
)
appendln()
}
appendln()
// DYNAMIC
appendln(
"""
/**
* 只引用这个对象, 而不跟踪其成员.
* 仅适用于基础类型, 用于 mutable list/map 等情况; 或标注了 [Serializable] 的类.
*/
abstract class DynamicReferenceValue<T : Any> internal constructor() : Value<T>()
"""
)
}

View File

@ -0,0 +1,134 @@
/*
* Copyright 2020 Mamoe Technologies and contributors.
*
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
* Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
*
* https://github.com/mamoe/mirai/blob/master/LICENSE
*/
package net.mamoe.mirai.console.setting
import kotlinx.serialization.*
import net.mamoe.yamlkt.Yaml
import net.mamoe.yamlkt.YamlConfiguration
import kotlin.reflect.KProperty
import kotlin.reflect.full.findAnnotation
internal abstract class AbstractSetting {
@JvmField
internal var valueList: MutableList<Pair<Value<*>, KProperty<*>>> = mutableListOf()
@JvmField
internal var built: Boolean = false
internal val updaterSerializer: KSerializer<SettingSerializerMark> by lazy {
built = true
SettingUpdaterSerializer(this as Setting)
}
internal val kotlinSerializer: KSerializer<Setting> by lazy {
object : KSerializer<Setting> {
override val descriptor: SerialDescriptor
get() = this@AbstractSetting.updaterSerializer.descriptor
override fun deserialize(decoder: Decoder): Setting {
this@AbstractSetting.updaterSerializer.deserialize(decoder)
return this@AbstractSetting as Setting
}
override fun serialize(encoder: Encoder, value: Setting) {
this@AbstractSetting.updaterSerializer.serialize(encoder, SettingSerializerMark)
}
}
}
internal fun onElementChanged(value: Value<*>) {
println("my value changed!")
}
companion object {
@JvmStatic
internal val yaml =
Yaml(
configuration = YamlConfiguration(
nonStrictNullability = true,
nonStrictNumber = true,
stringSerialization = YamlConfiguration.StringSerialization.NONE,
classSerialization = YamlConfiguration.MapSerialization.FLOW_MAP,
listSerialization = YamlConfiguration.ListSerialization.FLOW_SEQUENCE
)
)
}
}
internal class SettingUpdaterSerializer(
private val instance: Setting
) : KSerializer<SettingSerializerMark> {
override val descriptor: SerialDescriptor by lazy {
SerialDescriptor(instance.serialName) {
for ((value, property) in instance.valueList) {
element(property.serialNameOrPropertyName, value.serializer.descriptor, annotations, true)
}
}
}
@Suppress("UNCHECKED_CAST") // erased, no problem.
override fun deserialize(decoder: Decoder): SettingSerializerMark = decoder.decodeStructure(descriptor) {
if (this.decodeSequentially()) {
instance.valueList.forEachIndexed { index, (value, _) ->
val v = value as Value<Any>
v.value = this.decodeSerializableElement(
value.serializer.descriptor,
index,
v.serializer
)
}
} else {
while (true) {
val index = this.decodeElementIndex(descriptor)
if (index == CompositeDecoder.READ_DONE) return@decodeStructure SettingSerializerMark
val value = instance.valueList[index].first
this.decodeSerializableElement(
descriptor,
index,
value.serializer
)
}
}
SettingSerializerMark
}
override fun serialize(encoder: Encoder, value: SettingSerializerMark) = encoder.encodeStructure(descriptor) {
instance.valueList.forEachIndexed { index, (value, _) ->
@Suppress("UNCHECKED_CAST") // erased, no problem.
this.encodeSerializableElement(
descriptor,
index,
value.serializer as KSerializer<Any>,
value.value
)
}
}
}
internal object SettingSerializerMark
internal val KProperty<*>.serialNameOrPropertyName: String get() = this.findAnnotation<SerialName>()?.value ?: this.name
internal inline fun <E> KSerializer<E>.bind(
crossinline setter: (E) -> Unit,
crossinline getter: () -> E
): KSerializer<E> {
return object : KSerializer<E> {
override val descriptor: SerialDescriptor get() = this@bind.descriptor
override fun deserialize(decoder: Decoder): E = this@bind.deserialize(decoder).also { setter(it) }
@Suppress("UNCHECKED_CAST")
override fun serialize(encoder: Encoder, value: E) =
this@bind.serialize(encoder, getter())
}
}

View File

@ -11,35 +11,18 @@
package net.mamoe.mirai.console.setting
import kotlinx.serialization.*
import net.mamoe.yamlkt.Yaml
import net.mamoe.yamlkt.YamlConfiguration
import net.mamoe.yamlkt.YamlConfiguration.ListSerialization.FLOW_SEQUENCE
import net.mamoe.yamlkt.YamlConfiguration.MapSerialization.FLOW_MAP
import kotlinx.serialization.KSerializer
import kotlin.properties.ReadWriteProperty
import kotlin.reflect.KProperty
import kotlin.reflect.full.findAnnotation
internal inline fun <E> KSerializer<E>.bind(
crossinline setter: (E) -> Unit,
crossinline getter: () -> E
): KSerializer<E> {
return object : KSerializer<E> {
override val descriptor: SerialDescriptor get() = this@bind.descriptor
override fun deserialize(decoder: Decoder): E = this@bind.deserialize(decoder).also { setter(it) }
@Suppress("UNCHECKED_CAST")
override fun serialize(encoder: Encoder, value: E) =
this@bind.serialize(encoder, getter())
}
}
typealias SerialName = kotlinx.serialization.SerialName
/**
* 配置的基类
* 配置的基类. 所有配置必须拥有一个无参构造器, 以用于在 [MutableList] [MutableMap] 中动态识别类型
*/
abstract class Setting {
@Suppress("EXPOSED_SUPER_CLASS")
abstract class Setting : AbstractSetting() {
open val serialName: String
get() = this::class.findAnnotation<SerialName>()?.value
?: this::class.qualifiedName
@ -56,103 +39,9 @@ abstract class Setting {
return this
}
@JvmField
internal var valueList: MutableList<Pair<Value<*>, KProperty<*>>> = mutableListOf()
private var built: Boolean = false
internal val updaterSerializer: KSerializer<SettingSerializerMark> by lazy {
built = true
SettingUpdaterSerializer(this)
}
internal val kotlinSerializer: KSerializer<Setting> by lazy {
object : KSerializer<Setting> {
override val descriptor: SerialDescriptor
get() = this@Setting.updaterSerializer.descriptor
override fun deserialize(decoder: Decoder): Setting {
this@Setting.updaterSerializer.deserialize(decoder)
return this@Setting
}
override fun serialize(encoder: Encoder, value: Setting) {
this@Setting.updaterSerializer.serialize(encoder, SettingSerializerMark)
}
}
}
internal fun onElementChanged(value: Value<*>) {
println("my value changed!")
}
companion object {
private val yaml =
Yaml(configuration = YamlConfiguration(classSerialization = FLOW_MAP, listSerialization = FLOW_SEQUENCE))
}
override fun toString(): String = yaml.stringify(this.serializer, this)
}
@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 {
SerialDescriptor(instance.serialName) {
for ((value, property) in instance.valueList) {
element(property.serialNameOrPropertyName, value.serializer.descriptor, annotations, true)
}
}
}
@Suppress("UNCHECKED_CAST") // erased, no problem.
override fun deserialize(decoder: Decoder): SettingSerializerMark = decoder.decodeStructure(descriptor) {
if (this.decodeSequentially()) {
instance.valueList.forEachIndexed { index, (value, _) ->
this.decodeSerializableElement(
value.serializer.descriptor,
index,
value.serializer as KSerializer<Any>
)
}
} else {
while (true) {
val index = this.decodeElementIndex(descriptor)
if (index == CompositeDecoder.READ_DONE) return@decodeStructure SettingSerializerMark
val value = instance.valueList[index].first
this.decodeSerializableElement(
descriptor,
index,
value.serializer
)
}
}
SettingSerializerMark
}
override fun serialize(encoder: Encoder, value: SettingSerializerMark) = encoder.encodeStructure(descriptor) {
instance.valueList.forEachIndexed { index, (value, _) ->
@Suppress("UNCHECKED_CAST") // erased, no problem.
this.encodeSerializableElement(
descriptor,
index,
value.serializer as KSerializer<Any>,
value.value
)
}
}
}
internal object SettingSerializerMark
internal val KProperty<*>.serialNameOrPropertyName: String get() = this.findAnnotation<SerialName>()?.value ?: this.name
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

@ -0,0 +1,313 @@
/*
* 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 <reified T : Setting> Setting.valueImpl(
default: List<T>
): SettingListValue<T> = valueImpl(default, T::class.createInstance().serializer)
@PublishedApi
@JvmName("valueImplSettingMutable")
@Suppress("UNCHECKED_CAST")
internal inline fun <reified T : Setting> Setting.valueImpl(
default: MutableList<T>
): MutableSettingListValue<T> = valueImpl(default, T::class.createInstance().serializer)
/*
@PublishedApi
@JvmName("valueImpl1")
internal fun <T : Any> Setting.valueImpl(
default: MutableList<T>,
valueMapper: (T) -> Value<T>,
elementSerializer: KSerializer<T>
): MutableListValue<T> = valueImpl(default.mapTo(mutableListOf(), valueMapper), valueMapper, elementSerializer)
*/
internal fun <T : Any> Setting.valueImpl(
default: MutableList<Value<T>>,
valueMapper: (T) -> Value<T>,
elementSerializer: KSerializer<T>
): MutableListValue<T> {
var internalValue: MutableList<Value<T>> = default
fun updateShadow(): MutableList<T> =
internalValue.shadowMap(transform = { it.value }, transformBack = { valueMapper(it) })
var shadowed: MutableList<T> = updateShadow()
return object : MutableListValue<T>(), MutableList<T> by dynamicMutableList({ shadowed }) {
override var value: MutableList<Value<T>>
get() = internalValue
set(new) {
if (new != internalValue) {
internalValue = new
shadowed = updateShadow()
onElementChanged(this)
}
}
override val serializer: KSerializer<MutableList<Value<T>>> = object : KSerializer<MutableList<Value<T>>> {
private val delegate = ListSerializer(elementSerializer)
override val descriptor: SerialDescriptor = delegate.descriptor
override fun deserialize(decoder: Decoder): MutableList<Value<T>> {
return delegate.deserialize(decoder).mapTo(mutableListOf(), valueMapper)
}
override fun serialize(encoder: Encoder, value: MutableList<Value<T>>) {
delegate.serialize(encoder, value.map { it.value })
}
}
}
}
@PublishedApi
internal fun <T : Setting> Setting.valueImpl(
default: MutableList<T>,
elementSerializer: KSerializer<T>
): MutableSettingListValue<T> {
var internalValue: MutableList<T> = default
return object : MutableSettingListValue<T>(), MutableList<T> by dynamicMutableList({ internalValue }) {
override var value: MutableList<T>
get() = internalValue
set(new) {
if (new != internalValue) {
internalValue = new
onElementChanged(this)
}
}
override val serializer: KSerializer<MutableList<T>> = object : KSerializer<MutableList<T>> {
private val delegate = ListSerializer(elementSerializer)
override val descriptor: SerialDescriptor = delegate.descriptor
override fun deserialize(decoder: Decoder): MutableList<T> {
return delegate.deserialize(decoder).toMutableList() // TODO: 2020/5/17 ATTACH OBSERVER
}
override fun serialize(encoder: Encoder, value: MutableList<T>) {
delegate.serialize(encoder, value)
}
}
}
}
@PublishedApi
internal fun <T : Setting> Setting.valueImpl(
default: List<T>,
elementSerializer: KSerializer<T>
): SettingListValue<T> {
var internalValue: List<T> = default
return object : SettingListValue<T>(), List<T> by dynamicList({ internalValue }) {
override var value: List<T>
get() = internalValue
set(new) {
if (new != internalValue) {
internalValue = new
onElementChanged(this)
}
}
override val serializer: KSerializer<List<T>> = object : KSerializer<List<T>> {
private val delegate = ListSerializer(elementSerializer)
override val descriptor: SerialDescriptor = delegate.descriptor
override fun deserialize(decoder: Decoder): List<T> {
return delegate.deserialize(decoder) // TODO: 2020/5/17 ATTACH OBSERVER
}
override fun serialize(encoder: Encoder, value: List<T>) {
delegate.serialize(encoder, value)
}
}
}
}
@PublishedApi
internal fun <T : Setting> Setting.valueImpl(
default: Set<T>,
elementSerializer: KSerializer<T>
): SettingSetValue<T> {
var internalValue: Set<T> = default
return object : SettingSetValue<T>(), Set<T> by dynamicSet({ internalValue }) {
override var value: Set<T>
get() = internalValue
set(new) {
if (new != internalValue) {
internalValue = new
onElementChanged(this)
}
}
override val serializer: KSerializer<Set<T>> = object : KSerializer<Set<T>> {
private val delegate = SetSerializer(elementSerializer)
override val descriptor: SerialDescriptor = delegate.descriptor
override fun deserialize(decoder: Decoder): Set<T> {
return delegate.deserialize(decoder) // TODO: 2020/5/17 ATTACH OBSERVER
}
override fun serialize(encoder: Encoder, value: Set<T>) {
delegate.serialize(encoder, value)
}
}
}
}
@PublishedApi
internal fun <T : Setting> Setting.valueImpl(
default: MutableSet<T>,
elementSerializer: KSerializer<T>
): MutableSettingSetValue<T> {
var internalValue: MutableSet<T> = default
return object : MutableSettingSetValue<T>(), MutableSet<T> by dynamicMutableSet({ internalValue }) {
override var value: MutableSet<T>
get() = internalValue
set(new) {
if (new != internalValue) {
internalValue = new
onElementChanged(this)
}
}
override val serializer: KSerializer<MutableSet<T>> = object : KSerializer<MutableSet<T>> {
private val delegate = SetSerializer(elementSerializer)
override val descriptor: SerialDescriptor = delegate.descriptor
override fun deserialize(decoder: Decoder): MutableSet<T> {
return delegate.deserialize(decoder).toMutableSet() // TODO: 2020/5/17 ATTACH OBSERVER
}
override fun serialize(encoder: Encoder, value: MutableSet<T>) {
delegate.serialize(encoder, value)
}
}
}
}
// endregion
// region MUTABLE SET
@PublishedApi
@JvmName("valueImplSetting")
@Suppress("UNCHECKED_CAST")
internal inline fun <reified T : Setting> Setting.valueImpl(
default: Set<T>
): SettingSetValue<T> = valueImpl(default, T::class.createInstance().serializer)
@PublishedApi
@JvmName("valueImplSettingMutable")
@Suppress("UNCHECKED_CAST")
internal inline fun <reified T : Setting> Setting.valueImpl(
default: MutableSet<T>
): MutableSettingSetValue<T> = valueImpl(default, T::class.createInstance().serializer)
/*
@JvmName("valueImpl1")
@PublishedApi
internal fun <T : Any> Setting.valueImpl(
default: MutableSet<T>,
valueMapper: (T) -> Value<T>,
elementSerializer: KSerializer<T>
): MutableSetValue<T> = valueImpl(default.mapTo(mutableSetOf(), valueMapper), valueMapper, elementSerializer)
*/
@JvmName("valueImplMutable")
internal fun <T : Any> Setting.valueImpl(
default: MutableSet<Value<T>>,
valueMapper: (T) -> Value<T>,
elementSerializer: KSerializer<T>
): MutableSetValue<T> {
var internalValue: MutableSet<Value<T>> = default
fun updateShadow(): MutableSet<T> =
internalValue.shadowMap(transform = { it.value }, transformBack = { valueMapper(it) })
var shadowed: MutableSet<T> = updateShadow()
return object : MutableSetValue<T>(), MutableSet<T> by dynamicMutableSet({ shadowed }) {
override var value: MutableSet<Value<T>>
get() = internalValue
set(new) {
if (new != internalValue) {
internalValue = new
shadowed = updateShadow()
onElementChanged(this)
}
}
override val serializer: KSerializer<MutableSet<Value<T>>> = object : KSerializer<MutableSet<Value<T>>> {
private val delegate = SetSerializer(elementSerializer)
override val descriptor: SerialDescriptor = delegate.descriptor
override fun deserialize(decoder: Decoder): MutableSet<Value<T>> {
return delegate.deserialize(decoder).mapTo(mutableSetOf(), valueMapper)
}
override fun serialize(encoder: Encoder, value: MutableSet<Value<T>>) {
delegate.serialize(encoder, value.mapTo(mutableSetOf()) { it.value })
}
}
}
}
// endregion
// region DYNAMIC PRIMITIVES AND SERIALIZABLE
/**
* For primitives and serializable only
*/
@PublishedApi
internal inline fun <reified T : Any> Setting.valueImpl(default: T): Value<T> =
valueImpl(default, T::class)
@PublishedApi
internal fun <T : Any> Setting.valueImpl(default: T, clazz: KClass<out T>): Value<T> {
if (default is Setting) @Suppress("UNCHECKED_CAST") return valueImpl(default as Setting) as Value<T>
@OptIn(ImplicitReflectionSerializer::class)
requireNotNull(clazz.serializerOrNull()) {
"${clazz.qualifiedName} is not serializable"
}
return object : DynamicReferenceValue<T>() {
override var value: T = default
override val serializer: KSerializer<T>
get() = object : KSerializer<T> {
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

View File

@ -1,4 +1,3 @@
/*
* Copyright 2020 Mamoe Technologies and contributors.
*
@ -52,4 +51,88 @@ fun Setting.value(default: List<Double>): DoubleListValue = valueImpl(default)
fun Setting.value(default: List<Boolean>): BooleanListValue = valueImpl(default)
fun Setting.value(default: List<Char>): CharListValue = valueImpl(default)
fun Setting.value(default: List<String>): StringListValue = valueImpl(default)
fun Setting.value(default: Set<Int>): IntSetValue = valueImpl(default)
fun Setting.value(default: Set<Short>): ShortSetValue = valueImpl(default)
fun Setting.value(default: Set<Byte>): ByteSetValue = valueImpl(default)
fun Setting.value(default: Set<Long>): LongSetValue = valueImpl(default)
fun Setting.value(default: Set<Float>): FloatSetValue = valueImpl(default)
fun Setting.value(default: Set<Double>): DoubleSetValue = valueImpl(default)
fun Setting.value(default: Set<Boolean>): BooleanSetValue = valueImpl(default)
fun Setting.value(default: Set<Char>): CharSetValue = valueImpl(default)
fun Setting.value(default: Set<String>): StringSetValue = valueImpl(default)
@JvmName("valueMutable")
fun Setting.value(default: MutableList<Int>): MutableIntListValue = valueImpl(default)
@JvmName("valueMutable")
fun Setting.value(default: MutableList<Short>): MutableShortListValue = valueImpl(default)
@JvmName("valueMutable")
fun Setting.value(default: MutableList<Byte>): MutableByteListValue = valueImpl(default)
@JvmName("valueMutable")
fun Setting.value(default: MutableList<Long>): MutableLongListValue = valueImpl(default)
@JvmName("valueMutable")
fun Setting.value(default: MutableList<Float>): MutableFloatListValue = valueImpl(default)
@JvmName("valueMutable")
fun Setting.value(default: MutableList<Double>): MutableDoubleListValue = valueImpl(default)
@JvmName("valueMutable")
fun Setting.value(default: MutableList<Boolean>): MutableBooleanListValue = valueImpl(default)
@JvmName("valueMutable")
fun Setting.value(default: MutableList<Char>): MutableCharListValue = valueImpl(default)
@JvmName("valueMutable")
fun Setting.value(default: MutableList<String>): MutableStringListValue = valueImpl(default)
@JvmName("valueMutable")
fun Setting.value(default: MutableSet<Int>): MutableIntSetValue = valueImpl(default)
@JvmName("valueMutable")
fun Setting.value(default: MutableSet<Short>): MutableShortSetValue = valueImpl(default)
@JvmName("valueMutable")
fun Setting.value(default: MutableSet<Byte>): MutableByteSetValue = valueImpl(default)
@JvmName("valueMutable")
fun Setting.value(default: MutableSet<Long>): MutableLongSetValue = valueImpl(default)
@JvmName("valueMutable")
fun Setting.value(default: MutableSet<Float>): MutableFloatSetValue = valueImpl(default)
@JvmName("valueMutable")
fun Setting.value(default: MutableSet<Double>): MutableDoubleSetValue = valueImpl(default)
@JvmName("valueMutable")
fun Setting.value(default: MutableSet<Boolean>): MutableBooleanSetValue = valueImpl(default)
@JvmName("valueMutable")
fun Setting.value(default: MutableSet<Char>): MutableCharSetValue = valueImpl(default)
@JvmName("valueMutable")
fun Setting.value(default: MutableSet<String>): MutableStringSetValue = valueImpl(default)
fun <T : Setting> Setting.value(default: T): Value<T> {
require(this::class != default::class) {
"Recursive nesting is prohibited"
}
return valueImpl(default)
}
inline fun <T : Setting> Setting.value(default: T, crossinline initializer: T.() -> Unit): Value<T> =
value(default).also { it.value.apply(initializer) }
inline fun <reified T : Setting> Setting.value(default: List<T>): SettingListValue<T> = valueImpl(default)
@JvmName("valueMutable")
inline fun <reified T : Setting> Setting.value(default: MutableList<T>): MutableSettingListValue<T> = valueImpl(default)
inline fun <reified T : Setting> Setting.value(default: Set<T>): SettingSetValue<T> = valueImpl(default)
@JvmName("valueMutable")
inline fun <reified T : Setting> Setting.value(default: MutableSet<T>): MutableSettingSetValue<T> = valueImpl(default)

View File

@ -9,15 +9,12 @@
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.codegen.ValuesCodegen.kt
* !!! for better performance
* !!! DO NOT MODIFY THIS FILE MANUALLY
*/
@ -25,11 +22,23 @@ import kotlin.reflect.KProperty
sealed class Value<T : Any> : ReadWriteProperty<Setting, T> {
abstract var value: T
/**
* 用于更新 [value] 的序列化器
*/
abstract val serializer: KSerializer<T>
override fun getValue(thisRef: Setting, property: KProperty<*>): T = value
override fun setValue(thisRef: Setting, property: KProperty<*>, value: T) {
this.value = value
}
override fun equals(other: Any?): Boolean {
if (other == null) return false
if (other::class != this::class) return false
other as Value<*>
return other.value == this.value
}
override fun hashCode(): Int = value.hashCode()
}
sealed class PrimitiveValue<T : Any> : Value<T>()
@ -103,35 +112,57 @@ abstract class BooleanListValue internal constructor() : ListValue<Boolean>()
abstract class CharListValue internal constructor() : ListValue<Char>()
abstract class StringListValue internal constructor() : ListValue<String>()
abstract class SettingListValue<T : Setting> internal constructor() : Value<List<T>>(), List<T>
sealed class SetValue<E> : Value<Set<E>>(), Iterable<E> {
override fun iterator() = this.value.iterator()
}
abstract class IntSetValue internal constructor() : SetValue<Int>()
abstract class ShortSetValue internal constructor() : SetValue<Short>()
abstract class ByteSetValue internal constructor() : SetValue<Byte>()
abstract class LongSetValue internal constructor() : SetValue<Long>()
abstract class FloatSetValue internal constructor() : SetValue<Float>()
abstract class DoubleSetValue internal constructor() : SetValue<Double>()
abstract class BooleanSetValue internal constructor() : SetValue<Boolean>()
abstract class CharSetValue internal constructor() : SetValue<Char>()
abstract class StringSetValue internal constructor() : SetValue<String>()
abstract class SettingSetValue<T : Setting> internal constructor() : Value<Set<T>>(), Set<T>
abstract class SettingValue<T : Setting> internal constructor() : Value<T>()
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
abstract class MutableListValue<T : Any> internal constructor() : Value<MutableList<Value<T>>>(), MutableList<T>
override fun deserialize(decoder: Decoder): T {
internalValue.updaterSerializer.deserialize(decoder)
return internalValue
}
abstract class MutableIntListValue internal constructor() : Value<MutableList<Int>>(), MutableList<Int>
abstract class MutableShortListValue internal constructor() : Value<MutableList<Short>>(), MutableList<Short>
abstract class MutableByteListValue internal constructor() : Value<MutableList<Byte>>(), MutableList<Byte>
abstract class MutableLongListValue internal constructor() : Value<MutableList<Long>>(), MutableList<Long>
abstract class MutableFloatListValue internal constructor() : Value<MutableList<Float>>(), MutableList<Float>
abstract class MutableDoubleListValue internal constructor() : Value<MutableList<Double>>(), MutableList<Double>
abstract class MutableBooleanListValue internal constructor() : Value<MutableList<Boolean>>(), MutableList<Boolean>
abstract class MutableCharListValue internal constructor() : Value<MutableList<Char>>(), MutableList<Char>
abstract class MutableStringListValue internal constructor() : Value<MutableList<String>>(), MutableList<String>
override fun serialize(encoder: Encoder, value: T) {
internalValue.updaterSerializer.serialize(encoder, SettingSerializerMark)
}
abstract class MutableSettingListValue<T : Setting> internal constructor() : Value<MutableList<T>>(), MutableList<T>
}.bind(
getter = { internalValue },
setter = { internalValue = it }
)
}
}
abstract class MutableSetValue<T : Any> internal constructor() : Value<MutableSet<Value<T>>>(), MutableSet<T>
abstract class MutableIntSetValue internal constructor() : Value<MutableSet<Int>>(), MutableSet<Int>
abstract class MutableShortSetValue internal constructor() : Value<MutableSet<Short>>(), MutableSet<Short>
abstract class MutableByteSetValue internal constructor() : Value<MutableSet<Byte>>(), MutableSet<Byte>
abstract class MutableLongSetValue internal constructor() : Value<MutableSet<Long>>(), MutableSet<Long>
abstract class MutableFloatSetValue internal constructor() : Value<MutableSet<Float>>(), MutableSet<Float>
abstract class MutableDoubleSetValue internal constructor() : Value<MutableSet<Double>>(), MutableSet<Double>
abstract class MutableBooleanSetValue internal constructor() : Value<MutableSet<Boolean>>(), MutableSet<Boolean>
abstract class MutableCharSetValue internal constructor() : Value<MutableSet<Char>>(), MutableSet<Char>
abstract class MutableStringSetValue internal constructor() : Value<MutableSet<String>>(), MutableSet<String>
abstract class MutableSettingSetValue<T : Setting> internal constructor() : Value<MutableSet<T>>(), MutableSet<T>
/**
* 只引用这个对象, 而不跟踪其成员.
* 仅适用于基础类型, 用于 mutable list/map 等情况; 或标注了 [Serializable] 的类.
*/
abstract class DynamicReferenceValue<T : Any> internal constructor() : Value<T>()

View File

@ -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 <E, R> MutableList<E>.shadowMap(transform: (E) -> R, transformBack: (R) -> E): MutableList<R> {
return object : MutableList<R> {
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<R>): 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<R> = object : MutableIterator<R> {
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<R>): Boolean =
this@shadowMap.addAll(index, elements.map(transformBack))
override fun addAll(elements: Collection<R>): Boolean = this@shadowMap.addAll(elements.map(transformBack))
override fun clear() = this@shadowMap.clear()
override fun listIterator(): MutableListIterator<R> = object : MutableListIterator<R> {
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<R> = object : MutableListIterator<R> {
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<R>): Boolean = elements.all(::remove)
override fun removeAt(index: Int): R = this@shadowMap.removeAt(index).let(transform)
override fun retainAll(elements: Collection<R>): 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<R> =
this@shadowMap.subList(fromIndex, toIndex).map(transform).toMutableList()
}
}
internal fun <E, R> MutableSet<E>.shadowMap(transform: (E) -> R, transformBack: (R) -> E): MutableSet<R> {
return object : MutableSet<R> {
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<R>): Boolean = elements.all(::contains)
override fun isEmpty(): Boolean = this@shadowMap.isEmpty()
override fun iterator(): MutableIterator<R> = object : MutableIterator<R> {
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<R>): 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<R>): Boolean = elements.all(::remove)
override fun retainAll(elements: Collection<R>): Boolean = this@shadowMap.retainAll(elements.map(transformBack))
}
}
internal fun <T> dynamicList(supplier: () -> List<T>): List<T> {
return object : List<T> {
override val size: Int get() = supplier().size
override fun contains(element: T): Boolean = supplier().contains(element)
override fun containsAll(elements: Collection<T>): 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<T> = supplier().iterator()
override fun lastIndexOf(element: T): Int = supplier().lastIndexOf(element)
override fun listIterator(): ListIterator<T> = supplier().listIterator()
override fun listIterator(index: Int): ListIterator<T> = supplier().listIterator(index)
override fun subList(fromIndex: Int, toIndex: Int): List<T> = supplier().subList(fromIndex, toIndex)
}
}
internal fun <T> dynamicSet(supplier: () -> Set<T>): Set<T> {
return object : Set<T> {
override val size: Int get() = supplier().size
override fun contains(element: T): Boolean = supplier().contains(element)
override fun containsAll(elements: Collection<T>): Boolean = supplier().containsAll(elements)
override fun isEmpty(): Boolean = supplier().isEmpty()
override fun iterator(): Iterator<T> = supplier().iterator()
}
}
internal fun <T> dynamicMutableList(supplier: () -> MutableList<T>): MutableList<T> {
return object : MutableList<T> {
override val size: Int get() = supplier().size
override fun contains(element: T): Boolean = supplier().contains(element)
override fun containsAll(elements: Collection<T>): 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<T> = 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<T>): Boolean = supplier().addAll(index, elements)
override fun addAll(elements: Collection<T>): Boolean = supplier().addAll(elements)
override fun clear() = supplier().clear()
override fun listIterator(): MutableListIterator<T> = supplier().listIterator()
override fun listIterator(index: Int): MutableListIterator<T> = supplier().listIterator(index)
override fun remove(element: T): Boolean = supplier().remove(element)
override fun removeAll(elements: Collection<T>): Boolean = supplier().removeAll(elements)
override fun removeAt(index: Int): T = supplier().removeAt(index)
override fun retainAll(elements: Collection<T>): Boolean = supplier().retainAll(elements)
override fun set(index: Int, element: T): T = supplier().set(index, element)
override fun subList(fromIndex: Int, toIndex: Int): MutableList<T> = supplier().subList(fromIndex, toIndex)
}
}
internal fun <T> dynamicMutableSet(supplier: () -> MutableSet<T>): MutableSet<T> {
return object : MutableSet<T> {
override val size: Int get() = supplier().size
override fun contains(element: T): Boolean = supplier().contains(element)
override fun containsAll(elements: Collection<T>): Boolean = supplier().containsAll(elements)
override fun isEmpty(): Boolean = supplier().isEmpty()
override fun iterator(): MutableIterator<T> = supplier().iterator()
override fun add(element: T): Boolean = supplier().add(element)
override fun addAll(elements: Collection<T>): Boolean = supplier().addAll(elements)
override fun clear() = supplier().clear()
override fun remove(element: T): Boolean = supplier().remove(element)
override fun removeAll(elements: Collection<T>): Boolean = supplier().removeAll(elements)
override fun retainAll(elements: Collection<T>): Boolean = supplier().retainAll(elements)
}
}
internal inline fun <T> MutableList<T>.observable(crossinline onChanged: () -> Unit): MutableList<T> {
return object : MutableList<T> {
override val size: Int get() = this@observable.size
override fun contains(element: T): Boolean = this@observable.contains(element)
override fun containsAll(elements: Collection<T>): 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<T> = object : MutableIterator<T> {
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<T>): Boolean =
this@observable.addAll(index, elements).also { onChanged() }
override fun addAll(elements: Collection<T>): Boolean = this@observable.addAll(elements).also { onChanged() }
override fun clear() = this@observable.clear().also { onChanged() }
override fun listIterator(): MutableListIterator<T> = object : MutableListIterator<T> {
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<T> = object : MutableListIterator<T> {
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<T>): Boolean =
this@observable.removeAll(elements).also { onChanged() }
override fun removeAt(index: Int): T = this@observable.removeAt(index).also { onChanged() }
override fun retainAll(elements: Collection<T>): 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<T> = this@observable.subList(fromIndex, toIndex)
}
}
internal inline fun <T> MutableSet<T>.observable(crossinline onChanged: () -> Unit): MutableSet<T> {
return object : MutableSet<T> {
override val size: Int get() = this@observable.size
override fun contains(element: T): Boolean = this@observable.contains(element)
override fun containsAll(elements: Collection<T>): Boolean = this@observable.containsAll(elements)
override fun isEmpty(): Boolean = this@observable.isEmpty()
override fun iterator(): MutableIterator<T> = object : MutableIterator<T> {
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<T>): 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<T>): Boolean =
this@observable.removeAll(elements).also { onChanged() }
override fun retainAll(elements: Collection<T>): Boolean =
this@observable.retainAll(elements).also { onChanged() }
}
}
@OptIn(ImplicitReflectionSerializer::class)
internal fun <R : Any> Any.smartCastPrimitive(clazz: KClass<R>): R {
kotlin.runCatching {
return Yaml.default.parse(clazz.serializer(), this.toString())
}.getOrElse {
throw IllegalArgumentException("Cannot cast '$this' to ${clazz.qualifiedName}", it)
}
}