Ayfri
01/20/2023, 4:17 PMsealed interface Namespaced : Argument {
val name: String
val namespace: String
override fun asString() = "$namespace:$name"
}
interface Biome : Namespaced {
companion object {
operator fun invoke(biome: String, namespace: String = "minecraft") = object : Biome {
override val name = biome
override val namespace = namespace
}
}
}
interface MobEffect : Namespaced {
companion object {
operator fun invoke(name: String, namespace: String = "minecraft") = object : MobEffect {
override val name = name
override val namespace = namespace
}
}
}
// etc
So I can avoid having the same companion object again and again, some of the interfaces might change so I would prefer to have an interface the companion object
implements, but I can't figure out how to do it
I have to stick with interfaces because every one of them are implemented by an enum listing the native data of each in the game (for example there is a Biome
enum implementing the Biome
interface so you can use the raw values of the enum as an Argument
object).
It helps me for serialization also with the asString()
method which is custom in enums to include the name of the enum entry as lowercase.Sam
01/20/2023, 4:29 PMinterface Argument {
fun asString(): String
}
private interface Named {
val name: String
val namespace: String
}
private class NameImpl(override val name: String, override val namespace: String): Named
sealed interface Namespaced : Argument {
val name: String
val namespace: String
override fun asString() = "$namespace:$name"
}
interface Factory<out T: Namespaced> {
operator fun invoke(name: String, namespace: String): T
}
interface Biome : Namespaced {
companion object: Factory<Biome> {
override fun invoke(name: String, namespace: String): Biome =
object: Biome, Named by NameImpl(name, namespace) {}
}
}
interface MobEffect : Namespaced {
companion object: Factory<MobEffect> {
override fun invoke(name: String, namespace: String): MobEffect =
object: MobEffect, Named by NameImpl(name, namespace) {}
}
}
Not exactly simpler than your version, though…ephemient
01/20/2023, 4:31 PMinterface Namespaced {
open class Factory<out T : Namespaced>(private val make: (name: String, namespace: String) -> T) {
operator fun invoke(name: String, namespace: String = "minecraft"): T =
make(name, namespace)
}
}
interface Biome : Namespaced {
private class Impl(override val name: String, override val namespace: String) : Biome
companion object : Namespaced.Factory<Biome>(::Impl)
}
Ayfri
01/20/2023, 4:35 PM