Undo caching of enum value codec

This commit is contained in:
DBotThePony 2023-03-06 18:18:02 +07:00
parent 59f275c91e
commit b063175b8c
Signed by: DBot
GPG Key ID: DCC23B5715498507
3 changed files with 19 additions and 37 deletions

View File

@ -6,7 +6,6 @@ import com.mojang.serialization.Codec
import com.mojang.serialization.DataResult import com.mojang.serialization.DataResult
import com.mojang.serialization.DynamicOps import com.mojang.serialization.DynamicOps
import net.minecraft.nbt.NbtAccounter import net.minecraft.nbt.NbtAccounter
import net.minecraft.util.StringRepresentable
import net.minecraft.world.item.ItemStack import net.minecraft.world.item.ItemStack
import ru.dbotthepony.mc.otm.core.immutableMap import ru.dbotthepony.mc.otm.core.immutableMap
import ru.dbotthepony.mc.otm.core.math.readDecimal import ru.dbotthepony.mc.otm.core.math.readDecimal
@ -87,14 +86,14 @@ val LongValueCodec = StreamCodec(DataInputStream::readLong, 8L, DataOutputStream
val FloatValueCodec = StreamCodec(DataInputStream::readFloat, 4L, DataOutputStream::writeFloat) val FloatValueCodec = StreamCodec(DataInputStream::readFloat, 4L, DataOutputStream::writeFloat)
val DoubleValueCodec = StreamCodec(DataInputStream::readDouble, 8L, DataOutputStream::writeDouble) val DoubleValueCodec = StreamCodec(DataInputStream::readDouble, 8L, DataOutputStream::writeDouble)
val ItemStackValueCodec = StreamCodec(DataInputStream::readItem, DataOutputStream::writeItem, ItemStack::copy) { a, b -> a.equals(b, true) } val ItemStackValueCodec = StreamCodec(DataInputStream::readItem, DataOutputStream::writeItem, ItemStack::copy) { a, b -> a.equals(b, true) }
val ImpreciseFractionValueCodec = StreamCodec(DataInputStream::readDecimal, DataOutputStream::writeDecimal) val DecimalValueCodec = StreamCodec(DataInputStream::readDecimal, DataOutputStream::writeDecimal)
val BigDecimalValueCodec = StreamCodec(DataInputStream::readBigDecimal, DataOutputStream::writeBigDecimal) val BigDecimalValueCodec = StreamCodec(DataInputStream::readBigDecimal, DataOutputStream::writeBigDecimal)
val UUIDValueCodec = StreamCodec({ s, a -> a.accountBytes(8L); UUID(s.readLong(), s.readLong()) }, { s, v -> s.writeLong(v.mostSignificantBits); s.writeLong(v.leastSignificantBits) }) val UUIDValueCodec = StreamCodec({ s, a -> a.accountBytes(8L); UUID(s.readLong(), s.readLong()) }, { s, v -> s.writeLong(v.mostSignificantBits); s.writeLong(v.leastSignificantBits) })
val VarIntValueCodec = StreamCodec(DataInputStream::readVarIntLE, DataOutputStream::writeVarIntLE) val VarIntValueCodec = StreamCodec(DataInputStream::readVarIntLE, DataOutputStream::writeVarIntLE)
val VarLongValueCodec = StreamCodec(DataInputStream::readVarLongLE, DataOutputStream::writeVarLongLE) val VarLongValueCodec = StreamCodec(DataInputStream::readVarLongLE, DataOutputStream::writeVarLongLE)
val BinaryStringCodec = StreamCodec(DataInputStream::readBinaryString, DataOutputStream::writeBinaryString) val BinaryStringCodec = StreamCodec(DataInputStream::readBinaryString, DataOutputStream::writeBinaryString)
class EnumValueCodec<V : Enum<V>> private constructor(clazz: Class<out V>) : IStreamCodec<V>, Codec<V> { class EnumValueCodec<V : Enum<V>>(clazz: Class<out V>) : IStreamCodec<V>, Codec<V> {
val clazz = searchClass(clazz) val clazz = searchClass(clazz)
val values: ImmutableList<V> = ImmutableList.copyOf(this.clazz.enumConstants!!) val values: ImmutableList<V> = ImmutableList.copyOf(this.clazz.enumConstants!!)
val valuesMap = immutableMap { val valuesMap = immutableMap {
@ -137,22 +136,6 @@ class EnumValueCodec<V : Enum<V>> private constructor(clazz: Class<out V>) : ISt
} }
companion object { companion object {
private val codecs = WeakHashMap<Class<*>, EnumValueCodec<*>>()
fun <T : Enum<T>> of(clazz: Class<out T>): EnumValueCodec<T> {
synchronized(codecs) {
val search = searchClass(clazz)
if (search !== clazz) {
val result = codecs.computeIfAbsent(search) { EnumValueCodec(it as Class<T>) } as EnumValueCodec<T>
codecs.putIfAbsent(clazz, result)
return result
}
return codecs.computeIfAbsent(clazz) { EnumValueCodec(it as Class<T>) } as EnumValueCodec<T>
}
}
/** /**
* FIXME: enums with abstract methods which get compiled to subclasses, whose DO NOT expose "parent's" enum constants array * FIXME: enums with abstract methods which get compiled to subclasses, whose DO NOT expose "parent's" enum constants array
* *
@ -174,8 +157,8 @@ class EnumValueCodec<V : Enum<V>> private constructor(clazz: Class<out V>) : ISt
} }
} }
fun <E : Enum<E>> Class<E>.codec() = EnumValueCodec.of(this) fun <E : Enum<E>> Class<E>.codec() = EnumValueCodec(this)
fun <E : Enum<E>> KClass<E>.codec() = EnumValueCodec.of(this.java) fun <E : Enum<E>> KClass<E>.codec() = EnumValueCodec(this.java)
fun OutputStream.writeInt(value: Int) { fun OutputStream.writeInt(value: Int) {
if (this is DataOutput) { if (this is DataOutput) {
@ -376,7 +359,7 @@ private val codecs: List<IndexedStreamCodec<*>> = com.google.common.collect.Immu
it.add(IndexedStreamCodec(codecID++, FloatValueCodec)) it.add(IndexedStreamCodec(codecID++, FloatValueCodec))
it.add(IndexedStreamCodec(codecID++, DoubleValueCodec)) it.add(IndexedStreamCodec(codecID++, DoubleValueCodec))
it.add(IndexedStreamCodec(codecID++, ItemStackValueCodec)) it.add(IndexedStreamCodec(codecID++, ItemStackValueCodec))
it.add(IndexedStreamCodec(codecID++, ImpreciseFractionValueCodec)) it.add(IndexedStreamCodec(codecID++, DecimalValueCodec))
it.add(IndexedStreamCodec(codecID++, BigDecimalValueCodec)) it.add(IndexedStreamCodec(codecID++, BigDecimalValueCodec))
it.add(IndexedStreamCodec(codecID++, UUIDValueCodec)) it.add(IndexedStreamCodec(codecID++, UUIDValueCodec))
it.add(IndexedStreamCodec(codecID++, BinaryStringCodec)) it.add(IndexedStreamCodec(codecID++, BinaryStringCodec))

View File

@ -10,7 +10,7 @@ inline fun <reified E : Enum<E>> EnumInputWithFeedback(menu: MatteryMenu, state:
inline fun <reified E : Enum<E>> EnumInputWithFeedback(menu: MatteryMenu, state: GetterSetter<E>) = EnumInputWithFeedback(menu, E::class.java, state) inline fun <reified E : Enum<E>> EnumInputWithFeedback(menu: MatteryMenu, state: GetterSetter<E>) = EnumInputWithFeedback(menu, E::class.java, state)
class EnumInputWithFeedback<E : Enum<E>>(menu: MatteryMenu, clazz: Class<E>) : AbstractPlayerInputWithFeedback<E>() { class EnumInputWithFeedback<E : Enum<E>>(menu: MatteryMenu, clazz: Class<E>) : AbstractPlayerInputWithFeedback<E>() {
val codec = EnumValueCodec.of(clazz) val codec = EnumValueCodec(clazz)
private val default = codec.values.first() private val default = codec.values.first()
override val input = menu.PlayerInput(codec, false) { consumer?.invoke(it) } override val input = menu.PlayerInput(codec, false) { consumer?.invoke(it) }

View File

@ -5,7 +5,6 @@ import it.unimi.dsi.fastutil.objects.Reference2ObjectFunction
import it.unimi.dsi.fastutil.objects.Reference2ObjectOpenHashMap import it.unimi.dsi.fastutil.objects.Reference2ObjectOpenHashMap
import it.unimi.dsi.fastutil.objects.ReferenceArraySet import it.unimi.dsi.fastutil.objects.ReferenceArraySet
import net.minecraft.world.item.ItemStack import net.minecraft.world.item.ItemStack
import org.apache.logging.log4j.LogManager
import ru.dbotthepony.mc.otm.core.* import ru.dbotthepony.mc.otm.core.*
import ru.dbotthepony.mc.otm.core.collect.ProxiedMap import ru.dbotthepony.mc.otm.core.collect.ProxiedMap
import ru.dbotthepony.mc.otm.core.math.Decimal import ru.dbotthepony.mc.otm.core.math.Decimal
@ -17,7 +16,7 @@ import ru.dbotthepony.mc.otm.core.util.DoubleValueCodec
import ru.dbotthepony.mc.otm.core.util.EnumValueCodec import ru.dbotthepony.mc.otm.core.util.EnumValueCodec
import ru.dbotthepony.mc.otm.core.util.FloatValueCodec import ru.dbotthepony.mc.otm.core.util.FloatValueCodec
import ru.dbotthepony.mc.otm.core.util.IStreamCodec import ru.dbotthepony.mc.otm.core.util.IStreamCodec
import ru.dbotthepony.mc.otm.core.util.ImpreciseFractionValueCodec import ru.dbotthepony.mc.otm.core.util.DecimalValueCodec
import ru.dbotthepony.mc.otm.core.util.IntValueCodec import ru.dbotthepony.mc.otm.core.util.IntValueCodec
import ru.dbotthepony.mc.otm.core.util.ItemStackValueCodec import ru.dbotthepony.mc.otm.core.util.ItemStackValueCodec
import ru.dbotthepony.mc.otm.core.util.LongValueCodec import ru.dbotthepony.mc.otm.core.util.LongValueCodec
@ -148,7 +147,7 @@ class FieldSynchronizer(private val callback: Runnable, private val alwaysCallCa
fun uuid(getter: () -> UUID) = ComputedField(getter, UUIDValueCodec) fun uuid(getter: () -> UUID) = ComputedField(getter, UUIDValueCodec)
fun int(getter: () -> Int) = ComputedField(getter, VarIntValueCodec) fun int(getter: () -> Int) = ComputedField(getter, VarIntValueCodec)
fun fixedInt(getter: () -> Int) = ComputedField(getter, IntValueCodec) fun fixedInt(getter: () -> Int) = ComputedField(getter, IntValueCodec)
fun fraction(getter: () -> Decimal) = ComputedField(getter, ImpreciseFractionValueCodec) fun fraction(getter: () -> Decimal) = ComputedField(getter, DecimalValueCodec)
fun bigDecimal(getter: () -> BigDecimal) = ComputedField(getter, BigDecimalValueCodec) fun bigDecimal(getter: () -> BigDecimal) = ComputedField(getter, BigDecimalValueCodec)
fun item(getter: () -> ItemStack) = ComputedField(getter, ItemStackValueCodec) fun item(getter: () -> ItemStack) = ComputedField(getter, ItemStackValueCodec)
fun string(getter: () -> String) = ComputedField(getter, BinaryStringCodec) fun string(getter: () -> String) = ComputedField(getter, BinaryStringCodec)
@ -163,7 +162,7 @@ class FieldSynchronizer(private val callback: Runnable, private val alwaysCallCa
fun uuid(getter: KProperty0<UUID>) = ComputedField(getter, UUIDValueCodec) fun uuid(getter: KProperty0<UUID>) = ComputedField(getter, UUIDValueCodec)
fun int(getter: KProperty0<Int>) = ComputedField(getter, VarIntValueCodec) fun int(getter: KProperty0<Int>) = ComputedField(getter, VarIntValueCodec)
fun fixedInt(getter: KProperty0<Int>) = ComputedField(getter, IntValueCodec) fun fixedInt(getter: KProperty0<Int>) = ComputedField(getter, IntValueCodec)
fun fraction(getter: KProperty0<Decimal>) = ComputedField(getter, ImpreciseFractionValueCodec) fun fraction(getter: KProperty0<Decimal>) = ComputedField(getter, DecimalValueCodec)
fun bigDecimal(getter: KProperty0<BigDecimal>) = ComputedField(getter, BigDecimalValueCodec) fun bigDecimal(getter: KProperty0<BigDecimal>) = ComputedField(getter, BigDecimalValueCodec)
fun item(getter: KProperty0<ItemStack>) = ComputedField(getter, ItemStackValueCodec) fun item(getter: KProperty0<ItemStack>) = ComputedField(getter, ItemStackValueCodec)
fun string(getter: KProperty0<String>) = ComputedField(getter, BinaryStringCodec) fun string(getter: KProperty0<String>) = ComputedField(getter, BinaryStringCodec)
@ -178,19 +177,19 @@ class FieldSynchronizer(private val callback: Runnable, private val alwaysCallCa
fun uuid(getter: Supplier<UUID>) = ComputedField(getter::get, UUIDValueCodec) fun uuid(getter: Supplier<UUID>) = ComputedField(getter::get, UUIDValueCodec)
fun int(getter: Supplier<Int>) = ComputedField(getter::get, VarIntValueCodec) fun int(getter: Supplier<Int>) = ComputedField(getter::get, VarIntValueCodec)
fun fixedInt(getter: Supplier<Int>) = ComputedField(getter::get, IntValueCodec) fun fixedInt(getter: Supplier<Int>) = ComputedField(getter::get, IntValueCodec)
fun fraction(getter: Supplier<Decimal>) = ComputedField(getter::get, ImpreciseFractionValueCodec) fun fraction(getter: Supplier<Decimal>) = ComputedField(getter::get, DecimalValueCodec)
fun bigDecimal(getter: Supplier<BigDecimal>) = ComputedField(getter::get, BigDecimalValueCodec) fun bigDecimal(getter: Supplier<BigDecimal>) = ComputedField(getter::get, BigDecimalValueCodec)
fun item(getter: Supplier<ItemStack>) = ComputedField(getter::get, ItemStackValueCodec) fun item(getter: Supplier<ItemStack>) = ComputedField(getter::get, ItemStackValueCodec)
fun string(getter: Supplier<String>) = ComputedField(getter::get, BinaryStringCodec) fun string(getter: Supplier<String>) = ComputedField(getter::get, BinaryStringCodec)
fun <T : Enum<T>> enum(type: Class<T>, getter: () -> T) = ComputedField(getter, EnumValueCodec.of(type)) fun <T : Enum<T>> enum(type: Class<T>, getter: () -> T) = ComputedField(getter, EnumValueCodec(type))
inline fun <reified T : Enum<T>> enum(noinline getter: () -> T) = ComputedField(getter, EnumValueCodec.of(T::class.java)) inline fun <reified T : Enum<T>> enum(noinline getter: () -> T) = ComputedField(getter, EnumValueCodec(T::class.java))
fun <T : Enum<T>> enum(type: Class<T>, getter: KProperty0<T>) = ComputedField(getter, EnumValueCodec.of(type)) fun <T : Enum<T>> enum(type: Class<T>, getter: KProperty0<T>) = ComputedField(getter, EnumValueCodec(type))
inline fun <reified T : Enum<T>> enum(getter: KProperty0<T>) = ComputedField(getter, EnumValueCodec.of(T::class.java)) inline fun <reified T : Enum<T>> enum(getter: KProperty0<T>) = ComputedField(getter, EnumValueCodec(T::class.java))
fun <T : Enum<T>> enum(type: Class<T>, getter: Supplier<T>) = ComputedField(getter::get, EnumValueCodec.of(type)) fun <T : Enum<T>> enum(type: Class<T>, getter: Supplier<T>) = ComputedField(getter::get, EnumValueCodec(type))
inline fun <reified T : Enum<T>> enum(getter: Supplier<T>) = ComputedField(getter::get, EnumValueCodec.of(T::class.java)) inline fun <reified T : Enum<T>> enum(getter: Supplier<T>) = ComputedField(getter::get, EnumValueCodec(T::class.java))
@JvmOverloads @JvmOverloads
fun byte( fun byte(
@ -309,7 +308,7 @@ class FieldSynchronizer(private val callback: Runnable, private val alwaysCallCa
setter: FieldSetter<Decimal>? = null, setter: FieldSetter<Decimal>? = null,
): Field<Decimal> { ): Field<Decimal> {
return Field(value, ImpreciseFractionValueCodec, getter, setter) return Field(value, DecimalValueCodec, getter, setter)
} }
@JvmOverloads @JvmOverloads
@ -330,7 +329,7 @@ class FieldSynchronizer(private val callback: Runnable, private val alwaysCallCa
setter: FieldSetter<T>? = null, setter: FieldSetter<T>? = null,
): Field<T> { ): Field<T> {
return Field(value, EnumValueCodec.of(type), getter, setter) return Field(value, EnumValueCodec(type), getter, setter)
} }
@JvmOverloads @JvmOverloads
@ -340,7 +339,7 @@ class FieldSynchronizer(private val callback: Runnable, private val alwaysCallCa
setter: FieldSetter<T>? = null, setter: FieldSetter<T>? = null,
): Field<T> { ): Field<T> {
return Field(value, EnumValueCodec.of(value::class.java), getter, setter) return Field(value, EnumValueCodec(value::class.java), getter, setter)
} }
@JvmOverloads @JvmOverloads