Skip to content

Commit 7aaf2a2

Browse files
committed
setting group and configurable level setting editing
1 parent 7f58d84 commit 7aaf2a2

File tree

29 files changed

+344
-279
lines changed

29 files changed

+344
-279
lines changed

src/main/kotlin/com/lambda/config/AutomationConfig.kt

Lines changed: 14 additions & 123 deletions
Original file line numberDiff line numberDiff line change
@@ -31,10 +31,8 @@ import com.lambda.event.events.onStaticRender
3131
import com.lambda.interaction.construction.result.Drawable
3232
import com.lambda.module.Module
3333
import com.lambda.util.NamedEnum
34-
import kotlin.reflect.KProperty0
35-
import kotlin.reflect.jvm.isAccessible
3634

37-
@Suppress("unchecked_cast", "unused")
35+
3836
open class AutomationConfig(
3937
override val name: String,
4038
configuration: Configuration = AutomationConfigs
@@ -45,7 +43,6 @@ open class AutomationConfig(
4543
Place("Place"),
4644
Interact("Interact"),
4745
Rotation("Rotation"),
48-
Interaction("Interaction"),
4946
Inventory("Inventory"),
5047
Hotbar("Hotbar"),
5148
Eat("Eat"),
@@ -66,11 +63,19 @@ open class AutomationConfig(
6663

6764
companion object {
6865
context(module: Module)
69-
fun automationConfig(name: String = module.name, edits: (AutomationConfig.() -> Unit)? = null): AutomationConfig =
70-
AutomationConfig("Default $name Automation Config").apply { edits?.invoke(this) }
71-
72-
fun automationConfig(name: String, edits: (AutomationConfig.() -> Unit)? = null): AutomationConfig =
73-
AutomationConfig("Default $name Automation Config").apply { edits?.invoke(this) }
66+
fun MutableAutomationConfig.setDefaultAutomationConfig(
67+
name: String = module.name,
68+
edits: (AutomationConfig.() -> Unit)? = null
69+
) {
70+
defaultAutomationConfig = AutomationConfig("Default $name Automation Config").apply { edits?.invoke(this) }
71+
}
72+
73+
fun MutableAutomationConfig.setDefaultAutomationConfig(
74+
name: String,
75+
edits: (AutomationConfig.() -> Unit)? = null
76+
) {
77+
defaultAutomationConfig = AutomationConfig("Default $name Automation Config").apply { edits?.invoke(this) }
78+
}
7479

7580
object DEFAULT : AutomationConfig("Default") {
7681
val renders by setting("Render", false).group(Group.Render)
@@ -91,118 +96,4 @@ open class AutomationConfig(
9196
}
9297
}
9398
}
94-
95-
@DslMarker
96-
annotation class SettingEditorDsl
97-
98-
private val KProperty0<*>.delegate
99-
get() = try {
100-
apply { isAccessible = true }.getDelegate()
101-
} catch (e: Exception) {
102-
throw IllegalStateException("Could not access delegate for property $name", e)
103-
}
104-
105-
@SettingEditorDsl
106-
internal inline fun <T : Any> KProperty0<T>.edit(edits: TypedEditBuilder<T>.(AbstractSetting<T>) -> Unit) {
107-
val setting = delegate as? AbstractSetting<T> ?: throw IllegalStateException("Setting delegate did not match current value's type")
108-
TypedEditBuilder(this@AutomationConfig, listOf(setting)).edits(setting)
109-
}
110-
111-
@SettingEditorDsl
112-
internal inline fun <T : Any, R : Any> KProperty0<T>.editWith(
113-
other: KProperty0<R>,
114-
edits: TypedEditBuilder<T>.(AbstractSetting<R>) -> Unit
115-
) {
116-
val setting = delegate as? AbstractSetting<T> ?: throw IllegalStateException("Setting delegate did not match current value's type")
117-
TypedEditBuilder(this@AutomationConfig, listOf(setting)).edits(other.delegate as AbstractSetting<R>)
118-
}
119-
120-
@SettingEditorDsl
121-
fun edit(
122-
vararg settings: KProperty0<*>,
123-
edits: BasicEditBuilder.() -> Unit
124-
) { BasicEditBuilder(this@AutomationConfig, settings.map { it.delegate } as List<AbstractSetting<*>>).apply(edits) }
125-
126-
@SettingEditorDsl
127-
internal inline fun <T : Any> editWith(
128-
vararg settings: KProperty0<*>,
129-
other: KProperty0<T>,
130-
edits: BasicEditBuilder.(AbstractSetting<T>) -> Unit
131-
) { BasicEditBuilder(this@AutomationConfig, settings.map { it.delegate } as List<AbstractSetting<*>>).edits(other.delegate as AbstractSetting<T>) }
132-
133-
@SettingEditorDsl
134-
internal inline fun <T : Any> editTyped(
135-
vararg settings: KProperty0<T>,
136-
edits: TypedEditBuilder<T>.() -> Unit
137-
) { TypedEditBuilder(this@AutomationConfig, settings.map { it.delegate } as List<AbstractSetting<T>>).apply(edits) }
138-
139-
@SettingEditorDsl
140-
internal inline fun <T : Any, R : Any> editTypedWith(
141-
vararg settings: KProperty0<T>,
142-
other: KProperty0<R>,
143-
edits: TypedEditBuilder<T>.(AbstractSetting<R>) -> Unit
144-
) = TypedEditBuilder(this@AutomationConfig, settings.map { it.delegate } as List<AbstractSetting<T>>).edits(other.delegate as AbstractSetting<R>)
145-
146-
@SettingEditorDsl
147-
fun hide(vararg settings: KProperty0<*>) {
148-
hideAll((settings.map { it.delegate } as List<AbstractSetting<*>>))
149-
}
150-
151-
@SettingEditorDsl
152-
fun hideAll(settingGroup: SettingGroup) = hideAll(settingGroup.settings)
153-
154-
@SettingEditorDsl
155-
fun hideAll(settings: Collection<AbstractSetting<*>>) {
156-
this@AutomationConfig.settings.removeAll(settings)
157-
hiddenSettings.addAll(settings)
158-
}
159-
160-
@SettingEditorDsl
161-
fun hideAll(vararg settingGroups: SettingGroup) {
162-
settingGroups.forEach { hideAll(it.settings) }
163-
}
164-
165-
@SettingEditorDsl
166-
fun hideAllExcept(settingGroup: SettingGroup, vararg settings: KProperty0<*>) {
167-
this@AutomationConfig.settings.removeIf {
168-
return@removeIf if (it in settingGroup.settings && it !in (settings.toList() as List<AbstractSetting<*>>)) {
169-
hiddenSettings.add(it)
170-
true
171-
} else false
172-
}
173-
}
174-
175-
open class BasicEditBuilder(val c: AutomationConfig, open val settings: Collection<AbstractSetting<*>>) {
176-
@SettingEditorDsl
177-
fun visibility(vis: () -> Boolean) =
178-
settings.forEach { it.visibility = vis }
179-
180-
@SettingEditorDsl
181-
fun hide() = c.hideAll(settings)
182-
183-
@SettingEditorDsl
184-
fun groups(vararg groups: NamedEnum) =
185-
settings.forEach { it.groups = mutableListOf(groups.toList()) }
186-
187-
@SettingEditorDsl
188-
fun groups(groups: MutableList<List<NamedEnum>>) =
189-
settings.forEach { it.groups = groups }
190-
}
191-
192-
open class TypedEditBuilder<T : Any>(
193-
c: AutomationConfig,
194-
override val settings: Collection<AbstractSetting<T>>
195-
) : BasicEditBuilder(c, settings) {
196-
@SettingEditorDsl
197-
fun defaultValue(value: T) =
198-
settings.forEach {
199-
it.defaultValue = value
200-
it.value = value
201-
}
202-
}
203-
204-
enum class InsertMode {
205-
Above,
206-
Below
207-
}
20899
}
Lines changed: 143 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,143 @@
1+
/*
2+
* Copyright 2025 Lambda
3+
*
4+
* This program is free software: you can redistribute it and/or modify
5+
* it under the terms of the GNU General Public License as published by
6+
* the Free Software Foundation, either version 3 of the License, or
7+
* (at your option) any later version.
8+
*
9+
* This program is distributed in the hope that it will be useful,
10+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+
* GNU General Public License for more details.
13+
*
14+
* You should have received a copy of the GNU General Public License
15+
* along with this program. If not, see <http://www.gnu.org/licenses/>.
16+
*/
17+
18+
package com.lambda.config
19+
20+
import com.lambda.config.AutomationConfig.Companion.DEFAULT.hiddenSettings
21+
import com.lambda.util.NamedEnum
22+
import kotlin.reflect.KProperty0
23+
import kotlin.reflect.jvm.isAccessible
24+
25+
@DslMarker
26+
annotation class SettingEditorDsl
27+
28+
@SettingEditorDsl
29+
fun <T : Configurable> T.applyEdits(edits: ConfigurableEditor<T>.() -> Unit) {
30+
ConfigurableEditor(this).apply(edits)
31+
}
32+
33+
@Suppress("unchecked_cast", "unused")
34+
open class SettingGroupEditor<T : Configurable>(open val c: T) {
35+
val KProperty0<*>.delegate
36+
get() = try {
37+
apply { isAccessible = true }.getDelegate()
38+
} catch (e: Exception) {
39+
throw IllegalStateException("Could not access delegate for property $name", e)
40+
}
41+
42+
fun <T : Any> KProperty0<*>.settingDelegate() =
43+
this.delegate as? AbstractSetting<T>
44+
?: throw IllegalStateException("Setting (${(delegate as AbstractSetting<*>).name}) delegate did not match current value's type")
45+
46+
@SettingEditorDsl
47+
inline fun <T : Any> KProperty0<T>.edit(edits: TypedEditBuilder<T>.(AbstractSetting<T>) -> Unit) {
48+
val setting = settingDelegate<T>()
49+
TypedEditBuilder(this@SettingGroupEditor, listOf(setting)).edits(setting)
50+
}
51+
52+
@SettingEditorDsl
53+
inline fun <T : Any, R : Any> KProperty0<T>.editWith(
54+
other: KProperty0<R>,
55+
edits: TypedEditBuilder<T>.(AbstractSetting<R>) -> Unit
56+
) {
57+
val setting = settingDelegate<T>()
58+
TypedEditBuilder(this@SettingGroupEditor, listOf(setting)).edits(other.settingDelegate())
59+
}
60+
61+
@SettingEditorDsl
62+
fun edit(
63+
vararg settings: KProperty0<*>,
64+
edits: BasicEditBuilder.() -> Unit
65+
) { BasicEditBuilder(this, settings.map { it.delegate } as List<AbstractSetting<*>>).apply(edits) }
66+
67+
@SettingEditorDsl
68+
inline fun <T : Any> editWith(
69+
vararg settings: KProperty0<*>,
70+
other: KProperty0<T>,
71+
edits: BasicEditBuilder.(AbstractSetting<T>) -> Unit
72+
) = BasicEditBuilder(this, settings.map { it.delegate } as List<AbstractSetting<*>>).edits(other.settingDelegate())
73+
74+
@SettingEditorDsl
75+
inline fun <T : Any> editTyped(
76+
vararg settings: KProperty0<T>,
77+
edits: TypedEditBuilder<T>.() -> Unit
78+
) { TypedEditBuilder(this, settings.map { it.delegate } as List<AbstractSetting<T>>).apply(edits) }
79+
80+
@SettingEditorDsl
81+
inline fun <T : Any, R : Any> editTypedWith(
82+
vararg settings: KProperty0<T>,
83+
other: KProperty0<R>,
84+
edits: TypedEditBuilder<T>.(AbstractSetting<R>) -> Unit
85+
) = TypedEditBuilder(this, settings.map { it.delegate } as List<AbstractSetting<T>>).edits(other.delegate as AbstractSetting<R>)
86+
87+
@SettingEditorDsl
88+
fun hide(settings: Collection<AbstractSetting<*>>) {
89+
c.settings.removeAll(settings)
90+
hiddenSettings.addAll(settings)
91+
}
92+
93+
@SettingEditorDsl
94+
fun hide(vararg settings: KProperty0<*>) =
95+
hide((settings.map { it.delegate } as List<AbstractSetting<*>>))
96+
97+
open class BasicEditBuilder(val c: SettingGroupEditor<*>, open val settings: Collection<AbstractSetting<*>>) {
98+
@SettingEditorDsl
99+
fun visibility(vis: () -> Boolean) =
100+
settings.forEach { it.visibility = vis }
101+
102+
@SettingEditorDsl
103+
fun hide() = c.hide(settings)
104+
105+
@SettingEditorDsl
106+
fun groups(vararg groups: NamedEnum) =
107+
settings.forEach { it.groups = mutableListOf(groups.toList()) }
108+
109+
@SettingEditorDsl
110+
fun groups(groups: MutableList<List<NamedEnum>>) =
111+
settings.forEach { it.groups = groups }
112+
}
113+
114+
class TypedEditBuilder<T : Any>(
115+
c: SettingGroupEditor<*>,
116+
override val settings: Collection<AbstractSetting<T>>
117+
) : BasicEditBuilder(c, settings) {
118+
@SettingEditorDsl
119+
fun defaultValue(value: T) =
120+
settings.forEach {
121+
it.defaultValue = value
122+
it.value = value
123+
}
124+
}
125+
}
126+
127+
@Suppress("unchecked_cast", "unused")
128+
class ConfigurableEditor<T : Configurable>(override val c: T) : SettingGroupEditor<T>(c) {
129+
@SettingEditorDsl
130+
fun hideGroup(settingGroup: ISettingGroup) = hide(settingGroup.settings)
131+
132+
@SettingEditorDsl
133+
fun hideGroupExcept(settingGroup: ISettingGroup, vararg except: KProperty0<*>) =
134+
hide(*((settingGroup.settings as List<KProperty0<*>>) - except.toSet()).toTypedArray())
135+
136+
@SettingEditorDsl
137+
fun hideGroups(vararg settingGroups: ISettingGroup) =
138+
settingGroups.forEach { hide(it.settings) }
139+
140+
@SettingEditorDsl
141+
fun hideAllGroupsExcept(vararg except: ISettingGroup) =
142+
hideGroups(*(c.settingGroups - except.toSet()).toTypedArray())
143+
}

src/main/kotlin/com/lambda/config/Configurable.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ abstract class Configurable(
6060
private val configuration: Configuration,
6161
) : Jsonable, Nameable {
6262
val settings = mutableListOf<AbstractSetting<*>>()
63+
val settingGroups = mutableListOf<SettingGroup>()
6364

6465
init {
6566
registerConfigurable()

src/main/kotlin/com/lambda/config/SettingGroup.kt

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,12 @@
1717

1818
package com.lambda.config
1919

20-
abstract class SettingGroup() {
21-
val settings = mutableListOf<AbstractSetting<*>>()
20+
interface ISettingGroup {
21+
val settings: MutableList<AbstractSetting<*>>
22+
}
23+
24+
abstract class SettingGroup() : ISettingGroup {
25+
override val settings = mutableListOf<AbstractSetting<*>>()
2226

2327
fun <T : Any> AbstractSetting<T>.index(): AbstractSetting<T> {
2428
settings.add(this)

src/main/kotlin/com/lambda/config/groups/BreakSettings.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ import java.awt.Color
3131

3232
open class BreakSettings(
3333
c: Configurable,
34-
baseGroup: NamedEnum,
34+
baseGroup: NamedEnum
3535
) : SettingGroup(), BreakConfig {
3636
private enum class Group(override val displayName: String) : NamedEnum {
3737
General("General"),

src/main/kotlin/com/lambda/config/groups/BuildConfig.kt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,12 @@
1717

1818
package com.lambda.config.groups
1919

20+
import com.lambda.config.ISettingGroup
2021
import com.lambda.interaction.request.rotating.visibilty.PointSelection
2122
import com.lambda.util.Describable
2223
import com.lambda.util.NamedEnum
2324

24-
interface BuildConfig {
25+
interface BuildConfig : ISettingGroup {
2526
// General
2627
val pathing: Boolean
2728
val stayInRange: Boolean

src/main/kotlin/com/lambda/config/groups/EatConfig.kt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717

1818
package com.lambda.config.groups
1919

20+
import com.lambda.config.ISettingGroup
2021
import com.lambda.context.Automated
2122
import com.lambda.context.AutomatedSafeContext
2223
import com.lambda.interaction.material.StackSelection.Companion.selectStack
@@ -28,7 +29,7 @@ import net.minecraft.entity.effect.StatusEffects
2829
import net.minecraft.item.Item
2930
import net.minecraft.item.ItemStack
3031

31-
interface EatConfig {
32+
interface EatConfig : ISettingGroup {
3233
val eatOnHunger: Boolean
3334
val minFoodLevel: Int
3435
val nutritiousFood: List<Item>

src/main/kotlin/com/lambda/config/groups/FormatterConfig.kt

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,13 @@
1717

1818
package com.lambda.config.groups
1919

20+
import com.lambda.config.ISettingGroup
2021
import com.lambda.util.Describable
2122
import com.lambda.util.NamedEnum
2223
import java.time.format.DateTimeFormatter
23-
import java.util.Locale
24+
import java.util.*
2425

25-
interface FormatterConfig {
26+
interface FormatterConfig : ISettingGroup {
2627
val locale: Locale
2728
val separator: String
2829
val prefix: String

src/main/kotlin/com/lambda/config/groups/Targeting.kt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,6 @@ abstract class Targeting(
5555
private val defaultRange: Double,
5656
private val maxRange: Double,
5757
) : SettingGroup(), TargetingConfig {
58-
5958
/**
6059
* The range within which entities can be targeted. This value is configurable and constrained
6160
* between 1.0 and [maxRange].

0 commit comments

Comments
 (0)