Got modes working for the node lister

This commit is contained in:
Peter Slattery 2019-11-01 05:46:40 -07:00
parent 619c1370fe
commit e51400c313
7 changed files with 187 additions and 129 deletions

View File

@ -357,12 +357,13 @@ RELOAD_STATIC_DATA(ReloadStaticData)
RegisterKeyPressCommand(&State->InputCommandRegistry, KeyCode_A, false, KeyCode_Invalid, OpenNodeLister);
RegisterKeyPressCommand(&State->InputCommandRegistry, KeyCode_Tab, false, KeyCode_Invalid, ToggleNodeDisplay);
// Node Lister
RegisterKeyPressCommand(&State->NodeListerCommandRegistry, KeyCode_DownArrow, false, KeyCode_Invalid, SearchListerNextItem);
RegisterKeyPressCommand(&State->NodeListerCommandRegistry, KeyCode_UpArrow, false, KeyCode_Invalid, SearchListerPrevItem);
RegisterKeyPressCommand(&State->NodeListerCommandRegistry, KeyCode_Enter, false, KeyCode_Invalid, SelectAndCloseSearchLister);
RegisterKeyPressCommand(&State->NodeListerCommandRegistry, KeyCode_MouseLeftButton, false, KeyCode_Invalid, CloseSearchLister);
RegisterKeyPressCommand(&State->NodeListerCommandRegistry, KeyCode_Esc, false, KeyCode_Invalid, CloseSearchLister);
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);
InitializeTextInputCommands(&State->NodeListerCommandRegistry, State->Permanent);
}
}
@ -378,10 +379,6 @@ INITIALIZE_APPLICATION(InitializeApplication)
InitMemoryArena(&State->SACNMemory, 0, 0, Context.PlatformAlloc);
{ // MODES PLAYGROUND
State->Modes.ActiveModesCount = 0;
}
InitializeInputCommandRegistry(&State->InputCommandRegistry, 32, State->Permanent);
InitializeInputCommandRegistry(&State->NodeListerCommandRegistry, 128, State->Permanent);
State->ActiveCommands = &State->InputCommandRegistry;
@ -394,30 +391,6 @@ INITIALIZE_APPLICATION(InitializeApplication)
State->ActiveTextEntry.Buffer = MakeString(PushArray(State->Permanent, char, 256), 0, 256);
{ // Search Lister
State->SearchLister.SourceListCount = NodeSpecificationsCount;
State->SearchLister.SourceList = PushArray(State->Permanent, string, State->SearchLister.SourceListCount);
{
for (s32 i = 0; i < State->SearchLister.SourceListCount; i++)
{
State->SearchLister.SourceList[i] = MakeString(
NodeSpecifications[i].Name,
NodeSpecifications[i].NameLength);
}
}
State->SearchLister.Filter = State->ActiveTextEntry.Buffer;
// TODO(Peter): This doesn't allow for using this search lister on different sources
//
// TODO(Peter): In general right now we support memory lifetimes of 1 frame, and permanent
// we need to support some intermediate lifetimes like
// temporary multiframe operation like searching.
//
State->SearchLister.FilteredListMax = State->SearchLister.SourceListCount;
State->SearchLister.FilteredListCount = 0;
State->SearchLister.FilteredIndexLUT = PushArray(State->Permanent, s32, State->SearchLister.SourceListCount);
}
// TODO(Peter): put in InitializeInterface?
r32 FontSize = 14;
{
@ -522,6 +495,14 @@ INITIALIZE_APPLICATION(InitializeApplication)
InitializeEmptyString(&State->GeneralPurposeSearchString, PushArray(State->Permanent, char, 256), 256);
ReloadStaticData(Context, GlobalDebugServices);
{ // MODES PLAYGROUND
State->Modes.ActiveModesCount = 0;
s32 ModesMemorySize = Kilobytes(32);
u8* ModesMemory = PushSize(State->Permanent, ModesMemorySize);
InitMemoryArena(&State->Modes.Arena, ModesMemory, ModesMemorySize, 0);
}
}
UPDATE_AND_RENDER(UpdateAndRender)
@ -540,7 +521,14 @@ UPDATE_AND_RENDER(UpdateAndRender)
GuiMouse.OldPos = Mouse.OldPos;
GuiMouse.DeltaPos = Mouse.DeltaPos;
GuiMouse.DownPos = Mouse.DownPos;
{
input_command_registry* ActiveCommands = State->ActiveCommands;
if (State->Modes.ActiveModesCount > 0)
{
ActiveCommands = &State->Modes.ActiveModes[State->Modes.ActiveModesCount - 1].Commands;
}
ActivateQueuedCommandRegistry(State);
// CommandQueue holds the list of commands, generated from the current InputCommandRegistry
@ -553,7 +541,7 @@ UPDATE_AND_RENDER(UpdateAndRender)
{
input_entry Event = InputQueue.Entries[EventIdx];
input_command* Command = FindExistingCommand(State->ActiveCommands, Event.Key, (key_code)0);
input_command* Command = FindExistingCommand(ActiveCommands, Event.Key, (key_code)0);
if (Command)
{
if (KeyTransitionedDown(Event))
@ -885,32 +873,6 @@ UPDATE_AND_RENDER(UpdateAndRender)
if (State->NodeRenderSettings.Display)
{
RenderNodeList(State->NodeList, State->NodeRenderSettings, RenderBuffer);
if (State->InterfaceShowNodeLister)
{
v2 TopLeft = State->NodeListMenuPosition;
v2 Dimension = v2{300, 30};
if (State->ActiveTextEntry.Buffer.Length > 0)
{
s32 x = 5;
}
// Filter the lister
State->SearchLister.Filter = State->ActiveTextEntry.Buffer;
FilterSearchLister(&State->SearchLister);
// Display Search Lister
search_lister_result NodeListerResult = EvaluateSearchLister (RenderBuffer, TopLeft, Dimension,
MakeStringLiteral("Nodes List"),
State->SearchLister.SourceList,
State->SearchLister.FilteredIndexLUT,
State->SearchLister.FilteredListCount,
State->SearchLister.HotItem,
&State->ActiveTextEntry.Buffer,
State->ActiveTextEntry.CursorPosition,
State->Font, State->Interface, GuiMouse);
}
}
if (State->ColorPickerEditValue != 0)
@ -924,6 +886,12 @@ UPDATE_AND_RENDER(UpdateAndRender)
}
}
for (s32 m = 0; m < State->Modes.ActiveModesCount; m++)
{
operation_mode OperationMode = State->Modes.ActiveModes[m];
OperationMode.Render(State, RenderBuffer, OperationMode, GuiMouse);
}
DrawDebugInterface(RenderBuffer, 25,
State->Interface, Context.WindowWidth, Context.WindowHeight - TopBarHeight,
Context.DeltaTime, State, State->Camera, GuiMouse, State->Transient);

View File

@ -65,10 +65,11 @@ struct app_state
camera Camera;
operation_mode Operation_AddNode;
operation_mode_system Modes;
input_command_registry InputCommandRegistry;
// TODO(Peter): At the moment this is only still here because text input into nodes utilizes it.
// Get rid of this once Modes are working and you can switch all text input over to various modes
input_command_registry NodeListerCommandRegistry;
// NOTE(Peter): stores the address of the command registry to be activated next frame.
// was having a problem where switching command registry's in the middle of the loop trying to
@ -78,7 +79,6 @@ struct app_state
input_command_queue CommandQueue;
text_entry ActiveTextEntry;
search_lister SearchLister;
streaming_acn SACN;
s32 TotalLEDsCount;
@ -101,7 +101,6 @@ struct app_state
v2 UniverseOutputDisplayOffset;
r32 UniverseOutputDisplayZoom;
b32 InterfaceShowNodeLister;
v2 NodeListMenuPosition;
node_list* NodeList;
@ -119,5 +118,6 @@ struct app_state
#include "foldhaus_command_dispatch.cpp"
#include "foldhaus_node.cpp"
#include "foldhaus_text_entry.cpp"
#include "foldhaus_interface.cpp"
#include "foldhaus_search_lister.cpp"
#include "foldhaus_search_lister.cpp"
#include "foldhaus_interface.cpp"

View File

@ -20,21 +20,12 @@ DrawDebugInterface (render_command_buffer* RenderBuffer, r32 StartX, interface_c
r32 FramesPerSecond = 1.0f / DeltaTime;
string InputCommands = MakeStringLiteral("Default Input Registry");
string NodeListerCommands = MakeStringLiteral("Node Lister Input Registry");
string ActiveInputRegistry = {};
if (State->ActiveCommands == &State->InputCommandRegistry)
{
ActiveInputRegistry = InputCommands;
}
else if (State->ActiveCommands == &State->NodeListerCommandRegistry)
{
ActiveInputRegistry = NodeListerCommands;
}
PrintF(&DebugString, "Framerate: %.*f s %d fps | Modes: %d",
PrintF(&DebugString, "Framerate: %.*f s %d fps | Modes: %d Memory Used: %d / %d",
5, DeltaTime,
(u32)FramesPerSecond,
State->Modes.ActiveModesCount);
State->Modes.ActiveModesCount,
State->Modes.Arena.CurrentRegion->Used,
State->Modes.Arena.CurrentRegion->Size);
DrawString(RenderBuffer, DebugString, Interface.Font, Interface.FontSize, TopOfScreenLinePos, WhiteV4);
v2 ButtonDim = v2{200, (r32)NewLineYOffset(*Interface.Font) + 10};

View File

@ -38,18 +38,128 @@ FOLDHAUS_INPUT_COMMAND_PROC(ToggleUniverseDebugView)
State->DrawUniverseOutputDisplay = !State->DrawUniverseOutputDisplay;
}
FOLDHAUS_INPUT_COMMAND_PROC(OpenNodeLister)
{
ActivateOperationMode(State->Operation_AddNode, &State->Modes);
State->InterfaceShowNodeLister = true;
State->NodeListMenuPosition = Mouse.Pos;
SetTextInputDestinationToString(&State->ActiveTextEntry, &State->GeneralPurposeSearchString);
State->ActiveCommands = &State->NodeListerCommandRegistry;
}
FOLDHAUS_INPUT_COMMAND_PROC(ToggleNodeDisplay)
{
State->NodeRenderSettings.Display = !State->NodeRenderSettings.Display;
}
}
////////////////////////////////////////
//
// Universe View
//
///////////////////////////////////////
OPERATION_RENDER_PROC(RenderUniverseView)
{
}
////////////////////////////////////////
//
// Node Lister
//
///////////////////////////////////////
struct node_lister_operation_state
{
search_lister SearchLister;
};
OPERATION_RENDER_PROC(RenderNodeLister)
{
node_lister_operation_state* OpState = (node_lister_operation_state*)Operation.OpStateMemory;
v2 TopLeft = State->NodeListMenuPosition;
v2 Dimension = v2{300, 30};
// Filter the lister
OpState->SearchLister.Filter = State->ActiveTextEntry.Buffer;
FilterSearchLister(&OpState->SearchLister);
// Display Search Lister
search_lister_result NodeListerResult = EvaluateSearchLister (RenderBuffer, TopLeft, Dimension,
MakeStringLiteral("Nodes List"),
OpState->SearchLister.SourceList,
OpState->SearchLister.FilteredIndexLUT,
OpState->SearchLister.FilteredListCount,
OpState->SearchLister.HotItem,
&State->ActiveTextEntry.Buffer,
State->ActiveTextEntry.CursorPosition,
State->Font, State->Interface, GuiMouse);
}
FOLDHAUS_INPUT_COMMAND_PROC(NodeListerNextItem)
{
// TODO(Peter): Pass this in as a parameter
operation_mode Mode = State->Modes.ActiveModes[State->Modes.ActiveModesCount - 1];
node_lister_operation_state* OpState = (node_lister_operation_state*)Mode.OpStateMemory;
OpState->SearchLister.HotItem = GetNextFilteredItem(OpState->SearchLister);
}
FOLDHAUS_INPUT_COMMAND_PROC(NodeListerPrevItem)
{
// TODO(Peter): Pass this in as a parameter
operation_mode Mode = State->Modes.ActiveModes[State->Modes.ActiveModesCount - 1];
node_lister_operation_state* OpState = (node_lister_operation_state*)Mode.OpStateMemory;
OpState->SearchLister.HotItem = GetPrevFilteredItem(OpState->SearchLister);
}
FOLDHAUS_INPUT_COMMAND_PROC(CloseNodeLister)
{
DeactivateCurrentOperationMode(&State->Modes);
}
FOLDHAUS_INPUT_COMMAND_PROC(SelectAndCloseNodeLister)
{
// TODO(Peter): Pass this in as a parameter
operation_mode Mode = State->Modes.ActiveModes[State->Modes.ActiveModesCount - 1];
node_lister_operation_state* OpState = (node_lister_operation_state*)Mode.OpStateMemory;
s32 FilteredNodeIndex = OpState->SearchLister.HotItem;
s32 NodeIndex = OpState->SearchLister.FilteredIndexLUT[FilteredNodeIndex];
PushNodeOnListFromSpecification(State->NodeList, NodeSpecifications[NodeIndex],
Mouse.Pos, State->NodeRenderSettings, State->Permanent);
CloseNodeLister(State, Event, Mouse);
}
FOLDHAUS_INPUT_COMMAND_PROC(OpenNodeLister)
{
// TODO(Peter): This won't work with hot code reloading
operation_mode* AddNodeOperation = ActivateOperationMode(&State->Modes);
{ // 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);
InitializeTextInputCommands(&AddNodeOperation->Commands, &State->Modes.Arena);
}
AddNodeOperation->Render = RenderNodeLister;
node_lister_operation_state* OpState = PushStruct(&State->Modes.Arena, node_lister_operation_state);
AddNodeOperation->OpStateMemory = (u8*)OpState;
{
OpState->SearchLister.SourceListCount = NodeSpecificationsCount;
OpState->SearchLister.SourceList = PushArray(&State->Modes.Arena, string, OpState->SearchLister.SourceListCount);
{
for (s32 i = 0; i < OpState->SearchLister.SourceListCount; i++)
{
OpState->SearchLister.SourceList[i] = MakeString(
NodeSpecifications[i].Name,
NodeSpecifications[i].NameLength);
}
}
OpState->SearchLister.Filter = State->ActiveTextEntry.Buffer;
OpState->SearchLister.FilteredListMax = OpState->SearchLister.SourceListCount;
OpState->SearchLister.FilteredListCount = 0;
OpState->SearchLister.FilteredIndexLUT = PushArray(&State->Modes.Arena, s32, OpState->SearchLister.SourceListCount);
}
State->NodeListMenuPosition = Mouse.Pos;
SetTextInputDestinationToString(&State->ActiveTextEntry, &State->GeneralPurposeSearchString);
}

