Fixed up a bunch of node lister, search lister, and text entry stuff. Began playing with modes

This commit is contained in:
Peter Slattery 2019-11-01 04:17:46 -07:00
parent e00e90f2fd
commit 619c1370fe
10 changed files with 152 additions and 68 deletions

View File

@ -378,6 +378,10 @@ INITIALIZE_APPLICATION(InitializeApplication)
InitMemoryArena(&State->SACNMemory, 0, 0, Context.PlatformAlloc); InitMemoryArena(&State->SACNMemory, 0, 0, Context.PlatformAlloc);
{ // MODES PLAYGROUND
State->Modes.ActiveModesCount = 0;
}
InitializeInputCommandRegistry(&State->InputCommandRegistry, 32, State->Permanent); InitializeInputCommandRegistry(&State->InputCommandRegistry, 32, State->Permanent);
InitializeInputCommandRegistry(&State->NodeListerCommandRegistry, 128, State->Permanent); InitializeInputCommandRegistry(&State->NodeListerCommandRegistry, 128, State->Permanent);
State->ActiveCommands = &State->InputCommandRegistry; State->ActiveCommands = &State->InputCommandRegistry;
@ -390,6 +394,30 @@ INITIALIZE_APPLICATION(InitializeApplication)
State->ActiveTextEntry.Buffer = MakeString(PushArray(State->Permanent, char, 256), 0, 256); 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? // TODO(Peter): put in InitializeInterface?
r32 FontSize = 14; r32 FontSize = 14;
{ {
@ -863,15 +891,25 @@ UPDATE_AND_RENDER(UpdateAndRender)
v2 TopLeft = State->NodeListMenuPosition; v2 TopLeft = State->NodeListMenuPosition;
v2 Dimension = v2{300, 30}; 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, search_lister_result NodeListerResult = EvaluateSearchLister (RenderBuffer, TopLeft, Dimension,
MakeStringLiteral("Nodes List"), MakeStringLiteral("Nodes List"),
NodeSpecificationsCount, (u8*)NodeSpecifications, State->SearchLister.SourceList,
State->GeneralPurposeSearchHotItem, State->SearchLister.FilteredIndexLUT,
NodeListerGetNodeName, State->SearchLister.FilteredListCount,
State->SearchLister.HotItem,
&State->ActiveTextEntry.Buffer, &State->ActiveTextEntry.Buffer,
State->ActiveTextEntry.CursorPosition, State->ActiveTextEntry.CursorPosition,
State->Font, State->Interface, GuiMouse); State->Font, State->Interface, GuiMouse);
State->GeneralPurposeSearchHotItem = NodeListerResult.HotItem;
} }
} }

View File

@ -48,9 +48,8 @@ struct assembly
typedef struct app_state app_state; typedef struct app_state app_state;
#include "foldhaus_command_dispatch.h" #include "foldhaus_command_dispatch.h"
#include "foldhaus_operation_mode.h"
#include "foldhaus_text_entry.h" #include "foldhaus_text_entry.h"
@ -66,6 +65,9 @@ struct app_state
camera Camera; camera Camera;
operation_mode Operation_AddNode;
operation_mode_system Modes;
input_command_registry InputCommandRegistry; input_command_registry InputCommandRegistry;
input_command_registry NodeListerCommandRegistry; input_command_registry NodeListerCommandRegistry;
// NOTE(Peter): stores the address of the command registry to be activated next frame. // NOTE(Peter): stores the address of the command registry to be activated next frame.
@ -76,6 +78,7 @@ struct app_state
input_command_queue CommandQueue; input_command_queue CommandQueue;
text_entry ActiveTextEntry; text_entry ActiveTextEntry;
search_lister SearchLister;
streaming_acn SACN; streaming_acn SACN;
s32 TotalLEDsCount; s32 TotalLEDsCount;
@ -109,8 +112,6 @@ struct app_state
v4* ColorPickerEditValue; v4* ColorPickerEditValue;
string GeneralPurposeSearchString; string GeneralPurposeSearchString;
s32 GeneralPurposeSearchHotItem;
}; };
#include "foldhaus_debug_visuals.h" #include "foldhaus_debug_visuals.h"

View File

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

View File

