diff --git a/meta/build.bat b/meta/build.bat index 7c459fe..b4b0d8f 100644 --- a/meta/build.bat +++ b/meta/build.bat @@ -16,10 +16,7 @@ set CommonLinkerFlags= -opt:ref pushd build -del *.pdb > NUL 2> NUL - -REM cl %CommonCompilerFlags% ..\meta\main_meta.cpp /link %CommonLinkerFlags% user32.lib winmm.lib gdi32.lib -incremental:no -cl %CommonCompilerFlags% ..\meta\foldhaus_meta.cpp /link %CommonLinkerFlags% +cl %CommonCompilerFlags% -IC:\programs-dev\gs_libs\src ..\meta\foldhaus_meta.cpp /link %CommonLinkerFlags% C:\programs\ctime\ctime.exe -end C:\projects\foldhaus\build\win32_gs_meta_build_time.ctm %LastError% C:\programs\ctime\ctime.exe -stats C:\projects\foldhaus\build\win32_gs_meta_build_time.ctm diff --git a/meta/foldhaus_meta.cpp b/meta/foldhaus_meta.cpp index 160f9f7..af1b95a 100644 --- a/meta/foldhaus_meta.cpp +++ b/meta/foldhaus_meta.cpp @@ -1,21 +1,19 @@ -#include "..\src\gs_language.h" -#include "..\src\foldhaus_memory.h" +#include +#include + +#include +#include "..\src\gs_platform.h" +#include #include "..\src\gs_string.h" #include "gs_meta_error.h" #include "gs_meta_lexer.h" -#include -#include - error_list GlobalErrorList = {}; PLATFORM_ALLOC(StdAlloc) { - platform_memory_result Result = {}; - Result.Base = (u8*)malloc(Size); - Result.Size = Size; - Result.Error = 0; + u8* Result = (u8*)malloc(Size); return Result; } @@ -26,12 +24,80 @@ struct source_code_file string Contents; }; -struct code_block_builder +#define STRING_BUILDER_BUFFER_CAPACITY 4096 +struct string_builder_buffer { - memory_arena Data; + u8* BufferMemory; string String; + string_builder_buffer* Next; }; +struct string_builder +{ + string_builder_buffer* Buffers; + string_builder_buffer* Head; +}; + +internal void +GrowStringBuilder(string_builder* StringBuilder) +{ + u8* BufferAndHeader = (u8*)malloc(sizeof(string_builder_buffer) + STRING_BUILDER_BUFFER_CAPACITY); + string_builder_buffer* NewBuffer = (string_builder_buffer*)BufferAndHeader; + *NewBuffer = {0}; + + NewBuffer->BufferMemory = (u8*)(NewBuffer + 1); + NewBuffer->String = MakeString((char*)NewBuffer->BufferMemory, 0, STRING_BUILDER_BUFFER_CAPACITY); + + if (!StringBuilder->Buffers) + { + StringBuilder->Buffers = NewBuffer; + StringBuilder->Head = NewBuffer; + } + else + { + StringBuilder->Head->Next = NewBuffer; + StringBuilder->Head = NewBuffer; + } +} + +internal void +Write(string Text, string_builder* StringBuilder) +{ + string TextLeft = Text; + + if (StringBuilder->Buffers == 0) + { + GrowStringBuilder(StringBuilder); + } + + while (TextLeft.Length > 0) + { + // Copy what there is room for + s32 SpaceAvailable = StringBuilder->Head->String.Max - StringBuilder->Head->String.Length; + + ConcatString(TextLeft, GSMin(SpaceAvailable, TextLeft.Length), &StringBuilder->Head->String); + TextLeft.Memory += SpaceAvailable; + TextLeft.Length -= SpaceAvailable; + + if (TextLeft.Length > 0) + { + GrowStringBuilder(StringBuilder); + } + } +} + +internal void +WriteStringBuilderToFile(string_builder StringBuilder, FILE* WriteFile) +{ + string_builder_buffer* BufferAt = StringBuilder.Buffers; + while (BufferAt) + { + string String = BufferAt->String; + fwrite(String.Memory, 1, String.Length, WriteFile); + BufferAt = BufferAt->Next; + } +} + #define TYPE_TABLE_IDENTIFIER_MAX_LENGTH 128 #define TYPE_TABLE_BUFFER_MAX 64 struct type_table_buffer @@ -56,9 +122,7 @@ AddTypeToTable (string Identifier, s32 Size, type_table* Table) { if (!Table->Head || Table->TotalUsed >= Table->TotalMax) { - s32 NewHeadSize = sizeof(type_table_buffer) + ((sizeof(string) + TYPE_TABLE_IDENTIFIER_MAX_LENGTH + sizeof(s32)) * TYPE_TABLE_BUFFER_MAX); - u8* NewHeadBuffer = (u8*)malloc(NewHeadSize); - static_memory_arena Memory = CreateMemoryArena(NewHeadBuffer, NewHeadSize); + memory_arena Memory = {}; type_table_buffer* NewHead = PushStruct(&Memory, type_table_buffer); NewHead->IdentifiersBackbuffer = PushArray(&Memory, u8, TYPE_TABLE_IDENTIFIER_MAX_LENGTH * TYPE_TABLE_BUFFER_MAX); @@ -119,44 +183,6 @@ GetSizeOfType (string Identifier, type_table* TypeTable) return Result; } -internal code_block_builder -InitCodeBlockBuilder() -{ - code_block_builder Result = {}; - InitMemoryArena(&Result.Data, 0, 0, StdAlloc); - return Result; -} - -internal void -CodeBlockPrint (code_block_builder* Block, string Source) -{ - char* NewCode = PushArray(&Block->Data, char, Source.Length); - GSMemCopy(Source.Memory, NewCode, Source.Length); - if (Block->String.Memory == 0) - { - Block->String.Memory = NewCode; - } - Block->String.Max += Source.Length; - Block->String.Length += Source.Length; -} - -internal void -WriteMemoryRegionToFile (memory_region* Region, FILE* WriteFile) -{ - if (Region->PreviousRegion) - { - WriteMemoryRegionToFile(Region->PreviousRegion, WriteFile); - } - fwrite(Region->Base, 1, Region->Used, WriteFile); -} - -internal void -WriteCodeBlockToFile(code_block_builder CodeBlock, FILE* WriteFile) -{ - memory_region* Region = CodeBlock.Data.CurrentRegion; - WriteMemoryRegionToFile (Region, WriteFile); -} - internal s32 GetFileSize (char* FileName) { @@ -240,7 +266,7 @@ FindSeenStructInList (seen_node_struct* SeenStructList, string Name) } internal void -ParseNodeStruct (token* NodeStruct, code_block_builder* NodeMembersBlock, seen_node_struct* SeenStruct, type_table* TypeTable) +ParseNodeStruct (token* NodeStruct, string_builder* NodeMembersBlock, seen_node_struct* SeenStruct, type_table* TypeTable) { token* OpenParen = NodeStruct->Next; token* StructName = OpenParen->Next; @@ -251,7 +277,7 @@ ParseNodeStruct (token* NodeStruct, code_block_builder* NodeMembersBlock, seen_n PrintF(&Buffer, "node_struct_member MemberList_%.*s[] = {\n", StructName->Text.Length, StructName->Text.Memory); - CodeBlockPrint(NodeMembersBlock, Buffer); + Write(Buffer, NodeMembersBlock); token* Token = StructName->Next; while (Token->Type != Token_RightCurlyBracket) @@ -343,14 +369,14 @@ ParseNodeStruct (token* NodeStruct, code_block_builder* NodeMembersBlock, seen_n (IsInput ? "IsInputMember" : ""), (IsInput && IsOutput ? "|" : ""), (IsOutput ? "IsOutputMember" : "")); - CodeBlockPrint(NodeMembersBlock, Buffer); + Write(Buffer, NodeMembersBlock); SeenStruct->MembersCount++; Token = GetNextTokenOfType(Token, Token_Semicolon)->Next; } } - CodeBlockPrint(NodeMembersBlock, MakeStringLiteral("};\n\n")); + Write(MakeStringLiteral("};\n\n"), NodeMembersBlock); } internal s32 @@ -460,9 +486,9 @@ ParseTypedefs (token* Tokens, type_table* TypeTable) internal void ParseNodeProc (token* NodeProc, - code_block_builder* NodeTypeBlock, - code_block_builder* NodeSpecificationsBlock, - code_block_builder* CallNodeProcBlock, + string_builder* NodeTypeBlock, + string_builder* NodeSpecificationsBlock, + string_builder* CallNodeProcBlock, seen_node_struct* SeenStructs, b32 IsPatternProc) { @@ -473,7 +499,7 @@ ParseNodeProc (token* NodeProc, // Types Enum PrintF(&Buffer, "NodeType_%.*s,\n", ProcName->Text.Length, ProcName->Text.Memory); - CodeBlockPrint(NodeTypeBlock, Buffer); + Write(Buffer, NodeTypeBlock); // Node Specification string ArgName = ProcArg->Text; @@ -487,7 +513,7 @@ ParseNodeProc (token* NodeProc, ArgStruct->MembersSize, ArgStruct->MembersCount, (IsPatternProc ? 4 : 5), (IsPatternProc ? "true" : "false")); - CodeBlockPrint(NodeSpecificationsBlock, Buffer); + Write(Buffer, NodeSpecificationsBlock); // Call Node Proc if (IsPatternProc) @@ -500,17 +526,17 @@ ParseNodeProc (token* NodeProc, ProcName->Text.Length, ProcName->Text.Memory, ProcName->Text.Length, ProcName->Text.Memory, ProcArg->Text.Length, ProcArg->Text.Memory); - CodeBlockPrint(CallNodeProcBlock, Buffer); + Write(Buffer, CallNodeProcBlock); } } internal s32 PreprocessStructsAndProcs (string StructSearchString, string ProcSearchString, b32 FindingPatterns, token* Tokens, - code_block_builder* NodeMembersBlock, - code_block_builder* NodeTypeBlock, - code_block_builder* NodeSpecificationsBlock, - code_block_builder* CallNodeProcBlock, + string_builder* NodeMembersBlock, + string_builder* NodeTypeBlock, + string_builder* NodeSpecificationsBlock, + string_builder* CallNodeProcBlock, type_table* TypeTable) { // Node Structs @@ -568,21 +594,19 @@ int main(int ArgCount, char** ArgV) type_table TypeTable = {}; memory_arena SourceFileArena = {}; - InitMemoryArena(&SourceFileArena, 0, 0, StdAlloc); - code_block_builder NodeTypeBlock = InitCodeBlockBuilder(); - CodeBlockPrint(&NodeTypeBlock, MakeStringLiteral("enum node_type\n{\n")); + string_builder NodeTypeBlock = {}; + Write(MakeStringLiteral("enum node_type\n{\n"), &NodeTypeBlock); - code_block_builder NodeMembersBlock = InitCodeBlockBuilder(); + string_builder NodeMembersBlock = {}; - code_block_builder NodeSpecificationsBlock = InitCodeBlockBuilder(); - CodeBlockPrint(&NodeSpecificationsBlock, MakeStringLiteral("node_specification NodeSpecifications[] = {\n")); + string_builder NodeSpecificationsBlock = {}; + Write(MakeStringLiteral("node_specification NodeSpecifications[] = {\n"), &NodeSpecificationsBlock); - code_block_builder CallNodeProcBlock = InitCodeBlockBuilder(); - CodeBlockPrint(&CallNodeProcBlock, MakeStringLiteral("internal void CallNodeProc(node_header* Node, u8* Data, led* LEDs, s32 LEDsCount, r32 DeltaTime)\n{\n")); - CodeBlockPrint(&CallNodeProcBlock, - MakeStringLiteral("node_specification Spec = NodeSpecifications[Node->Type];\n")); - CodeBlockPrint(&CallNodeProcBlock, MakeStringLiteral("switch (Spec.Type)\n{\n")); + string_builder CallNodeProcBlock = {}; + Write(MakeStringLiteral("internal void CallNodeProc(u32 SpecificationIndex, u8* Data, led* LEDs, s32 LEDsCount, r32 DeltaTime)\n{\n"), &CallNodeProcBlock); + Write(MakeStringLiteral("node_specification Spec = NodeSpecifications[SpecificationIndex];\n"), &CallNodeProcBlock); + Write(MakeStringLiteral("switch (Spec.Type)\n{\n"), &CallNodeProcBlock); // Build Search Paths Array @@ -649,7 +673,8 @@ int main(int ArgCount, char** ArgV) { source_code_file* File = SourceFiles + SourceFilesUsed++; - PushString(&File->Path, &SourceFileArena, SearchPathString->Length + CharArrayLength(FindFileData.cFileName)); + u32 PathLength = SearchPathString->Length + CharArrayLength(FindFileData.cFileName); + File->Path = MakeString(PushArray(&SourceFileArena, char, PathLength), 0, PathLength); CopyStringTo(Substring(*SearchPathString, 0, SearchPathString->Length - 2), &File->Path); ConcatCharArrayToString(FindFileData.cFileName, &File->Path); NullTerminate(&File->Path); @@ -657,7 +682,8 @@ int main(int ArgCount, char** ArgV) File->FileSize = FindFileData.nFileSizeLow; ErrorAssert(FindFileData.nFileSizeHigh == 0, &GlobalErrorList, "File Too Big. Peter needs to handle this. File: %.*s", FileName.Length, FileName.Memory); - PushString(&File->Contents, &SourceFileArena, File->FileSize + 1); + u32 FileSize = File->FileSize + 1; + File->Contents = MakeString(PushArray(&SourceFileArena, char, FileSize), FileSize); File->Contents.Length = ReadEntireFileAndNullTerminate(File->Path.Memory, File->Contents.Memory, File->Contents.Max); } @@ -727,23 +753,23 @@ int main(int ArgCount, char** ArgV) MakeStringBuffer(Buffer, 256); // Close Types Block - overwrite the last comma and '\' newline character with newlines. - CodeBlockPrint(&NodeTypeBlock, MakeStringLiteral("NodeType_Count,\n};\n\n")); + Write(MakeStringLiteral("NodeType_Count,\n};\n\n"), &NodeTypeBlock); // Close Specifications Block - CodeBlockPrint(&NodeSpecificationsBlock, MakeStringLiteral("};\n")); + Write(MakeStringLiteral("};\n"), &NodeSpecificationsBlock); PrintF(&Buffer, "s32 NodeSpecificationsCount = %d;\n\n", NodeProcCount); - CodeBlockPrint(&NodeSpecificationsBlock, Buffer); + Write(Buffer, &NodeSpecificationsBlock); // Close Call Node Proc Block - CodeBlockPrint(&CallNodeProcBlock, MakeStringLiteral("}\n}\n")); + Write(MakeStringLiteral("}\n}\n"), &CallNodeProcBlock); FILE* NodeGeneratedCPP = fopen("C:\\projects\\foldhaus\\src\\generated\\foldhaus_nodes_generated.cpp", "w"); if (NodeGeneratedCPP) { - WriteCodeBlockToFile(NodeTypeBlock, NodeGeneratedCPP); - WriteCodeBlockToFile(NodeMembersBlock, NodeGeneratedCPP); - WriteCodeBlockToFile(NodeSpecificationsBlock, NodeGeneratedCPP); - WriteCodeBlockToFile(CallNodeProcBlock, NodeGeneratedCPP); + WriteStringBuilderToFile(NodeTypeBlock, NodeGeneratedCPP); + WriteStringBuilderToFile(NodeMembersBlock, NodeGeneratedCPP); + WriteStringBuilderToFile(NodeSpecificationsBlock, NodeGeneratedCPP); + WriteStringBuilderToFile(CallNodeProcBlock, NodeGeneratedCPP); fclose(NodeGeneratedCPP); } diff --git a/src/animation/foldhaus_animation.h b/src/animation/foldhaus_animation.h index 3044ef0..81fc30d 100644 --- a/src/animation/foldhaus_animation.h +++ b/src/animation/foldhaus_animation.h @@ -33,9 +33,3 @@ struct animation_system r32 AnimationStart; r32 AnimationEnd; }; - -internal void -InitializeAnimationSystem(animation_system* System) -{ - *System = {0}; -} diff --git a/src/foldhaus_app.cpp b/src/foldhaus_app.cpp index 9e5c584..562d289 100644 --- a/src/foldhaus_app.cpp +++ b/src/foldhaus_app.cpp @@ -181,7 +181,7 @@ INITIALIZE_APPLICATION(InitializeApplication) State->Modes.Arena.FindAddressRule = FindAddress_InLastBufferOnly; { // Animation PLAYGROUND - InitializeAnimationSystem(&State->AnimationSystem); + State->AnimationSystem = {}; State->AnimationSystem.SecondsPerFrame = 1.f / 24.f; State->AnimationSystem.AnimationStart = 0; State->AnimationSystem.AnimationEnd = 15; diff --git a/src/foldhaus_node.cpp b/src/foldhaus_node.cpp index c462359..e02160c 100644 --- a/src/foldhaus_node.cpp +++ b/src/foldhaus_node.cpp @@ -4,1158 +4,3 @@ PushNodeOnWorkspace(s32 NodeSpecificationIndex, pattern_node_workspace* Workspac pattern_node* NewNode = Workspace->Nodes.TakeElement(); NewNode->SpecificationIndex = NodeSpecificationIndex; } - - - - - - - - -// vv Old vv - -internal node_list_iterator -GetNodeListIterator(node_list List) -{ - node_list_iterator Result = {}; - Result.List = List; - Result.CurrentBuffer = List.First; - Result.At = Result.CurrentBuffer->Headers; - Result.TotalIndexAt = 0; - Result.BufferIndexAt = 0; - - return Result; -} - -internal b32 -NodeIteratorIsValid(node_list_iterator Iter) -{ - b32 Result = (Iter.At != 0); - Result &= Iter.TotalIndexAt < Iter.List.TotalUsed && Iter.TotalIndexAt >= 0; - Result &= Iter.BufferIndexAt < Iter.CurrentBuffer->Used && Iter.BufferIndexAt >= 0; - return Result; -} - -internal void -Next (node_list_iterator* Iter) -{ - if (Iter->BufferIndexAt < Iter->CurrentBuffer->Used) - { - Iter->At++; - Iter->TotalIndexAt++; - Iter->BufferIndexAt++; - if (Iter->At->Handle == 0) { Next(Iter); } - } - else if (Iter->CurrentBuffer->Next) - { - Iter->CurrentBuffer = Iter->CurrentBuffer->Next; - Iter->At = Iter->CurrentBuffer->Headers; - Iter->TotalIndexAt++; - Iter->BufferIndexAt = 0; - if (Iter->At->Handle == 0) { Next(Iter); } - } - else - { - Iter->At = 0; - Iter->TotalIndexAt = -1; - Iter->BufferIndexAt = -1; - } -} - -internal node_list_buffer* -AllocateNodeListBuffer (memory_arena* Storage, s32 Count) -{ - node_list_buffer* Result = PushStruct(Storage, node_list_buffer);; - Result->Headers = PushArray(Storage, node_header, Count); - Result->Max = Count; - Result->Used = 0; - Result->Next = 0; - return Result; -} - -internal node_list* -AllocateNodeList (memory_arena* Storage, s32 InitialCount) -{ - node_list* Result = PushStruct(Storage, node_list); - Result->First = AllocateNodeListBuffer(Storage, InitialCount); - Result->Head = Result->First; - Result->TotalMax = InitialCount; - Result->TotalUsed = 0; - Result->HandleAccumulator = 0; - return Result; -} - -global_variable char* OutputName = "Output"; - -internal string -GetNodeName (node_header Node) -{ - string Result = {}; - - node_specification Spec = NodeSpecifications[Node.Type]; - Result = MakeString(Spec.Name, Spec.NameLength); - - return Result; -} - -internal node_header* -PushNodeOnList (node_list* List, s32 ConnectionsCount, v2 Min, v2 Dim, memory_arena* Storage) -{ - node_header* Result = 0; - - if ((List->TotalUsed + 1) >= List->TotalMax) - { - node_list_buffer* Buf = AllocateNodeListBuffer(Storage, List->Head->Max); - List->Head->Next = Buf; - List->Head = Buf; - List->TotalMax += Buf->Max; - } - Assert(List->TotalUsed + 1 <= List->TotalMax); - - Result = List->Head->Headers + List->Head->Used; - Result->Handle = ++List->HandleAccumulator; - - // :ConnectionsToStretchyBuffer - Assert(List->ConnectionsUsed + ConnectionsCount < NODE_LIST_CONNECTIONS_MAX); - Result->ConnectionsCount = ConnectionsCount; - Result->Connections = (node_connection*)(List->Connections + List->ConnectionsUsed); - List->ConnectionsUsed += ConnectionsCount; - - for (s32 c = 0; c < Result->ConnectionsCount; c++) - { - Result->Connections[c].NodeHandle = Result->Handle; - } - - Result->Min = Min; - Result->Dim = Dim; - - List->Head->Used++; - List->TotalUsed++; - - return Result; -} - -internal void -FreeNodeOnList (node_list* List, node_header* Node) -{ - // TODO(Peter): -} - -internal void -InitializeNodeConnection (node_connection* Connection, node_struct_member Member, node_header* Node) -{ - Connection->Type = Member.Type; - Connection->UpstreamNodeHandle = 0; - Connection->UpstreamNodePortIndex = -1; - Connection->DownstreamNodeHandle = 0; - Connection->DownstreamNodePortIndex = -1; - Connection->DirectionMask = Member.IsInput; - - Connection->Ptr = Node->PersistentData + Member.Offset; - - switch (Member.Type) - { - case MemberType_s32: - { - *Connection->S32ValuePtr = 0; - }break; - - case MemberType_r32: - { - *Connection->R32ValuePtr = 0; - }break; - - case MemberType_v4: - { - *Connection->V4ValuePtr = v4{0, 0, 0, 1}; - }break; - - case MemberType_NODE_COLOR_BUFFER: - { - *Connection->LEDsValuePtr = {}; - }break; - - InvalidDefaultCase; - } - -} - -inline r32 -CalculateNodeHeight (s32 Members) -{ - r32 Result = (NODE_PORT_STEP * Members) + NODE_HEADER_HEIGHT; - return Result; -} - -internal node_header* -PushNodeOnListFromSpecification (node_list* List, node_type Type, v2 Min, memory_arena* Storage) -{ - node_header* Node = 0; - - node_specification Spec = NodeSpecifications[Type]; - - // :NodesDontNeedToKnowTheirBounds - r32 NodeHeight = CalculateNodeHeight (Spec.MemberListLength); - Node = PushNodeOnList(List, - Spec.MemberListLength, - Min, - v2{150, NodeHeight}, - Storage); - Node->Type = Type; - Node->PersistentData = PushArray(Storage, u8, Spec.DataStructSize); - - node_struct_member* MemberList = Spec.MemberList; - for (u32 MemberIdx = 0; MemberIdx < Spec.MemberListLength; MemberIdx++) - { - node_struct_member Member = MemberList[MemberIdx]; - InitializeNodeConnection(Node->Connections + MemberIdx, Member, Node); - } - - return Node; -} - -internal node_header* -PushOutputNodeOnList (node_list* List, v2 Min, memory_arena* Storage) -{ - node_header* Result = PushNodeOnListFromSpecification(List, NodeType_OutputNode, Min, Storage); - return Result; -} - -internal node_header* -GetNodeWithHandle(node_list* List, s32 Handle) -{ - DEBUG_TRACK_FUNCTION; - node_header* Result = 0; - - node_list_iterator Iter = GetNodeListIterator(*List); - while (NodeIteratorIsValid(Iter)) - { - if(Iter.At->Handle == Handle) - { - Result = Iter.At; - break; - } - Next(&Iter); - } - - return Result; -} - -internal rect -CalculateNodeBounds (node_header* Node, node_render_settings Settings) -{ - rect Result = {}; - Result.Min = Node->Min; - Result.Max = Node->Min + Node->Dim + v2{0, NODE_HEADER_HEIGHT}; - return Result; -} - -internal rect -CalculateNodeInputPortBounds (node_header* Node, s32 Index, node_render_settings RenderSettings) -{ - rect Result = {}; - - Result.Min = v2{ - Node->Min.x, - Node->Min.y + Node->Dim.y - ((NODE_PORT_STEP * (Index + 1)) + NODE_HEADER_HEIGHT)}; - Result.Max = Result.Min + NODE_PORT_DIM; - - return Result; -} - -internal rect -CalculateNodeInputValueBounds (node_header* Node, s32 Index, node_render_settings RenderSettings) -{ - rect Result = {}; - rect Port = CalculateNodeInputPortBounds(Node, Index, RenderSettings); - Result.Min = v2{Port.Max.x, Port.Min.y}; - Result.Max = Result.Min + v2{NODE_PORT_DIM.x * 2, NODE_PORT_DIM.y}; - return Result; -} - -internal rect -CalculateNodeOutputPortBounds (node_header* Node, s32 Index, node_render_settings RenderSettings) -{ - rect Result = {}; - Result.Min = v2{ - Node->Min.x + Node->Dim.x - NODE_PORT_DIM.x, - Node->Min.y + Node->Dim.y - ((NODE_PORT_STEP * (Index + 1)) + NODE_HEADER_HEIGHT)}; - Result.Max = Result.Min + NODE_PORT_DIM; - return Result; -} - -internal rect -CalculateNodeOutputValueBounds (node_header* Node, s32 Index, node_render_settings RenderSettings) -{ - rect Result = {}; - rect Port = CalculateNodeOutputPortBounds(Node, Index, RenderSettings); - Result.Min = v2{Port.Min.x - (NODE_PORT_DIM.x * 2), Port.Min.y}; - Result.Max = v2{Port.Min.x, Port.Max.y}; - return Result; -} - -internal rect -GetBoundsOfPortConnectedToInput (node_header* Node, s32 PortIndex, node_list* NodeList, node_render_settings RenderSettings) -{ - node_header* ConnectedNode = - GetNodeWithHandle(NodeList, Node->Connections[PortIndex].UpstreamNodeHandle); - rect Result = CalculateNodeOutputPortBounds(ConnectedNode, Node->Connections[PortIndex].UpstreamNodePortIndex, RenderSettings); - return Result; -} - -internal rect -GetBoundsOfPortConnectedToOutput (node_header* Node, s32 PortIndex, node_list* NodeList, node_render_settings RenderSettings) -{ - node_header* ConnectedNode = GetNodeWithHandle(NodeList, Node->Connections[PortIndex].DownstreamNodeHandle); - rect Result = CalculateNodeInputPortBounds(ConnectedNode, Node->Connections[PortIndex].DownstreamNodePortIndex, RenderSettings); - return Result; -} - -internal rect -CalculateNodeDragHandleBounds (rect NodeBounds, s32 Index, node_render_settings RenderSettings) -{ - rect Result {}; - v2 HorizontalOffset = v2{Width(NodeBounds) / 3, 0}; - Result.Min = v2{NodeBounds.Min.x, NodeBounds.Max.y - NODE_HEADER_HEIGHT} + (HorizontalOffset * Index); - Result.Max = Result.Min + v2{HorizontalOffset.x, NODE_HEADER_HEIGHT}; - return Result; -} - -internal node_interaction -NewEmptyNodeInteraction () -{ - node_interaction Result = {}; - Result.NodeHandle = 0; - Result.InputPort = -1; - Result.InputValue = -1; - Result.OutputPort = -1; - Result.OutputValue = -1; - return Result; -} - -internal node_interaction -NewNodeInteraction (s32 NodeHandle, v2 MouseOffset) -{ - node_interaction Result = {}; - Result.NodeHandle = NodeHandle; - Result.MouseOffset = MouseOffset; - Result.InputPort = -1; - Result.InputValue = -1; - Result.OutputPort = -1; - Result.OutputValue = -1; - return Result; -} - -internal b32 -IsDraggingNode (node_interaction Interaction) -{ - b32 Result = ((Interaction.NodeHandle > 0) && - (Interaction.InputPort < 0 && Interaction.InputValue < 0) && - (Interaction.OutputPort < 0 && Interaction.InputValue < 0)); - return Result; -} - -internal b32 -IsDraggingNodePort (node_interaction Interaction) -{ - b32 Result = ((Interaction.NodeHandle > 0) && - (Interaction.InputPort >= 0 || Interaction.OutputPort >= 0) && - (Interaction.InputValue < 0 && Interaction.OutputValue < 0)); - return Result; -} - -internal b32 -IsDraggingNodeValue (node_interaction Interaction) -{ - b32 Result = ((Interaction.NodeHandle > 0) && - (Interaction.InputPort < 0 && Interaction.OutputPort < 0) && - (Interaction.InputValue >= 0 || Interaction.OutputValue >= 0)); - return Result; -} - -internal b32 -IsDraggingNodeInput (node_interaction Interaction) -{ - b32 Result = ((Interaction.NodeHandle > 0) && - (Interaction.InputPort >= 0 || Interaction.InputValue >= 0) && - (Interaction.OutputPort < 0 && Interaction.OutputValue < 0)); - return Result; -} - -internal b32 -IsDraggingNodeInputPort (node_interaction Interaction) -{ - b32 Result = ((Interaction.NodeHandle > 0) && - (Interaction.InputPort >= 0) && (Interaction.InputValue < 0) && - (Interaction.OutputPort < 0 && Interaction.OutputValue < 0)); - return Result; -} - -internal b32 -IsDraggingNodeInputValue (node_interaction Interaction) -{ - b32 Result = ((Interaction.NodeHandle > 0) && - (Interaction.InputPort < 0) && (Interaction.InputValue >= 0) && - (Interaction.OutputPort < 0 && Interaction.OutputValue < 0)); - return Result; -} - -internal b32 -IsDraggingNodeOutput (node_interaction Interaction) -{ - b32 Result = ((Interaction.NodeHandle > 0) && - (Interaction.OutputPort >= 0 || Interaction.OutputValue >= 0) && - (Interaction.InputPort < 0 && Interaction.InputValue < 0)); - return Result; -} - -internal b32 -IsDraggingNodeOutputPort (node_interaction Interaction) -{ - b32 Result = ((Interaction.NodeHandle > 0) && - (Interaction.OutputPort >= 0) && (Interaction.OutputValue < 0) && - (Interaction.InputPort < 0 && Interaction.InputValue < 0)); - return Result; -} - -internal b32 -IsDraggingNodeOutputValue (node_interaction Interaction) -{ - b32 Result = ((Interaction.NodeHandle > 0) && - (Interaction.OutputPort < 0) && (Interaction.OutputValue >= 0) && - (Interaction.InputPort < 0 && Interaction.InputValue < 0)); - return Result; -} - -internal b32 -ConnectionIsConnected (node_connection Connection) -{ - b32 Result = (Connection.UpstreamNodeHandle > 0) || (Connection.DownstreamNodeHandle > 0); - return Result; -} - -internal b32 -ConnectionIsConnected (node_header* Node, s32 Index) -{ - b32 Result = ConnectionIsConnected(Node->Connections[Index]); - return Result; -} - -internal b32 -ConnectionHasUpstreamConnection (node_connection Connection) -{ - b32 Result = (Connection.UpstreamNodeHandle > 0); - return Result; -} - -internal b32 -ConnectionHasUpstreamConnection (node_header* Node, s32 Index) -{ - b32 Result = ConnectionHasUpstreamConnection(Node->Connections[Index]); - return Result; -} - -internal b32 -ConnectionHasDownstreamConnection (node_connection Connection) -{ - b32 Result = (Connection.DownstreamNodeHandle > 0); - return Result; -} - -internal b32 -ConnectionHasDownstreamConnection (node_header* Node, s32 Index) -{ - b32 Result = ConnectionHasDownstreamConnection(Node->Connections[Index]); - return Result; -} - -internal b32 -ConnectionIsInput (node_connection Connection) -{ - b32 Result = (Connection.DirectionMask & IsInputMember) > 0; - return Result; -} - -internal b32 -ConnectionIsInput (node_header* Node, s32 ConnectionIdx) -{ - return ConnectionIsInput(Node->Connections[ConnectionIdx]); -} - -internal b32 -ConnectionIsOutput (node_connection Connection) -{ - b32 Result = (Connection.DirectionMask & IsOutputMember) > 0; - return Result; -} - -internal b32 -ConnectionIsOutput (node_header* Node, s32 ConnectionIdx) -{ - return ConnectionIsOutput(Node->Connections[ConnectionIdx]); -} - -internal b32 -CheckForRecursionWithHandle (node_list* NodeList, s32 LookForNodeHandle, node_header* StartNode) -{ - DEBUG_TRACK_FUNCTION; - b32 Result = false; - - for (s32 Connection = 0; Connection < StartNode->ConnectionsCount; Connection++) - { - if (!ConnectionIsOutput(StartNode->Connections[Connection])) { continue; } - - if (StartNode->Connections[Connection].DownstreamNodeHandle == LookForNodeHandle) - { - Result = true; - break; - } - - if (StartNode->Connections[Connection].DownstreamNodeHandle > 0) - { - node_header* NextNode = GetNodeWithHandle(NodeList, StartNode->Connections[Connection].DownstreamNodeHandle); - Result = CheckForRecursionWithHandle(NodeList, LookForNodeHandle, NextNode); - if (Result) { break; } - } - } - - return Result; -} - -internal b32 -PortTypesMatch (node_header* UpstreamNode, s32 UpstreamNode_OutputPort, node_header* DownstreamNode, s32 DownstreamNode_InputPort) -{ - Assert(ConnectionIsOutput(UpstreamNode, UpstreamNode_OutputPort)); - Assert(ConnectionIsInput(DownstreamNode, DownstreamNode_InputPort)); - b32 Result = UpstreamNode->Connections[UpstreamNode_OutputPort].Type == DownstreamNode->Connections[DownstreamNode_InputPort].Type; - return Result; -} - -internal void -ConnectNodes(node_list* NodeList, - s32 UpstreamNodeHandle, s32 UpstreamNodePort, - s32 DownstreamNodeHandle, s32 DownstreamNodePort) -{ - node_header* UpstreamNode = 0; - node_header* DownstreamNode = GetNodeWithHandle(NodeList, DownstreamNodeHandle); - if (!CheckForRecursionWithHandle(NodeList, UpstreamNodeHandle, DownstreamNode)) - { - UpstreamNode = GetNodeWithHandle(NodeList, UpstreamNodeHandle); - if (PortTypesMatch(UpstreamNode, UpstreamNodePort, - DownstreamNode, DownstreamNodePort)) - { - Assert(ConnectionIsOutput(UpstreamNode, UpstreamNodePort)); - Assert(ConnectionIsInput(DownstreamNode, DownstreamNodePort)); - - DownstreamNode->Connections[DownstreamNodePort].UpstreamNodeHandle = UpstreamNodeHandle; - DownstreamNode->Connections[DownstreamNodePort].UpstreamNodePortIndex = UpstreamNodePort; - UpstreamNode->Connections[UpstreamNodePort].DownstreamNodeHandle = DownstreamNodeHandle; - UpstreamNode->Connections[UpstreamNodePort].DownstreamNodePortIndex = DownstreamNodePort; - } - } -} - -internal void -UnconnectNodes (node_list* NodeList, - s32 DownstreamNodeHandle, s32 DownstreamNode_OutputPort, s32 UpstreamNodeHandle, s32 UpstreamNode_InputPort) -{ - node_header* DownstreamNode = GetNodeWithHandle(NodeList, DownstreamNodeHandle); - node_header* UpstreamNode = GetNodeWithHandle(NodeList, UpstreamNodeHandle); - - Assert(ConnectionIsOutput(DownstreamNode, DownstreamNode_OutputPort)); - Assert(ConnectionIsInput(UpstreamNode, UpstreamNode_InputPort)); - - DownstreamNode->Connections[DownstreamNode_OutputPort].DownstreamNodeHandle = 0; - DownstreamNode->Connections[DownstreamNode_OutputPort].DownstreamNodePortIndex = -1; - UpstreamNode->Connections[UpstreamNode_InputPort].UpstreamNodeHandle = 0; - UpstreamNode->Connections[UpstreamNode_InputPort].UpstreamNodePortIndex = -1; -} - -internal node_header* -GetNodeUnderPoint (node_list* NodeList, v2 Point, node_render_settings RenderSettings) -{ - DEBUG_TRACK_FUNCTION; - node_header* Result = 0; - - node_list_iterator NodeIter = GetNodeListIterator(*NodeList); - while (NodeIteratorIsValid(NodeIter)) - { - node_header* Node = NodeIter.At; - rect NodeBounds = CalculateNodeBounds(Node, RenderSettings); - if (PointIsInRect(Point, NodeBounds)) - { - Result = Node; - break; - } - Next(&NodeIter); - } - - return Result; -} - -internal node_interaction -GetNodeInteractionType (node_header* ActiveNode, v2 MousePos, node_render_settings RenderSettings) -{ - DEBUG_TRACK_FUNCTION; - - node_interaction Interaction = NewNodeInteraction(ActiveNode->Handle, ActiveNode->Min - MousePos); - - rect NodeBounds = CalculateNodeBounds(ActiveNode, RenderSettings); - - - for (s32 Connection = 0; Connection < ActiveNode->ConnectionsCount; Connection++) - { - // Inputs - if (ConnectionIsInput(ActiveNode, Connection)) - { - rect InputBounds = CalculateNodeInputPortBounds(ActiveNode, Connection, RenderSettings); - rect ValueBounds = CalculateNodeInputValueBounds(ActiveNode, Connection, RenderSettings); - if (PointIsInRect(MousePos, InputBounds)) - { - Interaction.InputPort = Connection; - Interaction.MouseOffset = MousePos - InputBounds.Min; - } - else if(PointIsInRect(MousePos, ValueBounds)) - { - Interaction.InputValue = Connection; - Interaction.MouseOffset = MousePos - ValueBounds.Min; - } - } - - // Outputs - if (ConnectionIsOutput(ActiveNode, Connection)) - { - rect OutputBounds = CalculateNodeOutputPortBounds(ActiveNode, Connection, RenderSettings); - rect ValueBounds = CalculateNodeOutputValueBounds(ActiveNode, Connection, RenderSettings); - if (PointIsInRect(MousePos, OutputBounds)) - { - Interaction.OutputPort = Connection; - Interaction.MouseOffset = MousePos - OutputBounds.Min; - } - else if(PointIsInRect(MousePos, ValueBounds)) - { - Interaction.OutputValue = Connection; - Interaction.MouseOffset = MousePos - ValueBounds.Min; - } - } - } - - // Drag Handles - rect DragUpstreamHandleBounds = CalculateNodeDragHandleBounds(NodeBounds, 0, RenderSettings); - rect DragAllHandleBounds = CalculateNodeDragHandleBounds(NodeBounds, 1, RenderSettings); - rect DragDownstreamHandleBounds = CalculateNodeDragHandleBounds(NodeBounds, 2, RenderSettings); - if (PointIsInRect(MousePos, DragUpstreamHandleBounds)) - { - Interaction.Flags = NodeInteraction_AllUpstream; - } - else if (PointIsInRect(MousePos, DragAllHandleBounds)) - { - Interaction.Flags = NodeInteraction_AllUpstream | NodeInteraction_AllDownstream; - } - else if (PointIsInRect(MousePos, DragDownstreamHandleBounds)) - { - Interaction.Flags = NodeInteraction_AllDownstream; - } - - return Interaction; -} - -internal void -TryConnectNodes (node_interaction Interaction, v2 Point, node_list* NodeList, node_render_settings RenderSettings) -{ - DEBUG_TRACK_FUNCTION; - - if (IsDraggingNodeOutput(Interaction)) - { - node_header* UpstreamNode = GetNodeUnderPoint(NodeList, Point, RenderSettings); - if (UpstreamNode) - { - for (s32 Connection = 0; Connection < UpstreamNode->ConnectionsCount; Connection++) - { - if (ConnectionIsOutput(UpstreamNode, Connection)) { continue; } - - rect InputBounds = CalculateNodeInputPortBounds(UpstreamNode, Connection, RenderSettings); - if (PointIsInRect(Point, InputBounds)) - { - ConnectNodes(NodeList, Interaction.NodeHandle, Interaction.OutputPort, - UpstreamNode->Handle, Connection); - break; - } - } - } - } - else if (IsDraggingNodeInput(Interaction)) - { - node_header* DownstreamNode = GetNodeUnderPoint(NodeList, Point, RenderSettings); - if (DownstreamNode) - { - for (s32 Connection = 0; Connection < DownstreamNode->ConnectionsCount; Connection++) - { - if (ConnectionIsInput(DownstreamNode, Connection)) { continue; } - - rect OutputBounds = CalculateNodeOutputPortBounds(DownstreamNode, Connection, RenderSettings); - if (PointIsInRect(Point, OutputBounds)) - { - ConnectNodes(NodeList, - DownstreamNode->Handle, Connection, - Interaction.NodeHandle, Interaction.InputPort); - break; - } - } - } - } -} - -internal void -PlaceNode (node_list* NodeList, node_header* Node, v2 Position, b32 Flags) -{ - DEBUG_TRACK_FUNCTION; - - v2 Offset = Position - Node->Min; - - if (Flags & NodeInteraction_AllDownstream) - { - for (s32 Connection = 0; Connection < Node->ConnectionsCount; Connection++) - { - if (!ConnectionIsOutput(Node, Connection)) { continue; } - - s32 ConnectionHandle = Node->Connections[Connection].DownstreamNodeHandle; - if (ConnectionHandle > 0) - { - node_header* ConnectedNode = GetNodeWithHandle(NodeList, ConnectionHandle); - v2 CurrPos = ConnectedNode->Min; - v2 NewPos = CurrPos + Offset; - // NOTE(Peter): Have to negate the all downstream component so it doesn't turn around and try - // to move this node again. - PlaceNode(NodeList, ConnectedNode, NewPos, Flags & ~NodeInteraction_AllUpstream); - } - } - } - - if (Flags & NodeInteraction_AllUpstream) - { - for (s32 Connection = 0; Connection < Node->ConnectionsCount; Connection++) - { - if (!ConnectionIsInput(Node, Connection)) { continue; } - - s32 ConnectionHandle = Node->Connections[Connection].UpstreamNodeHandle; - if (ConnectionHandle > 0) - { - node_header* ConnectedNode = GetNodeWithHandle(NodeList, ConnectionHandle); - v2 CurrPos = ConnectedNode->Min; - v2 NewPos = CurrPos + Offset; - // NOTE(Peter): Have to negate the all upstream component so it doesn't turn around and try - // to move this node again. - PlaceNode(NodeList, ConnectedNode, NewPos, Flags & ~NodeInteraction_AllDownstream); - } - } - } - - Node->Min = Position; -} - -internal void -UpdateDraggingNode (v2 MousePos, node_interaction Interaction, node_list* NodeList, node_render_settings RenderSettings) -{ - DEBUG_TRACK_FUNCTION; - - if (IsDraggingNode(Interaction)) - { - node_header* ActiveNode = GetNodeWithHandle(NodeList, Interaction.NodeHandle); - PlaceNode(NodeList, ActiveNode, MousePos + Interaction.MouseOffset, Interaction.Flags); - } -} - -internal void -UpdateDraggingNodePort (v2 MousePos, node_interaction Interaction, node_list* NodeList, node_render_settings RenderSettings, render_command_buffer* RenderBuffer) -{ - DEBUG_TRACK_FUNCTION; - - if (IsDraggingNodePort(Interaction)) - { - node_header* ActiveNode = GetNodeWithHandle(NodeList, Interaction.NodeHandle); - rect PortBounds = {}; - if (IsDraggingNodeInput(Interaction)) - { - PortBounds = CalculateNodeInputPortBounds(ActiveNode, Interaction.InputPort, RenderSettings); - } - else if (IsDraggingNodeOutput(Interaction)) - { - PortBounds = CalculateNodeOutputPortBounds(ActiveNode, Interaction.OutputPort, RenderSettings); - } - - v2 PortCenter = CalculateRectCenter(PortBounds); - PushRenderLine2D(RenderBuffer, PortCenter, MousePos, 1, WhiteV4); - } -} - -internal void -UpdateDraggingNodeValue (v2 MousePos, v2 LastFrameMousePos, node_interaction Interaction, node_list* NodeList, node_render_settings RenderSettings, app_state* State) -{ - DEBUG_TRACK_FUNCTION; - - if(IsDraggingNodeValue(Interaction)) - { - v2 MouseDelta = MousePos - LastFrameMousePos; - node_header* Node = GetNodeWithHandle(NodeList, Interaction.NodeHandle); - - node_connection* Connection = 0; - if (IsDraggingNodeInputValue(Interaction)) - { - Connection = Node->Connections + Interaction.InputValue; - Assert(ConnectionIsInput(*Connection)); - } - else if (IsDraggingNodeOutputValue(Interaction)) - { - Connection = Node->Connections + Interaction.OutputValue; - Assert(ConnectionIsOutput(*Connection)); - } - Assert(Connection); - - switch (Connection->Type) - { - case MemberType_s32: - { - *Connection->S32ValuePtr += (s32)(MouseDelta.y * .05f); - }break; - - case MemberType_r32: - { - *Connection->R32ValuePtr += (MouseDelta.y * .05f); - }break; - - case MemberType_v4: - { - }break; - - case MemberType_NODE_COLOR_BUFFER: {} break; // NOTE(Peter): Unused for now - InvalidDefaultCase; - } - } -} - - -internal void UpdateNodeCalculation (node_header* Node, node_list* NodeList, - memory_arena* Permanent, memory_arena* Transient, - led* LEDs, pixel* ColorsInit, s32 LEDCount, r32 DeltaTime); - -internal void -UpdateNodesConnectedUpstream (node_header* Node, node_list* NodeList, - memory_arena* Permanent, memory_arena* Transient, - led* LEDs, pixel* ColorsInit, s32 LEDCount, r32 DeltaTime) -{ - for (s32 ConnectionIdx = 0; ConnectionIdx < Node->ConnectionsCount; ConnectionIdx++) - { - node_connection* Connection = 0; - if (ConnectionIsInput(Node->Connections[ConnectionIdx])) - { - Connection = Node->Connections + ConnectionIdx; - - if (ConnectionHasUpstreamConnection(*Connection)) - { - node_header* UpstreamNode = GetNodeWithHandle(NodeList, Connection->UpstreamNodeHandle); - if (!UpstreamNode->UpdatedThisFrame) - { - UpdateNodeCalculation(UpstreamNode, NodeList, Permanent, Transient, LEDs, ColorsInit, LEDCount, DeltaTime); - } - - node_connection UpstreamConnection = UpstreamNode->Connections[Connection->UpstreamNodePortIndex]; - - switch (Connection->Type) - { - case MemberType_s32: - { - *Connection->S32ValuePtr = *UpstreamConnection.S32ValuePtr; - }break; - - case MemberType_r32: - { - *Connection->R32ValuePtr = *UpstreamConnection.R32ValuePtr; - }break; - - case MemberType_v4: - { - *Connection->V4ValuePtr = *UpstreamConnection.V4ValuePtr; - }break; - - case MemberType_NODE_COLOR_BUFFER: - { - *Connection->LEDsValuePtr = *UpstreamConnection.LEDsValuePtr; - }break; - - InvalidDefaultCase; - } - } - } - } -} - -internal void -UpdateNodeCalculation (node_header* Node, node_list* NodeList, - memory_arena* Permanent, memory_arena* Transient, - led* LEDs, pixel* ColorsInit, s32 LEDCount, r32 DeltaTime) -{ - DEBUG_TRACK_FUNCTION; - Assert(Node->PersistentData != 0); - Assert(Node->Type != NodeType_OutputNode); - - // NOTE(Peter): Have to subtract one here so that we account for the - // NodeType_OutputNode entry in the enum - node_specification Spec = NodeSpecifications[Node->Type]; - node_struct_member* MemberList = Spec.MemberList; - - // NOTE(Peter): We do this at the beginning in case there is a node connected to this one - // which has a connection that is both an Input and Output. In that case, if UpdatedThisFrame - // were not set before hand, the two nodes would pingpong back and forth trying to get - // eachother to update. - Node->UpdatedThisFrame = true; - - pixel* Colors = ColorsInit; - - UpdateNodesConnectedUpstream(Node, NodeList, Permanent, Transient, LEDs, Colors, LEDCount, DeltaTime); - - for (s32 ConnectionIdx = 0; ConnectionIdx < Node->ConnectionsCount; ConnectionIdx++) - { - node_connection Connection = Node->Connections[ConnectionIdx]; - - // TODO(Peter): We're currently passing in a pointer to the leds array for every single - // NODE_COLOR_BUFFER. We shouldn't do that, and just require each data structure that - // needs the leds to request that as its own member/parameter. - if (Connection.Type == MemberType_NODE_COLOR_BUFFER) - { - node_led_color_connection* ColorConnection = Connection.LEDsValuePtr; - if (!ColorConnection->Colors) - { - pixel* ColorsCopy = PushArray(Transient, pixel, LEDCount); - GSMemSet((u8*)ColorsCopy, 0, sizeof(pixel) * LEDCount); - - ColorConnection->Colors = ColorsCopy; - ColorConnection->LEDs = LEDs; - ColorConnection->LEDCount = LEDCount; - } - } - } - - CallNodeProc(Node, Node->PersistentData, LEDs, LEDCount, DeltaTime); - - for (s32 ConnectionIdx = 0; ConnectionIdx < Node->ConnectionsCount; ConnectionIdx++) - { - if (!ConnectionIsOutput(Node, ConnectionIdx)) { continue; } - node_connection* Connection = Node->Connections + ConnectionIdx; - } -} - -internal void -UpdateOutputNodeCalculations (node_header* OutputNode, node_list* NodeList, - memory_arena* Permanent, memory_arena* Transient, - led* LEDs, pixel* Colors, s32 LEDCount, r32 DeltaTime) -{ - Assert(OutputNode->Type == NodeType_OutputNode); - - UpdateNodesConnectedUpstream(OutputNode, NodeList, Permanent, Transient, LEDs, Colors, LEDCount, DeltaTime); - - node_connection ColorsConnection = OutputNode->Connections[0]; - if (ColorsConnection.LEDsValuePtr->Colors) - { - pixel* DestPixel = Colors; - pixel* SourcePixel = ColorsConnection.LEDsValuePtr->Colors; - for (s32 i = 0; i < LEDCount; i++) - { - *DestPixel++ = *SourcePixel++; - } - } -} - -#if 0 -// Trying to put updating nodes in terms of connections, rather than nodes. -internal void -UpdateAllNodesFloodFill (node_list* NodeList, memory_arena* Permanent, memory_arena* Transient, led* LEDs, pixel* Colors, s32 LEDCount, r32 DeltaTime) -{ - s32 NodesUpdated = 0; - - s32 DEBUGIterations = 0; - while(NodesUpdated < NodeList->TotalUsed) - { - node_list_iterator NodeIter = GetNodeListIterator(*NodeList); - while (NodeIteratorIsValid(NodeIter)) - { - node_header* Node = NodeIter.At; - - s32 ConnectionsReady = 0; - // Check if all upstream connections have been updated - // TODO(Peter): we should move the HasBeenUpdated field into the connections - // and have connections push their updates upstream - for (s32 c = 0; c < Node->ConnectionsCount; c++) - { - node_connection* Connection = Node->Connections + c; - if (ConnectionIsInput(*Connection) && - ConnectionHasUpstreamConnection(*Connection)) - { - node_header* UpstreamNode = GetNodeWithHandle(NodeList, Connection->UpstreamNodeHandle); - if (UpstreamNode->UpdatedThisFrame) - { - ConnectionsReady += 1; - } - else - { - break; - } - } - } - - if (ConnectionsReady == Node->ConnectionsCount) - { - - } - } - DEBUGIterations++; - } -} -#endif - -internal void -UpdateAllNodeCalculations (node_list* NodeList, memory_arena* Permanent, memory_arena* Transient, led* LEDs, pixel* Colors, s32 LEDCount, r32 DeltaTime) -{ - node_list_iterator NodeIter = GetNodeListIterator(*NodeList); - while (NodeIteratorIsValid(NodeIter)) - { - node_header* Node = NodeIter.At; - if (!Node->UpdatedThisFrame) - { - UpdateNodeCalculation(Node, NodeList, Permanent, Transient, LEDs, Colors, LEDCount, DeltaTime); - } - Next(&NodeIter); - } -} - -internal void -ClearTransientNodeColorBuffers (node_list* NodeList) -{ - node_list_iterator NodeIter = GetNodeListIterator(*NodeList); - while (NodeIteratorIsValid(NodeIter)) - { - node_header* Node = NodeIter.At; - for (s32 ConnectionIdx = 0; ConnectionIdx < Node->ConnectionsCount; ConnectionIdx++) - { - node_connection* Connection = Node->Connections + ConnectionIdx; - if (Connection->Type == MemberType_NODE_COLOR_BUFFER) - { - Connection->LEDsValuePtr->Colors = 0; - } - } - Next(&NodeIter); - } -} - -internal void -DrawValueDisplay (render_command_buffer* RenderBuffer, rect Bounds, node_connection Value, bitmap_font* Font) -{ - PushRenderQuad2D(RenderBuffer, Bounds.Min, Bounds.Max, BlackV4); - - char Buffer[32]; - string String = MakeString(Buffer, 32); - - switch (Value.Type) - { - case MemberType_s32: - { - PrintF(&String, "%.*d", 4, *Value.S32ValuePtr); - DrawString(RenderBuffer, String, Font, Bounds.Min + v2{2, 2}, WhiteV4); - }break; - - case MemberType_r32: - { - PrintF(&String, "%.*f", 4, *Value.R32ValuePtr); - DrawString(RenderBuffer, String, Font, Bounds.Min + v2{2, 2}, WhiteV4); - }break; - - case MemberType_v4: - { - PushRenderQuad2D(RenderBuffer, Bounds.Min + v2{2, 2}, Bounds.Max - v2{2, 2}, *Value.V4ValuePtr); - }break; - - case MemberType_NODE_COLOR_BUFFER: - { - PrintF(&String, "LEDs"); - DrawString(RenderBuffer, String, Font, Bounds.Min + v2{2, 2}, WhiteV4); - }break; - - InvalidDefaultCase; - } -} - -internal void -DrawPort (render_command_buffer* RenderBuffer, rect Bounds, v4 Color) -{ - PushRenderQuad2D(RenderBuffer, Bounds.Min, Bounds.Max, Color); -} - -internal void -ResetNodesUpdateState (node_list* NodeList) -{ - node_list_iterator NodeIter = GetNodeListIterator(*NodeList); - while (NodeIteratorIsValid(NodeIter)) - { - node_header* Node = NodeIter.At; - Node->UpdatedThisFrame = false; - Next(&NodeIter); - } -} - -internal b32 -SpecificationPassesFilter(string SpecificationName, string SearchString) -{ - return (SearchString.Length == 0 || StringContainsStringCaseInsensitive(SpecificationName, SearchString)); -} - -internal s32 -NodeListerConvertHotItemToListIndex (s32 HotItem, u8* NodeSpecificationsList, s32 NodeSpecificationsListCount, - string SearchString) -{ - s32 ListIndex = 0; - s32 FilteredItemsCount = 0; - - for (s32 i = 0; i < NodeSpecificationsListCount; i++) - { - node_specification* Specification = (node_specification*)NodeSpecificationsList + i; - string ItemName = MakeString(Specification->Name); - b32 PassesFilter = SpecificationPassesFilter(ItemName, SearchString); - if (PassesFilter) - { - if (FilteredItemsCount == HotItem) - { - break; - } - FilteredItemsCount++; - } - ListIndex++; - } - - return ListIndex; -} - -internal string -NodeListerGetNodeName (u8* NodeSpecificationsList, s32 NodeSpecificationsListCount, string SearchString, s32 Offset) -{ - s32 FilteredItemsCount = 0; - node_specification* Specification = (node_specification*)NodeSpecificationsList; - string Result = {}; - for (s32 i = 0; i < NodeSpecificationsListCount; i++) - { - string ItemName = MakeString(Specification->Name); - b32 PassesFilter = SpecificationPassesFilter(ItemName, SearchString); - if (PassesFilter) - { - if (FilteredItemsCount == Offset) - { - Result = ItemName; - break; - } - FilteredItemsCount++; - } - - Specification++; - } - - return Result; -} \ No newline at end of file diff --git a/src/foldhaus_node.h b/src/foldhaus_node.h index 8391313..cd4504d 100644 --- a/src/foldhaus_node.h +++ b/src/foldhaus_node.h @@ -19,21 +19,6 @@ s32 name##LEDCount; #define NODE_COLOR_BUFFER_IN(name) NAMED_NODE_COLOR_BUFFER(name) #define NODE_COLOR_BUFFER_OUT(name) NAMED_NODE_COLOR_BUFFER(name) -enum mouse_node_interaction -{ - NodeInteraction_None, - NodeInteraction_MouseDragNode, - NodeInteraction_MouseDragInput, - NodeInteraction_KeyboardEnterPortValue, - MouseNodeInteraction_Count, -}; - -enum node_port_direction -{ - NodePort_Input, - NodePort_Output, -}; - // TODO(Peter): Generate this enum struct_member_type { @@ -45,114 +30,6 @@ enum struct_member_type MemberTypeCount, }; -struct node_led_color_connection -{ - NODE_COLOR_BUFFER; -}; - -struct node_connection -{ - s32 NodeHandle; - struct_member_type Type; - - // TODO(Peter): probably can unify these pairs into a struct - s32 UpstreamNodeHandle; - s32 UpstreamNodePortIndex; - s32 DownstreamNodeHandle; - s32 DownstreamNodePortIndex; - b32 DirectionMask; - - union - { - u8* Ptr; - s32* S32ValuePtr; - r32* R32ValuePtr; - v4* V4ValuePtr; - node_led_color_connection* LEDsValuePtr; - }; -}; - -// TODO(Peter): cant decide if this needs to be dynamic or just a really big number -// reevaluate once you have some examples -#define NODE_CONNECTIONS_MAX 8 -struct node_header -{ - s32 Handle; // NOTE(Peter): stores a non-zero handle. must come first to match node_free_list_member - node_type Type; - - v2 Min, Dim; - - s32 ConnectionsCount; - node_connection* Connections; - - b32 UpdatedThisFrame; - - u8* PersistentData; -}; - -struct node_list_buffer -{ - node_header* Headers; - s32 Max; - s32 Used; - - node_list_buffer* Next; -}; - -#define NODE_LIST_CONNECTIONS_MAX 256 -struct node_list -{ - node_list_buffer* First; - node_list_buffer* Head; - s32 TotalMax; - s32 TotalUsed; - - s32 HandleAccumulator; - - // TODO(Peter): Replace this with some sort of stretchy bufferf - // :ConnectionsToStretchyBuffer - s32 ConnectionsUsed; - node_connection Connections[NODE_LIST_CONNECTIONS_MAX]; -}; - -struct node_list_iterator -{ - node_list List; - node_list_buffer* CurrentBuffer; - node_header* At; - s32 BufferIndexAt; - s32 TotalIndexAt; -}; - -enum node_interaction_flag -{ - NodeInteraction_AllUpstream = 0x1, - NodeInteraction_AllDownstream = 0x2, -}; - -struct node_interaction -{ - s32 NodeHandle; - v2 MouseOffset; - b32 Flags; - - // TODO(Peter): Inputs and outputs are all stored in the same array. Should this just be flags, - // and we store the Port and Value? - s32 InputPort; - s32 InputValue; - s32 OutputPort; - s32 OutputValue; -}; - -struct node_render_settings -{ - v4 PortColors[MemberTypeCount]; - bitmap_font* Font; - b32 Display; -}; - -// ^^ OLD ^^ - struct node_struct_member { struct_member_type Type; @@ -201,21 +78,6 @@ struct pattern_node_workspace }; -// vv OLD vv - -v4 DragButtonColors[] = { - v4{.7f, .7f, .7f, 1}, - BlackV4, - v4{.7f, .7f, .7f, 1}, -}; - -#define NODE_HEADER_HEIGHT 20 - -#define NODE_PORT_X 20 -#define NODE_PORT_Y 15 -#define NODE_PORT_DIM v2{NODE_PORT_X, NODE_PORT_Y} -#define NODE_PORT_STEP NODE_PORT_Y + 20 - /////////////////////////////////////////////// // Pre Processor Macros /////////////////////////////////////////////// @@ -245,4 +107,4 @@ NODE_STRUCT(output_node_data) NODE_PROC(OutputNode, output_node_data) { -} +} \ No newline at end of file diff --git a/src/generated/foldhaus_nodes_generated.cpp b/src/generated/foldhaus_nodes_generated.cpp index 2543f5b..55d3dfb 100644 --- a/src/generated/foldhaus_nodes_generated.cpp +++ b/src/generated/foldhaus_nodes_generated.cpp @@ -47,6 +47,7 @@ node_struct_member MemberList_sin_wave_data[] = { node_struct_member MemberList_multiply_patterns_data[] = { { MemberType_NODE_COLOR_BUFFER, "ALEDs", (u64)&((multiply_patterns_data*)0)->ALEDs, IsInputMember }, +{ MemberType_NODE_COLOR_BUFFER, "BLEDs", (u64)&((multiply_patterns_data*)0)->BLEDs, IsInputMember }, { MemberType_NODE_COLOR_BUFFER, "ResultLEDs", (u64)&((multiply_patterns_data*)0)->ResultLEDs, IsOutputMember}, }; @@ -82,8 +83,8 @@ node_specification NodeSpecifications[] = { { NodeType_VectorValue, "VectorValue", 11, MemberList_vector_data, 32, 5, false}, { NodeType_MultiplyNodeProc, "MultiplyNodeProc", 16, MemberList_multiply_data, 12, 3, false}, { NodeType_AddNodeProc, "AddNodeProc", 11, MemberList_add_data, 48, 3, false}, -{ NodeType_SinWave, "SinWave", 7, MemberList_sin_wave_data, 16, 4, false}, -{ NodeType_MultiplyPatterns, "MultiplyPatterns", 16, MemberList_multiply_patterns_data, 40, 2, false}, +{ NodeType_SinWave, "SinWave", 7, MemberList_sin_wave_data, 20, 4, false}, +{ NodeType_MultiplyPatterns, "MultiplyPatterns", 16, MemberList_multiply_patterns_data, 60, 3, false}, { NodeType_OutputNode, "OutputNode", 10, MemberList_output_node_data, 20, 1, false}, { NodeType_SolidColorProc, "SolidColorProc", 14, MemberList_solid_color_data, 36, 2, false}, { NodeType_VerticalColorFadeProc, "VerticalColorFadeProc", 21, MemberList_vertical_color_fade_data, 44, 4, false}, @@ -91,12 +92,12 @@ node_specification NodeSpecifications[] = { }; s32 NodeSpecificationsCount = 10; -internal void CallNodeProc(node_header* Node, u8* Data, led* LEDs, s32 LEDsCount, r32 DeltaTime) - { - node_specification Spec = NodeSpecifications[Node->Type]; - switch (Spec.Type) - { - case NodeType_FloatValue: { FloatValue((float_value_data*)Data, DeltaTime); } break; +internal void CallNodeProc(u32 SpecificationIndex, u8* Data, led* LEDs, s32 LEDsCount, r32 DeltaTime) +{ +node_specification Spec = NodeSpecifications[SpecificationIndex]; +switch (Spec.Type) +{ +case NodeType_FloatValue: { FloatValue((float_value_data*)Data, DeltaTime); } break; case NodeType_VectorValue: { VectorValue((vector_data*)Data, DeltaTime); } break; case NodeType_MultiplyNodeProc: { MultiplyNodeProc((multiply_data*)Data, DeltaTime); } break; case NodeType_AddNodeProc: { AddNodeProc((add_data*)Data, DeltaTime); } break; diff --git a/src/panels/foldhaus_panel_node_graph.h b/src/panels/foldhaus_panel_node_graph.h index 43c20ac..fd5d271 100644 --- a/src/panels/foldhaus_panel_node_graph.h +++ b/src/panels/foldhaus_panel_node_graph.h @@ -6,7 +6,7 @@ struct visual_node struct visual_port { - u32 SparseNodeIndex; + gs_list_handle SparseNodeHandle; u32 PortIndex; rect PortBounds; }; @@ -113,15 +113,18 @@ FOLDHAUS_INPUT_COMMAND_PROC(EndConnectNodesOperation) rect ViewAdjustedBounds = RectOffsetByVector(VisualPort.PortBounds, GraphState->ViewOffset); if (PointIsInRect(Mouse.Pos, ViewAdjustedBounds)) { - pattern_node_connection Connection = {}; visual_port UpstreamPort = (OpState->IsInput & IsInputMember) ? VisualPort : OpState->VisualPort; visual_port DownstreamPort = (OpState->IsInput & IsInputMember) ? OpState->VisualPort : VisualPort; // Make Connection - // TODO(Peter): START HERE - //start here; - // You were working on connection UpstreamPort and DownstreamPort - // You need to get each node's handle and add a new connection to the connection bucket + pattern_node_connection Connection = {}; + Connection.UpstreamNodeHandle = UpstreamPort.SparseNodeHandle; + Connection.DownstreamNodeHandle = DownstreamPort.SparseNodeHandle; + Connection.UpstreamPortIndex = UpstreamPort.PortIndex; + Connection.DownstreamPortIndex = DownstreamPort.PortIndex; + + State->NodeWorkspace.Connections.PushElementOnBucket(Connection); + GraphState->LayoutIsDirty = true; } } @@ -330,8 +333,10 @@ ArrangeNodes(pattern_node_workspace Workspace, r32 NodeWidth, r32 LayerDistance, for (u32 n = 0; n < Result.SparseToContiguousNodeMapCount; n++) { u32 NodeIndex = Result.SparseToContiguousNodeMap[n]; - pattern_node* Node = Workspace.Nodes.GetElementAtIndex(NodeIndex); - u32 SpecIndex = Node->SpecificationIndex; + gs_list_entry* NodeEntry = Workspace.Nodes.GetEntryAtIndex(NodeIndex); + pattern_node Node = NodeEntry->Value; + + u32 SpecIndex = Node.SpecificationIndex; node_specification Spec = NodeSpecifications[SpecIndex]; u32 NodeLayer = Result.VisualNodeLayers[n]; @@ -363,7 +368,7 @@ ArrangeNodes(pattern_node_workspace Workspace, r32 NodeWidth, r32 LayerDistance, PortBounds.Max = PortBounds.Min + v2{8, 8}; visual_port* VisualPort = Result.VisualPorts + VisualPortsUsed++; - VisualPort->SparseNodeIndex = n; + VisualPort->SparseNodeHandle = NodeEntry->Handle; VisualPort->PortIndex = p; VisualPort->PortBounds = PortBounds; }