From 30123e47a2fb371c32a2a3926175457a32a1a91b Mon Sep 17 00:00:00 2001 From: PS Date: Sat, 14 Nov 2020 17:18:38 -0800 Subject: [PATCH] fixed some problems with ui retained states --- src/app/editor/foldhaus_editor.cpp | 53 ++++++++----- src/app/editor/foldhaus_interface.cpp | 3 +- .../foldhaus_panel_animation_timeline.h | 6 +- .../editor/panels/foldhaus_panel_file_view.h | 2 +- .../editor/panels/foldhaus_panel_hierarchy.h | 2 +- .../editor/panels/foldhaus_panel_profiler.h | 2 +- src/app/foldhaus_app.cpp | 3 +- src/app/interface.h | 76 +++++++++++-------- src/app/platform_win32/win32_foldhaus.cpp | 6 +- .../win32_foldhaus_work_queue.h | 2 + src/gs_libs/gs_types.cpp | 25 ++++-- src/todo.txt | 1 - src/todo_done.txt | 2 + 13 files changed, 120 insertions(+), 63 deletions(-) diff --git a/src/app/editor/foldhaus_editor.cpp b/src/app/editor/foldhaus_editor.cpp index ecef055..cd3e5f5 100644 --- a/src/app/editor/foldhaus_editor.cpp +++ b/src/app/editor/foldhaus_editor.cpp @@ -105,7 +105,7 @@ Editor_DrawWidget(app_state* State, context* Context, render_command_buffer* Ren PushRenderQuad2D(RenderBuffer, Widget.Bounds.Min, Widget.Bounds.Max, Color); } - if (Widget.String.Length > 0) + if (ui_WidgetIsFlagSet(Widget, UIWidgetFlag_DrawString) && Widget.String.Length > 0) { v4 Color = State->Interface.Style.TextColor; render_quad_batch_constructor BatchConstructor = PushRenderTexture2DBatch(RenderBuffer, @@ -155,25 +155,22 @@ Editor_DrawWidget(app_state* State, context* Context, render_command_buffer* Ren } internal void -Editor_Render(app_state* State, context* Context, render_command_buffer* RenderBuffer) +TestRender(app_state* State, context* Context, render_command_buffer* RenderBuffer) { - PushRenderOrthographic(RenderBuffer, State->WindowBounds); - PushRenderClearScreen(RenderBuffer); - ui_InterfaceReset(&State->Interface); State->Interface.RenderBuffer = RenderBuffer; - ui_PushLayout(&State->Interface, Context->WindowBounds, LayoutDirection_TopDown); + ui_PushLayout(&State->Interface, Context->WindowBounds, LayoutDirection_TopDown, MakeString("TestRender Layout")); - rect2 Rects[2]; - RectVSplitAtPercent(Context->WindowBounds, .5f, &Rects[0], &Rects[1]); + ui_widget_id Ids[2]; + + gs_string String = MakeString("Select"); + ui_StartRow(&State->Interface, 2); for (u32 j = 0; j < 2; j++) { - ui_PushLayout(&State->Interface, Rects[j], LayoutDirection_TopDown); - - if (ui_BeginDropdown(&State->Interface, MakeString("Select"))) + if (ui_BeginDropdown(&State->Interface, String)) { - for (s32 i = 0; i < GlobalPanelDefsCount; i++) + for (u32 i = 0; i < State->PanelSystem.PanelDefsCount; i++) { panel_definition Def = State->PanelSystem.PanelDefs[i]; gs_string DefName = MakeString(Def.PanelName, Def.PanelNameLength); @@ -184,11 +181,30 @@ Editor_Render(app_state* State, context* Context, render_command_buffer* RenderB } } ui_EndDropdown(&State->Interface); - - ui_PopLayout(&State->Interface); } + ui_EndRow(&State->Interface); + + ui_PopLayout(&State->Interface); + + Assert(!ui_WidgetIdsEqual(Ids[0], Ids[1])); +} + +internal void +Editor_Render(app_state* State, context* Context, render_command_buffer* RenderBuffer) +{ + PushRenderOrthographic(RenderBuffer, State->WindowBounds); + PushRenderClearScreen(RenderBuffer); #if 0 + TestRender(State, Context, RenderBuffer); + //ui_widget_id IdTwo = TestRender(State, Context, RenderBuffer); + //Assert(ui_WidgetIdsEqual(IdOne, IdTwo)); + +#else + ui_InterfaceReset(&State->Interface); + State->Interface.RenderBuffer = RenderBuffer; + ui_PushLayout(&State->Interface, Context->WindowBounds, LayoutDirection_TopDown, MakeString("Editor Layout")); + DrawAllPanels(State->PanelSystem, RenderBuffer, &Context->Mouse, State, *Context); for (s32 m = 0; m < State->Modes.ActiveModesCount; m++) @@ -199,13 +215,16 @@ Editor_Render(app_state* State, context* Context, render_command_buffer* RenderB OperationMode.Render(State, RenderBuffer, OperationMode, Context->Mouse, *Context); } } -#endif ui_PopLayout(&State->Interface); +#endif // Draw the Interface - ui_widget Widget = *State->Interface.DrawOrderRoot; - Editor_DrawWidget(State, Context, RenderBuffer, Widget); + if (State->Interface.DrawOrderRoot != 0) + { + ui_widget Widget = *State->Interface.DrawOrderRoot; + Editor_DrawWidget(State, Context, RenderBuffer, Widget); + } Context->GeneralWorkQueue->CompleteQueueWork(Context->GeneralWorkQueue, Context->ThreadContext); Context->GeneralWorkQueue->ResetWorkQueue(Context->GeneralWorkQueue); diff --git a/src/app/editor/foldhaus_interface.cpp b/src/app/editor/foldhaus_interface.cpp index 7a83912..29258ec 100644 --- a/src/app/editor/foldhaus_interface.cpp +++ b/src/app/editor/foldhaus_interface.cpp @@ -386,7 +386,8 @@ DrawPanelFooter(panel* Panel, render_command_buffer* RenderBuffer, rect2 FooterB rect2 PanelSelectBtnBounds = MakeRect2MinDim(FooterBounds.Min + v2{30, 1}, v2{100, 23}); - if (ui_BeginDropdown(&State->Interface, MakeString("Select"), PanelSelectBtnBounds)) + panel_definition CurrentDef = State->PanelSystem.PanelDefs[Panel->TypeIndex]; + if (ui_BeginDropdown(&State->Interface, MakeString(CurrentDef.PanelName, CurrentDef.PanelNameLength), PanelSelectBtnBounds)) { for (s32 i = 0; i < GlobalPanelDefsCount; i++) { diff --git a/src/app/editor/panels/foldhaus_panel_animation_timeline.h b/src/app/editor/panels/foldhaus_panel_animation_timeline.h index 1bd2d16..253f42e 100644 --- a/src/app/editor/panels/foldhaus_panel_animation_timeline.h +++ b/src/app/editor/panels/foldhaus_panel_animation_timeline.h @@ -587,7 +587,7 @@ PANEL_MODAL_OVERRIDE_CALLBACK(LoadAnimationFileCallback) internal void DrawAnimationClipsList(rect2 PanelBounds, ui_interface* Interface, u32 SelectedAnimationLayerHandle, animation_system* AnimationSystem) { - ui_PushLayout(Interface, PanelBounds, LayoutDirection_TopDown); + ui_PushLayout(Interface, PanelBounds, LayoutDirection_TopDown, MakeString("AnimClips Layout")); for (s32 i = 0; i < GlobalAnimationClipsCount; i++) { animation_clip Clip = GlobalAnimationClips[i]; @@ -605,7 +605,7 @@ PlayBar_Render(animation_timeline_state* TimelineState, rect2 Bounds, panel* Pan { animation_system* AnimSystem = &State->AnimationSystem; ui_interface* Interface = &State->Interface; - ui_PushLayout(Interface, Bounds, LayoutDirection_TopDown); + ui_PushLayout(Interface, Bounds, LayoutDirection_TopDown, MakeString("PlayBar Layout")); ui_FillRect(Interface, Bounds, Interface->Style.PanelBGColors[0]); ui_StartRow(&State->Interface, 4); @@ -792,7 +792,7 @@ AnimInfoView_Render(animation_timeline_state* TimelineState, rect2 Bounds, rende animation* ActiveAnim = AnimationSystem_GetActiveAnimation(AnimSystem); ui_interface* Interface = &State->Interface; - ui_PushLayout(Interface, Bounds, LayoutDirection_TopDown); + ui_PushLayout(Interface, Bounds, LayoutDirection_TopDown, MakeString("AnimInfo Layout")); ui_FillRect(&State->Interface, Bounds, Interface->Style.PanelBGColors[0]); diff --git a/src/app/editor/panels/foldhaus_panel_file_view.h b/src/app/editor/panels/foldhaus_panel_file_view.h index b80ba25..fdf8b54 100644 --- a/src/app/editor/panels/foldhaus_panel_file_view.h +++ b/src/app/editor/panels/foldhaus_panel_file_view.h @@ -88,7 +88,7 @@ internal void FileView_Render(panel* Panel, rect2 PanelBounds, render_command_buffer* RenderBuffer, app_state* State, context Context) { file_view_state* FileViewState = Panel_GetStateStruct(Panel, file_view_state); - ui_PushLayout(&State->Interface, PanelBounds, LayoutDirection_TopDown); + ui_PushLayout(&State->Interface, PanelBounds, LayoutDirection_TopDown, MakeString("FileView Layout")); if (ui_Button(&State->Interface, MakeString("Exit"))) { diff --git a/src/app/editor/panels/foldhaus_panel_hierarchy.h b/src/app/editor/panels/foldhaus_panel_hierarchy.h index d110e17..12c9fc2 100644 --- a/src/app/editor/panels/foldhaus_panel_hierarchy.h +++ b/src/app/editor/panels/foldhaus_panel_hierarchy.h @@ -38,7 +38,7 @@ GSMetaTag(panel_type_hierarchy); internal void HierarchyView_Render(panel* Panel, rect2 PanelBounds, render_command_buffer* RenderBuffer, app_state* State, context Context) { - ui_PushLayout(&State->Interface, PanelBounds, LayoutDirection_TopDown); + ui_PushLayout(&State->Interface, PanelBounds, LayoutDirection_TopDown, MakeString("Hierarchy Layout")); // TODO(pjs): Come back to this after the layout stuff is handled. // Ideally it handles the visuals of the hierarchy itself. diff --git a/src/app/editor/panels/foldhaus_panel_profiler.h b/src/app/editor/panels/foldhaus_panel_profiler.h index 7cdf042..d58b3fb 100644 --- a/src/app/editor/panels/foldhaus_panel_profiler.h +++ b/src/app/editor/panels/foldhaus_panel_profiler.h @@ -179,7 +179,7 @@ ProfilerView_Render(panel* Panel, rect2 PanelBounds, render_command_buffer* Rend debug_frame* VisibleFrame = GetLastDebugFrame(GlobalDebugServices); - ui_widget* Layout = ui_PushLayout(&State->Interface, ProcListBounds, LayoutDirection_TopDown); + ui_widget* Layout = ui_PushLayout(&State->Interface, ProcListBounds, LayoutDirection_TopDown, MakeString("Profiler Layout")); ui_StartRow(&State->Interface, 4); { diff --git a/src/app/foldhaus_app.cpp b/src/app/foldhaus_app.cpp index f3038f6..90ce10b 100644 --- a/src/app/foldhaus_app.cpp +++ b/src/app/foldhaus_app.cpp @@ -110,6 +110,8 @@ INITIALIZE_APPLICATION(InitializeApplication) State->Interface.WidgetsCountMax = 4096; State->Interface.Widgets = PushArray(&State->Permanent, ui_widget, State->Interface.WidgetsCountMax); + State->Interface.PerFrameMemory = PushStruct(&State->Permanent, gs_memory_arena); + *State->Interface.PerFrameMemory = CreateMemoryArena(Context.ThreadContext.Allocator); State->SACN = SACN_Initialize(Context); @@ -150,7 +152,6 @@ INITIALIZE_APPLICATION(InitializeApplication) AnimationArray_Push(&State->AnimationSystem.Animations, Anim); } // End Animation Playground - PanelSystem_Init(&State->PanelSystem, GlobalPanelDefs, GlobalPanelDefsCount, &State->Permanent); PanelSystem_PushPanel(&State->PanelSystem, PanelType_SculptureView, State, Context); } diff --git a/src/app/interface.h b/src/app/interface.h index 6509468..80b3ada 100644 --- a/src/app/interface.h +++ b/src/app/interface.h @@ -276,6 +276,7 @@ struct ui_widget_retained_state { ui_widget_id Id; bool Value; + u32 FramesSinceAccess; }; struct ui_interface @@ -299,6 +300,8 @@ struct ui_interface #define RETAINED_STATE_MAX 128 ui_widget_retained_state RetainedState[RETAINED_STATE_MAX]; u64 RetainedStateCount; + + gs_memory_arena* PerFrameMemory; }; internal void @@ -307,6 +310,16 @@ ui_InterfaceReset(ui_interface* Interface) Interface->WidgetsCount = 0; Interface->DrawOrderHead = 0; Interface->DrawOrderRoot = 0; + ClearArena(Interface->PerFrameMemory); + + for (u32 i = 0; i < Interface->RetainedStateCount; i++) + { + Interface->RetainedState[i].FramesSinceAccess += 1; + if (Interface->RetainedState[i].FramesSinceAccess > 1) + { + Interface->RetainedState[i] = {0}; + } + } } internal bool @@ -324,6 +337,7 @@ ui_GetRetainedState(ui_interface* Interface, ui_widget_id Id) { if (ui_WidgetIdsEqual(Interface->RetainedState[i].Id, Id)) { + Interface->RetainedState[i].FramesSinceAccess = 0; Result = Interface->RetainedState + i; break; } @@ -332,11 +346,11 @@ ui_GetRetainedState(ui_interface* Interface, ui_widget_id Id) } internal ui_widget_retained_state* -ui_CreateRetainedState(ui_interface* Interface, ui_widget_id Id) +ui_CreateRetainedState(ui_interface* Interface, ui_widget* Widget) { u64 Index = Interface->RetainedStateCount++; ui_widget_retained_state* Result = Interface->RetainedState + Index; - Result->Id = Id; + Result->Id = Widget->Id; return Result; } @@ -345,6 +359,8 @@ ui_CreateWidget(ui_interface* Interface, gs_string String) { Assert(Interface->WidgetsCount < Interface->WidgetsCountMax); ui_widget* Result = Interface->Widgets + Interface->WidgetsCount++; + ZeroStruct(Result); + Result->Parent = Interface->ActiveLayout; u64 Id = HashDJB2ToU64(StringExpand(String)); @@ -352,10 +368,11 @@ ui_CreateWidget(ui_interface* Interface, gs_string String) { Id = HashAppendDJB2ToU32(Id, Result->Parent->Id.Id); Id = HashAppendDJB2ToU32(Id, Result->Parent->ChildCount); + Result->Id.ParentId = Result->Parent->Id.Id; } Result->Id.Id = Id; - Result->String = String; + Result->String = PushStringCopy(Interface->PerFrameMemory, String.ConstString); Result->Alignment = Align_Left; Result->Next = 0; Result->ChildrenRoot = 0; @@ -364,6 +381,21 @@ ui_CreateWidget(ui_interface* Interface, gs_string String) return Result; } +internal void +ui_WidgetSetFlag(ui_widget* Widget, u64 Flag) +{ + u64 Value = ((u64)1 << Flag); + Widget->Flags = Widget->Flags | Value; +} + +internal bool +ui_WidgetIsFlagSet(ui_widget Widget, u64 Flag) +{ + u64 Value = ((u64)1 << Flag); + bool Result = (Widget.Flags & Value); + return Result; +} + // // Interaction // @@ -379,13 +411,16 @@ ui_MouseClickedRect(ui_interface Interface, rect2 Rect) // Layout static ui_widget* -ui_PushLayout(ui_interface* Interface, rect2 Bounds, ui_layout_direction FillDir) +ui_PushLayout(ui_interface* Interface, rect2 Bounds, ui_layout_direction FillDir, gs_string Name) { - ui_widget* Result = ui_CreateWidget(Interface, MakeString("Layout")); + ui_widget* Result = ui_CreateWidget(Interface, Name); + ui_WidgetSetFlag(Result, UIWidgetFlag_DrawOutline); + Result->Bounds = Bounds; Result->Margin = Interface->Style.Margin; Result->RowHeight = Interface->Style.RowHeight; Result->FillDirection = FillDir; + switch(FillDir) { case LayoutDirection_BottomUp: @@ -418,7 +453,7 @@ static void ui_PopLayout(ui_interface* Interface) { Assert(Interface->ActiveLayout != 0); - ui_EvaluateWidget(Interface, Interface->ActiveLayout, Interface->ActiveLayout->Bounds); + //ui_EvaluateWidget(Interface, Interface->ActiveLayout, Interface->ActiveLayout->Bounds); Interface->ActiveLayout = Interface->ActiveLayout->Parent; } @@ -534,35 +569,14 @@ ui_LayoutRemaining(ui_widget Layout) // Widgets -internal void -ui_WidgetSetFlag(ui_widget* Widget, u64 Flag) -{ - u64 Value = ((u64)1 << Flag); - Widget->Flags = Widget->Flags | Value; -} - -internal bool -ui_WidgetIsFlagSet(ui_widget Widget, u64 Flag) -{ - u64 Value = ((u64)1 << Flag); - bool Result = (Widget.Flags & Value); - return Result; -} - internal ui_eval_result ui_EvaluateWidget(ui_interface* Interface, ui_widget* Widget, rect2 Bounds) { ui_eval_result Result = {}; - //Assert(Interface->WidgetsCount < Interface->WidgetsCountMax); - //u64 Index = Interface->WidgetsCount++; - - Widget->Id.Id = HashDJB2ToU64(StringExpand(Widget->String)); - Widget->Id.ParentId = Interface->ActiveLayout->Id.Id; - Widget->Bounds = Bounds; - //Interface->Widgets[Index] = *Widget; SLLPushOrInit(Interface->ActiveLayout->ChildrenRoot, Interface->ActiveLayout->ChildrenHead, Widget); + Interface->ActiveLayout->ChildCount += 1; if (ui_WidgetIsFlagSet(*Widget, UIWidgetFlag_Clickable)) { @@ -711,7 +725,7 @@ ui_EvaluateDropdown(ui_interface* Interface, ui_widget* Widget, ui_eval_result E { ui_widget_retained_state* State = ui_GetRetainedState(Interface, Widget->Id); if (!State) { - State = ui_CreateRetainedState(Interface, Widget->Id); + State = ui_CreateRetainedState(Interface, Widget); } if (EvalResult.Clicked) @@ -747,7 +761,7 @@ ui_EvaluateDropdown(ui_interface* Interface, ui_widget* Widget, ui_eval_result E }; } - ui_widget* Layout = ui_PushLayout(Interface, MenuBounds, Direction); + ui_widget* Layout = ui_PushLayout(Interface, MenuBounds, Direction, MakeString("WidgetLayout")); Layout->WidgetReference = Widget->Id; } @@ -760,6 +774,7 @@ ui_BeginDropdown(ui_interface* Interface, gs_string Text, rect2 Bounds) ui_widget* Widget = ui_CreateWidget(Interface, Text); ui_WidgetSetFlag(Widget, UIWidgetFlag_Clickable); ui_WidgetSetFlag(Widget, UIWidgetFlag_DrawBackground); + ui_WidgetSetFlag(Widget, UIWidgetFlag_DrawString); ui_eval_result Result = ui_EvaluateWidget(Interface, Widget, Bounds); return ui_EvaluateDropdown(Interface, Widget, Result); } @@ -770,6 +785,7 @@ ui_BeginDropdown(ui_interface* Interface, gs_string Text) ui_widget* Widget = ui_CreateWidget(Interface, Text); ui_WidgetSetFlag(Widget, UIWidgetFlag_Clickable); ui_WidgetSetFlag(Widget, UIWidgetFlag_DrawBackground); + ui_WidgetSetFlag(Widget, UIWidgetFlag_DrawString); ui_eval_result Result = ui_EvaluateWidget(Interface, Widget); return ui_EvaluateDropdown(Interface, Widget, Result); } diff --git a/src/app/platform_win32/win32_foldhaus.cpp b/src/app/platform_win32/win32_foldhaus.cpp index 653dbe6..1d2bb65 100644 --- a/src/app/platform_win32/win32_foldhaus.cpp +++ b/src/app/platform_win32/win32_foldhaus.cpp @@ -413,7 +413,7 @@ Win32_SendAddressedDataBuffers(gs_thread_context Context, addressed_data_buffer_ gs_string OutputStr = AllocatorAllocString(Context.Allocator, 256); PrintF(&OutputStr, "Buffers Sent: %d\n", BuffersSent); NullTerminate(&OutputStr); - OutputDebugStringA(OutputStr.Str); + //OutputDebugStringA(OutputStr.Str); } internal void @@ -685,6 +685,10 @@ WinMain ( LastFrameSecondsElapsed = SecondsElapsed; LastFrameEnd = GetWallClock(); + + + OutputDebugStringA("-- Frame END -- \n"); + } Context.CleanupApplication(Context); diff --git a/src/app/platform_win32/win32_foldhaus_work_queue.h b/src/app/platform_win32/win32_foldhaus_work_queue.h index 2db58f3..0b31fa6 100644 --- a/src/app/platform_win32/win32_foldhaus_work_queue.h +++ b/src/app/platform_win32/win32_foldhaus_work_queue.h @@ -46,6 +46,8 @@ Win32CreateThreadContext(gs_memory_arena* Transient = 0) Win32EnumerateDirectory, Result.Transient); + Result.DebugOutput.Print = Win32DebugPrint; + return Result; } diff --git a/src/gs_libs/gs_types.cpp b/src/gs_libs/gs_types.cpp index a42bdae..f69657c 100644 --- a/src/gs_libs/gs_types.cpp +++ b/src/gs_libs/gs_types.cpp @@ -1979,31 +1979,31 @@ PrintFArgsList (gs_string* String, char* Format, va_list Args) if (FormatAt[0] == 'h' && FormatAt[1] == 'h') { LengthSpecified = true; - LengthSpecified = 1; + Length = 1; FormatAt += 2; } else if (FormatAt[0] == 'h') { LengthSpecified = true; - LengthSpecified = 2; + Length = 2; FormatAt++; } else if (FormatAt[0] == 'l' && FormatAt[1] == 'l') { LengthSpecified = true; - LengthSpecified = 8; + Length = 8; FormatAt += 2; } else if (FormatAt[0] == 'l') { LengthSpecified = true; - LengthSpecified = 4; + Length = 4; FormatAt++; } else if (FormatAt[0] == 'j') { LengthSpecified = true; - LengthSpecified = 8; + Length = 8; FormatAt++; } else if (FormatAt[0] == 'z') @@ -2034,7 +2034,7 @@ PrintFArgsList (gs_string* String, char* Format, va_list Args) } else if (FormatAt[0] == 'u') { - u32 UnsignedInt = ReadVarArgsUnsignedInteger(Length, &Args); + u64 UnsignedInt = ReadVarArgsUnsignedInteger(Length, &Args); U64ToASCII(&StringRemaining, UnsignedInt, 10, Base10Chars); } else if (FormatAt[0] == 'o') @@ -2475,6 +2475,19 @@ PushStringF(gs_memory_arena* Arena, u32 MaxLength, char* Format, ...) return Result; } +internal gs_string +PushStringCopy(gs_memory_arena* Arena, gs_const_string String) +{ + gs_string Result = PushString(Arena, String.Length); + Result.Size = String.Length; + Result.Length = String.Length; + for (u32 i = 0; i < String.Length; i++) + { + Result.Str[i] = String.Str[i]; + } + return Result; +} + internal void ClearArena(gs_memory_arena* Arena) { diff --git a/src/todo.txt b/src/todo.txt index 3dcb1f0..c2ef7b1 100644 --- a/src/todo.txt +++ b/src/todo.txt @@ -43,7 +43,6 @@ STREAM #1: 3D Overhaul - :ErrorLogging - Animation System - - blending between animation - layers - layer masks by sculpture - layer masks by tag / value diff --git a/src/todo_done.txt b/src/todo_done.txt index 6aae2d4..ac67406 100644 --- a/src/todo_done.txt +++ b/src/todo_done.txt @@ -1,3 +1,5 @@ +x blending between animation + x saving animation timelines x Buckets & Lists x On second thought, I just really don't like these. Lets get rid of them, and put custom structures in place