diff --git a/src/integration-test/kotlin/de/bixilon/minosoft/gui/rendering/input/key/manager/InputTestUtil.kt b/src/integration-test/kotlin/de/bixilon/minosoft/gui/rendering/input/key/manager/InputTestUtil.kt index de608f184..fb2306b8f 100644 --- a/src/integration-test/kotlin/de/bixilon/minosoft/gui/rendering/input/key/manager/InputTestUtil.kt +++ b/src/integration-test/kotlin/de/bixilon/minosoft/gui/rendering/input/key/manager/InputTestUtil.kt @@ -25,8 +25,8 @@ import de.bixilon.minosoft.gui.rendering.input.key.manager.binding.actions.bindi import de.bixilon.minosoft.gui.rendering.input.key.manager.binding.actions.keysPressed import de.bixilon.minosoft.gui.rendering.system.window.KeyChangeTypes import de.bixilon.minosoft.test.IT +import de.bixilon.minosoft.util.KUtil.set import it.unimi.dsi.fastutil.objects.Object2LongOpenHashMap -import java.util.* object InputTestUtil { private val profile = BindingsManager::class.java.getDeclaredField("profile").apply { isAccessible = true } @@ -50,7 +50,7 @@ object InputTestUtil { manager::bindings.forceSet(bindings) manager::handler.forceSet(handler) this.times.forceSet(manager, Object2LongOpenHashMap().apply { defaultReturnValue(-1L) }) - keysPressed[manager] = EnumSet.noneOf(KeyCodes::class.java) + keysPressed[manager] = KeyCodes.set() return manager } diff --git a/src/integration-test/kotlin/de/bixilon/minosoft/gui/rendering/input/key/manager/binding/actions/KeyActionFilterTest.kt b/src/integration-test/kotlin/de/bixilon/minosoft/gui/rendering/input/key/manager/binding/actions/KeyActionFilterTest.kt index 5c88a5487..e0cdb9d6e 100644 --- a/src/integration-test/kotlin/de/bixilon/minosoft/gui/rendering/input/key/manager/binding/actions/KeyActionFilterTest.kt +++ b/src/integration-test/kotlin/de/bixilon/minosoft/gui/rendering/input/key/manager/binding/actions/KeyActionFilterTest.kt @@ -25,10 +25,10 @@ import de.bixilon.minosoft.gui.rendering.input.key.manager.binding.BindingsManag import de.bixilon.minosoft.gui.rendering.input.key.manager.binding.KeyBindingFilterState import de.bixilon.minosoft.gui.rendering.input.key.manager.binding.KeyBindingState import de.bixilon.minosoft.test.IT.OBJENESIS +import de.bixilon.minosoft.util.KUtil.set import org.testng.Assert.assertFalse import org.testng.Assert.assertTrue import org.testng.annotations.Test -import java.util.* val keysPressed = InputManager::class.java.getDeclaredField("pressed").apply { isAccessible = true } @@ -41,7 +41,7 @@ fun input(): InputManager { bindingsPressed[bindings] = mutableSetOf() manager::bindings.forceSet(bindings) - keysPressed[manager] = EnumSet.noneOf(KeyCodes::class.java) + keysPressed[manager] = KeyCodes.set() return manager } diff --git a/src/main/java/de/bixilon/minosoft/config/key/KeyCodes.kt b/src/main/java/de/bixilon/minosoft/config/key/KeyCodes.kt index 5c277eed3..320ef9e6c 100644 --- a/src/main/java/de/bixilon/minosoft/config/key/KeyCodes.kt +++ b/src/main/java/de/bixilon/minosoft/config/key/KeyCodes.kt @@ -13,6 +13,8 @@ package de.bixilon.minosoft.config.key +import de.bixilon.kutil.enums.EnumUtil +import de.bixilon.kutil.enums.ValuesEnum import java.util.* enum class KeyCodes { @@ -159,8 +161,9 @@ enum class KeyCodes { val keyName = name.uppercase(Locale.getDefault()).removePrefix("KEY_") - companion object { - val VALUES = values() + companion object : ValuesEnum { + override val VALUES = values() + override val NAME_MAP = EnumUtil.getEnumValues(VALUES) val KEY_CODE_MAP: Map init { diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/input/key/manager/InputManager.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/input/key/manager/InputManager.kt index b5ce90a08..632bff9c4 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/input/key/manager/InputManager.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/input/key/manager/InputManager.kt @@ -31,6 +31,7 @@ import de.bixilon.minosoft.gui.rendering.util.vec.vec2.Vec2dUtil.EMPTY import de.bixilon.minosoft.modding.EventPriorities import de.bixilon.minosoft.modding.event.listener.CallbackEventListener.Companion.listen import de.bixilon.minosoft.protocol.network.connection.play.PlayConnection +import de.bixilon.minosoft.util.KUtil.set import it.unimi.dsi.fastutil.objects.Object2LongMap import it.unimi.dsi.fastutil.objects.Object2LongOpenHashMap import java.util.* @@ -45,7 +46,7 @@ class InputManager( val interaction = InteractionManagerKeys(this, connection.camera.interactions) - private val pressed: EnumSet = EnumSet.noneOf(KeyCodes::class.java) + private val pressed: EnumSet = KeyCodes.set() private val times: Object2LongMap = Object2LongOpenHashMap().apply { defaultReturnValue(-1L) } var mousePosition: Vec2d = Vec2d.EMPTY diff --git a/src/main/java/de/bixilon/minosoft/protocol/packets/s2c/play/tab/TabListS2CP.kt b/src/main/java/de/bixilon/minosoft/protocol/packets/s2c/play/tab/TabListS2CP.kt index 49f5b5009..6a73065ed 100644 --- a/src/main/java/de/bixilon/minosoft/protocol/packets/s2c/play/tab/TabListS2CP.kt +++ b/src/main/java/de/bixilon/minosoft/protocol/packets/s2c/play/tab/TabListS2CP.kt @@ -52,7 +52,7 @@ class TabListS2CP(buffer: PlayInByteBuffer) : PlayS2CPacket { this.entries = entries } - private fun EnumSet.actions(): Array { + private fun Set.actions(): Array { val array = arrayOfNulls(this.size) for ((index, entry) in this.withIndex()) { array[index] = entry.action diff --git a/src/main/java/de/bixilon/minosoft/protocol/protocol/buffers/play/PlayInByteBuffer.kt b/src/main/java/de/bixilon/minosoft/protocol/protocol/buffers/play/PlayInByteBuffer.kt index 710e90fdf..1ac3be60a 100644 --- a/src/main/java/de/bixilon/minosoft/protocol/protocol/buffers/play/PlayInByteBuffer.kt +++ b/src/main/java/de/bixilon/minosoft/protocol/protocol/buffers/play/PlayInByteBuffer.kt @@ -14,6 +14,7 @@ package de.bixilon.minosoft.protocol.protocol.buffers.play import de.bixilon.kotlinglm.vec3.Vec3d import de.bixilon.kotlinglm.vec3.Vec3i +import de.bixilon.kutil.enums.ValuesEnum import de.bixilon.kutil.json.JsonUtil.asJsonObject import de.bixilon.kutil.json.JsonUtil.toMutableJsonObject import de.bixilon.minosoft.config.DebugOptions @@ -48,6 +49,7 @@ import de.bixilon.minosoft.protocol.protocol.buffers.InByteBuffer import de.bixilon.minosoft.protocol.protocol.encryption.CryptManager import de.bixilon.minosoft.recipes.Ingredient import de.bixilon.minosoft.util.KUtil +import de.bixilon.minosoft.util.KUtil.set import de.bixilon.minosoft.util.logging.Log import de.bixilon.minosoft.util.logging.LogLevels import de.bixilon.minosoft.util.logging.LogMessageType @@ -298,15 +300,33 @@ class PlayInByteBuffer : InByteBuffer { return MessageHeader(readOptional { readByteArray() }, readUUID()) } - inline fun > readEnumSet(values: Array): EnumSet { - val bitset = readBitSet(values.size) - val set = EnumSet.noneOf(T::class.java) - for (index in values.indices) { + inline fun > readEnumSet(enum: ValuesEnum): Set { + val bitset = readBitSet(enum.VALUES.size) + if (bitset.isEmpty) { + return emptySet() + } + val set = enum.set() + readEnumSet(bitset, set, enum.VALUES) + return set + } + + fun > readEnumSet(bitset: BitSet, set: MutableSet, values: Array) { + for (index in 0 until minOf(bitset.length(), values.size)) { if (!bitset.get(index)) { continue } set += values[index] } + } + + @Deprecated("use values enum") + inline fun > readEnumSet(values: Array): Set { + val bitset = readBitSet(values.size) + if (bitset.isEmpty) { + return emptySet() + } + val set = EnumSet.noneOf(T::class.java) + readEnumSet(bitset, set, values) return set } diff --git a/src/main/java/de/bixilon/minosoft/util/KUtil.kt b/src/main/java/de/bixilon/minosoft/util/KUtil.kt index de8bbe67b..80c61dd1e 100644 --- a/src/main/java/de/bixilon/minosoft/util/KUtil.kt +++ b/src/main/java/de/bixilon/minosoft/util/KUtil.kt @@ -28,6 +28,7 @@ import de.bixilon.kutil.collections.CollectionUtil.synchronizedSetOf import de.bixilon.kutil.collections.CollectionUtil.toSynchronizedSet import de.bixilon.kutil.concurrent.pool.DefaultThreadPool import de.bixilon.kutil.concurrent.schedule.TaskScheduler +import de.bixilon.kutil.enums.ValuesEnum import de.bixilon.kutil.latch.AbstractLatch import de.bixilon.kutil.primitive.BooleanUtil.decide import de.bixilon.kutil.primitive.DoubleUtil @@ -350,4 +351,13 @@ object KUtil { waitForChange(timeout) } } + + val REGULAR_ENUM_SET = Class.forName("java.util.RegularEnumSet").declaredConstructors.first().apply { isAccessible = true } + val JUMBO_ENUM_SET = Class.forName("java.util.RegularEnumSet").declaredConstructors.first().apply { isAccessible = true } + + @Deprecated("kutil 1.24") + inline fun > ValuesEnum.set(): EnumSet { + val clazz = if (VALUES.size <= 64) REGULAR_ENUM_SET else JUMBO_ENUM_SET + return clazz.newInstance(T::class.java, VALUES).unsafeCast() + } }