View File

@ -1,6 +1,13 @@
typedef struct operation_mode operation_mode;
#define OPERATION_RENDER_PROC(name) void name(app_state* State, render_command_buffer* RenderBuffer, operation_mode Operation, gui_mouse GuiMouse)
typedef OPERATION_RENDER_PROC(operation_render_proc);
struct operation_mode
{
input_command_registry Commands;
operation_render_proc* Render;
u8* OpStateMemory;
};
#define OPERATION_MODES_MAX 32
@ -8,18 +15,27 @@ struct operation_mode_system
{
s32 ActiveModesCount;
operation_mode ActiveModes[OPERATION_MODES_MAX];
arena_snapshot ModeMemorySnapshots[OPERATION_MODES_MAX];
// NOTE(Peter): This acts as mode scoped memory. When a mode gets activated, it can allocate
// temporary memory which then gets freed when the mode is deactivated
memory_arena Arena;
};
internal void
ActivateOperationMode (operation_mode Mode, operation_mode_system* System)
internal operation_mode*
ActivateOperationMode (operation_mode_system* System)
{
Assert(System->ActiveModesCount < OPERATION_MODES_MAX);
System->ActiveModes[System->ActiveModesCount++] = Mode;
s32 ModeIndex = System->ActiveModesCount++;
System->ActiveModes[ModeIndex] = {};
System->ModeMemorySnapshots[ModeIndex] = TakeSnapshotOfArena(System->Arena);
return &System->ActiveModes[ModeIndex];
}
internal void
DeactivateCurrentOperationMode (operation_mode_system* System)
{
Assert(System->ActiveModesCount > 0);
System->ActiveModesCount--;
s32 ModeIndex = --System->ActiveModesCount;
ClearArenaToSnapshot(&System->Arena, System->ModeMemorySnapshots[ModeIndex]);
}

