@@ -22,6 +22,7 @@ import com.lambda.context.SafeContext
2222import com.lambda.core.Loadable
2323import com.lambda.event.events.KeyboardEvent
2424import com.lambda.event.events.MouseEvent
25+ import it.unimi.dsi.fastutil.ints.Int2IntArrayMap
2526import org.lwjgl.glfw.GLFW
2627import org.lwjgl.glfw.GLFW.GLFW_KEY_LEFT_ALT
2728import org.lwjgl.glfw.GLFW.GLFW_KEY_LEFT_CONTROL
@@ -38,21 +39,7 @@ import org.lwjgl.glfw.GLFW.glfwGetKey
3839import org.lwjgl.glfw.GLFW.glfwGetMouseButton
3940
4041object InputUtils : Loadable {
41- private val keys = KeyCode .entries.map { it.code }
42- private val scancodes = keys.associateWith { GLFW .glfwGetKeyScancode(it) }
43-
44- private val mouses = GLFW_MOUSE_BUTTON_1 .. GLFW_MOUSE_BUTTON_8
45-
46- private val modMap = mapOf (
47- GLFW_KEY_LEFT_SHIFT to 0x1 ,
48- GLFW_KEY_RIGHT_SHIFT to 0x1 ,
49- GLFW_KEY_LEFT_CONTROL to 0x2 ,
50- GLFW_KEY_RIGHT_CONTROL to 0x2 ,
51- GLFW_KEY_LEFT_ALT to 0x4 ,
52- GLFW_KEY_RIGHT_ALT to 0x4 ,
53- GLFW_KEY_LEFT_SUPER to 0x8 ,
54- GLFW_KEY_RIGHT_SUPER to 0x8 ,
55- )
42+ private val lastPressedKeys = Int2IntArrayMap () // Keep track of the previously pressed keys to report GLFW_RELEASE states
5643
5744 /* *
5845 * Returns whether any of the key-codes (not scan-codes) are being pressed
@@ -61,15 +48,23 @@ object InputUtils : Loadable {
6148 keys.any { glfwGetKey(mc.window.handle, it) >= GLFW_PRESS }
6249
6350 /* *
64- * Creates a new event from the currently pressed keys
51+ * Creates a new event from the currently pressed keys.
52+ * Note: This function is extremely expensive to execute, it is recommended to not use
53+ * it unless you absolutely need to. Additionally, you might screw with the key cache.
6554 */
6655 fun newKeyboardEvent (): KeyboardEvent .Press ? {
6756 val pressedKeys = keys
6857 .associateWith { glfwGetKey(mc.window.handle, it) }
69- .filter { (_, state) -> state >= GLFW_PRESS }
58+ .filter { (key, state) -> state >= GLFW_PRESS || lastPressedKeys[key] >= GLFW_PRESS }
59+ .also { lastPressedKeys.clear() }
60+ .onEach { (key, state) -> lastPressedKeys[key] = state }
61+
62+ // FixMe: If you are pressing two or more keys considered 'modifier' keys, you must release both of them at the
63+ // same time in order to receive an update stipulating that the last key (not actually a modifier) was released alongside its modifiers.
64+ // For the time being, I will allow this as players can still bind unique 'modifier' keys with no issues.
7065
7166 val mods = pressedKeys.keys
72- .filter { it in GLFW_KEY_LEFT_SHIFT .. GLFW_KEY_RIGHT_SUPER }
67+ .filter { it in GLFW_KEY_LEFT_SHIFT .. GLFW_KEY_RIGHT_SUPER && lastPressedKeys.keys.firstOrNull()?.equals(it) == false }
7368 .foldRight(0 ) { v, acc -> acc or modMap.getValue(v) }
7469
7570 val key = pressedKeys
@@ -94,4 +89,20 @@ object InputUtils : Loadable {
9489
9590 return MouseEvent .Click (mouse, GLFW_PRESS , mods)
9691 }
92+
93+ private val keys = KeyCode .entries.map { it.code }
94+ private val scancodes = keys.associateWith { GLFW .glfwGetKeyScancode(it) }
95+
96+ private val mouses = GLFW_MOUSE_BUTTON_1 .. GLFW_MOUSE_BUTTON_8
97+
98+ private val modMap = mapOf (
99+ GLFW_KEY_LEFT_SHIFT to 0x1 ,
100+ GLFW_KEY_RIGHT_SHIFT to 0x1 ,
101+ GLFW_KEY_LEFT_CONTROL to 0x2 ,
102+ GLFW_KEY_RIGHT_CONTROL to 0x2 ,
103+ GLFW_KEY_LEFT_ALT to 0x4 ,
104+ GLFW_KEY_RIGHT_ALT to 0x4 ,
105+ GLFW_KEY_LEFT_SUPER to 0x8 ,
106+ GLFW_KEY_RIGHT_SUPER to 0x8 ,
107+ )
97108}
0 commit comments