From 5197235181b7ccfed42af190f5b4aea10d4d9b94 Mon Sep 17 00:00:00 2001 From: Mona <59416038+meowora@users.noreply.github.com> Date: Mon, 23 Jun 2025 21:10:27 +0200 Subject: [PATCH 1/3] feat: delegate delegates to allow for cool stuff --- .../resourcefulconfigkt/api/ConfigKt.kt | 10 +- .../resourcefulconfigkt/api/Entries.kt | 95 ++++++++++--------- .../api/builders/EntriesBuilder.kt | 6 +- 3 files changed, 64 insertions(+), 47 deletions(-) diff --git a/common/src/main/kotlin/com/teamresourceful/resourcefulconfigkt/api/ConfigKt.kt b/common/src/main/kotlin/com/teamresourceful/resourcefulconfigkt/api/ConfigKt.kt index 261be56..a0e679f 100644 --- a/common/src/main/kotlin/com/teamresourceful/resourcefulconfigkt/api/ConfigKt.kt +++ b/common/src/main/kotlin/com/teamresourceful/resourcefulconfigkt/api/ConfigKt.kt @@ -11,7 +11,7 @@ import org.jetbrains.annotations.Range import java.util.function.UnaryOperator open class ConfigKt( - @Pattern("^[a-z0-9_/-]+$") private val file: String + @Pattern("^[a-z0-9_/-]+$") private val file: String, ) : CategoryBuilder(file) { private var registered: Boolean = false @@ -20,7 +20,13 @@ open class ConfigKt( open val patches: Map> = mapOf() override fun build(parent: ResourcefulConfig?): ResourcefulConfig { - val config = ParsedConfig(this.version, this.file, ConfigKtInfo(this), this.elements, LinkedHashMap()) + val config = ParsedConfig( + this.version, + this.file, + ConfigKtInfo(this), + this.elements, + LinkedHashMap() + ) for ((id, builder) in this.categories) { config.categories[id] = builder.build(config) } diff --git a/common/src/main/kotlin/com/teamresourceful/resourcefulconfigkt/api/Entries.kt b/common/src/main/kotlin/com/teamresourceful/resourcefulconfigkt/api/Entries.kt index 6c57df3..d78bf0b 100644 --- a/common/src/main/kotlin/com/teamresourceful/resourcefulconfigkt/api/Entries.kt +++ b/common/src/main/kotlin/com/teamresourceful/resourcefulconfigkt/api/Entries.kt @@ -11,12 +11,13 @@ import kotlin.reflect.KProperty class EntryDelegate internal constructor( private val default: T, private var value: T, -) { +) : RConfigKtEntry { - internal var onChange: (T, T) -> Unit = { _, _ -> } + override var onChange: (T, T) -> Unit = { _, _ -> } + override val parent: EntryDelegate = this - operator fun getValue(thisRef: Any?, property: Any?): T = get() - operator fun setValue(thisRef: Any?, property: Any?, value: T) = set(value) + override operator fun getValue(thisRef: Any?, property: Any?): T = get() + override operator fun setValue(thisRef: Any?, property: Any?, value: T) = set(value) fun get(): T { return value @@ -37,24 +38,21 @@ class EntryDelegate internal constructor( } class TransformedEntryDelegate internal constructor( - private val parent: EntryDelegate, + val actualParent: RConfigKtEntry, private val from: (R) -> T, private val to: (T) -> R, -) { +) : RConfigKtEntry { - private var value: R = to(parent.get()) + override val parent: RConfigKtEntry = this - init { - parent.onChange = { old, new -> - value = to(new) + override var onChange: (R, R) -> Unit + get() = { p1, p2 -> actualParent.onChange(from(p1), from(p2)) } + set(value) { + actualParent.onChange = { p1, p2 -> value(to(p1), to(p2))} } - } - operator fun getValue(thisRef: Any?, property: Any?): R = value - operator fun setValue(thisRef: Any?, property: Any?, value: R) { - parent.set(from(value)) - this.value = value - } + override operator fun getValue(thisRef: Any?, property: Any?): R = to(actualParent.getValue(thisRef, property)) + override operator fun setValue(thisRef: Any?, property: Any?, value: R) = actualParent.setValue(thisRef, property, from(value)) } class Entry internal constructor( @@ -63,60 +61,71 @@ class Entry internal constructor( private val builderFactory: (String) -> B, private val builderFiller: (B) -> Unit, private val value: T, -) { +) : ConfigDelegateProvider> { - operator fun provideDelegate(builder: EntriesBuilder, prop: KProperty<*>): EntryDelegate { + override operator fun provideDelegate(entries: EntriesBuilder, prop: KProperty<*>): EntryDelegate { val id = id ?: prop.name val entryBuilder = builderFactory(id).apply(builderFiller) - var data = entryBuilder.toEntryData() + val data = entryBuilder.toEntryData() val property = EntryDelegate(this.value, this.value) - builder.element(EntryElementKt( - id, - entryBuilder, - KotlinConfigEntry( - type, - { property.set(it as T) }, - { property.get() as Any }, - data, - value as Any + entries.element( + EntryElementKt( + id, + entryBuilder, + KotlinConfigEntry( + type, + { property.set(it as T) }, + { property.get() as Any }, + data, + value as Any + ) ) - )) + ) return property } } -class ObservableEntry( - private val entry: Entry, - private val onChange: (T, T) -> Unit -) { - operator fun provideDelegate(builder: EntriesBuilder, prop: KProperty<*>): EntryDelegate { - val property = entry.provideDelegate(builder, prop) +class ObservableEntry( + private val entry: ConfigDelegateProvider>, + private val onChange: (T, T) -> Unit, +) : ConfigDelegateProvider> { + override operator fun provideDelegate(entries: EntriesBuilder, prop: KProperty<*>): RConfigKtEntry { + val property = entry.provideDelegate(entries, prop) property.onChange = onChange return property } } -class TransformedEntry( - private val entry: Entry, +class TransformedEntry( + private val entry: ConfigDelegateProvider>, private val from: (R) -> T, private val to: (T) -> R, -) { - operator fun provideDelegate(builder: EntriesBuilder, prop: KProperty<*>): TransformedEntryDelegate { - val property = entry.provideDelegate(builder, prop) - return TransformedEntryDelegate(property, from, to) +) : ConfigDelegateProvider> { + override operator fun provideDelegate(entries: EntriesBuilder, prop: KProperty<*>): RConfigKtEntry { + val property = entry.provideDelegate(entries, prop) + return TransformedEntryDelegate(property.parent, from, to) } } class ObjectProperty( val instance: T, - val factory: TypeBuilder.() -> Unit = {} + val factory: TypeBuilder.() -> Unit = {}, ) { - operator fun provideDelegate(entries: EntriesBuilder, prop: KProperty<*>): Lazy { val builder = TypeBuilder(prop.name).apply(factory) entries.element(ObjectEntryElementKt(prop.name, builder, instance.build(builder.toEntryData()))) return lazyOf(instance) } +} +interface RConfigKtEntry { + val parent: RConfigKtEntry + var onChange: (T, T) -> Unit + operator fun getValue(thisRef: Any?, property: Any?): T + operator fun setValue(thisRef: Any?, property: Any?, value: T) } + +interface ConfigDelegateProvider { + operator fun provideDelegate(entries: EntriesBuilder, prop: KProperty<*>): D +} \ No newline at end of file diff --git a/common/src/main/kotlin/com/teamresourceful/resourcefulconfigkt/api/builders/EntriesBuilder.kt b/common/src/main/kotlin/com/teamresourceful/resourcefulconfigkt/api/builders/EntriesBuilder.kt index 6988a6b..ed80657 100644 --- a/common/src/main/kotlin/com/teamresourceful/resourcefulconfigkt/api/builders/EntriesBuilder.kt +++ b/common/src/main/kotlin/com/teamresourceful/resourcefulconfigkt/api/builders/EntriesBuilder.kt @@ -4,8 +4,10 @@ import com.teamresourceful.resourcefulconfig.api.types.ResourcefulConfigElement import com.teamresourceful.resourcefulconfig.api.types.elements.ResourcefulConfigEntryElement import com.teamresourceful.resourcefulconfig.api.types.options.EntryType import com.teamresourceful.resourcefulconfig.api.types.options.TranslatableValue +import com.teamresourceful.resourcefulconfigkt.api.ConfigDelegateProvider import com.teamresourceful.resourcefulconfigkt.api.Entry import com.teamresourceful.resourcefulconfigkt.api.ObservableEntry +import com.teamresourceful.resourcefulconfigkt.api.RConfigKtEntry import com.teamresourceful.resourcefulconfigkt.api.TransformedEntry open class EntriesBuilder { @@ -93,8 +95,8 @@ open class EntriesBuilder { fun > draggable(vararg value: T, builder: DraggableBuilder.() -> Unit = {}) = Entry(null, EntryType.ENUM, { DraggableBuilder(it, getEmptyArray(value.javaClass)) }, builder, value) fun > draggable(id: String, vararg value: T, builder: DraggableBuilder.() -> Unit = {}) = Entry(id, EntryType.ENUM, { DraggableBuilder(it, getEmptyArray(value.javaClass)) }, builder, value) - fun observable(entry: Entry, onChange: (T, T) -> Unit) = ObservableEntry(entry, onChange) - fun transform(entry: Entry, from: (R) -> T, to: (T) -> R) = TransformedEntry(entry, from, to) + fun observable(entry: ConfigDelegateProvider>, onChange: (T, T) -> Unit) = ObservableEntry(entry, onChange) + fun transform(entry: ConfigDelegateProvider>, from: (R) -> T, to: (T) -> R) = TransformedEntry(entry, from, to) companion object { From 58bd3b922d53dc586f6b5d4c698b23c39e634b44 Mon Sep 17 00:00:00 2001 From: Mona <59416038+meowora@users.noreply.github.com> Date: Mon, 23 Jun 2025 21:24:18 +0200 Subject: [PATCH 2/3] changed changes --- .../resourcefulconfigkt/api/builders/EntriesBuilder.kt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/common/src/main/kotlin/com/teamresourceful/resourcefulconfigkt/api/builders/EntriesBuilder.kt b/common/src/main/kotlin/com/teamresourceful/resourcefulconfigkt/api/builders/EntriesBuilder.kt index ed80657..1721ff1 100644 --- a/common/src/main/kotlin/com/teamresourceful/resourcefulconfigkt/api/builders/EntriesBuilder.kt +++ b/common/src/main/kotlin/com/teamresourceful/resourcefulconfigkt/api/builders/EntriesBuilder.kt @@ -95,7 +95,9 @@ open class EntriesBuilder { fun > draggable(vararg value: T, builder: DraggableBuilder.() -> Unit = {}) = Entry(null, EntryType.ENUM, { DraggableBuilder(it, getEmptyArray(value.javaClass)) }, builder, value) fun > draggable(id: String, vararg value: T, builder: DraggableBuilder.() -> Unit = {}) = Entry(id, EntryType.ENUM, { DraggableBuilder(it, getEmptyArray(value.javaClass)) }, builder, value) + fun observable(entry: Entry, onChange: (T, T) -> Unit) = ObservableEntry(entry, onChange) fun observable(entry: ConfigDelegateProvider>, onChange: (T, T) -> Unit) = ObservableEntry(entry, onChange) + fun transform(entry: Entry, from: (R) -> T, to: (T) -> R) = TransformedEntry(entry, from, to) fun transform(entry: ConfigDelegateProvider>, from: (R) -> T, to: (T) -> R) = TransformedEntry(entry, from, to) companion object { From 3f06de6328a1798d56fea0fde25737d8fae273ca Mon Sep 17 00:00:00 2001 From: Mona <59416038+meowora@users.noreply.github.com> Date: Mon, 23 Jun 2025 22:12:55 +0200 Subject: [PATCH 3/3] backwards compat (im sorry) --- .../resourcefulconfigkt/api/Entries.kt | 31 +++++++++++++------ .../api/builders/EntriesBuilder.kt | 2 +- 2 files changed, 22 insertions(+), 11 deletions(-) diff --git a/common/src/main/kotlin/com/teamresourceful/resourcefulconfigkt/api/Entries.kt b/common/src/main/kotlin/com/teamresourceful/resourcefulconfigkt/api/Entries.kt index d78bf0b..4e2c244 100644 --- a/common/src/main/kotlin/com/teamresourceful/resourcefulconfigkt/api/Entries.kt +++ b/common/src/main/kotlin/com/teamresourceful/resourcefulconfigkt/api/Entries.kt @@ -8,22 +8,24 @@ import com.teamresourceful.resourcefulconfigkt.impl.EntryElementKt import com.teamresourceful.resourcefulconfigkt.impl.ObjectEntryElementKt import kotlin.reflect.KProperty -class EntryDelegate internal constructor( +class EntryDelegate internal constructor(entry: RConfigKtEntry): RConfigKtEntry by entry + +class EntryDelegateImpl internal constructor( private val default: T, private var value: T, ) : RConfigKtEntry { override var onChange: (T, T) -> Unit = { _, _ -> } - override val parent: EntryDelegate = this + override val parent: EntryDelegateImpl = this override operator fun getValue(thisRef: Any?, property: Any?): T = get() override operator fun setValue(thisRef: Any?, property: Any?, value: T) = set(value) - fun get(): T { + override fun get(): T { return value } - fun set(newValue: T) { + override fun set(newValue: T) { val oldValue = this.value this.value = newValue @@ -32,7 +34,7 @@ class EntryDelegate internal constructor( } } - fun reset() { + override fun reset() { this.value = default } } @@ -51,6 +53,10 @@ class TransformedEntryDelegate internal constructor( actualParent.onChange = { p1, p2 -> value(to(p1), to(p2))} } + override fun get(): R = to(actualParent.get()) + override fun set(newValue: R) = actualParent.set(from(newValue)) + override fun reset() = actualParent.reset() + override operator fun getValue(thisRef: Any?, property: Any?): R = to(actualParent.getValue(thisRef, property)) override operator fun setValue(thisRef: Any?, property: Any?, value: R) = actualParent.setValue(thisRef, property, from(value)) } @@ -67,7 +73,7 @@ class Entry internal constructor( val id = id ?: prop.name val entryBuilder = builderFactory(id).apply(builderFiller) val data = entryBuilder.toEntryData() - val property = EntryDelegate(this.value, this.value) + val property = EntryDelegateImpl(this.value, this.value) entries.element( EntryElementKt( @@ -82,7 +88,7 @@ class Entry internal constructor( ) ) ) - return property + return EntryDelegate(property) } } @@ -90,10 +96,10 @@ class ObservableEntry( private val entry: ConfigDelegateProvider>, private val onChange: (T, T) -> Unit, ) : ConfigDelegateProvider> { - override operator fun provideDelegate(entries: EntriesBuilder, prop: KProperty<*>): RConfigKtEntry { + override operator fun provideDelegate(entries: EntriesBuilder, prop: KProperty<*>): EntryDelegate { val property = entry.provideDelegate(entries, prop) property.onChange = onChange - return property + return EntryDelegate(property) } } @@ -102,7 +108,7 @@ class TransformedEntry( private val from: (R) -> T, private val to: (T) -> R, ) : ConfigDelegateProvider> { - override operator fun provideDelegate(entries: EntriesBuilder, prop: KProperty<*>): RConfigKtEntry { + override operator fun provideDelegate(entries: EntriesBuilder, prop: KProperty<*>): TransformedEntryDelegate { val property = entry.provideDelegate(entries, prop) return TransformedEntryDelegate(property.parent, from, to) } @@ -122,6 +128,11 @@ class ObjectProperty( interface RConfigKtEntry { val parent: RConfigKtEntry var onChange: (T, T) -> Unit + + fun get(): T + fun set(newValue: T) + fun reset() + operator fun getValue(thisRef: Any?, property: Any?): T operator fun setValue(thisRef: Any?, property: Any?, value: T) } diff --git a/common/src/main/kotlin/com/teamresourceful/resourcefulconfigkt/api/builders/EntriesBuilder.kt b/common/src/main/kotlin/com/teamresourceful/resourcefulconfigkt/api/builders/EntriesBuilder.kt index 1721ff1..8d2b631 100644 --- a/common/src/main/kotlin/com/teamresourceful/resourcefulconfigkt/api/builders/EntriesBuilder.kt +++ b/common/src/main/kotlin/com/teamresourceful/resourcefulconfigkt/api/builders/EntriesBuilder.kt @@ -6,8 +6,8 @@ import com.teamresourceful.resourcefulconfig.api.types.options.EntryType import com.teamresourceful.resourcefulconfig.api.types.options.TranslatableValue import com.teamresourceful.resourcefulconfigkt.api.ConfigDelegateProvider import com.teamresourceful.resourcefulconfigkt.api.Entry -import com.teamresourceful.resourcefulconfigkt.api.ObservableEntry import com.teamresourceful.resourcefulconfigkt.api.RConfigKtEntry +import com.teamresourceful.resourcefulconfigkt.api.ObservableEntry import com.teamresourceful.resourcefulconfigkt.api.TransformedEntry open class EntriesBuilder {