Incorporated a new *shudders* c++ template based list implementation. Hopefully I can stop writing list implementations now
This commit is contained in:
parent
c5404e3296
commit
9973cf4ed9
|
@ -17,27 +17,11 @@ struct animation_block
|
|||
u32 Layer;
|
||||
};
|
||||
|
||||
struct animation_block_handle
|
||||
{
|
||||
s32 Index;
|
||||
// NOTE(Peter): Zero is invalid
|
||||
u32 Generation;
|
||||
};
|
||||
|
||||
struct animation_block_entry
|
||||
{
|
||||
u32 Generation;
|
||||
animation_block Block;
|
||||
free_list Free;
|
||||
};
|
||||
|
||||
#define ANIMATION_SYSTEM_LAYERS_MAX 128
|
||||
#define ANIMATION_SYSTEM_BLOCKS_MAX 128
|
||||
struct animation_system
|
||||
{
|
||||
animation_block_entry Blocks[ANIMATION_SYSTEM_BLOCKS_MAX];
|
||||
free_list FreeList;
|
||||
u32 BlocksCount;
|
||||
gs_list<animation_block> Blocks;
|
||||
|
||||
r32 Time;
|
||||
s32 LastUpdatedFrame;
|
||||
|
@ -50,98 +34,8 @@ struct animation_system
|
|||
r32 AnimationEnd;
|
||||
};
|
||||
|
||||
internal b32
|
||||
AnimationBlockHandlesAreEqual(animation_block_handle A, animation_block_handle B)
|
||||
{
|
||||
b32 Result = ((A.Index == B.Index) && (A.Generation == B.Generation));
|
||||
return Result;
|
||||
}
|
||||
|
||||
internal b32
|
||||
AnimationBlockHandleIsValid(animation_block_handle Handle)
|
||||
{
|
||||
b32 Result = Handle.Generation != 0;
|
||||
return Result;
|
||||
}
|
||||
|
||||
internal void
|
||||
InitializeAnimationSystem(animation_system* System)
|
||||
{
|
||||
*System = {0};
|
||||
System->FreeList.Next = &System->FreeList;
|
||||
}
|
||||
|
||||
inline b32
|
||||
AnimationBlockIsFree(animation_block_entry Entry)
|
||||
{
|
||||
// NOTE(Peter): If we've set Free.Next to zero, we've removed it from the
|
||||
// free list.
|
||||
b32 Result = Entry.Free.Next != 0;
|
||||
return Result;
|
||||
}
|
||||
|
||||
internal animation_block_entry*
|
||||
GetEntryAtIndex(u32 Index, animation_system* System)
|
||||
{
|
||||
Assert(Index < System->BlocksCount);
|
||||
animation_block_entry* Result = System->Blocks + Index;
|
||||
return Result;
|
||||
}
|
||||
|
||||
internal animation_block*
|
||||
GetAnimationBlockWithHandle(animation_block_handle Handle, animation_system* System)
|
||||
{
|
||||
animation_block* Result = 0;
|
||||
animation_block_entry* Entry = GetEntryAtIndex(Handle.Index, System);
|
||||
if (Entry && Entry->Generation == Handle.Generation)
|
||||
{
|
||||
Result = &Entry->Block;
|
||||
}
|
||||
return Result;
|
||||
}
|
||||
|
||||
internal animation_block_handle
|
||||
AddAnimationBlock(animation_block Block, animation_system* System)
|
||||
{
|
||||
animation_block_handle Result = {0};
|
||||
|
||||
if (System->FreeList.Next != 0
|
||||
&& System->FreeList.Next != &System->FreeList)
|
||||
{
|
||||
free_list* FreeEntry = System->FreeList.Next;
|
||||
Result.Index = FreeEntry->Index;
|
||||
System->FreeList.Next = FreeEntry->Next;
|
||||
}
|
||||
else
|
||||
{
|
||||
Assert(System->BlocksCount < ANIMATION_SYSTEM_BLOCKS_MAX);
|
||||
Result.Index = System->BlocksCount++;
|
||||
}
|
||||
|
||||
animation_block_entry* Entry = GetEntryAtIndex(Result.Index, System);
|
||||
Entry->Generation += 1;
|
||||
Result.Generation = Entry->Generation;
|
||||
System->Blocks[Result.Index].Block = Block;
|
||||
System->Blocks[Result.Index].Free.Next = 0;
|
||||
|
||||
return Result;
|
||||
}
|
||||
|
||||
internal void
|
||||
RemoveAnimationBlock(animation_block_handle Handle, animation_system* System)
|
||||
{
|
||||
animation_block_entry* Entry = GetEntryAtIndex(Handle.Index, System);
|
||||
|
||||
// NOTE(Peter): I'm pretty sure this doesn't need to be an assert but at the moment, there
|
||||
// is no reason why we shouldn't always be able to remove an entry when we request it.
|
||||
// For now, I'm putting this assert here so we deal with this intentionally when the first
|
||||
// case comes up.
|
||||
// TODO: When we do deal with the above note, I'm guessing we want to return true or false
|
||||
// to signal if we were able to remove the entry or not so that the calling site can deal
|
||||
// with the removed reference
|
||||
Assert(Handle.Generation == Entry->Generation);
|
||||
|
||||
Entry->Free.Index = Handle.Index;
|
||||
Entry->Free.Next = System->FreeList.Next;
|
||||
System->FreeList.Next = &Entry->Free;
|
||||
}
|
||||
|
|
|
@ -162,9 +162,6 @@ INITIALIZE_APPLICATION(InitializeApplication)
|
|||
State->Camera.Position = v3{0, 0, -250};
|
||||
State->Camera.LookAt = v3{0, 0, 0};
|
||||
|
||||
State->AssemblyList.BucketSize = 32;
|
||||
State->AssemblyList.FreeList.Next = &State->AssemblyList.FreeList;
|
||||
State->ActiveAssemblyIndecies.BucketSize = 32;
|
||||
#if 1
|
||||
char Path[] = "radialumia.fold";
|
||||
LoadAssembly(State, Context, Path);
|
||||
|
@ -331,19 +328,19 @@ UPDATE_AND_RENDER(UpdateAndRender)
|
|||
State->AnimationSystem.LastUpdatedFrame = CurrentFrame;
|
||||
r32 FrameTime = CurrentFrame * State->AnimationSystem.SecondsPerFrame;
|
||||
|
||||
for (u32 i = 0; i < State->AnimationSystem.BlocksCount; i++)
|
||||
for (u32 i = 0; i < State->AnimationSystem.Blocks.Used; i++)
|
||||
{
|
||||
animation_block_entry BlockEntry = State->AnimationSystem.Blocks[i];
|
||||
if (!AnimationBlockIsFree(BlockEntry))
|
||||
gs_list_entry<animation_block>* BlockEntry = State->AnimationSystem.Blocks.GetEntryAtIndex(i);
|
||||
if (!EntryIsFree(BlockEntry))
|
||||
{
|
||||
animation_block Block = BlockEntry.Block;
|
||||
animation_block Block = BlockEntry->Value;
|
||||
if (State->AnimationSystem.Time >= Block.StartTime
|
||||
&& State->AnimationSystem.Time <= Block.EndTime)
|
||||
{
|
||||
for (s32 j = 0; j < State->ActiveAssemblyIndecies.Used; j++)
|
||||
for (u32 j = 0; j < State->ActiveAssemblyIndecies.Used; j++)
|
||||
{
|
||||
array_entry_handle* AssemblyHandle = GetElementAtIndex(j, State->ActiveAssemblyIndecies);
|
||||
assembly* Assembly = GetElementWithHandle(*AssemblyHandle, State->AssemblyList);
|
||||
gs_list_handle AssemblyHandle = *State->ActiveAssemblyIndecies.GetElementAtIndex(j);
|
||||
assembly* Assembly = State->AssemblyList.GetElementWithHandle(AssemblyHandle);
|
||||
Block.Proc(Assembly, FrameTime - Block.StartTime);
|
||||
}
|
||||
}
|
||||
|
@ -353,10 +350,10 @@ UPDATE_AND_RENDER(UpdateAndRender)
|
|||
|
||||
s32 HeaderSize = State->NetworkProtocolHeaderSize;
|
||||
dmx_buffer_list* DMXBuffers = 0;
|
||||
for (s32 i = 0; i < State->ActiveAssemblyIndecies.Used; i++)
|
||||
for (u32 i = 0; i < State->ActiveAssemblyIndecies.Used; i++)
|
||||
{
|
||||
array_entry_handle* AssemblyHandle = GetElementAtIndex(i, State->ActiveAssemblyIndecies);
|
||||
assembly* Assembly = GetElementWithHandle(*AssemblyHandle, State->AssemblyList);
|
||||
gs_list_handle AssemblyHandle = *State->ActiveAssemblyIndecies.GetElementAtIndex(i);
|
||||
assembly* Assembly = State->AssemblyList.GetElementWithHandle(AssemblyHandle);
|
||||
dmx_buffer_list* NewDMXBuffers = CreateDMXBuffers(*Assembly, HeaderSize, &State->Transient);
|
||||
DMXBuffers = DMXBufferListAppend(DMXBuffers, NewDMXBuffers);
|
||||
}
|
||||
|
@ -411,10 +408,10 @@ UPDATE_AND_RENDER(UpdateAndRender)
|
|||
{
|
||||
DEBUG_TRACK_SCOPE(OverflowChecks);
|
||||
AssertAllocationsNoOverflow(State->Permanent);
|
||||
for (s32 i = 0; i < State->ActiveAssemblyIndecies.Used; i++)
|
||||
for (u32 i = 0; i < State->ActiveAssemblyIndecies.Used; i++)
|
||||
{
|
||||
array_entry_handle* AssemblyHandle = GetElementAtIndex(i, State->ActiveAssemblyIndecies);
|
||||
assembly* Assembly = GetElementWithHandle(*AssemblyHandle, State->AssemblyList);
|
||||
gs_list_handle AssemblyHandle = *State->ActiveAssemblyIndecies.GetElementAtIndex(i);
|
||||
assembly* Assembly = State->AssemblyList.GetElementWithHandle(AssemblyHandle);
|
||||
AssertAllocationsNoOverflow(Assembly->Arena);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -53,8 +53,8 @@ struct app_state
|
|||
streaming_acn SACN;
|
||||
|
||||
s32 TotalLEDsCount;
|
||||
assembly_array AssemblyList;
|
||||
array_entry_handle_contiguous_array ActiveAssemblyIndecies;
|
||||
gs_list<assembly> AssemblyList;
|
||||
gs_list<gs_list_handle> ActiveAssemblyIndecies;
|
||||
|
||||
camera Camera;
|
||||
r32 PixelsToWorldScale;
|
||||
|
@ -66,7 +66,7 @@ struct app_state
|
|||
interface_config Interface;
|
||||
|
||||
animation_system AnimationSystem;
|
||||
animation_block_handle SelectedAnimationBlockHandle;
|
||||
gs_list_handle SelectedAnimationBlockHandle;
|
||||
|
||||
panel_system PanelSystem;
|
||||
panel* HotPanel;
|
||||
|
|
|
@ -91,26 +91,26 @@ LoadAssembly (app_state* State, context Context, char* Path)
|
|||
Offset,
|
||||
Scale,
|
||||
AssemblyArena);
|
||||
array_entry_handle NewAssemblyHandle = PushElement(NewAssembly, &State->AssemblyList);
|
||||
PushElement(NewAssemblyHandle, &State->ActiveAssemblyIndecies);
|
||||
gs_list_handle NewAssemblyHandle = State->AssemblyList.PushElementOnList(NewAssembly);
|
||||
State->ActiveAssemblyIndecies.PushElementOnList(NewAssemblyHandle);
|
||||
|
||||
State->TotalLEDsCount += NewAssembly.LEDCount;
|
||||
}
|
||||
|
||||
internal void
|
||||
UnloadAssembly (s32 AssemblyIndex, app_state* State, context Context)
|
||||
UnloadAssembly (u32 AssemblyIndex, app_state* State, context Context)
|
||||
{
|
||||
assembly* Assembly = GetElementAtIndex(AssemblyIndex, State->AssemblyList);
|
||||
assembly* Assembly = State->AssemblyList.GetElementAtIndex(AssemblyIndex);
|
||||
State->TotalLEDsCount -= Assembly->LEDCount;
|
||||
FreeMemoryArena(&Assembly->Arena, (gs_memory_free*)Context.PlatformFree);
|
||||
|
||||
RemoveElementAtIndex(AssemblyIndex, &State->AssemblyList);
|
||||
for (s32 i = 0; i < State->ActiveAssemblyIndecies.Used; i++)
|
||||
State->AssemblyList.FreeElementAtIndex(AssemblyIndex);
|
||||
for (u32 i = 0; i < State->ActiveAssemblyIndecies.Used; i++)
|
||||
{
|
||||
array_entry_handle Handle = *GetElementAtIndex(i, State->ActiveAssemblyIndecies);
|
||||
gs_list_handle Handle = *State->ActiveAssemblyIndecies.GetElementAtIndex(i);
|
||||
if (Handle.Index == AssemblyIndex)
|
||||
{
|
||||
RemoveElementAtIndex(i, &State->ActiveAssemblyIndecies);
|
||||
State->ActiveAssemblyIndecies.FreeElementAtIndex(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -36,5 +36,3 @@ struct assembly
|
|||
s32 LEDUniverseMapCount;
|
||||
leds_in_universe_range* LEDUniverseMap;
|
||||
};
|
||||
|
||||
TYPEDEF_ARRAY(assembly);
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
#include <windows.h>
|
||||
|
||||
#define GS_LANGUAGE_NO_PROFILER_DEFINES
|
||||
#include <gs_language.h>
|
||||
#include "gs_platform.h"
|
||||
#include "gs_array.h"
|
||||
#include <gs_list.h>
|
||||
|
||||
#define GS_MEMORY_TRACK_ALLOCATIONS
|
||||
#define GS_MEMORY_NO_STD_LIBS
|
||||
|
|
|
@ -39,7 +39,7 @@ AddAnimationBlock(r32 StartTime, r32 EndTime, animation_proc* Proc, animation_sy
|
|||
NewBlock.StartTime = StartTime;
|
||||
NewBlock.EndTime = EndTime;
|
||||
NewBlock.Proc = Proc;
|
||||
AddAnimationBlock(NewBlock, AnimationSystem);
|
||||
AnimationSystem->Blocks.PushElementOnList(NewBlock);
|
||||
}
|
||||
|
||||
#define NEW_ANIMATION_BLOCK_DURATION 3
|
||||
|
@ -51,14 +51,14 @@ AddAnimationBlockAtCurrentTime (animation_proc* Proc, animation_system* System)
|
|||
}
|
||||
|
||||
internal void
|
||||
DeleteAnimationBlock(animation_block_handle AnimationBlockHandle, app_state* State)
|
||||
DeleteAnimationBlock(gs_list_handle AnimationBlockHandle, app_state* State)
|
||||
{
|
||||
RemoveAnimationBlock(State->SelectedAnimationBlockHandle, &State->AnimationSystem);
|
||||
State->AnimationSystem.Blocks.FreeElementWithHandle(AnimationBlockHandle);
|
||||
State->SelectedAnimationBlockHandle = {0};
|
||||
}
|
||||
|
||||
internal void
|
||||
SelectAnimationBlock(animation_block_handle BlockHandle, app_state* State)
|
||||
SelectAnimationBlock(gs_list_handle BlockHandle, app_state* State)
|
||||
{
|
||||
State->SelectedAnimationBlockHandle = BlockHandle;
|
||||
}
|
||||
|
@ -71,10 +71,7 @@ DeselectCurrentAnimationBlock(app_state* State)
|
|||
|
||||
FOLDHAUS_INPUT_COMMAND_PROC(DeleteAnimationBlockCommand)
|
||||
{
|
||||
if (AnimationBlockHandleIsValid(State->SelectedAnimationBlockHandle))
|
||||
{
|
||||
DeleteAnimationBlock(State->SelectedAnimationBlockHandle, State);
|
||||
}
|
||||
DeleteAnimationBlock(State->SelectedAnimationBlockHandle, State);
|
||||
}
|
||||
|
||||
//
|
||||
|
@ -145,7 +142,7 @@ OPERATION_RENDER_PROC(UpdateDragAnimationClip)
|
|||
r32 TimeAtMouseX = GetTimeFromPointInAnimationPanel(Mouse.Pos, OpState->TimelineBounds, OpState->AnimationPanel_StartFrame, OpState->AnimationPanel_EndFrame, State->AnimationSystem.SecondsPerFrame);
|
||||
r32 TimeOffset = TimeAtMouseX - TimeAtMouseDownX;
|
||||
|
||||
animation_block* AnimationBlock = GetAnimationBlockWithHandle(State->SelectedAnimationBlockHandle, &State->AnimationSystem);
|
||||
animation_block* AnimationBlock = State->AnimationSystem.Blocks.GetElementWithHandle(State->SelectedAnimationBlockHandle);
|
||||
|
||||
if (GSAbs(Mouse.DownPos.x - ClipInitialStartTimeXPosition) < CLICK_ANIMATION_BLOCK_EDGE_MAX_SCREEN_DISTANCE)
|
||||
{
|
||||
|
@ -162,17 +159,12 @@ OPERATION_RENDER_PROC(UpdateDragAnimationClip)
|
|||
}
|
||||
}
|
||||
|
||||
FOLDHAUS_INPUT_COMMAND_PROC(EndDragAnimationClip)
|
||||
{
|
||||
DeactivateCurrentOperationMode(&State->Modes);
|
||||
}
|
||||
|
||||
input_command DragAnimationClipCommands [] = {
|
||||
{ KeyCode_MouseLeftButton, KeyCode_Invalid, Command_Ended, EndDragAnimationClip },
|
||||
{ KeyCode_MouseLeftButton, KeyCode_Invalid, Command_Ended, EndCurrentOperationMode },
|
||||
};
|
||||
|
||||
internal void
|
||||
SelectAndBeginDragAnimationBlock(animation_block_handle BlockHandle, s32 PanelStartFrame, s32 PanelEndFrame, rect TimelineBounds, app_state* State)
|
||||
SelectAndBeginDragAnimationBlock(gs_list_handle BlockHandle, s32 PanelStartFrame, s32 PanelEndFrame, rect TimelineBounds, app_state* State)
|
||||
{
|
||||
SelectAnimationBlock(BlockHandle, State);
|
||||
|
||||
|
@ -185,7 +177,7 @@ SelectAndBeginDragAnimationBlock(animation_block_handle BlockHandle, s32 PanelSt
|
|||
OpState->AnimationPanel_StartFrame = PanelStartFrame;
|
||||
OpState->AnimationPanel_EndFrame = PanelEndFrame ;
|
||||
|
||||
animation_block* SelectedBlock = GetAnimationBlockWithHandle(BlockHandle, &State->AnimationSystem);
|
||||
animation_block* SelectedBlock = State->AnimationSystem.Blocks.GetElementWithHandle(BlockHandle);
|
||||
OpState->SelectedClip_InitialStartTime = SelectedBlock->StartTime;
|
||||
OpState->SelectedClip_InitialEndTime = SelectedBlock->EndTime;
|
||||
}
|
||||
|
@ -205,7 +197,7 @@ FOLDHAUS_INPUT_COMMAND_PROC(AddAnimationBlockCommand)
|
|||
Block.EndTime = NewBlockTimeEnd;
|
||||
Block.Proc = TestPatternThree;
|
||||
|
||||
animation_block_handle NewBlockHandle = AddAnimationBlock(Block, &State->AnimationSystem);
|
||||
gs_list_handle NewBlockHandle = State->AnimationSystem.Blocks.PushElementOnList(Block);
|
||||
SelectAnimationBlock(NewBlockHandle, State);
|
||||
}
|
||||
|
||||
|
@ -288,13 +280,13 @@ DrawAnimationBlock (animation_block AnimationBlock, v4 BlockColor, r32 SecondsPe
|
|||
return BlockBounds;
|
||||
}
|
||||
|
||||
internal animation_block_handle
|
||||
DrawAnimationTimeline (animation_system* AnimationSystem, s32 StartFrame, s32 EndFrame, rect PanelBounds, animation_block_handle SelectedBlockHandle, render_command_buffer* RenderBuffer, app_state* State, mouse_state Mouse)
|
||||
internal gs_list_handle
|
||||
DrawAnimationTimeline (animation_system* AnimationSystem, s32 StartFrame, s32 EndFrame, rect PanelBounds, gs_list_handle SelectedBlockHandle, render_command_buffer* RenderBuffer, app_state* State, mouse_state Mouse)
|
||||
{
|
||||
string TempString = MakeString(PushArray(&State->Transient, char, 256), 256);
|
||||
s32 FrameCount = EndFrame - StartFrame;
|
||||
|
||||
animation_block_handle Result = SelectedBlockHandle;
|
||||
gs_list_handle Result = SelectedBlockHandle;
|
||||
|
||||
r32 AnimationPanelHeight = PanelBounds.Max.y - PanelBounds.Min.y;
|
||||
r32 AnimationPanelWidth = PanelBounds.Max.x - PanelBounds.Min.x;
|
||||
|
@ -318,19 +310,16 @@ DrawAnimationTimeline (animation_system* AnimationSystem, s32 StartFrame, s32 En
|
|||
// Animation Blocks
|
||||
rect TimelineBounds = rect{ PanelBounds.Min, v2{PanelBounds.Max.x, FrameBarBottom} };
|
||||
b32 MouseDownAndNotHandled = MouseButtonTransitionedDown(Mouse.LeftButtonState);
|
||||
for (u32 i = 0; i < AnimationSystem->BlocksCount; i++)
|
||||
for (u32 i = 0; i < AnimationSystem->Blocks.Used; i++)
|
||||
{
|
||||
animation_block_entry* AnimationBlockEntry = GetEntryAtIndex(i, AnimationSystem);
|
||||
if (AnimationBlockIsFree(*AnimationBlockEntry)) { continue; }
|
||||
gs_list_entry<animation_block>* AnimationBlockEntry = AnimationSystem->Blocks.GetEntryAtIndex(i);
|
||||
if (AnimationBlockEntry->Free.NextFreeEntry != 0) { continue; }
|
||||
|
||||
animation_block_handle CurrentBlockHandle = {};
|
||||
CurrentBlockHandle.Index = i;
|
||||
CurrentBlockHandle.Generation = AnimationBlockEntry->Generation;
|
||||
|
||||
animation_block AnimationBlockAt = AnimationBlockEntry->Block;
|
||||
gs_list_handle CurrentBlockHandle = AnimationBlockEntry->Handle;
|
||||
animation_block AnimationBlockAt = AnimationBlockEntry->Value;
|
||||
|
||||
v4 BlockColor = BlackV4;
|
||||
if (AnimationBlockHandlesAreEqual(SelectedBlockHandle, CurrentBlockHandle))
|
||||
if (GSListHandlesAreEqual(SelectedBlockHandle, CurrentBlockHandle))
|
||||
{
|
||||
BlockColor = PinkV4;
|
||||
}
|
||||
|
@ -425,7 +414,7 @@ DrawAnimationClipsList(rect PanelBounds, mouse_state Mouse, render_command_buffe
|
|||
|
||||
PANEL_RENDER_PROC(AnimationTimeline_Render)
|
||||
{
|
||||
animation_block_handle SelectedBlockHandle = State->SelectedAnimationBlockHandle;
|
||||
gs_list_handle SelectedBlockHandle = State->SelectedAnimationBlockHandle;
|
||||
|
||||
r32 OptionsRowHeight = 25;
|
||||
rect AnimationClipListBounds = rect{
|
||||
|
|
|
@ -31,15 +31,15 @@ PANEL_RENDER_PROC(HierarchyView_Render)
|
|||
v2 TextOffset = v2{10, 4};
|
||||
string TempString = MakeString(PushArray(&State->Transient, char, 256), 256);
|
||||
|
||||
s32 LineCount = (s32)(PanelHeight / List.ListElementDimensions.y) + 1;
|
||||
for (s32 i = 0; i < LineCount; i++)
|
||||
u32 LineCount = (u32)(PanelHeight / List.ListElementDimensions.y) + 1;
|
||||
for (u32 i = 0; i < LineCount; i++)
|
||||
{
|
||||
rect ElementBounds = DrawListElementBackground(&List, Mouse, RenderBuffer);
|
||||
|
||||
if (i < State->ActiveAssemblyIndecies.Used)
|
||||
{
|
||||
array_entry_handle AssemblyHandle = *GetElementAtIndex(i, State->ActiveAssemblyIndecies);
|
||||
assembly Assembly = *GetElementWithHandle(AssemblyHandle, State->AssemblyList);
|
||||
gs_list_handle AssemblyHandle = *State->ActiveAssemblyIndecies.GetElementAtIndex(i);
|
||||
assembly Assembly = *State->AssemblyList.GetElementWithHandle(AssemblyHandle);
|
||||
PrintF(&TempString, "%S", Assembly.Name);
|
||||
|
||||
DrawString(RenderBuffer, TempString, State->Interface.Font, ElementBounds.Min + TextOffset, WhiteV4);
|
||||
|
|
|
@ -4,6 +4,53 @@ struct node_graph_state
|
|||
};
|
||||
|
||||
|
||||
struct temp_node_connection
|
||||
{
|
||||
u32 DownstreamNodeIndex;
|
||||
u32 DownstreamNodePort;
|
||||
|
||||
u32 UpstreamNodeIndex;
|
||||
u32 UpstreamNodePort;
|
||||
};
|
||||
|
||||
struct visual_node
|
||||
{
|
||||
node_specification Spec;
|
||||
v2 Position;
|
||||
};
|
||||
|
||||
#define TEMP_NODE_LIST_MAX 10
|
||||
global_variable u32 TEMP_NodeListUsed = 0;
|
||||
global_variable node_specification TEMP_NodeList[TEMP_NODE_LIST_MAX];
|
||||
|
||||
#define TEMP_CONNECTIONS_LIST_MAX 10
|
||||
global_variable u32 TEMP_NodeConnectionsUsed = 0;
|
||||
global_variable temp_node_connection TEMP_NodeConnections[TEMP_CONNECTIONS_LIST_MAX];
|
||||
|
||||
internal void
|
||||
PushNodeOnNodeList(node_specification Spec)
|
||||
{
|
||||
if (TEMP_NodeListUsed < TEMP_NODE_LIST_MAX)
|
||||
{
|
||||
u32 Index = TEMP_NodeListUsed++;
|
||||
TEMP_NodeList[Index] = Spec;
|
||||
}
|
||||
}
|
||||
|
||||
internal void
|
||||
PushConnectionOnConnectionsList(u32 UpstreamNodeIndex, u32 UpstreamNodePort, u32 DownstreamNodeIndex, u32 DownstreamNodePort)
|
||||
{
|
||||
if (TEMP_NodeConnectionsUsed < TEMP_CONNECTIONS_LIST_MAX)
|
||||
{
|
||||
u32 Index = TEMP_NodeConnectionsUsed++;
|
||||
TEMP_NodeConnections[Index].DownstreamNodeIndex = DownstreamNodeIndex;
|
||||
TEMP_NodeConnections[Index].DownstreamNodePort = DownstreamNodePort;
|
||||
TEMP_NodeConnections[Index].UpstreamNodeIndex = UpstreamNodeIndex;
|
||||
TEMP_NodeConnections[Index].UpstreamNodePort = UpstreamNodePort;;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Pan Node Graph
|
||||
//
|
||||
|
@ -39,6 +86,41 @@ FOLDHAUS_INPUT_COMMAND_PROC(BeginPanNodeGraph)
|
|||
OpState->ViewOffset = &NodeGraphState->ViewOffset;
|
||||
}
|
||||
|
||||
//
|
||||
// Connect Nodes
|
||||
//
|
||||
|
||||
OPERATION_STATE_DEF(connect_nodes_operation_state)
|
||||
{
|
||||
u32 NodeIndex;
|
||||
u32 PortIndex;
|
||||
};
|
||||
|
||||
OPERATION_RENDER_PROC(UpdateConnectNodeOperation)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
FOLDHAUS_INPUT_COMMAND_PROC(EndConnectNodesOperation)
|
||||
{
|
||||
connect_nodes_operation_state* OpState = GetCurrentOperationState(State->Modes, connect_nodes_operation_state);
|
||||
|
||||
EndCurrentOperationMode(State, Event, Mouse);
|
||||
}
|
||||
|
||||
input_command ConnectNodesOperationCommands[] = {
|
||||
{ KeyCode_MouseLeftButton, KeyCode_Invalid, Command_Began, EndConnectNodesOperation },
|
||||
};
|
||||
|
||||
internal void
|
||||
BeginConnectNodesOperation(u32 NodeIndex, u32 PortIndex, app_state* State)
|
||||
{
|
||||
operation_mode* ConnectNodesOperation = ActivateOperationModeWithCommands(&State->Modes, ConnectNodesOperationCommands, UpdateConnectNodeOperation);
|
||||
connect_nodes_operation_state* OpState = CreateOperationState(ConnectNodesOperation, &State->Modes, connect_nodes_operation_state);
|
||||
OpState->NodeIndex = NodeIndex;
|
||||
OpState->PortIndex = PortIndex;
|
||||
}
|
||||
|
||||
//
|
||||
// Node Graph Panel
|
||||
//
|
||||
|
@ -96,9 +178,13 @@ DrawGrid (v2 Offset, v2 GridSquareDim, rect PanelBounds, render_command_buffer*
|
|||
|
||||
}
|
||||
|
||||
internal void
|
||||
DrawNodePorts(node_specification Spec, b32 InputMask, v2 Position, r32 LineHeight, string_alignment TextAlign, v2 TextOffset, interface_config Interface, render_command_buffer* RenderBuffer)
|
||||
internal s32
|
||||
DrawNodePorts(node_specification Spec, b32 InputMask, v2 Position, r32 LineHeight, string_alignment TextAlign, v2 TextOffset, interface_config Interface, render_command_buffer* RenderBuffer, mouse_state Mouse)
|
||||
{
|
||||
s32 PortClicked = -1;
|
||||
|
||||
rect PortBounds = rect{v2{0, 0}, v2{6, 6}};
|
||||
|
||||
v2 LinePosition = Position;
|
||||
for (u32 i = 0; i < Spec.MemberListLength; i++)
|
||||
{
|
||||
|
@ -108,15 +194,36 @@ DrawNodePorts(node_specification Spec, b32 InputMask, v2 Position, r32 LineHeigh
|
|||
string MemberName = MakeString(Member.Name, CharArrayLength(Member.Name));
|
||||
DrawString(RenderBuffer, MemberName, Interface.Font, LinePosition + TextOffset, WhiteV4, TextAlign);
|
||||
|
||||
rect PositionedPortBounds = PortBounds;
|
||||
PositionedPortBounds.Min += LinePosition + v2{0, LineHeight / 4};
|
||||
PositionedPortBounds.Max += LinePosition + v2{0, LineHeight / 4};
|
||||
if (TextAlign == Align_Left)
|
||||
{
|
||||
PositionedPortBounds.Min -= v2{PortBounds.Max.x, 0};
|
||||
PositionedPortBounds.Max -= v2{PortBounds.Max.x, 0};
|
||||
}
|
||||
|
||||
|
||||
PushRenderQuad2D(RenderBuffer, PositionedPortBounds.Min, PositionedPortBounds.Max, WhiteV4);
|
||||
|
||||
if (MouseButtonTransitionedDown(Mouse.LeftButtonState)
|
||||
&& PointIsInRect(Mouse.DownPos, PositionedPortBounds))
|
||||
{
|
||||
PortClicked = i;
|
||||
}
|
||||
|
||||
LinePosition.y -= LineHeight;
|
||||
}
|
||||
}
|
||||
|
||||
return PortClicked;
|
||||
}
|
||||
|
||||
internal void
|
||||
DrawNode (v2 Position, node_specification NodeSpecification, r32 NodeWidth, r32 LineHeight, interface_config Interface, render_command_buffer* RenderBuffer)
|
||||
internal s32
|
||||
DrawNode (v2 Position, node_specification NodeSpecification, r32 NodeWidth, r32 LineHeight, interface_config Interface, render_command_buffer* RenderBuffer, mouse_state Mouse)
|
||||
{
|
||||
s32 PortClicked = -1;
|
||||
|
||||
u32 InputMembers = 0;
|
||||
u32 OutputMembers = 0;
|
||||
for (u32 i = 0; i < NodeSpecification.MemberListLength; i++)
|
||||
|
@ -147,44 +254,23 @@ DrawNode (v2 Position, node_specification NodeSpecification, r32 NodeWidth, r32
|
|||
LinePosition.y -= LineHeight;
|
||||
|
||||
// Draw Ports
|
||||
DrawNodePorts(NodeSpecification, IsInputMember, LinePosition, LineHeight, Align_Left, TextOffset, Interface, RenderBuffer);
|
||||
s32 InputPortClicked = DrawNodePorts(NodeSpecification, IsInputMember, LinePosition, LineHeight, Align_Left, TextOffset, Interface, RenderBuffer, Mouse);
|
||||
|
||||
v2 OutputLinePosition = v2{LinePosition.x + NodeDim.x, LinePosition.y };
|
||||
v2 OutputTextOffset = v2{-TextOffset.x, TextOffset.y};
|
||||
DrawNodePorts(NodeSpecification, IsOutputMember, OutputLinePosition, LineHeight, Align_Right, OutputTextOffset, Interface, RenderBuffer);
|
||||
}
|
||||
|
||||
struct temp_node_connection
|
||||
{
|
||||
u32 DownstreamNodeIndex;
|
||||
u32 DownstreamNodePort;
|
||||
s32 OutputPortClicked = DrawNodePorts(NodeSpecification, IsOutputMember, OutputLinePosition, LineHeight, Align_Right, OutputTextOffset, Interface, RenderBuffer, Mouse);
|
||||
|
||||
u32 UpstreamNodeIndex;
|
||||
u32 UpstreamNodePort;
|
||||
};
|
||||
|
||||
struct visual_node
|
||||
{
|
||||
node_specification Spec;
|
||||
v2 Position;
|
||||
};
|
||||
|
||||
#define TEMP_NODE_LIST_MAX 10
|
||||
global_variable u32 TEMP_NodeListUsed = 0;
|
||||
global_variable node_specification TEMP_NodeList[TEMP_NODE_LIST_MAX];
|
||||
|
||||
#define TEMP_CONNECTIONS_LIST_MAX 10
|
||||
global_variable u32 TEMP_NodeConnectionsUsed = 0;
|
||||
global_variable temp_node_connection TEMP_NodeConnections[TEMP_CONNECTIONS_LIST_MAX];
|
||||
|
||||
internal void
|
||||
PushNodeOnNodeList(node_specification Spec)
|
||||
{
|
||||
if (TEMP_NodeListUsed < TEMP_NODE_LIST_MAX)
|
||||
|
||||
if (InputPortClicked >= 0)
|
||||
{
|
||||
u32 Index = TEMP_NodeListUsed++;
|
||||
TEMP_NodeList[Index] = Spec;
|
||||
PortClicked = InputPortClicked;
|
||||
}
|
||||
else if (OutputPortClicked >= 0)
|
||||
{
|
||||
PortClicked = OutputPortClicked;
|
||||
}
|
||||
|
||||
return PortClicked;
|
||||
}
|
||||
|
||||
internal visual_node*
|
||||
|
@ -270,7 +356,11 @@ PANEL_RENDER_PROC(NodeGraph_Render)
|
|||
for (u32 i = 0; i < TEMP_NodeListUsed; i++)
|
||||
{
|
||||
visual_node VisualNode = VisualNodes[i];
|
||||
DrawNode(VisualNode.Position + GraphState->ViewOffset, VisualNode.Spec, NodeWidth, LineHeight, State->Interface, RenderBuffer);
|
||||
s32 PortClicked = DrawNode(VisualNode.Position + GraphState->ViewOffset, VisualNode.Spec, NodeWidth, LineHeight, State->Interface, RenderBuffer, Mouse);
|
||||
if (PortClicked >= 0)
|
||||
{
|
||||
BeginConnectNodesOperation(i, PortClicked, State);
|
||||
}
|
||||
}
|
||||
|
||||
// Node Selection Panel
|
||||
|
|
|
@ -138,10 +138,10 @@ PANEL_RENDER_PROC(SculptureView_Render)
|
|||
s32 MaxLEDsPerJob = 2048;
|
||||
render_quad_batch_constructor RenderLEDsBatch = PushRenderQuad3DBatch(RenderBuffer, State->TotalLEDsCount);
|
||||
|
||||
for (s32 i = 0; i < State->ActiveAssemblyIndecies.Used; i++)
|
||||
for (u32 i = 0; i < State->ActiveAssemblyIndecies.Used; i++)
|
||||
{
|
||||
array_entry_handle AssemblyHandle = *GetElementAtIndex(i, State->ActiveAssemblyIndecies);
|
||||
assembly Assembly = *GetElementWithHandle(AssemblyHandle, State->AssemblyList);
|
||||
gs_list_handle AssemblyHandle = *State->ActiveAssemblyIndecies.GetElementAtIndex(i);
|
||||
assembly Assembly = *State->AssemblyList.GetElementWithHandle(AssemblyHandle);
|
||||
s32 JobsNeeded = IntegerDivideRoundUp(Assembly.LEDCount, MaxLEDsPerJob);
|
||||
|
||||
for (s32 Job = 0; Job < JobsNeeded; Job++)
|
||||
|
|
Loading…
Reference in New Issue