isXander / YetAnotherConfigLib

YetAnotherConfigLib (yacl) is just that. A builder-based configuration library for Minecraft.
GNU Lesser General Public License v3.0
95 stars 36 forks source link

Add kotlin DSL for list options #196

Open solonovamax opened 1 month ago

solonovamax commented 1 month ago

Currently, there is no kotlin DSL for list options.

Here is a very quick implementation I made of that (in my implementation I had to use reflection to grab the groupKey, but that's only bc I don't have access to your private api)


// OptionRegistrar (API.kt)
interface OptionRegistrar {
    fun <T> registerList(id: String, @BuilderInference block: ListOptionDsl<T>.() -> Unit): ListOption<T>

    fun <T> registeringList(id: String? = null, @BuilderInference block: ListOptionDsl<T>.() -> Unit): RegisterableActionDelegateProvider<ListOptionDsl<T>, ListOption<T>>
}

// API.kt
interface ListOptionDsl<T> : ListOption.Builder<T>, Buildable<ListOption<T>> {
    val optionKey: String
    val optionId: String
    val thisOption: CompletableFuture<ListOption<T>>

    fun OptionDescription.Builder.addDefaultText(lines: Int? = null) = addDefaultText("$optionKey.description", lines)
}

// OptionRegistrarImpl (Impl.kt)
class OptionRegistratImpl {
    override fun <T> registerList(id: String, @BuilderInference block: ListOptionDsl<T>.() -> Unit) = register(id, ListOptionDslImpl<T>(id, groupKey).apply(block).build())

    override fun <T> registeringList(id: String? = null, @BuilderInference block: ListOptionDsl<T>.() -> Unit) = RegisterableActionDelegateProvider(this::registerList, block, id)
}

// Impl.kt
class ListOptionDslImpl<T>(
    override val optionId: String,
    groupKey: String,
    private val builder: ListOption.Builder<T> = ListOption.createBuilder(),
) : ListOptionDsl<T>, ListOption.Builder<T> by builder {
    override val optionKey = "$groupKey.option.$optionId"

    override val thisOption = CompletableFuture<ListOption<T>>()
    override val built = thisOption

    init {
        builder.name(Text.translatable(optionKey))
    }

    override fun OptionDescription.Builder.addDefaultText(lines: Int?) = addDefaultText(prefix = "$optionKey.description", lines = lines)

    override fun build(): ListOption<T> = builder.build().also { thisOption.complete(it) }
}

// Extensions.kt
fun <T : Any> ListOption.Builder<T>.binding(property: KMutableProperty0<List<T>>, default: List<T>) {
    binding(default, { property.get() }, { property.set(it) })
}
solonovamax commented 1 month ago

nvm, they need to be added as a group, not an option, so all that code there is useless.

however, the issue still applies.

solonovamax commented 1 month ago

nvm part two, it does work, but it can only be used on rootOptions.

also there's some weird generics issue with the builder inference, so just remove it lol nvm, the issue has to do with using lambdas. idfk what it is.