From 22e15858e5a57491aeb26a8f708305d7c360ca3f Mon Sep 17 00:00:00 2001 From: Peter Slattery Date: Fri, 1 Nov 2019 09:09:05 -0700 Subject: [PATCH] Fixed input handling for events that need to be held. Added support for events that only get called on a button release --- src/foldhaus_app.cpp | 53 ++++++++++++------------ src/foldhaus_command_dispatch.cpp | 67 +++++++++++++++++++++---------- src/foldhaus_command_dispatch.h | 19 +++++---- src/foldhaus_debug_visuals.h | 5 ++- src/foldhaus_interface.cpp | 20 ++++----- src/foldhaus_text_entry.cpp | 8 ++-- src/win32_foldhaus.cpp | 1 + todo.txt | 6 +-- 8 files changed, 103 insertions(+), 76 deletions(-) diff --git a/src/foldhaus_app.cpp b/src/foldhaus_app.cpp index b61809c..9de8cd3 100644 --- a/src/foldhaus_app.cpp +++ b/src/foldhaus_app.cpp @@ -350,18 +350,18 @@ RELOAD_STATIC_DATA(ReloadStaticData) if (State->InputCommandRegistry.Size > 0) { - RegisterKeyPressCommand(&State->InputCommandRegistry, KeyCode_MouseLeftButton, true, KeyCode_Invalid, + RegisterKeyPressCommand(&State->InputCommandRegistry, KeyCode_MouseLeftButton, Command_Began | Command_Held | Command_Ended, KeyCode_Invalid, CameraMouseControl); - RegisterKeyPressCommand(&State->InputCommandRegistry, KeyCode_U, false, KeyCode_Invalid, OpenUniverseView); - RegisterKeyPressCommand(&State->InputCommandRegistry, KeyCode_A, false, KeyCode_Invalid, OpenNodeLister); - RegisterKeyPressCommand(&State->InputCommandRegistry, KeyCode_Tab, false, KeyCode_Invalid, OpenNodeView); + RegisterKeyPressCommand(&State->InputCommandRegistry, KeyCode_U, Command_Began, KeyCode_Invalid, OpenUniverseView); + RegisterKeyPressCommand(&State->InputCommandRegistry, KeyCode_A, Command_Began, KeyCode_Invalid, OpenNodeLister); + RegisterKeyPressCommand(&State->InputCommandRegistry, KeyCode_Tab, Command_Began, KeyCode_Invalid, OpenNodeView); // Node Lister - RegisterKeyPressCommand(&State->NodeListerCommandRegistry, KeyCode_DownArrow, false, KeyCode_Invalid, NodeListerNextItem); - RegisterKeyPressCommand(&State->NodeListerCommandRegistry, KeyCode_UpArrow, false, KeyCode_Invalid, NodeListerPrevItem); - RegisterKeyPressCommand(&State->NodeListerCommandRegistry, KeyCode_Enter, false, KeyCode_Invalid, SelectAndCloseNodeLister); - RegisterKeyPressCommand(&State->NodeListerCommandRegistry, KeyCode_MouseLeftButton, false, KeyCode_Invalid, CloseNodeLister); - RegisterKeyPressCommand(&State->NodeListerCommandRegistry, KeyCode_Esc, false, KeyCode_Invalid, CloseNodeLister); + RegisterKeyPressCommand(&State->NodeListerCommandRegistry, KeyCode_DownArrow, Command_Began, KeyCode_Invalid, NodeListerNextItem); + RegisterKeyPressCommand(&State->NodeListerCommandRegistry, KeyCode_UpArrow, Command_Began, KeyCode_Invalid, NodeListerPrevItem); + RegisterKeyPressCommand(&State->NodeListerCommandRegistry, KeyCode_Enter, Command_Began, KeyCode_Invalid, SelectAndCloseNodeLister); + RegisterKeyPressCommand(&State->NodeListerCommandRegistry, KeyCode_MouseLeftButton, Command_Began, KeyCode_Invalid, CloseNodeLister); + RegisterKeyPressCommand(&State->NodeListerCommandRegistry, KeyCode_Esc, Command_Began, KeyCode_Invalid, CloseNodeLister); InitializeTextInputCommands(&State->NodeListerCommandRegistry, State->Permanent); } } @@ -511,12 +511,6 @@ UPDATE_AND_RENDER(UpdateAndRender) ActivateQueuedCommandRegistry(State); - // CommandQueue holds the list of commands, generated from the current InputCommandRegistry - // Every command entry in the queue should be executed. - // For every Input Event, attempt to add an entry to the CommandQueue if an appropriate command - // exists in ActiveCommands - RemoveNonPersistantCommandsFromQueueAndUpdatePersistentEvents(&State->CommandQueue); - for (s32 EventIdx = 0; EventIdx < InputQueue.QueueUsed; EventIdx++) { input_entry Event = InputQueue.Entries[EventIdx]; @@ -524,13 +518,23 @@ UPDATE_AND_RENDER(UpdateAndRender) input_command* Command = FindExistingCommand(ActiveCommands, Event.Key, (key_code)0); if (Command) { - if (KeyTransitionedDown(Event)) + if ((KeyTransitionedDown(Event) && ((Command->Flags & Command_Began) > 0))) { - PushCommandOnQueue(&State->CommandQueue, *Command, Event); + PushCommandOnQueue(&State->CommandQueue, + *Command, + Event, + (Command->Flags & Command_Held) == 0); } - else if (Command->PersistsUntilReleased && KeyTransitionedUp(Event)) + else if (KeyTransitionedUp(Event) && ((Command->Flags & Command_Ended) > 0)) { - RemoveCommandFromQueue(&State->CommandQueue, *Command, Event); + if ((Command->Flags & Command_Held) == 0) + { + PushCommandOnQueue(&State->CommandQueue, *Command, Event, true); + } + else + { + FlagCommandForRemoval(&State->CommandQueue, *Command, Event); + } } } @@ -552,11 +556,13 @@ UPDATE_AND_RENDER(UpdateAndRender) } // Execute all commands in CommandQueue - for (s32 CommandIdx = 0; CommandIdx < State->CommandQueue.Used; CommandIdx++) + for (s32 CommandIdx = State->CommandQueue.Used - 1; CommandIdx >= 0; CommandIdx--) { - command_queue_entry Entry = State->CommandQueue.Commands[CommandIdx]; - Entry.Command.Proc(State, Entry.Event, Mouse); + command_queue_entry* Entry = &State->CommandQueue.Commands[CommandIdx]; + Entry->Command.Proc(State, Entry->Event, Mouse); } + + RemoveNonPersistantCommandsFromQueueAndUpdatePersistentEvents(&State->CommandQueue); } if (State->LEDBufferList) @@ -746,9 +752,6 @@ UPDATE_AND_RENDER(UpdateAndRender) // Figuring Out Nodes ////////////////////////////////////// - //NodeViewMousePickNode(State, {}, Mouse); - //RenderNodeView(State, RenderBuffer, {}, Mouse); - for (s32 m = 0; m < State->Modes.ActiveModesCount; m++) { operation_mode OperationMode = State->Modes.ActiveModes[m]; diff --git a/src/foldhaus_command_dispatch.cpp b/src/foldhaus_command_dispatch.cpp index c8a88f1..03c5604 100644 --- a/src/foldhaus_command_dispatch.cpp +++ b/src/foldhaus_command_dispatch.cpp @@ -29,7 +29,7 @@ FindExistingCommand (input_command_registry* CommandRegistry, key_code Key, key_ internal void RegisterKeyPressCommand (input_command_registry* CommandRegistry, key_code Key, - b32 PersistsUntilReleased, + b32 Flags, key_code Mdfr, input_command_proc* Proc) { @@ -44,7 +44,7 @@ RegisterKeyPressCommand (input_command_registry* CommandRegistry, } Command->Key = Key; - Command->PersistsUntilReleased = PersistsUntilReleased; + Command->Flags = Flags; Command->Mdfr = Mdfr; Command->Proc = Proc; } @@ -56,6 +56,22 @@ RegisterMouseWheelCommand (input_command_registry* CommandRegistry, CommandRegistry->MouseWheelCommand = Proc; } +internal s32 +GetCommandIndexInQueue(input_command_queue* Queue, input_command Command, input_entry Event) +{ + s32 Result = -1; + for (s32 CommandIndex = 0; CommandIndex < Queue->Used; CommandIndex++) + { + command_queue_entry* Entry = Queue->Commands + CommandIndex; + if(Entry->Event.Key == Event.Key) + { + Result = CommandIndex; + break; + } + } + return Result; +} + internal input_command_queue InitializeCommandQueue(command_queue_entry* Memory, s32 MemorySize) { @@ -73,7 +89,7 @@ RemoveNonPersistantCommandsFromQueueAndUpdatePersistentEvents(input_command_queu for (s32 i = 0; i < Queue->Used; i++) { command_queue_entry* Entry = Queue->Commands + i; - if (Entry->Command.PersistsUntilReleased) + if (!Entry->RemoveOnExecute) { Entry->Event.State |= KeyState_WasDown; // NOTE(Peter): If i == PersistantCommandsCount, then we don't need to copy the @@ -89,27 +105,42 @@ RemoveNonPersistantCommandsFromQueueAndUpdatePersistentEvents(input_command_queu } internal void -PushCommandOnQueue(input_command_queue* Queue, input_command Command, input_entry Event) +PushCommandOnQueue(input_command_queue* Queue, input_command Command, input_entry Event, b32 RemoveOnExecute) { Assert(Queue->Used < Queue->Size); command_queue_entry Entry = {}; Entry.Command = Command; Entry.Event = Event; + Entry.RemoveOnExecute = RemoveOnExecute; Queue->Commands[Queue->Used++] = Entry; } +internal void +FlagCommandForRemoval(input_command_queue* Queue, input_command Command, input_entry Event) +{ + s32 CommandIndex = GetCommandIndexInQueue(Queue, Command, Event); + Queue->Commands[CommandIndex].RemoveOnExecute = true; +} + +internal void +RemoveCommandFromQueue(input_command_queue* Queue, s32 Index) +{ + s32 CommandIndex = Index; + if (CommandIndex < Queue->Used) + { + Queue->Used -= 1; + + for (; CommandIndex < Queue->Used; CommandIndex++) + { + Queue->Commands[CommandIndex] = Queue->Commands[CommandIndex + 1]; + } + } +} + internal void RemoveCommandFromQueue(input_command_queue* Queue, input_command Command, input_entry Event) { - s32 CommandIndex = 0; - for (CommandIndex = 0; CommandIndex < Queue->Used; CommandIndex++) - { - command_queue_entry* Entry = Queue->Commands + CommandIndex; - if(Entry->Event.Key == Event.Key) - { - break; - } - } + s32 CommandIndex = GetCommandIndexInQueue(Queue, Command, Event); // NOTE(Peter): If we made it through the queue without finding an event, there wasn't one // to remove. This happens when we've changed command registries as a result of an input command, @@ -121,15 +152,7 @@ RemoveCommandFromQueue(input_command_queue* Queue, input_command Command, input_ // For this reason, I'm allowing the case where we try and remove a command where non exists // I don't think this is a great solution but Im not super familiar with the codebase right now // so leaving it as is. revisit if it becomes a problem. - if (CommandIndex < Queue->Used) - { - Queue->Used -= 1; - - for (; CommandIndex < Queue->Used; CommandIndex++) - { - Queue->Commands[CommandIndex] = Queue->Commands[CommandIndex + 1]; - } - } + RemoveCommandFromQueue(Queue, CommandIndex); } internal void diff --git a/src/foldhaus_command_dispatch.h b/src/foldhaus_command_dispatch.h index 8a2383f..8f26752 100644 --- a/src/foldhaus_command_dispatch.h +++ b/src/foldhaus_command_dispatch.h @@ -1,21 +1,19 @@ -#if USAGE_CODE - -RegisterInputCommand(KeyCode_UpArrow, SACNView_DrawNextUniverse, Context); -RegisterInputCommand(KeyCode_MouseLeftButton, PanCamera, Context); - -ExecuteRegisteredCommands(Context, Input); - -#endif // USAGE_CODE - #define FOLDHAUS_INPUT_COMMAND_PROC(name) void name(app_state* State, input_entry Event, mouse_state Mouse) typedef FOLDHAUS_INPUT_COMMAND_PROC(input_command_proc); +enum input_command_flags +{ + Command_Began = 1 << 0, + Command_Held = 1 << 1, + Command_Ended = 1 << 2, +}; + // TODO(Peter): At the moment these are all key press commands. Need a way to differentiate between // press and hold. Probably add a second array to input_command_Registry struct input_command { key_code Key; - b32 PersistsUntilReleased; + b32 Flags; key_code Mdfr; input_command_proc* Proc; }; @@ -33,6 +31,7 @@ struct command_queue_entry { input_command Command; input_entry Event; + b32 RemoveOnExecute; }; struct input_command_queue diff --git a/src/foldhaus_debug_visuals.h b/src/foldhaus_debug_visuals.h index 92da5f4..9b3d156 100644 --- a/src/foldhaus_debug_visuals.h +++ b/src/foldhaus_debug_visuals.h @@ -20,12 +20,13 @@ DrawDebugInterface (render_command_buffer* RenderBuffer, r32 StartX, interface_c r32 FramesPerSecond = 1.0f / DeltaTime; - PrintF(&DebugString, "Framerate: %.*f s %d fps | Modes: %d Memory Used: %d / %d", + PrintF(&DebugString, "Framerate: %.*f s %d fps | Modes: %d Memory Used: %d / %d | Commands: %d", 5, DeltaTime, (u32)FramesPerSecond, State->Modes.ActiveModesCount, State->Modes.Arena.CurrentRegion->Used, - State->Modes.Arena.CurrentRegion->Size); + State->Modes.Arena.CurrentRegion->Size, + State->CommandQueue.Used); DrawString(RenderBuffer, DebugString, Interface.Font, Interface.FontSize, TopOfScreenLinePos, WhiteV4); v2 ButtonDim = v2{200, (r32)NewLineYOffset(*Interface.Font) + 10}; diff --git a/src/foldhaus_interface.cpp b/src/foldhaus_interface.cpp index bb9bc2b..ae79cf3 100644 --- a/src/foldhaus_interface.cpp +++ b/src/foldhaus_interface.cpp @@ -109,8 +109,8 @@ FOLDHAUS_INPUT_COMMAND_PROC(OpenUniverseView) { // Mode Commands InitializeInputCommandRegistry(&UniverseViewMode->Commands, 3, &State->Modes.Arena); - RegisterKeyPressCommand(&UniverseViewMode->Commands, KeyCode_MouseLeftButton, true, KeyCode_Invalid, UniverseViewPan); - RegisterKeyPressCommand(&UniverseViewMode->Commands, KeyCode_U, false, KeyCode_Invalid, CloseUniverseView); + RegisterKeyPressCommand(&UniverseViewMode->Commands, KeyCode_MouseLeftButton, Command_Began | Command_Ended, KeyCode_Invalid, UniverseViewPan); + RegisterKeyPressCommand(&UniverseViewMode->Commands, KeyCode_U, Command_Began, KeyCode_Invalid, CloseUniverseView); RegisterMouseWheelCommand(&UniverseViewMode->Commands, UniverseZoom); } @@ -198,11 +198,11 @@ FOLDHAUS_INPUT_COMMAND_PROC(OpenNodeLister) { // Mode Commands InitializeInputCommandRegistry(&AddNodeOperation->Commands, 128, &State->Modes.Arena); - RegisterKeyPressCommand(&AddNodeOperation->Commands, KeyCode_DownArrow, false, KeyCode_Invalid, NodeListerNextItem); - RegisterKeyPressCommand(&AddNodeOperation->Commands, KeyCode_UpArrow, false, KeyCode_Invalid, NodeListerPrevItem); - RegisterKeyPressCommand(&AddNodeOperation->Commands, KeyCode_Enter, false, KeyCode_Invalid, SelectAndCloseNodeLister); - RegisterKeyPressCommand(&AddNodeOperation->Commands, KeyCode_MouseLeftButton, false, KeyCode_Invalid, CloseNodeLister); - RegisterKeyPressCommand(&AddNodeOperation->Commands, KeyCode_Esc, false, KeyCode_Invalid, CloseNodeLister); + RegisterKeyPressCommand(&AddNodeOperation->Commands, KeyCode_DownArrow, Command_Began, KeyCode_Invalid, NodeListerNextItem); + RegisterKeyPressCommand(&AddNodeOperation->Commands, KeyCode_UpArrow, Command_Began, KeyCode_Invalid, NodeListerPrevItem); + RegisterKeyPressCommand(&AddNodeOperation->Commands, KeyCode_Enter, Command_Began, KeyCode_Invalid, SelectAndCloseNodeLister); + RegisterKeyPressCommand(&AddNodeOperation->Commands, KeyCode_MouseLeftButton, Command_Began, KeyCode_Invalid, CloseNodeLister); + RegisterKeyPressCommand(&AddNodeOperation->Commands, KeyCode_Esc, Command_Began, KeyCode_Invalid, CloseNodeLister); InitializeTextInputCommands(&AddNodeOperation->Commands, &State->Modes.Arena); } @@ -373,9 +373,9 @@ FOLDHAUS_INPUT_COMMAND_PROC(OpenNodeView) { // Mode Commands InitializeInputCommandRegistry(&NodeViewMode->Commands, 3, &State->Modes.Arena); - RegisterKeyPressCommand(&NodeViewMode->Commands, KeyCode_Tab, false, KeyCode_Invalid, CloseNodeView); - RegisterKeyPressCommand(&NodeViewMode->Commands, KeyCode_A, false, KeyCode_Invalid, OpenNodeLister); - RegisterKeyPressCommand(&NodeViewMode->Commands, KeyCode_MouseLeftButton, true, KeyCode_Invalid, + RegisterKeyPressCommand(&NodeViewMode->Commands, KeyCode_Tab, Command_Began, KeyCode_Invalid, CloseNodeView); + RegisterKeyPressCommand(&NodeViewMode->Commands, KeyCode_A, Command_Began, KeyCode_Invalid, OpenNodeLister); + RegisterKeyPressCommand(&NodeViewMode->Commands, KeyCode_MouseLeftButton, Command_Began | Command_Ended, KeyCode_Invalid, NodeViewMousePickNode); } diff --git a/src/foldhaus_text_entry.cpp b/src/foldhaus_text_entry.cpp index 720fd0c..a423bdc 100644 --- a/src/foldhaus_text_entry.cpp +++ b/src/foldhaus_text_entry.cpp @@ -107,13 +107,13 @@ InitializeTextInputCommands (input_command_registry* Commands, memory_arena* Per { if (Commands->Size > 0) { - RegisterKeyPressCommand(Commands, KeyCode_Backspace, false, KeyCode_Invalid, RemoveCharacterFromEntryString); - RegisterKeyPressCommand(Commands, KeyCode_LeftArrow, false, KeyCode_Invalid, TextEntryMoveCursorLeft); - RegisterKeyPressCommand(Commands, KeyCode_RightArrow, false, KeyCode_Invalid, TextEntryMoveCursorRight); + RegisterKeyPressCommand(Commands, KeyCode_Backspace, Command_Began, KeyCode_Invalid, RemoveCharacterFromEntryString); + RegisterKeyPressCommand(Commands, KeyCode_LeftArrow, Command_Began, KeyCode_Invalid, TextEntryMoveCursorLeft); + RegisterKeyPressCommand(Commands, KeyCode_RightArrow, Command_Began, KeyCode_Invalid, TextEntryMoveCursorRight); for (s32 i = KeyCode_a; i < KeyCode_UpArrow; i++) { - RegisterKeyPressCommand(Commands, (key_code)i, false, KeyCode_Invalid, TextEntryInsertChar); + RegisterKeyPressCommand(Commands, (key_code)i, Command_Began, KeyCode_Invalid, TextEntryInsertChar); } } diff --git a/src/win32_foldhaus.cpp b/src/win32_foldhaus.cpp index 87a6feb..2fcba4e 100644 --- a/src/win32_foldhaus.cpp +++ b/src/win32_foldhaus.cpp @@ -379,6 +379,7 @@ HandleWindowMessage (MSG Message, window* Window, input_queue* InputQueue, mouse AddInputEventEntry(InputQueue, KeyCode_MouseLeftButton, false, true, ShiftDown, AltDown, CtrlDown, false); + Mouse->DownPos = Mouse->Pos; }break; diff --git a/todo.txt b/todo.txt index 076683a..252185e 100644 --- a/todo.txt +++ b/todo.txt @@ -8,9 +8,9 @@ x Allow one operation at a time at first x Push/pop operations on a list? - Current Operations: - - View Sculpture (this might be an exception since its so central) -- - View/Edit Nodes -- x Add Node (needs nesting) -- x View SACN +x - View/Edit Nodes +- x Add Node (needs nesting) +- x View SACN - Why does backspacing in text entry not save when you close and reopen the node lister? - Typing a period into a float value doesn't register