diff --git a/src/foldhaus_app.cpp b/src/foldhaus_app.cpp index 82e633e..7dbc01d 100644 --- a/src/foldhaus_app.cpp +++ b/src/foldhaus_app.cpp @@ -625,7 +625,8 @@ UPDATE_AND_RENDER(UpdateAndRender) DEBUG_IF(GlobalDebugServices->Interface.RenderSculpture) // DebugServices RenderSculpture Toggle { - s32 JobsNeeded = IntegerDivideRoundUp(State->TotalLEDsCount, LED_BUFFER_SIZE); + s32 JobsNeeded = PLATFORM_THREAD_COUNT; + s32 LEDBufferSize = IntegerDivideRoundUp(State->TotalLEDsCount, JobsNeeded); draw_leds_job_data* JobDataBank = PushArray(State->Transient, draw_leds_job_data, JobsNeeded); s32 JobDataBankUsed = 0; @@ -645,7 +646,7 @@ UPDATE_AND_RENDER(UpdateAndRender) JobData->LEDs = LEDBuffer->LEDs; JobData->Colors = LEDBuffer->Colors; JobData->StartIndex = LEDBufferLEDsAssignedToJobs; - JobData->OnePastLastIndex = GSMin(JobData->StartIndex + LED_BUFFER_SIZE, LEDBuffer->Count); + JobData->OnePastLastIndex = GSMin(JobData->StartIndex + LEDBufferSize, LEDBuffer->Count); LEDBufferLEDsAssignedToJobs += JobData->OnePastLastIndex - JobData->StartIndex; diff --git a/src/foldhaus_app.h b/src/foldhaus_app.h index 2bb3f13..55ad2c2 100644 --- a/src/foldhaus_app.h +++ b/src/foldhaus_app.h @@ -6,7 +6,6 @@ #include "foldhaus_network_ordering.h" #include "foldhaus_sacn.h" -#define LED_BUFFER_SIZE 256 struct led { s32 Index; diff --git a/src/foldhaus_debug.h b/src/foldhaus_debug.h index 6bfaf03..960cd23 100644 --- a/src/foldhaus_debug.h +++ b/src/foldhaus_debug.h @@ -48,7 +48,9 @@ struct debug_services debug_timing_proc* GetWallClock; - debug_histogram_entry ScopeHistogram[SCOPE_HISTOGRAM_SIZE]; + debug_histogram_entry* ScopeHistogramUnsorted; + debug_histogram_entry* ScopeHistogramSorted; + s32 ScopeHistogramUsed; }; @@ -70,6 +72,9 @@ InitDebugServices (debug_services* Services, u8* Memory, s32 MemorySize, s32 Tra Services->Interface.RenderSculpture = true; Services->Interface.SendSACNData = false; + Services->ScopeHistogramUnsorted = PushArray(&Services->DebugStorage, debug_histogram_entry, SCOPE_HISTOGRAM_SIZE); + Services->ScopeHistogramSorted = PushArray(&Services->DebugStorage, debug_histogram_entry, SCOPE_HISTOGRAM_SIZE); + Services->ScopeHistogramUsed = 0; } @@ -79,7 +84,7 @@ DEBUGFindScopeHistogram (debug_services* Services, string Name) s32 Result = -1; for (s32 i = 0; i < SCOPE_HISTOGRAM_SIZE; i++) { - if (StringsEqual(Services->ScopeHistogram[i].ScopeName, Name)) + if (StringsEqual(Services->ScopeHistogramUnsorted[i].ScopeName, Name)) { Result = i; break; @@ -95,7 +100,7 @@ DEBUGAddScopeHistogram (debug_services* Services, scope_time_record Record) s32 Result = Services->ScopeHistogramUsed++; - debug_histogram_entry* Entry = Services->ScopeHistogram + Result; + debug_histogram_entry* Entry = Services->ScopeHistogramUnsorted + Result; Entry->ScopeName = MakeString(Entry->ScopeName_, 256); Entry->CurrentFrame = 0; @@ -112,7 +117,7 @@ DEBUGAddScopeHistogram (debug_services* Services, scope_time_record Record) internal void DEBUGRecordScopeInHistogram (debug_services* Services, s32 Index, scope_time_record Record) { - debug_histogram_entry* Entry = Services->ScopeHistogram + Index; + debug_histogram_entry* Entry = Services->ScopeHistogramUnsorted + Index; s32 FrameIndex = Entry->CurrentFrame; if (FrameIndex >= 0 && FrameIndex < HISTOGRAM_DEPTH) { @@ -138,6 +143,43 @@ DEBUGCacheScopeHistogramValues (debug_histogram_entry* Histogram) Histogram->Average_CallCount = (Histogram->Total_CallCount / HISTOGRAM_DEPTH); } +internal void +DEBUGSortedHistogramInsert(debug_histogram_entry Source, debug_histogram_entry* DestList, s32 DestCount, s32 Max) +{ + s32 CurrentFrame0 = Source.CurrentFrame; + s32 V0 = Source.Average_Cycles; //PerFrame_Cycles[CurrentFrame0]; + if (DestCount > 0) + { + for (s32 i = DestCount - 1; i >= 0; i--) + { + s32 CurrentFrame1 = DestList[i].CurrentFrame; + s32 V1 = DestList[i].Average_Cycles; //PerFrame_Cycles[CurrentFrame1]; + if (V0 < V1) + { + DestList[i + 1] = Source; + break; + } + else + { + DestList[i + 1] = DestList[i]; + } + } + } + else + { + DestList[0] = Source; + } +} + +internal void +DEBUGSortHistogram(debug_histogram_entry* Source, debug_histogram_entry* Dest, s32 Count, s32 Max) +{ + for (s32 i = 0; i < Count; i++) + { + DEBUGSortedHistogramInsert(Source[i], Dest, i, Max); + } +} + internal void DEBUGCollateScopeRecords (debug_services* Services) { @@ -155,8 +197,13 @@ DEBUGCollateScopeRecords (debug_services* Services) for (s32 h = 0; h < Services->ScopeHistogramUsed; h++) { - DEBUGCacheScopeHistogramValues(Services->ScopeHistogram + h); + DEBUGCacheScopeHistogramValues(Services->ScopeHistogramUnsorted + h); } + + DEBUGSortHistogram(Services->ScopeHistogramUnsorted, + Services->ScopeHistogramSorted, + Services->ScopeHistogramUsed, + SCOPE_HISTOGRAM_SIZE); } internal void @@ -169,14 +216,14 @@ EndDebugFrame (debug_services* Services) for (s32 i = 0; i < Services->ScopeHistogramUsed; i++) { - s32 NewFrame = Services->ScopeHistogram[i].CurrentFrame + 1; + s32 NewFrame = Services->ScopeHistogramUnsorted[i].CurrentFrame + 1; if (NewFrame >= HISTOGRAM_DEPTH) { NewFrame = 0; } - Services->ScopeHistogram[i].CurrentFrame = NewFrame; - Services->ScopeHistogram[i].PerFrame_Cycles[NewFrame] = 0; - Services->ScopeHistogram[i].PerFrame_CallCount[NewFrame] = 0; + Services->ScopeHistogramUnsorted[i].CurrentFrame = NewFrame; + Services->ScopeHistogramUnsorted[i].PerFrame_Cycles[NewFrame] = 0; + Services->ScopeHistogramUnsorted[i].PerFrame_CallCount[NewFrame] = 0; } } diff --git a/src/foldhaus_debug_visuals.h b/src/foldhaus_debug_visuals.h index 682431e..ebaf3e3 100644 --- a/src/foldhaus_debug_visuals.h +++ b/src/foldhaus_debug_visuals.h @@ -119,22 +119,22 @@ DrawDebugInterface (render_command_buffer* RenderBuffer, r32 StartX, interface_c { v2 Register = v2{ColumnsStartX, TopOfScreenLinePos.y}; - s32 CurrentFrame = GlobalDebugServices->ScopeHistogram[i].CurrentFrame - 1; + s32 CurrentFrame = GlobalDebugServices->ScopeHistogramSorted[i].CurrentFrame - 1; if (CurrentFrame < 0) { CurrentFrame = HISTOGRAM_DEPTH - 1; } - u64 CyclesPerHit = GlobalDebugServices->ScopeHistogram[i].PerFrame_Cycles[CurrentFrame]; + u64 CyclesPerHit = GlobalDebugServices->ScopeHistogramSorted[i].PerFrame_Cycles[CurrentFrame]; r32 SecondsPerHit = (r32)CyclesPerHit / (r32)GlobalDebugServices->PerformanceCountFrequency; // Column 1 PrintF(&DebugString, "%.*s", - GlobalDebugServices->ScopeHistogram[i].ScopeName.Length, - GlobalDebugServices->ScopeHistogram[i].ScopeName.Memory); + GlobalDebugServices->ScopeHistogramSorted[i].ScopeName.Length, + GlobalDebugServices->ScopeHistogramSorted[i].ScopeName.Memory); r32 ColumnOneX = DrawString(RenderBuffer, DebugString, Interface.Font, Interface.FontSize, Register, WhiteV4).x; Register.x += GSMax(ColumnOneX - Register.x, 250.f); // Column 2 - PrintF(&DebugString, "%d hits", GlobalDebugServices->ScopeHistogram[i].PerFrame_CallCount[CurrentFrame]); + PrintF(&DebugString, "%d hits", GlobalDebugServices->ScopeHistogramSorted[i].PerFrame_CallCount[CurrentFrame]); r32 ColumnTwoX = DrawString(RenderBuffer, DebugString, Interface.Font, Interface.FontSize, Register, WhiteV4).x; Register.x += GSMax(ColumnTwoX - Register.x, 150.f); diff --git a/src/foldhaus_interface.cpp b/src/foldhaus_interface.cpp index 7d44a40..a56d022 100644 --- a/src/foldhaus_interface.cpp +++ b/src/foldhaus_interface.cpp @@ -413,17 +413,18 @@ BeginDraggingNode(app_state* State, node_interaction Interaction) struct node_view_operation_state { + node_offset SelectedNodeOffset; }; FOLDHAUS_INPUT_COMMAND_PROC(NodeViewBeginMouseDragInteraction) { node_view_operation_state* OpState = GetCurrentOperationState(State->Modes, node_view_operation_state); - node_offset Node = GetNodeUnderPoint(State->NodeList, Mouse.DownPos, State->NodeRenderSettings); - if (Node.Node) + node_offset NodeOffset = GetNodeUnderPoint(State->NodeList, Mouse.DownPos, State->NodeRenderSettings); + if (NodeOffset.Node) { - node_interaction NewInteraction = GetNodeInteractionType(Node.Node, - Node.Offset, + node_interaction NewInteraction = GetNodeInteractionType(NodeOffset.Node, + NodeOffset.Offset, Mouse.Pos, State->NodeRenderSettings); if (IsDraggingNodePort(NewInteraction)) @@ -439,9 +440,14 @@ FOLDHAUS_INPUT_COMMAND_PROC(NodeViewBeginMouseDragInteraction) } else // IsDraggingNode { + OpState->SelectedNodeOffset = NodeOffset; BeginDraggingNode(State, NewInteraction); } } + else + { + OpState->SelectedNodeOffset = InvalidNodeOffset(); + } } FOLDHAUS_INPUT_COMMAND_PROC(NodeViewBeginMouseSelectInteraction) @@ -475,7 +481,108 @@ FOLDHAUS_INPUT_COMMAND_PROC(NodeViewBeginMouseSelectInteraction) OPERATION_RENDER_PROC(RenderNodeView) { node_view_operation_state* OpState = (node_view_operation_state*)Operation.OpStateMemory; - RenderNodeList(State->NodeList, State->NodeRenderSettings, RenderBuffer); + + DEBUG_TRACK_FUNCTION; + + node_list_iterator NodeIter = GetNodeListIterator(*State->NodeList); + while (NodeIteratorIsValid(NodeIter)) + { + interface_node* Node = NodeIter.At; + Node->Min = Node->MinAfterUpdate; + + rect NodeBounds = CalculateNodeBounds(Node, State->NodeRenderSettings); + b32 DrawFields = PointIsInRect(Mouse.Pos, NodeBounds); + + if (Node == OpState->SelectedNodeOffset.Node) + { + PushRenderQuad2D(RenderBuffer, NodeBounds.Min - v2{2, 2}, NodeBounds.Max + v2{2, 2}, WhiteV4); + } + + PushRenderQuad2D(RenderBuffer, NodeBounds.Min, NodeBounds.Max, v4{.5f, .5f, .5f, 1.f}); + + DrawString(RenderBuffer, Node->Name, State->NodeRenderSettings.Font, State->NodeRenderSettings.Font->PixelHeight, + v2{NodeBounds.Min.x + 5, NodeBounds.Max.y - (State->NodeRenderSettings.Font->PixelHeight + NODE_HEADER_HEIGHT + 5)}, + WhiteV4); + + for (s32 Connection = 0; Connection < Node->ConnectionsCount; Connection++) + { + v4 PortColor = State->NodeRenderSettings.PortColors[Node->Connections[Connection].Type]; + + // Inputs + if (ConnectionIsInput(Node, Connection)) + { + rect PortBounds = CalculateNodeInputPortBounds(Node, Connection, State->NodeRenderSettings); + DrawPort(RenderBuffer, PortBounds, PortColor); + + // + // TODO(Peter): I don't like excluding OutputNode, feels too much like a special case + // but I don't want to get in to the meta programming right now. + // We should just generate a spec and struct member types for NodeType_OutputNode + // + // :ExcludingOutputNodeSpecialCase + // + if (Node->Type != NodeType_OutputNode && DrawFields) + { + node_specification Spec = NodeSpecifications[Node->Type - 1]; + node_struct_member Member = Spec.MemberList[Connection]; + DrawString(RenderBuffer, MakeString(Member.Name), + State->NodeRenderSettings.Font, State->NodeRenderSettings.Font->PixelHeight, + v2{PortBounds.Min.x - 32, PortBounds.Min.y}, WhiteV4); + } + + rect ValueBounds = CalculateNodeInputValueBounds(Node, Connection, State->NodeRenderSettings); + DrawValueDisplay(RenderBuffer, ValueBounds, Node->Connections[Connection], State->NodeRenderSettings.Font); + + // NOTE(Peter): its way easier to draw the connection on the input port b/c its a 1:1 relationship, + // whereas output ports might have many connections, they really only know about the most recent one + // Not sure if this is a problem. We mostly do everything backwards here, starting at the + // most downstream node and working back up to find dependencies. + if (ConnectionHasUpstreamConnection(Node, Connection)) + { + rect ConnectedPortBounds = GetBoundsOfPortConnectedToInput(Node, Connection, State->NodeList, State->NodeRenderSettings); + v2 InputCenter = CalculateRectCenter(PortBounds); + v2 OutputCenter = CalculateRectCenter(ConnectedPortBounds); + PushRenderLine2D(RenderBuffer, OutputCenter, InputCenter, 1, WhiteV4); + } + } + + // Outputs + if (ConnectionIsOutput(Node, Connection)) + { + rect PortBounds = CalculateNodeOutputPortBounds(Node, Connection, State->NodeRenderSettings); + DrawPort(RenderBuffer, PortBounds, PortColor); + + if (DrawFields) + { + node_specification Spec = NodeSpecifications[Node->Type - 1]; + node_struct_member Member = Spec.MemberList[Connection]; + DrawString(RenderBuffer, MakeString(Member.Name), + State->NodeRenderSettings.Font, State->NodeRenderSettings.Font->PixelHeight, + v2{PortBounds.Max.x + 8, PortBounds.Min.y}, WhiteV4); + } + + rect ValueBounds = CalculateNodeOutputValueBounds(Node, Connection, State->NodeRenderSettings); + DrawValueDisplay(RenderBuffer, ValueBounds, Node->Connections[Connection], State->NodeRenderSettings.Font); + } + + for (s32 Button = 0; Button < 3; Button++) + { + rect ButtonRect = CalculateNodeDragHandleBounds(NodeBounds, Button, State->NodeRenderSettings); + PushRenderQuad2D(RenderBuffer, ButtonRect.Min, ButtonRect.Max, DragButtonColors[Button]); + } + } + + Next(&NodeIter); + } +} + +FOLDHAUS_INPUT_COMMAND_PROC(NodeViewDeleteNode) +{ + /*node_view_operation_state* OpState = (node_view_operation_state*)Operation.OpStateMemory; + if (IsValidOffset(OpState->SelectedNodeOffset)) + { + + }*/ } FOLDHAUS_INPUT_COMMAND_PROC(CloseNodeView) @@ -488,6 +595,7 @@ input_command NodeViewCommands [] = { { KeyCode_A, KeyCode_Invalid, Command_Began, OpenNodeLister}, { KeyCode_MouseLeftButton, KeyCode_Invalid, Command_Began, NodeViewBeginMouseDragInteraction}, { KeyCode_MouseLeftButton, KeyCode_Invalid, Command_Ended, NodeViewBeginMouseSelectInteraction}, + { KeyCode_X, KeyCode_Invalid, Command_Began, NodeViewDeleteNode}, }; FOLDHAUS_INPUT_COMMAND_PROC(OpenNodeView) @@ -498,6 +606,7 @@ FOLDHAUS_INPUT_COMMAND_PROC(OpenNodeView) node_view_operation_state* OpState = CreateOperationState(NodeViewMode, &State->Modes, node_view_operation_state); + OpState->SelectedNodeOffset = InvalidNodeOffset(); } //////////////////////////////////////// diff --git a/src/foldhaus_node.cpp b/src/foldhaus_node.cpp index 49709ff..5463581 100644 --- a/src/foldhaus_node.cpp +++ b/src/foldhaus_node.cpp @@ -1,3 +1,20 @@ +inline node_offset +InvalidNodeOffset() +{ + node_offset Result = {}; + + // NOTE(Peter): I'm not sure this is actually invalid. Should be. + // If it is valid, it implies you can have offset from somewhere other than the beginning of + // the array, but where that point is isn't captured here so it seems like that shouldn't be + // correct + Result.Offset = -1; + Result.Node = 0; // NOTE(Peter): Pretty sure this is invalid tho ;) + + return Result; +} + +#define IsValidOffset(off) ((off.Node != 0) && (off.Offset >= 0)) +#define IsInvalidOffset(off) ((off.Node == 0) && (off.Offset < 0)) inline s32 GetNodeMemorySize (interface_node Node) @@ -136,6 +153,7 @@ CalculateNodeHeight (s32 Members) internal void PushNodeOnListFromSpecification (node_list* List, node_specification Spec, v2 Min, memory_arena* Storage) { + // :NodesDontNeedToKnowTheirBounds r32 NodeHeight = CalculateNodeHeight (Spec.MemberListLength); interface_node* Node = PushNodeOnList(List, Spec.NameLength, @@ -1045,72 +1063,6 @@ DrawPort (render_command_buffer* RenderBuffer, rect Bounds, v4 Color) PushRenderQuad2D(RenderBuffer, Bounds.Min, Bounds.Max, Color); } -internal void -RenderNodeList (node_list* NodeList, node_render_settings RenderSettings, render_command_buffer* RenderBuffer) -{ - DEBUG_TRACK_FUNCTION; - - node_list_iterator NodeIter = GetNodeListIterator(*NodeList); - while (NodeIteratorIsValid(NodeIter)) - { - interface_node* Node = NodeIter.At; - Node->Min = Node->MinAfterUpdate; - - rect NodeBounds = CalculateNodeBounds(Node, RenderSettings); - - PushRenderQuad2D(RenderBuffer, NodeBounds.Min, NodeBounds.Max, v4{.5f, .5f, .5f, 1.f}); - - DrawString(RenderBuffer, Node->Name, RenderSettings.Font, RenderSettings.Font->PixelHeight, - v2{NodeBounds.Min.x + 5, NodeBounds.Max.y - (RenderSettings.Font->PixelHeight + NODE_HEADER_HEIGHT + 5)}, - WhiteV4); - - for (s32 Connection = 0; Connection < Node->ConnectionsCount; Connection++) - { - // Inputs - if (ConnectionIsInput(Node, Connection)) - { - rect PortBounds = CalculateNodeInputPortBounds(Node, Connection, RenderSettings); - v4 PortColor = RenderSettings.PortColors[Node->Connections[Connection].Type]; - DrawPort(RenderBuffer, PortBounds, PortColor); - - rect ValueBounds = CalculateNodeInputValueBounds(Node, Connection, RenderSettings); - DrawValueDisplay(RenderBuffer, ValueBounds, Node->Connections[Connection], RenderSettings.Font); - - // NOTE(Peter): its way easier to draw the connection on the input port b/c its a 1:1 relationship, - // whereas output ports might have many connections, they really only know about the most recent one - // Not sure if this is a problem. We mostly do everything backwards here, starting at the - // most downstream node and working back up to find dependencies. - if (ConnectionHasUpstreamConnection(Node, Connection)) - { - rect ConnectedPortBounds = GetBoundsOfPortConnectedToInput(Node, Connection, NodeList, RenderSettings); - v2 InputCenter = CalculateRectCenter(PortBounds); - v2 OutputCenter = CalculateRectCenter(ConnectedPortBounds); - PushRenderLine2D(RenderBuffer, OutputCenter, InputCenter, 1, WhiteV4); - } - } - - // Outputs - if (ConnectionIsOutput(Node, Connection)) - { - rect PortBounds = CalculateNodeOutputPortBounds(Node, Connection, RenderSettings); - v4 PortColor = RenderSettings.PortColors[Node->Connections[Connection].Type]; - DrawPort(RenderBuffer, PortBounds, PortColor); - - rect ValueBounds = CalculateNodeOutputValueBounds(Node, Connection, RenderSettings); - DrawValueDisplay(RenderBuffer, ValueBounds, Node->Connections[Connection], RenderSettings.Font); - } - - for (s32 Button = 0; Button < 3; Button++) - { - rect ButtonRect = CalculateNodeDragHandleBounds(NodeBounds, Button, RenderSettings); - PushRenderQuad2D(RenderBuffer, ButtonRect.Min, ButtonRect.Max, DragButtonColors[Button]); - } - } - - Next(&NodeIter); - } -} - internal void ResetNodesUpdateState (node_list* NodeList) { diff --git a/src/foldhaus_platform.h b/src/foldhaus_platform.h index eb4be56..c71f92e 100644 --- a/src/foldhaus_platform.h +++ b/src/foldhaus_platform.h @@ -57,6 +57,8 @@ typedef DRAW_FONT_CODEPOINT(platform_draw_font_codepoint); // Worker Threads +#define PLATFORM_THREAD_COUNT 4 + #define THREADED_WORK_PROC(name) void name(s32 ThreadID, void* Data) typedef THREADED_WORK_PROC(threaded_work_proc); diff --git a/src/interface.h b/src/interface.h index 62f2184..a9d81e0 100644 --- a/src/interface.h +++ b/src/interface.h @@ -18,6 +18,8 @@ DrawCharacter (render_quad_batch_constructor* BatchConstructor, char C, bitmap_f return v2{Position.x + CodepointInfo.Width * FontScale, Position.y}; } +// TODO(Peter): Why are we passing in both the bitmap_font and the point size when everywhere, we just +// use the native point size of the font??? internal v2 DrawString (render_command_buffer* RenderBuffer, string String, bitmap_font* Font, s32 PointSize, v2 Position, v4 Color) { diff --git a/src/win32_foldhaus.cpp b/src/win32_foldhaus.cpp index 2fcba4e..01f8a8f 100644 --- a/src/win32_foldhaus.cpp +++ b/src/win32_foldhaus.cpp @@ -533,22 +533,22 @@ INT NCmdShow // Set up worker threads // - const s32 WorkerThreadCount = 2; + const s32 WorkerThreadCount = PLATFORM_THREAD_COUNT; worker_thread_info* WorkerThreads = 0; - if (WorkerThreadCount > 0) + if (PLATFORM_THREAD_COUNT > 0) { - WorkerThreads = (worker_thread_info*)malloc(sizeof(worker_thread_info) * WorkerThreadCount); + WorkerThreads = (worker_thread_info*)malloc(sizeof(worker_thread_info) * PLATFORM_THREAD_COUNT); } work_queue WorkQueue = {}; - WorkQueue.SemaphoreHandle = CreateSemaphoreEx(0, 0, WorkerThreadCount, 0, 0, SEMAPHORE_ALL_ACCESS); + WorkQueue.SemaphoreHandle = CreateSemaphoreEx(0, 0, PLATFORM_THREAD_COUNT, 0, 0, SEMAPHORE_ALL_ACCESS); WorkQueue.JobsMax = 256; WorkQueue.NextJobIndex = 0; WorkQueue.PushWorkOnQueue = Win32PushWorkOnQueue; WorkQueue.DoQueueWorkUntilDone = Win32DoQueueWorkUntilDone; WorkQueue.ResetWorkQueue = ResetWorkQueue; - for (s32 i = 0; i < WorkerThreadCount; i++) + for (s32 i = 0; i < PLATFORM_THREAD_COUNT; i++) { // ID = 0 is reserved for this thread WorkerThreads[i].ID = i + 1; @@ -670,7 +670,7 @@ INT NCmdShow CleanupResult = WSACleanup(); }while(CleanupResult == SOCKET_ERROR); - for (s32 Thread = 0; Thread < WorkerThreadCount; Thread++) + for (s32 Thread = 0; Thread < PLATFORM_THREAD_COUNT; Thread++) { TerminateThread(WorkerThreads[Thread].Handle, 0); } diff --git a/todo.txt b/todo.txt index f1decd7..2ca35e9 100644 --- a/todo.txt +++ b/todo.txt @@ -8,27 +8,32 @@ Hardening - Then we want to think about separating out mode render functions from mode update functions. Not sure its necessary but having something that operates like an update funciton but is called render is weird. Might want some sort of coroutine functionality in place, where modes can add and remove optional, parallel update functions - memory visualization +- - Log memory allocations - separate rendering thread - cache led positions. Only update if they are moving - - shift drag to 10x drag speed -- select nodes -> delete nodes -- remove node connections UI Improvements - highlight node field under active edit -- print node field names on hover or on the node +- draw cursor in node field under active edit +x print node field names on hover or on the node +- Mouse Held Commands +- Actual cursor states + +API Improvements +- Clean up DrawString... good lord +- Add Text Alignment to DrawString +- Investigate why we're giving nodes bounds :NodesDontNeedToKnowTheirBounds +- - Cant we just calculate this at render time? Application - More efficient HSV <-> RGB - - Save and load a session -- - Serialize Nodes - Don't render if the window isn't visible Development - Fix your scope time tracker to account for threads. - Nest scope times so you can see totals/dig in -- Log memory allocations Interface - fullscreen @@ -40,10 +45,11 @@ Interface - Update the text system - use system fonts Switch To Nodes -- evaluation step (one node at a time) - selector node (has a list of connections that it can switch between) -- serialize - delete nodes +- remove node connections +- Serialize Nodes +- evaluation step (one node at a time) Structure - motion diff --git a/todo_done.txt b/todo_done.txt index 611c8c5..96ea083 100644 --- a/todo_done.txt +++ b/todo_done.txt @@ -20,6 +20,7 @@ x decided I don't like storing NodeRenderSettings in each operation mode. Probab /Debug x Make debug scope tracking thread safe - was throwing an error in stringsequal but that stopped. x Keep an eye out. +x Sort Scope Tracking Switch To Nodes x basic node elements