Extract functions from updateaction
This commit is contained in:
parent
00c02aab82
commit
1330fe6925
@ -0,0 +1,90 @@
|
||||
package ru.dbotthepony.mc.otm.matter
|
||||
|
||||
import com.google.common.collect.ImmutableList
|
||||
import com.google.gson.JsonArray
|
||||
import com.google.gson.JsonElement
|
||||
import com.google.gson.JsonObject
|
||||
import com.google.gson.JsonParseException
|
||||
import ru.dbotthepony.mc.otm.core.ImpreciseFraction
|
||||
import ru.dbotthepony.mc.otm.core.set
|
||||
import ru.dbotthepony.mc.otm.data.stream
|
||||
|
||||
class BoundMatterFunction<T : Number>(val function: MatterFunction, val value: T) {
|
||||
fun apply(self: T): T {
|
||||
return function.updateValue(self, value)
|
||||
}
|
||||
|
||||
fun toJson(): JsonObject {
|
||||
return JsonObject().also {
|
||||
it["type"] = function.name
|
||||
|
||||
if (value is Int || value is Double)
|
||||
it["value"] = value
|
||||
else
|
||||
it["value"] = value.toString()
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
inline fun <reified T : Number> getValue(value: JsonElement): T {
|
||||
return when (T::class) {
|
||||
ImpreciseFraction::class -> ImpreciseFraction(value.asString) as T
|
||||
Double::class -> value.asDouble as T
|
||||
Int::class -> value.asInt as T
|
||||
else -> throw RuntimeException("Unknown number type: ${T::class.qualifiedName}")
|
||||
}
|
||||
}
|
||||
|
||||
inline fun <reified T : Number> deserializeFunctionTree(input: JsonElement?, name: String): List<BoundMatterFunction<T>> {
|
||||
if (input == null) {
|
||||
return listOf()
|
||||
}
|
||||
|
||||
if (input !is JsonArray) {
|
||||
throw JsonParseException("Expected $name to be JsonArray, ${input::class.qualifiedName} given")
|
||||
}
|
||||
|
||||
return input.stream().map {
|
||||
if (it !is JsonObject) {
|
||||
throw JsonParseException("All elements in function tree must be JsonObjects, ${it::class.qualifiedName} given")
|
||||
}
|
||||
|
||||
val type = it["type"]?.asString ?: throw JsonParseException("Invalid `type` value in function object")
|
||||
val value = it["value"] ?: throw JsonParseException("Missing `value` value in function object")
|
||||
|
||||
val parsedValue: T = getValue(value)
|
||||
val fn: MatterFunction
|
||||
|
||||
try {
|
||||
fn = MatterFunction.valueOf(type.uppercase())
|
||||
} catch (err: NoSuchElementException) {
|
||||
throw JsonParseException("No such function: $type", err)
|
||||
}
|
||||
|
||||
return@map BoundMatterFunction(fn, parsedValue)
|
||||
}.collect(ImmutableList.toImmutableList())
|
||||
}
|
||||
|
||||
fun <T : Number> apply(value: T, funcs: Collection<BoundMatterFunction<T>>): T {
|
||||
if (funcs.isEmpty()) {
|
||||
return value
|
||||
}
|
||||
|
||||
var newValue = value
|
||||
|
||||
for (func in funcs) {
|
||||
newValue = func.apply(newValue)
|
||||
}
|
||||
|
||||
return newValue
|
||||
}
|
||||
|
||||
fun <T : Number> apply(funcs: Collection<BoundMatterFunction<T>>, value: T): T {
|
||||
return apply(value, funcs)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun <T : Number> Collection<BoundMatterFunction<T>>.apply(value: T): T {
|
||||
return BoundMatterFunction.apply(this, value)
|
||||
}
|
@ -112,24 +112,24 @@ open class MatterDataProvider(protected val dataGenerator: DataGenerator, val na
|
||||
}
|
||||
|
||||
class UpdateConfiguration(name: ResourceLocation) : Configuration(name) {
|
||||
val matterFunctions = ArrayList<UpdateAction.BoundFunction<ImpreciseFraction>>()
|
||||
val complexityFunctions = ArrayList<UpdateAction.BoundFunction<Double>>()
|
||||
val priorityFunctions = ArrayList<UpdateAction.BoundFunction<Int>>()
|
||||
val matterFunctions = ArrayList<BoundMatterFunction<ImpreciseFraction>>()
|
||||
val complexityFunctions = ArrayList<BoundMatterFunction<Double>>()
|
||||
val priorityFunctions = ArrayList<BoundMatterFunction<Int>>()
|
||||
|
||||
fun addMatterFunction(function: UpdateAction.Function, value: ImpreciseFraction): UpdateConfiguration {
|
||||
matterFunctions.add(UpdateAction.BoundFunction(function, value))
|
||||
fun addMatterFunction(function: MatterFunction, value: ImpreciseFraction): UpdateConfiguration {
|
||||
matterFunctions.add(BoundMatterFunction(function, value))
|
||||
matter = null
|
||||
return this
|
||||
}
|
||||
|
||||
fun addComplexityFunction(function: UpdateAction.Function, value: Double): UpdateConfiguration {
|
||||
complexityFunctions.add(UpdateAction.BoundFunction(function, value))
|
||||
fun addComplexityFunction(function: MatterFunction, value: Double): UpdateConfiguration {
|
||||
complexityFunctions.add(BoundMatterFunction(function, value))
|
||||
matter = null
|
||||
return this
|
||||
}
|
||||
|
||||
fun addPriorityFunction(function: UpdateAction.Function, value: Int): UpdateConfiguration {
|
||||
priorityFunctions.add(UpdateAction.BoundFunction(function, value))
|
||||
fun addPriorityFunction(function: MatterFunction, value: Int): UpdateConfiguration {
|
||||
priorityFunctions.add(BoundMatterFunction(function, value))
|
||||
matter = null
|
||||
return this
|
||||
}
|
||||
|
@ -0,0 +1,76 @@
|
||||
package ru.dbotthepony.mc.otm.matter
|
||||
|
||||
import com.google.gson.JsonParseException
|
||||
import ru.dbotthepony.mc.otm.core.ImpreciseFraction
|
||||
import ru.dbotthepony.mc.otm.core.integerDivisionDown
|
||||
import ru.dbotthepony.mc.otm.core.integerDivisionUp
|
||||
|
||||
enum class MatterFunction {
|
||||
ADD {
|
||||
override fun updateValue(self: Int, other: Int): Int = self + other
|
||||
override fun updateValue(self: ImpreciseFraction, other: ImpreciseFraction): ImpreciseFraction = self + other
|
||||
override fun updateValue(self: Double, other: Double): Double = self + other
|
||||
},
|
||||
SUBTRACT {
|
||||
override fun updateValue(self: Int, other: Int): Int = self - other
|
||||
override fun updateValue(self: ImpreciseFraction, other: ImpreciseFraction): ImpreciseFraction = self - other
|
||||
override fun updateValue(self: Double, other: Double): Double = self - other
|
||||
},
|
||||
MULTIPLY {
|
||||
override fun updateValue(self: Int, other: Int): Int = self * other
|
||||
override fun updateValue(self: ImpreciseFraction, other: ImpreciseFraction): ImpreciseFraction = self * other
|
||||
override fun updateValue(self: Double, other: Double): Double = self * other
|
||||
},
|
||||
DIVIDE {
|
||||
override fun updateValue(self: Int, other: Int): Int = self / other
|
||||
override fun updateValue(self: ImpreciseFraction, other: ImpreciseFraction): ImpreciseFraction = self / other
|
||||
override fun updateValue(self: Double, other: Double): Double = self / other
|
||||
},
|
||||
DIVIDE_UP {
|
||||
override fun updateValue(self: Int, other: Int): Int = integerDivisionUp(self, other)
|
||||
override fun updateValue(self: ImpreciseFraction, other: ImpreciseFraction): ImpreciseFraction = throw JsonParseException(
|
||||
"Integer division up is available only for integers"
|
||||
)
|
||||
override fun updateValue(self: Double, other: Double): Double = throw JsonParseException(
|
||||
"Integer division up is available only for integers"
|
||||
)
|
||||
},
|
||||
DIVIDE_DOWN {
|
||||
override fun updateValue(self: Int, other: Int): Int = integerDivisionDown(self, other)
|
||||
override fun updateValue(self: ImpreciseFraction, other: ImpreciseFraction): ImpreciseFraction = throw JsonParseException(
|
||||
"Integer division down is available only for integers"
|
||||
)
|
||||
override fun updateValue(self: Double, other: Double): Double = throw JsonParseException(
|
||||
"Integer division down is available only for integers"
|
||||
)
|
||||
},
|
||||
MODULO {
|
||||
override fun updateValue(self: Int, other: Int): Int = self % other
|
||||
override fun updateValue(self: ImpreciseFraction, other: ImpreciseFraction): ImpreciseFraction = self % other
|
||||
override fun updateValue(self: Double, other: Double): Double = self % other
|
||||
},
|
||||
AT_LEAST {
|
||||
override fun updateValue(self: Int, other: Int): Int = self.coerceAtLeast(other)
|
||||
override fun updateValue(self: ImpreciseFraction, other: ImpreciseFraction): ImpreciseFraction = self.coerceAtLeast(other)
|
||||
override fun updateValue(self: Double, other: Double): Double = self.coerceAtLeast(other)
|
||||
},
|
||||
AT_MOST {
|
||||
override fun updateValue(self: Int, other: Int): Int = self.coerceAtMost(other)
|
||||
override fun updateValue(self: ImpreciseFraction, other: ImpreciseFraction): ImpreciseFraction = self.coerceAtMost(other)
|
||||
override fun updateValue(self: Double, other: Double): Double = self.coerceAtMost(other)
|
||||
},
|
||||
;
|
||||
|
||||
protected abstract fun updateValue(self: Int, other: Int): Int
|
||||
protected abstract fun updateValue(self: ImpreciseFraction, other: ImpreciseFraction): ImpreciseFraction
|
||||
protected abstract fun updateValue(self: Double, other: Double): Double
|
||||
|
||||
fun <T : Number> updateValue(self: T, other: T): T {
|
||||
return when (self) {
|
||||
is ImpreciseFraction -> updateValue(self, other)
|
||||
is Double -> updateValue(self, other)
|
||||
is Int -> updateValue(self, other)
|
||||
else -> throw RuntimeException("Unknown number type: ${self::class.qualifiedName}")
|
||||
}
|
||||
}
|
||||
}
|
@ -113,6 +113,18 @@ object MatterManager : SimpleJsonResourceReloadListener(GsonBuilder().setPrettyP
|
||||
private val computedEntries = Reference2ObjectOpenHashMap<Item, Entry>()
|
||||
val computedEntriesView: Map<Item, Entry> = Collections.unmodifiableMap(computedEntries)
|
||||
|
||||
fun searchKeyEntry(index: ResourceLocation): KeyEntry? {
|
||||
return keyEntries[index]
|
||||
}
|
||||
|
||||
fun searchTagEntry(index: ResourceLocation): TagEntry? {
|
||||
return tagEntries.firstOrNull { it.tag.location == index }
|
||||
}
|
||||
|
||||
fun searchTagEntry(index: TagKey<Item>): TagEntry? {
|
||||
return tagEntries.firstOrNull { it.tag == index }
|
||||
}
|
||||
|
||||
private fun doGetDirectInner(value: Item): Entry? {
|
||||
val key = value.registryName ?: throw NullPointerException("$value has no registry name!")
|
||||
|
||||
|
@ -9,157 +9,14 @@ import net.minecraft.resources.ResourceLocation
|
||||
import net.minecraft.tags.TagKey
|
||||
import net.minecraft.world.item.Item
|
||||
import ru.dbotthepony.mc.otm.core.ImpreciseFraction
|
||||
import ru.dbotthepony.mc.otm.core.integerDivisionDown
|
||||
import ru.dbotthepony.mc.otm.core.integerDivisionUp
|
||||
import ru.dbotthepony.mc.otm.core.set
|
||||
import ru.dbotthepony.mc.otm.data.stream
|
||||
import ru.dbotthepony.mc.otm.matter.BoundMatterFunction.Companion.deserializeFunctionTree
|
||||
|
||||
class UpdateAction : AbstractRegistryAction {
|
||||
enum class Function {
|
||||
ADD {
|
||||
override fun updateValue(self: Int, other: Int): Int = self + other
|
||||
override fun updateValue(self: ImpreciseFraction, other: ImpreciseFraction): ImpreciseFraction = self + other
|
||||
override fun updateValue(self: Double, other: Double): Double = self + other
|
||||
},
|
||||
SUBTRACT {
|
||||
override fun updateValue(self: Int, other: Int): Int = self - other
|
||||
override fun updateValue(self: ImpreciseFraction, other: ImpreciseFraction): ImpreciseFraction = self - other
|
||||
override fun updateValue(self: Double, other: Double): Double = self - other
|
||||
},
|
||||
MULTIPLY {
|
||||
override fun updateValue(self: Int, other: Int): Int = self * other
|
||||
override fun updateValue(self: ImpreciseFraction, other: ImpreciseFraction): ImpreciseFraction = self * other
|
||||
override fun updateValue(self: Double, other: Double): Double = self * other
|
||||
},
|
||||
DIVIDE {
|
||||
override fun updateValue(self: Int, other: Int): Int = self / other
|
||||
override fun updateValue(self: ImpreciseFraction, other: ImpreciseFraction): ImpreciseFraction = self / other
|
||||
override fun updateValue(self: Double, other: Double): Double = self / other
|
||||
},
|
||||
DIVIDE_UP {
|
||||
override fun updateValue(self: Int, other: Int): Int = integerDivisionUp(self, other)
|
||||
override fun updateValue(self: ImpreciseFraction, other: ImpreciseFraction): ImpreciseFraction = throw JsonParseException(
|
||||
"Integer division up is available only for integers"
|
||||
)
|
||||
override fun updateValue(self: Double, other: Double): Double = throw JsonParseException(
|
||||
"Integer division up is available only for integers"
|
||||
)
|
||||
},
|
||||
DIVIDE_DOWN {
|
||||
override fun updateValue(self: Int, other: Int): Int = integerDivisionDown(self, other)
|
||||
override fun updateValue(self: ImpreciseFraction, other: ImpreciseFraction): ImpreciseFraction = throw JsonParseException(
|
||||
"Integer division down is available only for integers"
|
||||
)
|
||||
override fun updateValue(self: Double, other: Double): Double = throw JsonParseException(
|
||||
"Integer division down is available only for integers"
|
||||
)
|
||||
},
|
||||
MODULO {
|
||||
override fun updateValue(self: Int, other: Int): Int = self % other
|
||||
override fun updateValue(self: ImpreciseFraction, other: ImpreciseFraction): ImpreciseFraction = self % other
|
||||
override fun updateValue(self: Double, other: Double): Double = self % other
|
||||
},
|
||||
AT_LEAST {
|
||||
override fun updateValue(self: Int, other: Int): Int = self.coerceAtLeast(other)
|
||||
override fun updateValue(self: ImpreciseFraction, other: ImpreciseFraction): ImpreciseFraction = self.coerceAtLeast(other)
|
||||
override fun updateValue(self: Double, other: Double): Double = self.coerceAtLeast(other)
|
||||
},
|
||||
AT_MOST {
|
||||
override fun updateValue(self: Int, other: Int): Int = self.coerceAtMost(other)
|
||||
override fun updateValue(self: ImpreciseFraction, other: ImpreciseFraction): ImpreciseFraction = self.coerceAtMost(other)
|
||||
override fun updateValue(self: Double, other: Double): Double = self.coerceAtMost(other)
|
||||
},
|
||||
;
|
||||
|
||||
protected abstract fun updateValue(self: Int, other: Int): Int
|
||||
protected abstract fun updateValue(self: ImpreciseFraction, other: ImpreciseFraction): ImpreciseFraction
|
||||
protected abstract fun updateValue(self: Double, other: Double): Double
|
||||
|
||||
fun <T : Number> updateValue(self: T, other: T): T {
|
||||
return when (self) {
|
||||
is ImpreciseFraction -> updateValue(self, other)
|
||||
is Double -> updateValue(self, other)
|
||||
is Int -> updateValue(self, other)
|
||||
else -> throw RuntimeException("Unknown number type: ${self::class.qualifiedName}")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class BoundFunction<T : Number>(val function: Function, val value: T) {
|
||||
fun apply(self: T): T {
|
||||
return function.updateValue(self, value)
|
||||
}
|
||||
|
||||
fun toJson(): JsonObject {
|
||||
return JsonObject().also {
|
||||
it["type"] = function.name
|
||||
|
||||
if (value is Int || value is Double)
|
||||
it["value"] = value
|
||||
else
|
||||
it["value"] = value.toString()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
inline fun <reified T : Number> getValue(value: JsonElement): T {
|
||||
return when (T::class) {
|
||||
ImpreciseFraction::class -> ImpreciseFraction(value.asString) as T
|
||||
Double::class -> value.asDouble as T
|
||||
Int::class -> value.asInt as T
|
||||
else -> throw RuntimeException("Unknown number type: ${T::class.qualifiedName}")
|
||||
}
|
||||
}
|
||||
|
||||
inline fun <reified T : Number> deserializeFunctionTree(input: JsonElement?, name: String): List<BoundFunction<T>> {
|
||||
if (input == null) {
|
||||
return listOf()
|
||||
}
|
||||
|
||||
if (input !is JsonArray) {
|
||||
throw JsonParseException("Expected $name to be JsonArray, ${input::class.qualifiedName} given")
|
||||
}
|
||||
|
||||
return input.stream().map {
|
||||
if (it !is JsonObject) {
|
||||
throw JsonParseException("All elements in function tree must be JsonObjects, ${it::class.qualifiedName} given")
|
||||
}
|
||||
|
||||
val type = it["type"]?.asString ?: throw JsonParseException("Invalid `type` value in function object")
|
||||
val value = it["value"] ?: throw JsonParseException("Missing `value` value in function object")
|
||||
|
||||
val parsedValue: T = getValue(value)
|
||||
val fn: Function
|
||||
|
||||
try {
|
||||
fn = Function.valueOf(type.uppercase())
|
||||
} catch (err: NoSuchElementException) {
|
||||
throw JsonParseException("No such function: $type", err)
|
||||
}
|
||||
|
||||
return@map BoundFunction(fn, parsedValue)
|
||||
}.collect(ImmutableList.toImmutableList())
|
||||
}
|
||||
|
||||
fun <T : Number> apply(value: T, funcs: Collection<BoundFunction<T>>): T {
|
||||
if (funcs.isEmpty()) {
|
||||
return value
|
||||
}
|
||||
|
||||
var newValue = value
|
||||
|
||||
for (func in funcs) {
|
||||
newValue = func.apply(newValue)
|
||||
}
|
||||
|
||||
return newValue
|
||||
}
|
||||
}
|
||||
|
||||
val matterFunctions: List<BoundFunction<ImpreciseFraction>>
|
||||
val complexityFunctions: List<BoundFunction<Double>>
|
||||
val priorityFunctions: List<BoundFunction<Int>>
|
||||
val matterFunctions: List<BoundMatterFunction<ImpreciseFraction>>
|
||||
val complexityFunctions: List<BoundMatterFunction<Double>>
|
||||
val priorityFunctions: List<BoundMatterFunction<Int>>
|
||||
|
||||
constructor(json: JsonObject) : super(json) {
|
||||
matterFunctions = deserializeFunctionTree(json["matter_functions"], "matter_functions")
|
||||
@ -173,9 +30,9 @@ class UpdateAction : AbstractRegistryAction {
|
||||
complexity: Double? = null,
|
||||
priority: Int? = null,
|
||||
errorOnFailure: Boolean = false,
|
||||
matterFunctions: List<BoundFunction<ImpreciseFraction>> = ImmutableList.of(),
|
||||
complexityFunctions: List<BoundFunction<Double>> = ImmutableList.of(),
|
||||
priorityFunctions: List<BoundFunction<Int>> = ImmutableList.of(),
|
||||
matterFunctions: List<BoundMatterFunction<ImpreciseFraction>> = ImmutableList.of(),
|
||||
complexityFunctions: List<BoundMatterFunction<Double>> = ImmutableList.of(),
|
||||
priorityFunctions: List<BoundMatterFunction<Int>> = ImmutableList.of(),
|
||||
) : super(tag = tag, matter = matter, complexity = complexity, priority = priority, errorOnFailure = errorOnFailure) {
|
||||
check(matter != null || complexity != null || priority != null || matterFunctions.isNotEmpty() || complexityFunctions.isNotEmpty() || priorityFunctions.isNotEmpty()) {
|
||||
"Can't update existing entries without anything specified"
|
||||
@ -192,9 +49,9 @@ class UpdateAction : AbstractRegistryAction {
|
||||
complexity: Double? = null,
|
||||
priority: Int? = null,
|
||||
errorOnFailure: Boolean = false,
|
||||
matterFunctions: List<BoundFunction<ImpreciseFraction>> = ImmutableList.of(),
|
||||
complexityFunctions: List<BoundFunction<Double>> = ImmutableList.of(),
|
||||
priorityFunctions: List<BoundFunction<Int>> = ImmutableList.of(),
|
||||
matterFunctions: List<BoundMatterFunction<ImpreciseFraction>> = ImmutableList.of(),
|
||||
complexityFunctions: List<BoundMatterFunction<Double>> = ImmutableList.of(),
|
||||
priorityFunctions: List<BoundMatterFunction<Int>> = ImmutableList.of(),
|
||||
) : super(key = key, matter = matter, complexity = complexity, priority = priority, errorOnFailure = errorOnFailure) {
|
||||
check(matter != null || complexity != null || priority != null || matterFunctions.isNotEmpty() || complexityFunctions.isNotEmpty() || priorityFunctions.isNotEmpty()) {
|
||||
"Can't update existing entries without anything specified"
|
||||
@ -237,17 +94,17 @@ class UpdateAction : AbstractRegistryAction {
|
||||
|
||||
fun apply(value: MatterManager.MutableEntry, modifier: ResourceLocation) {
|
||||
if (matterFunctions.isNotEmpty())
|
||||
value.matter = apply(value.matter, matterFunctions)
|
||||
value.matter = matterFunctions.apply(value.matter)
|
||||
else if (matter != null)
|
||||
value.matter = matter
|
||||
|
||||
if (complexityFunctions.isNotEmpty())
|
||||
value.complexity = apply(value.complexity, complexityFunctions)
|
||||
value.complexity = complexityFunctions.apply(value.complexity)
|
||||
else if (complexity != null)
|
||||
value.complexity = complexity
|
||||
|
||||
if (priorityFunctions.isNotEmpty())
|
||||
value.priority = apply(value.priority, priorityFunctions)
|
||||
value.priority = priorityFunctions.apply(value.priority)
|
||||
else if (priority != null)
|
||||
value.priority = priority
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user