summaryrefslogtreecommitdiff
path: root/src/player-input.cpp
diff options
context:
space:
mode:
authorJonathan Bradley <jcb@pikum.xyz>2025-06-11 16:04:48 -0400
committerJonathan Bradley <jcb@pikum.xyz>2025-06-11 16:04:54 -0400
commit0f89d12e747b380b35143815a2c8e87c6ee752d4 (patch)
tree78617e7cb819093aa9c0ad107b5dc79891e8ff55 /src/player-input.cpp
parente478bae42cf886a12433331937887de4c4e85ce2 (diff)
pke: serialize PkeInput first-pass
Diffstat (limited to 'src/player-input.cpp')
-rw-r--r--src/player-input.cpp241
1 files changed, 122 insertions, 119 deletions
diff --git a/src/player-input.cpp b/src/player-input.cpp
index 8ecc2cc..252d706 100644
--- a/src/player-input.cpp
+++ b/src/player-input.cpp
@@ -79,34 +79,35 @@ PkeInputAction *FindActionByName(const char *actionName) {
}
return nullptr;
}
-template<InputEventHash T, typename S> InputEventHash FindActivePkeInputAction_ByAction(const PkeInputAction *inputAction, S *&activeEvent) {
+template<InputEventHash T, typename S> InputEventHash FindActivePkeInputAction_ByAction(const PkeInputAction *inputAction, S *&activeEvent, int32_t index) {
activeEvent = nullptr;
if constexpr((T & PKE_INPUT_HASH_EVENT_TYPE_CURSOR_ENTER) != InputEventHash{0}) {
- activeEvent = &registeredCursorEnterEvents[inputAction->eventIndex];
+ activeEvent = &registeredCursorEnterEvents[inputAction->event_indices[index]];
return PKE_INPUT_HASH_EVENT_TYPE_CURSOR_ENTER;
}
if constexpr((T & PKE_INPUT_HASH_EVENT_TYPE_CURSOR_POS) != InputEventHash{0}) {
- activeEvent = &registeredCursorPosEvents[inputAction->eventIndex];
+ activeEvent = &registeredCursorPosEvents[inputAction->event_indices[index]];
return PKE_INPUT_HASH_EVENT_TYPE_CURSOR_POS;
}
if constexpr((T & PKE_INPUT_HASH_EVENT_TYPE_KEY) != InputEventHash{0}) {
- activeEvent = &registeredKeyEvents[inputAction->eventIndex];
+ activeEvent = &registeredKeyEvents[inputAction->event_indices[index]];
return PKE_INPUT_HASH_EVENT_TYPE_KEY;
}
if constexpr((T & PKE_INPUT_HASH_EVENT_TYPE_MOUSE_BUTTON) != InputEventHash{0}) {
- activeEvent = &registeredMouseButtonEvents[inputAction->eventIndex];
+ activeEvent = &registeredMouseButtonEvents[inputAction->event_indices[index]];
return PKE_INPUT_HASH_EVENT_TYPE_MOUSE_BUTTON;
}
if constexpr((T & PKE_INPUT_HASH_EVENT_TYPE_SCROLL) != InputEventHash{0}) {
- activeEvent = &registeredScrollEvents[inputAction->eventIndex];
+ activeEvent = &registeredScrollEvents[inputAction->event_indices[index]];
return PKE_INPUT_HASH_EVENT_TYPE_SCROLL;
}
if constexpr((T & PKE_INPUT_HASH_EVENT_TYPE_WINDOW_FOCUS) != InputEventHash{0}) {
- activeEvent = &registeredWindowFocusEvents[inputAction->eventIndex];
+ activeEvent = &registeredWindowFocusEvents[inputAction->event_indices[index]];
return PKE_INPUT_HASH_EVENT_TYPE_WINDOW_FOCUS;
}
return InputEventHash{0};
}
+/*
template<InputEventHash T, typename S> InputEventHash FindActivePkeInputAction_ByName(const char *actionName, S *&activeEvent) {
activeEvent = nullptr;
bool any = false;
@@ -167,6 +168,7 @@ template<InputEventHash T, typename S> InputEventHash FindActivePkeInputAction_B
}
return InputEventHash{0};
}
+*/
template<InputEventHash T, typename S> InputEventHash FindActivePkeInputAction_ByType(const PkeInputEventMask &mask, S *&activeEvent) {
uint32_t count, i;
activeEvent = nullptr;
@@ -197,7 +199,7 @@ template<InputEventHash T, typename S> InputEventHash FindActivePkeInputAction_B
PkeInputSet &set = registeredInputSets[index];
for (int64_t k = 0; k < set.actionCount; ++k) {
PkeInputAction &inputAction = set.actions[k];
- for (int64_t l = 0; l < PKE_INPUT_ACTION_MASK_COUNT; ++l) {
+ for (int64_t l = 0; l < PKE_INPUT_ACTION_MASK_INDEX_COUNT; ++l) {
PkeInputEventMask &evMask = inputAction.masks[l];
if ((evMask.computedHash & mask.computedHash) == InputEventHash{0}) {
continue;
@@ -219,27 +221,27 @@ template<InputEventHash T, typename S> InputEventHash FindActivePkeInputAction_B
}
}
if constexpr((T & PKE_INPUT_HASH_EVENT_TYPE_CURSOR_ENTER) != InputEventHash{0}) {
- activeEvent = &registeredCursorEnterEvents[inputAction.eventIndex];
+ activeEvent = &registeredCursorEnterEvents[inputAction.event_indices[l]];
return PKE_INPUT_HASH_EVENT_TYPE_CURSOR_ENTER;
}
if constexpr((T & PKE_INPUT_HASH_EVENT_TYPE_CURSOR_POS) != InputEventHash{0}) {
- activeEvent = &registeredCursorPosEvents[inputAction.eventIndex];
+ activeEvent = &registeredCursorPosEvents[inputAction.event_indices[l]];
return PKE_INPUT_HASH_EVENT_TYPE_CURSOR_POS;
}
if constexpr((T & PKE_INPUT_HASH_EVENT_TYPE_KEY) != InputEventHash{0}) {
- activeEvent = &registeredKeyEvents[inputAction.eventIndex];
+ activeEvent = &registeredKeyEvents[inputAction.event_indices[l]];
return PKE_INPUT_HASH_EVENT_TYPE_KEY;
}
if constexpr((T & PKE_INPUT_HASH_EVENT_TYPE_MOUSE_BUTTON) != InputEventHash{0}) {
- activeEvent = &registeredMouseButtonEvents[inputAction.eventIndex];
+ activeEvent = &registeredMouseButtonEvents[inputAction.event_indices[l]];
return PKE_INPUT_HASH_EVENT_TYPE_MOUSE_BUTTON;
}
if constexpr((T & PKE_INPUT_HASH_EVENT_TYPE_SCROLL) != InputEventHash{0}) {
- activeEvent = &registeredScrollEvents[inputAction.eventIndex];
+ activeEvent = &registeredScrollEvents[inputAction.event_indices[l]];
return PKE_INPUT_HASH_EVENT_TYPE_SCROLL;
}
if constexpr((T & PKE_INPUT_HASH_EVENT_TYPE_WINDOW_FOCUS) != InputEventHash{0}) {
- activeEvent = &registeredWindowFocusEvents[inputAction.eventIndex];
+ activeEvent = &registeredWindowFocusEvents[inputAction.event_indices[l]];
return PKE_INPUT_HASH_EVENT_TYPE_WINDOW_FOCUS;
}
}
@@ -438,30 +440,39 @@ PkeInputEventHolder PkeInput_Query(const char *actionName) {
PkeInputEventBase *ev = nullptr;
auto *action = FindActionByName(actionName);
InputEventHash type = InputEventHash{0};
- if (bool(action->primaryHash.computedHash & PKE_INPUT_HASH_EVENT_TYPE_CURSOR_ENTER)) {
- PkeCursorEnterEvent *event;
- type = FindActivePkeInputAction_ByAction<PKE_INPUT_HASH_EVENT_TYPE_CURSOR_ENTER, PkeCursorEnterEvent>(action, event);
- ev = event;
- } else if (bool(action->primaryHash.computedHash & PKE_INPUT_HASH_EVENT_TYPE_CURSOR_POS)) {
- PkeCursorPosEvent *event;
- type = FindActivePkeInputAction_ByAction<PKE_INPUT_HASH_EVENT_TYPE_CURSOR_POS, PkeCursorPosEvent>(action, event);
- ev = event;
- } else if (bool(action->primaryHash.computedHash & PKE_INPUT_HASH_EVENT_TYPE_KEY)) {
- PkeKeyEvent *event;
- type = FindActivePkeInputAction_ByAction<PKE_INPUT_HASH_EVENT_TYPE_KEY, PkeKeyEvent>(action, event);
- ev = event;
- } else if (bool(action->primaryHash.computedHash & PKE_INPUT_HASH_EVENT_TYPE_MOUSE_BUTTON)) {
- PkeMouseButtonEvent *event;
- type = FindActivePkeInputAction_ByAction<PKE_INPUT_HASH_EVENT_TYPE_MOUSE_BUTTON, PkeMouseButtonEvent>(action, event);
- ev = event;
- } else if (bool(action->primaryHash.computedHash & PKE_INPUT_HASH_EVENT_TYPE_SCROLL)) {
- PkeScrollEvent *event;
- type = FindActivePkeInputAction_ByAction<PKE_INPUT_HASH_EVENT_TYPE_SCROLL, PkeScrollEvent>(action, event);
- ev = event;
- } else if (bool(action->primaryHash.computedHash & PKE_INPUT_HASH_EVENT_TYPE_WINDOW_FOCUS)) {
- PkeWindowFocusEvent *event;
- type = FindActivePkeInputAction_ByAction<PKE_INPUT_HASH_EVENT_TYPE_WINDOW_FOCUS, PkeWindowFocusEvent>(action, event);
- ev = event;
+ for (int32_t i = 0; i < PKE_INPUT_ACTION_MASK_INDEX_COUNT; ++i) {
+ PkeInputEventMask event_mask = action->masks[i];
+ if (bool(event_mask.computedHash & PKE_INPUT_HASH_EVENT_TYPE_CURSOR_ENTER)) {
+ PkeCursorEnterEvent *event;
+ type = FindActivePkeInputAction_ByAction<PKE_INPUT_HASH_EVENT_TYPE_CURSOR_ENTER, PkeCursorEnterEvent>(action, event, i);
+ ev = event;
+ break;
+ } else if (bool(event_mask.computedHash & PKE_INPUT_HASH_EVENT_TYPE_CURSOR_POS)) {
+ PkeCursorPosEvent *event;
+ type = FindActivePkeInputAction_ByAction<PKE_INPUT_HASH_EVENT_TYPE_CURSOR_POS, PkeCursorPosEvent>(action, event, i);
+ ev = event;
+ break;
+ } else if (bool(event_mask.computedHash & PKE_INPUT_HASH_EVENT_TYPE_KEY)) {
+ PkeKeyEvent *event;
+ type = FindActivePkeInputAction_ByAction<PKE_INPUT_HASH_EVENT_TYPE_KEY, PkeKeyEvent>(action, event, i);
+ ev = event;
+ break;
+ } else if (bool(event_mask.computedHash & PKE_INPUT_HASH_EVENT_TYPE_MOUSE_BUTTON)) {
+ PkeMouseButtonEvent *event;
+ type = FindActivePkeInputAction_ByAction<PKE_INPUT_HASH_EVENT_TYPE_MOUSE_BUTTON, PkeMouseButtonEvent>(action, event, i);
+ ev = event;
+ break;
+ } else if (bool(event_mask.computedHash & PKE_INPUT_HASH_EVENT_TYPE_SCROLL)) {
+ PkeScrollEvent *event;
+ type = FindActivePkeInputAction_ByAction<PKE_INPUT_HASH_EVENT_TYPE_SCROLL, PkeScrollEvent>(action, event, i);
+ ev = event;
+ break;
+ } else if (bool(event_mask.computedHash & PKE_INPUT_HASH_EVENT_TYPE_WINDOW_FOCUS)) {
+ PkeWindowFocusEvent *event;
+ type = FindActivePkeInputAction_ByAction<PKE_INPUT_HASH_EVENT_TYPE_WINDOW_FOCUS, PkeWindowFocusEvent>(action, event, i);
+ ev = event;
+ break;
+ }
}
return PkeInputEventHolder {
.type = type,
@@ -560,68 +571,55 @@ void PkeInput_ActivateSet(InputActionSetHandle handle) {
auto &set = registeredInputSets[index];
for (int64_t i = 0; i < set.actionCount; ++i) {
PkeInputAction &action = set.actions[i];
- // TODO doesn't support multiple masks - how do we align multiple event types?
- // EX: strafe with keyboard + joystick
- // creating multiple events doesn't make sense
- // - have to keep in sync - isPressed ?
- // - caller has to handle multiple scenarios
- // Maybe we need a unifying event, but that defeats the purpose of this refactor and wastes memory
- // Not to mention that the caller still has to know how to handle the unified response
- // Some combinations of event types cannot be combined, so the caller has to know to ignore certain values
- // Current design also has flaws
- // The caller explicitly casts to the correct event type because we know the event type.
- // If bindings were loaded dynamically, we would have to handle every scenario explicitly for every action
- // Godot has some similarities - is_action_pressed(name) could hide the type, and Godot expects the
- // programmer to know the input type in order to handle
- // If we went for a more query-based approach - PkeInput_GetPressCount(actionTitle) for example
- // there might be fewer oddities
- // Maybe you just have to restrict certain actions to certain input types
- if ((action.primaryHash.computedHash & PKE_INPUT_HASH_EVENT_TYPE_CURSOR_ENTER) != InputEventHash{0}) {
- action.eventIndex = registeredCursorEnterEvents.next;
- PkeCursorEnterEvent ev{};
- ev.sourceSet = handle;
- ev.isEntered = lastCursorEntered;
- pk_arr_append_t(&registeredCursorEnterEvents, ev);
- }
- if ((action.primaryHash.computedHash & PKE_INPUT_HASH_EVENT_TYPE_CURSOR_POS) != InputEventHash{0}) {
- action.eventIndex = registeredCursorPosEvents.next;
- PkeCursorPosEvent ev {};
- ev.sourceSet = handle;
- ev.xMotion = 0;
- ev.yMotion = 0;
- pk_arr_append_t(&registeredCursorPosEvents, ev);
- glfwGetCursorPos(window, &lastMousePos.x, &lastMousePos.y);
- }
- if ((action.primaryHash.computedHash & PKE_INPUT_HASH_EVENT_TYPE_KEY) != InputEventHash{0}) {
- action.eventIndex = registeredKeyEvents.next;
- PkeKeyEvent ev{};
- ev.sourceSet = handle;
- ev.button = action.primaryHash.button;
- ev.mods = action.primaryHash.mods;
- pk_arr_append_t(&registeredKeyEvents, ev);
- }
- if ((action.primaryHash.computedHash & PKE_INPUT_HASH_EVENT_TYPE_MOUSE_BUTTON) != InputEventHash{0}) {
- action.eventIndex = registeredMouseButtonEvents.next;
- PkeMouseButtonEvent ev{};
- ev.sourceSet = handle;
- ev.button = action.primaryHash.button;
- ev.mods = action.primaryHash.mods;
- pk_arr_append_t(&registeredMouseButtonEvents, ev);
- }
- if ((action.primaryHash.computedHash & PKE_INPUT_HASH_EVENT_TYPE_SCROLL) != InputEventHash{0}) {
- action.eventIndex = registeredScrollEvents.next;
- PkeScrollEvent ev{};
- ev.sourceSet = handle;
- ev.xMotion = 0;
- ev.yMotion = 0;
- pk_arr_append_t(&registeredScrollEvents, ev);
- }
- if ((action.primaryHash.computedHash & PKE_INPUT_HASH_EVENT_TYPE_WINDOW_FOCUS) != InputEventHash{0}) {
- action.eventIndex = registeredWindowFocusEvents.next;
- PkeWindowFocusEvent ev{};
- ev.sourceSet = handle;
- ev.isFocused = lastWindowFocus;
- pk_arr_append_t(&registeredWindowFocusEvents, ev);
+ for (int k = 0; k < PKE_INPUT_ACTION_MASK_INDEX_COUNT; ++k) {
+ PkeInputEventMask event_mask = action.masks[k];
+ if ((event_mask.computedHash & PKE_INPUT_HASH_EVENT_TYPE_CURSOR_ENTER) != InputEventHash{0}) {
+ action.event_indices[k] = registeredCursorEnterEvents.next;
+ PkeCursorEnterEvent ev{};
+ ev.sourceSet = handle;
+ ev.isEntered = lastCursorEntered;
+ pk_arr_append_t(&registeredCursorEnterEvents, ev);
+ }
+ if ((event_mask.computedHash & PKE_INPUT_HASH_EVENT_TYPE_CURSOR_POS) != InputEventHash{0}) {
+ action.event_indices[k] = registeredCursorPosEvents.next;
+ PkeCursorPosEvent ev {};
+ ev.sourceSet = handle;
+ ev.xMotion = 0;
+ ev.yMotion = 0;
+ pk_arr_append_t(&registeredCursorPosEvents, ev);
+ glfwGetCursorPos(window, &lastMousePos.x, &lastMousePos.y);
+ }
+ if ((event_mask.computedHash & PKE_INPUT_HASH_EVENT_TYPE_KEY) != InputEventHash{0}) {
+ action.event_indices[k] = registeredKeyEvents.next;
+ PkeKeyEvent ev{};
+ ev.sourceSet = handle;
+ ev.button = event_mask.button;
+ ev.mods = event_mask.mods;
+ pk_arr_append_t(&registeredKeyEvents, ev);
+ }
+ if ((event_mask.computedHash & PKE_INPUT_HASH_EVENT_TYPE_MOUSE_BUTTON) != InputEventHash{0}) {
+ action.event_indices[k] = registeredMouseButtonEvents.next;
+ PkeMouseButtonEvent ev{};
+ ev.sourceSet = handle;
+ ev.button = event_mask.button;
+ ev.mods = event_mask.mods;
+ pk_arr_append_t(&registeredMouseButtonEvents, ev);
+ }
+ if ((event_mask.computedHash & PKE_INPUT_HASH_EVENT_TYPE_SCROLL) != InputEventHash{0}) {
+ action.event_indices[k] = registeredScrollEvents.next;
+ PkeScrollEvent ev{};
+ ev.sourceSet = handle;
+ ev.xMotion = 0;
+ ev.yMotion = 0;
+ pk_arr_append_t(&registeredScrollEvents, ev);
+ }
+ if ((event_mask.computedHash & PKE_INPUT_HASH_EVENT_TYPE_WINDOW_FOCUS) != InputEventHash{0}) {
+ action.event_indices[k] = registeredWindowFocusEvents.next;
+ PkeWindowFocusEvent ev{};
+ ev.sourceSet = handle;
+ ev.isFocused = lastWindowFocus;
+ pk_arr_append_t(&registeredWindowFocusEvents, ev);
+ }
}
}
}
@@ -642,25 +640,26 @@ void PkeInput_DeactivateSet(InputActionSetHandle handle) {
auto &set = registeredInputSets[handleIndex];
for (int64_t i = set.actionCount - 1; i >= 0; --i) {
PkeInputAction &action = set.actions[i];
- // TODO doesn't support multiple masks - how do we align scroll + button
- // WITHOUT having two events allocated?
- if ((action.primaryHash.computedHash & PKE_INPUT_HASH_EVENT_TYPE_CURSOR_ENTER) != InputEventHash{0}) {
- pk_arr_remove_at(&registeredCursorEnterEvents, action.eventIndex);
- }
- if ((action.primaryHash.computedHash & PKE_INPUT_HASH_EVENT_TYPE_CURSOR_POS) != InputEventHash{0}) {
- pk_arr_remove_at(&registeredCursorPosEvents, action.eventIndex);
- }
- if ((action.primaryHash.computedHash & PKE_INPUT_HASH_EVENT_TYPE_KEY) != InputEventHash{0}) {
- pk_arr_remove_at(&registeredKeyEvents, action.eventIndex);
- }
- if ((action.primaryHash.computedHash & PKE_INPUT_HASH_EVENT_TYPE_MOUSE_BUTTON) != InputEventHash{0}) {
- pk_arr_remove_at(&registeredMouseButtonEvents, action.eventIndex);
- }
- if ((action.primaryHash.computedHash & PKE_INPUT_HASH_EVENT_TYPE_SCROLL) != InputEventHash{0}) {
- pk_arr_remove_at(&registeredScrollEvents, action.eventIndex);
- }
- if ((action.primaryHash.computedHash & PKE_INPUT_HASH_EVENT_TYPE_WINDOW_FOCUS) != InputEventHash{0}) {
- pk_arr_remove_at(&registeredWindowFocusEvents, action.eventIndex);
+ for (int k = 0; k < PKE_INPUT_ACTION_MASK_INDEX_COUNT; ++k) {
+ PkeInputEventMask event_mask = action.masks[k];
+ if ((event_mask.computedHash & PKE_INPUT_HASH_EVENT_TYPE_CURSOR_ENTER) != InputEventHash{0}) {
+ pk_arr_remove_at(&registeredCursorEnterEvents, action.event_indices[k]);
+ }
+ if ((event_mask.computedHash & PKE_INPUT_HASH_EVENT_TYPE_CURSOR_POS) != InputEventHash{0}) {
+ pk_arr_remove_at(&registeredCursorPosEvents, action.event_indices[k]);
+ }
+ if ((event_mask.computedHash & PKE_INPUT_HASH_EVENT_TYPE_KEY) != InputEventHash{0}) {
+ pk_arr_remove_at(&registeredKeyEvents, action.event_indices[k]);
+ }
+ if ((event_mask.computedHash & PKE_INPUT_HASH_EVENT_TYPE_MOUSE_BUTTON) != InputEventHash{0}) {
+ pk_arr_remove_at(&registeredMouseButtonEvents, action.event_indices[k]);
+ }
+ if ((event_mask.computedHash & PKE_INPUT_HASH_EVENT_TYPE_SCROLL) != InputEventHash{0}) {
+ pk_arr_remove_at(&registeredScrollEvents, action.event_indices[k]);
+ }
+ if ((event_mask.computedHash & PKE_INPUT_HASH_EVENT_TYPE_WINDOW_FOCUS) != InputEventHash{0}) {
+ pk_arr_remove_at(&registeredWindowFocusEvents, action.event_indices[k]);
+ }
}
}
pk_arr_remove_at(&activeInputSetStack, activeInputSetStack.next-1);
@@ -681,6 +680,10 @@ void PkeInput_UnregisterSet(InputActionSetHandle handle) {
pk_arr_remove_at(&registeredInputSets, index);
}
+pk_arr_t<PkeInputSet> &PkeInput_GetInputSets() {
+ return registeredInputSets;
+}
+
void PkeInput_Teardown() {
glfwSetWindowFocusCallback(window, prevWindowFocusCallback);
glfwSetScrollCallback(window, prevScrollCallback);