View File

@ -29,32 +29,3 @@ GetPrevFilteredItem (search_lister SearchLister)
s32 Result = GSMax(SearchLister.HotItem - 1, 0);
return Result;
}
FOLDHAUS_INPUT_COMMAND_PROC(SearchListerNextItem)
{
State->SearchLister.HotItem = GetNextFilteredItem(State->SearchLister);
}
FOLDHAUS_INPUT_COMMAND_PROC(SearchListerPrevItem)
{
State->SearchLister.HotItem = GetPrevFilteredItem(State->SearchLister);
}
FOLDHAUS_INPUT_COMMAND_PROC(CloseSearchLister)
{
DeactivateCurrentOperationMode(&State->Modes);
// TODO(Peter): This is to show the node list. Generalize to just a lister
State->InterfaceShowNodeLister = false;
// TODO(Peter): This also assumes we know where we came from. Probably need to implement
// push/pop functionality for the activecommands.
QueueNextFrameCommandRegistry(&State->InputCommandRegistry, State);
}
FOLDHAUS_INPUT_COMMAND_PROC(SelectAndCloseSearchLister)
{
s32 FilteredNodeIndex = State->SearchLister.HotItem;
s32 NodeIndex = State->SearchLister.FilteredIndexLUT[FilteredNodeIndex];
PushNodeOnListFromSpecification(State->NodeList, NodeSpecifications[NodeIndex],
Mouse.Pos, State->NodeRenderSettings, State->Permanent);
CloseSearchLister(State, Event, Mouse);
}

View File

@ -12,13 +12,15 @@ Intermediate Lifetime Memory & Operations
- - Add Node (needs nesting)
- - View SACN
- Why does backspacing in text entry not save when you close and reopen the node lister?
Plan
- start with adding nodes
- push/pop an operation
- create operation structure
- static size of operations list
- move command registry out of search lister and text entry into operation
- initialize/cleanup add node operation
x start with adding nodes
x push/pop an operation
x create operation structure
x static size of operations list
x move command registry out of search lister and text entry into operation
x initialize/cleanup add node operation
- extend to other operations
Hardening