Fixed input handling for events that need to be held. Added support for events that only get called on a button release
This commit is contained in:
parent
10cc9a4e95
commit
22e15858e5
|
@ -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];
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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};
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
Loading…
Reference in New Issue