@ -41,6 +41,8 @@ FOLDHAUS_INPUT_COMMAND_PROC(ToggleUniverseDebugView)
FOLDHAUS_INPUT_COMMAND_PROC(OpenNodeLister) FOLDHAUS_INPUT_COMMAND_PROC(OpenNodeLister)
{ {
ActivateOperationMode(State->Operation_AddNode, &State->Modes);
State->InterfaceShowNodeLister = true; State->InterfaceShowNodeLister = true;
State->NodeListMenuPosition = Mouse.Pos; State->NodeListMenuPosition = Mouse.Pos;
SetTextInputDestinationToString(&State->ActiveTextEntry, &State->GeneralPurposeSearchString); SetTextInputDestinationToString(&State->ActiveTextEntry, &State->GeneralPurposeSearchString);

View File

@ -0,0 +1,25 @@
struct operation_mode
{
input_command_registry Commands;
};
#define OPERATION_MODES_MAX 32
struct operation_mode_system
{
s32 ActiveModesCount;
operation_mode ActiveModes[OPERATION_MODES_MAX];
};
internal void
ActivateOperationMode (operation_mode Mode, operation_mode_system* System)
{
Assert(System->ActiveModesCount < OPERATION_MODES_MAX);
System->ActiveModes[System->ActiveModesCount++] = Mode;
}
internal void
DeactivateCurrentOperationMode (operation_mode_system* System)
{
Assert(System->ActiveModesCount > 0);
System->ActiveModesCount--;
}

View File

@ -1,77 +1,60 @@
internal string*
GetStringAtIndex (search_lister Lister, s32 Index)
{
string* Result = 0;
Assert(Index >= 0 && Index < Lister.ListLength);
u8* Element = Lister.ListMemory + (Lister.ElementStride * Index);
Result = (string*)(Element + Lister.OffsetToStringInElement);
return Result;
}
#define InitializeSearchLister(SearchLister, List, ListLength, StringFieldName) \
s32 ElementStride = (u8*)(List + 1) - (u8*)(List); \
s32 OffsetToString = (u8*)(List->#StringFieldName) - (u8*)(List); \
InitializeSearchLister_((u8*)List, ListLength, ElementStride, OffsetToString); \
internal void internal void
InitializeSearchLister_(search_lister* Lister, FilterSearchLister (search_lister* SearchLister)
u8* ListMemory,
s32 ListLength,
s32 ElementStride,
s32 OffsetToString)
{ {
Lister->ListLength = ListLength; Assert(SearchLister->FilteredIndexLUT != 0);
Lister->ListMemory = ListMemory; Assert(SearchLister->FilteredListMax == SearchLister->SourceListCount);
Lister->OffsetToStringInElement = OffsetToString;
Lister->ElementStride = ElementStride;
Lister->Filter.Length = 0;
SearchLister->FilteredListCount = 0;
for (s32 i = 0; i < SearchLister->SourceListCount; i++)
{
string* NameString = SearchLister->SourceList + i;
if (SpecificationPassesFilter(*NameString, SearchLister->Filter))
{
SearchLister->FilteredIndexLUT[SearchLister->FilteredListCount++] = i;
}
}
} }
internal s32 internal s32
GetNextHotItemIndex (s32 CurrentHotItem, s32 ListLength) GetNextFilteredItem (search_lister SearchLister)
{ {
s32 Result = GSMin(CurrentHotItem + 1, ListLength - 1); s32 Result = GSMin(SearchLister.HotItem + 1, SearchLister.FilteredListCount - 1);
return Result; return Result;
} }
internal s32 internal s32
GetPrevHotItemIndex (s32 CurrentHotItem) GetPrevFilteredItem (search_lister SearchLister)
{ {
s32 Result = GSMax(0, CurrentHotItem - 1); s32 Result = GSMax(SearchLister.HotItem - 1, 0);
return Result; return Result;
} }
FOLDHAUS_INPUT_COMMAND_PROC(SearchListerNextItem) FOLDHAUS_INPUT_COMMAND_PROC(SearchListerNextItem)
{ {
State->GeneralPurposeSearchHotItem = GetNextHotItemIndex(State->GeneralPurposeSearchHotItem, NodeSpecificationsCount); State->SearchLister.HotItem = GetNextFilteredItem(State->SearchLister);
} }
FOLDHAUS_INPUT_COMMAND_PROC(SearchListerPrevItem) FOLDHAUS_INPUT_COMMAND_PROC(SearchListerPrevItem)
{ {
State->GeneralPurposeSearchHotItem = GetPrevHotItemIndex(State->GeneralPurposeSearchHotItem); State->SearchLister.HotItem = GetPrevFilteredItem(State->SearchLister);
} }
FOLDHAUS_INPUT_COMMAND_PROC(CloseSearchLister) FOLDHAUS_INPUT_COMMAND_PROC(CloseSearchLister)
{ {
DeactivateCurrentOperationMode(&State->Modes);
// TODO(Peter): This is to show the node list. Generalize to just a lister // TODO(Peter): This is to show the node list. Generalize to just a lister
State->InterfaceShowNodeLister = false; State->InterfaceShowNodeLister = false;
// TODO(Peter): This also assumes we know where we came from. Probably need to implement // TODO(Peter): This also assumes we know where we came from. Probably need to implement
// push/pop functionality for the activecommands. // push/pop functionality for the activecommands.
QueueNextFrameCommandRegistry(&State->InputCommandRegistry, State); QueueNextFrameCommandRegistry(&State->InputCommandRegistry, State);
State->GeneralPurposeSearchHotItem = -1;
} }
FOLDHAUS_INPUT_COMMAND_PROC(SelectAndCloseSearchLister) FOLDHAUS_INPUT_COMMAND_PROC(SelectAndCloseSearchLister)
{ {
s32 HotItem = State->GeneralPurposeSearchHotItem; s32 FilteredNodeIndex = State->SearchLister.HotItem;
s32 ListIndexFromHotItem = NodeListerConvertHotItemToListIndex(HotItem, s32 NodeIndex = State->SearchLister.FilteredIndexLUT[FilteredNodeIndex];
(u8*)NodeSpecifications, PushNodeOnListFromSpecification(State->NodeList, NodeSpecifications[NodeIndex],
NodeSpecificationsCount,
State->ActiveTextEntry.Buffer);
PushNodeOnListFromSpecification(State->NodeList, NodeSpecifications[ListIndexFromHotItem],
Mouse.Pos, State->NodeRenderSettings, State->Permanent); Mouse.Pos, State->NodeRenderSettings, State->Permanent);
CloseSearchLister(State, Event, Mouse); CloseSearchLister(State, Event, Mouse);
} }

View File

@ -1,9 +1,20 @@
struct search_lister struct search_lister
{ {
s32 ListLength; // TODO(Peter): Giving up trying to just use the source list for now. At the moment
u8* ListMemory; // we are copying the strings you want to filter from and storing them here. Come back
s32 OffsetToStringInElement; // once its working and make the memory efficient version (ie store the existing memory
s32 ElementStride; // location, the element stride and the offset to the char*)
s32 SourceListCount;
string* SourceList;
// NOTE(Peter): stores the source indecies of each filtered item
// For example:
// Index 0 in this array contains 3. This means the first item that passes the filter
// is index 3 in ListMemory
s32 FilteredListMax;
s32 FilteredListCount;
s32* FilteredIndexLUT;
s32 HotItem;
string Filter; string Filter;
}; };

View File

@ -1749,6 +1749,7 @@ PrintFArgsList (char* Dest, s32 DestMax, char* Format, va_list Args)
if (SignedInt < 0) if (SignedInt < 0)
{ {
OutChar(&TempDest, '-'); OutChar(&TempDest, '-');
SignedInt *= -1;
} }
U64ToASCII(&TempDest, (u64)SignedInt, 10, DecimalDigits); U64ToASCII(&TempDest, (u64)SignedInt, 10, DecimalDigits);
} }

View File

@ -579,12 +579,11 @@ typedef string search_lister_get_list_item_at_offset(u8* ListMemory, s32 ListLen
internal search_lister_result internal search_lister_result
EvaluateSearchLister (render_command_buffer* RenderBuffer, v2 TopLeft, v2 Dimension, string Title, EvaluateSearchLister (render_command_buffer* RenderBuffer, v2 TopLeft, v2 Dimension, string Title,
s32 ListLength, u8* ListMemory, s32 HotItem, search_lister_get_list_item_at_offset* GetListItem, string* ItemList, s32* ListLUT, s32 ListLength,
s32 HotItem,
string* SearchString, s32 SearchStringCursorPosition, string* SearchString, s32 SearchStringCursorPosition,
bitmap_font* Font, interface_config Config, gui_mouse Mouse) bitmap_font* Font, interface_config Config, gui_mouse Mouse)
{ {
Assert(GetListItem != 0);
search_lister_result Result = {}; search_lister_result Result = {};
Result.ShouldRemainOpen = true; Result.ShouldRemainOpen = true;
Result.HotItem = HotItem; Result.HotItem = HotItem;
@ -592,6 +591,10 @@ EvaluateSearchLister (render_command_buffer* RenderBuffer, v2 TopLeft, v2 Dimens
// Title Bar // Title Bar
PushRenderQuad2D(RenderBuffer, v2{TopLeft.x, TopLeft.y - 30}, v2{TopLeft.x + 300, TopLeft.y}, v4{.3f, .3f, .3f, 1.f}); PushRenderQuad2D(RenderBuffer, v2{TopLeft.x, TopLeft.y - 30}, v2{TopLeft.x + 300, TopLeft.y}, v4{.3f, .3f, .3f, 1.f});
DrawString(RenderBuffer, Title, Font, 14, v2{TopLeft.x, TopLeft.y - 25}, WhiteV4); DrawString(RenderBuffer, Title, Font, 14, v2{TopLeft.x, TopLeft.y - 25}, WhiteV4);
MakeStringBuffer(DebugString, 256);
PrintF(&DebugString, "Hot Item: %d", HotItem);
DrawString(RenderBuffer, DebugString, Font, 14, v2{TopLeft.x + 256, TopLeft.y - 25}, WhiteV4);
TopLeft.y -= 30; TopLeft.y -= 30;
// Search Bar // Search Bar
@ -599,30 +602,29 @@ EvaluateSearchLister (render_command_buffer* RenderBuffer, v2 TopLeft, v2 Dimens
DrawStringWithCursor(RenderBuffer, *SearchString, SearchStringCursorPosition, Font, 14, v2{TopLeft.x, TopLeft.y - 25}, WhiteV4, GreenV4); DrawStringWithCursor(RenderBuffer, *SearchString, SearchStringCursorPosition, Font, 14, v2{TopLeft.x, TopLeft.y - 25}, WhiteV4, GreenV4);
TopLeft.y -= 30; TopLeft.y -= 30;
s32 VisibleItemIndex = 0; for (s32 i = 0; i < ListLength; i++)
string ListItemText = GetListItem(ListMemory, ListLength, *SearchString, VisibleItemIndex);
while(ListItemText.Length > 0)
{ {
s32 FilteredIndex = ListLUT[i];
string ListItemString = ItemList[FilteredIndex];
v2 Min = v2{TopLeft.x, TopLeft.y - 30}; v2 Min = v2{TopLeft.x, TopLeft.y - 30};
v2 Max = Min + Dimension - v2{0, Config.Margin.y}; v2 Max = Min + Dimension - v2{0, Config.Margin.y};
v4 ButtonColor = Config.ButtonColor_Inactive; v4 ButtonColor = Config.ButtonColor_Inactive;
if (VisibleItemIndex == HotItem) if (i == HotItem)
{ {
ButtonColor = Config.ButtonColor_Active; ButtonColor = Config.ButtonColor_Active;
} }
button_result Button = EvaluateButton(RenderBuffer, Min, Max, Config.Margin, ListItemText, button_result Button = EvaluateButton(RenderBuffer, Min, Max, Config.Margin, ListItemString,
ButtonColor, ButtonColor, Config.TextColor, Config.TextColor, ButtonColor, ButtonColor, Config.TextColor, Config.TextColor,
Config.Font, Mouse); Config.Font, Mouse);
if (Button.Pressed) if (Button.Pressed)
{ {
Result.SelectedItem = VisibleItemIndex; Result.SelectedItem = i;
} }
TopLeft.y -= 30; TopLeft.y -= 30;
ListItemText = GetListItem(ListMemory, ListLength, *SearchString, ++VisibleItemIndex);
} }
return Result; return Result;

View File

@ -1,5 +1,26 @@
TODO FOLDHAUS TODO FOLDHAUS
Intermediate Lifetime Memory & Operations
- Intermediate lifetime memory arena
- Temporary memory region = a multi frame operation
- Concept of an operation - temporary memory + interface command registry
- Allow one operation at a time at first
- Push/pop operations on a list?
- Current Operations:
- - View Sculpture
- - View/Edit Nodes
- - Add Node (needs nesting)
- - View SACN
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
- extend to other operations
Hardening Hardening
- memory visualization - memory visualization
- separate rendering thread - separate rendering thread