Created an initial version of a standard array template and swapped it in for the assembly array structure.
This commit is contained in:
parent
da76bb46f5
commit
a77d97a31f
|
@ -0,0 +1,11 @@
|
||||||
|
struct animation_block
|
||||||
|
{
|
||||||
|
r32 StartTime;
|
||||||
|
r32 EndTime;
|
||||||
|
animation_block* Next;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct animation_layer
|
||||||
|
{
|
||||||
|
animation_block* Blocks;
|
||||||
|
};
|
|
@ -137,7 +137,6 @@ LoadAssembly (app_state* State, context Context, char* Path)
|
||||||
string FileName = Substring(PathString, IndexOfLastSlash + 1);
|
string FileName = Substring(PathString, IndexOfLastSlash + 1);
|
||||||
|
|
||||||
r32 Scale = 100;
|
r32 Scale = 100;
|
||||||
Assert(State->AssembliesCount < ASSEMBLY_LIST_LENGTH);
|
|
||||||
s32 AssemblyMemorySize = GetAssemblyMemorySizeFromDefinition(AssemblyDefinition, FileName);
|
s32 AssemblyMemorySize = GetAssemblyMemorySizeFromDefinition(AssemblyDefinition, FileName);
|
||||||
u8* AssemblyMemory = Context.PlatformAlloc(AssemblyMemorySize);
|
u8* AssemblyMemory = Context.PlatformAlloc(AssemblyMemorySize);
|
||||||
|
|
||||||
|
@ -147,7 +146,9 @@ LoadAssembly (app_state* State, context Context, char* Path)
|
||||||
Scale,
|
Scale,
|
||||||
AssemblyMemory,
|
AssemblyMemory,
|
||||||
AssemblyMemorySize);
|
AssemblyMemorySize);
|
||||||
State->AssemblyList[State->AssembliesCount++] = NewAssembly;
|
array_entry_handle NewAssemblyHandle = PushElement(NewAssembly, &State->AssemblyList);
|
||||||
|
PushElement(NewAssemblyHandle, &State->ActiveAssemblyIndecies);
|
||||||
|
|
||||||
State->TotalLEDsCount += NewAssembly.LEDCount;
|
State->TotalLEDsCount += NewAssembly.LEDCount;
|
||||||
|
|
||||||
ClearArenaToSnapshot(State->Transient, TempMemorySnapshot);
|
ClearArenaToSnapshot(State->Transient, TempMemorySnapshot);
|
||||||
|
@ -156,19 +157,20 @@ LoadAssembly (app_state* State, context Context, char* Path)
|
||||||
internal void
|
internal void
|
||||||
UnloadAssembly (s32 AssemblyIndex, app_state* State, context Context)
|
UnloadAssembly (s32 AssemblyIndex, app_state* State, context Context)
|
||||||
{
|
{
|
||||||
assembly* Assembly = State->AssemblyList + AssemblyIndex;
|
assembly* Assembly = GetElementAtIndex(AssemblyIndex, State->AssemblyList);
|
||||||
State->TotalLEDsCount -= Assembly->LEDCount;
|
State->TotalLEDsCount -= Assembly->LEDCount;
|
||||||
Context.PlatformFree(Assembly->Arena.Base, Assembly->Arena.Size);
|
Context.PlatformFree(Assembly->Arena.Base, Assembly->Arena.Size);
|
||||||
|
|
||||||
if (AssemblyIndex != (State->AssembliesCount - 1))
|
RemoveElementAtIndex(AssemblyIndex, &State->AssemblyList);
|
||||||
|
for (s32 i = 0; i < State->ActiveAssemblyIndecies.Used; i++)
|
||||||
{
|
{
|
||||||
State->AssemblyList[AssemblyIndex] = State->AssemblyList[State->AssembliesCount - 1];
|
array_entry_handle Handle = *GetElementAtIndex(i, State->ActiveAssemblyIndecies);
|
||||||
}
|
if (Handle.Index == AssemblyIndex)
|
||||||
else
|
|
||||||
{
|
{
|
||||||
*Assembly = {};
|
RemoveElementAtIndex(i, &State->ActiveAssemblyIndecies);
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
State->AssembliesCount -= 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -287,6 +289,9 @@ INITIALIZE_APPLICATION(InitializeApplication)
|
||||||
State->Camera.Position = v3{0, 0, -250};
|
State->Camera.Position = v3{0, 0, -250};
|
||||||
State->Camera.LookAt = v3{0, 0, 0};
|
State->Camera.LookAt = v3{0, 0, 0};
|
||||||
|
|
||||||
|
State->AssemblyList.BucketSize = 32;
|
||||||
|
State->AssemblyList.FreeList.Next = &State->AssemblyList.FreeList;
|
||||||
|
State->ActiveAssemblyIndecies.BucketSize = 32;
|
||||||
#if 1
|
#if 1
|
||||||
char Path[] = "radialumia.fold";
|
char Path[] = "radialumia.fold";
|
||||||
LoadAssembly(State, Context, Path);
|
LoadAssembly(State, Context, Path);
|
||||||
|
@ -409,9 +414,10 @@ UPDATE_AND_RENDER(UpdateAndRender)
|
||||||
|
|
||||||
s32 HeaderSize = State->NetworkProtocolHeaderSize;
|
s32 HeaderSize = State->NetworkProtocolHeaderSize;
|
||||||
dmx_buffer_list* DMXBuffers = 0;
|
dmx_buffer_list* DMXBuffers = 0;
|
||||||
for (s32 i = 0; i < State->AssembliesCount; i++)
|
for (s32 i = 0; i < State->ActiveAssemblyIndecies.Used; i++)
|
||||||
{
|
{
|
||||||
assembly Assembly = State->AssemblyList[i];
|
array_entry_handle AssemblyHandle = *GetElementAtIndex(i, State->ActiveAssemblyIndecies);
|
||||||
|
assembly Assembly = *GetElementWithHandle(AssemblyHandle, State->AssemblyList);
|
||||||
dmx_buffer_list* NewDMXBuffers = CreateDMXBuffers(Assembly, HeaderSize, State->Transient);
|
dmx_buffer_list* NewDMXBuffers = CreateDMXBuffers(Assembly, HeaderSize, State->Transient);
|
||||||
DMXBuffers = DMXBufferListAppend(DMXBuffers, NewDMXBuffers);
|
DMXBuffers = DMXBufferListAppend(DMXBuffers, NewDMXBuffers);
|
||||||
}
|
}
|
||||||
|
@ -475,9 +481,10 @@ UPDATE_AND_RENDER(UpdateAndRender)
|
||||||
s32 MaxLEDsPerJob = 2048;
|
s32 MaxLEDsPerJob = 2048;
|
||||||
render_quad_batch_constructor RenderLEDsBatch = PushRenderQuad3DBatch(RenderBuffer, State->TotalLEDsCount);
|
render_quad_batch_constructor RenderLEDsBatch = PushRenderQuad3DBatch(RenderBuffer, State->TotalLEDsCount);
|
||||||
|
|
||||||
for (s32 AssemblyIdx = 0; AssemblyIdx < State->AssembliesCount; AssemblyIdx++)
|
for (s32 i = 0; i < State->ActiveAssemblyIndecies.Used; i++)
|
||||||
{
|
{
|
||||||
assembly Assembly = State->AssemblyList[AssemblyIdx];
|
array_entry_handle AssemblyHandle = *GetElementAtIndex(i, State->ActiveAssemblyIndecies);
|
||||||
|
assembly Assembly = *GetElementWithHandle(AssemblyHandle, State->AssemblyList);
|
||||||
s32 JobsNeeded = IntegerDivideRoundUp(Assembly.LEDCount, MaxLEDsPerJob);
|
s32 JobsNeeded = IntegerDivideRoundUp(Assembly.LEDCount, MaxLEDsPerJob);
|
||||||
|
|
||||||
for (s32 Job = 0; Job < JobsNeeded; Job++)
|
for (s32 Job = 0; Job < JobsNeeded; Job++)
|
||||||
|
@ -529,9 +536,11 @@ UPDATE_AND_RENDER(UpdateAndRender)
|
||||||
State->Interface, Mouse);
|
State->Interface, Mouse);
|
||||||
|
|
||||||
string InterfaceString = MakeString(PushArray(State->Transient, char, 256), 256);
|
string InterfaceString = MakeString(PushArray(State->Transient, char, 256), 256);
|
||||||
for (int i = 0; i < State->AssembliesCount; i++)
|
for (s32 i = 0; i < State->ActiveAssemblyIndecies.Used; i++)
|
||||||
{
|
{
|
||||||
PrintF(&InterfaceString, "Unload %.*s", State->AssemblyList[i].Name.Length, State->AssemblyList[i].Name.Memory);
|
array_entry_handle AssemblyHandle = *GetElementAtIndex(i, State->ActiveAssemblyIndecies);
|
||||||
|
assembly Assembly = *GetElementWithHandle(AssemblyHandle, State->AssemblyList);
|
||||||
|
PrintF(&InterfaceString, "Unload %.*s", Assembly.Name.Length, Assembly.Name.Memory);
|
||||||
|
|
||||||
ButtonPos.x += ButtonDim.x + 10;
|
ButtonPos.x += ButtonDim.x + 10;
|
||||||
button_result UnloadAssemblyBtn = EvaluateButton(RenderBuffer, ButtonPos, ButtonPos + ButtonDim,
|
button_result UnloadAssemblyBtn = EvaluateButton(RenderBuffer, ButtonPos, ButtonPos + ButtonDim,
|
||||||
|
|
|
@ -46,12 +46,8 @@ struct app_state
|
||||||
|
|
||||||
s32 TotalLEDsCount;
|
s32 TotalLEDsCount;
|
||||||
|
|
||||||
// TODO(Peter): Make this dynamic. We want them contiguous in memory since we'll be accessing them
|
assembly_array AssemblyList;
|
||||||
// mostly by looping through them. On the other hand, I don't expect there to ever be more than 100
|
array_entry_handle_contiguous_array ActiveAssemblyIndecies;
|
||||||
// of them at once.
|
|
||||||
#define ASSEMBLY_LIST_LENGTH 32
|
|
||||||
assembly AssemblyList[ASSEMBLY_LIST_LENGTH];
|
|
||||||
s32 AssembliesCount;
|
|
||||||
|
|
||||||
camera Camera;
|
camera Camera;
|
||||||
r32 PixelsToWorldScale;
|
r32 PixelsToWorldScale;
|
||||||
|
|
|
@ -36,3 +36,5 @@ struct assembly
|
||||||
s32 LEDUniverseMapCount;
|
s32 LEDUniverseMapCount;
|
||||||
leds_in_universe_range* LEDUniverseMap;
|
leds_in_universe_range* LEDUniverseMap;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
TYPEDEF_ARRAY(assembly);
|
||||||
|
|
|
@ -211,7 +211,7 @@ DrawDebugInterface (render_command_buffer* RenderBuffer, r32 StartX, interface_c
|
||||||
|
|
||||||
r32 FramesPerSecond = 1.0f / DeltaTime;
|
r32 FramesPerSecond = 1.0f / DeltaTime;
|
||||||
|
|
||||||
PrintF(&DebugString, "Framerate: %.*f s %d fps | Modes: %d Memory Used: %d / %d | Commands: %d",
|
PrintF(&DebugString, "Framerate: %.*f s %d fps | Modes: %d Memory Used: %d / %d | Commands: %d | HI SAM!!!! ",
|
||||||
5, DeltaTime,
|
5, DeltaTime,
|
||||||
(u32)FramesPerSecond,
|
(u32)FramesPerSecond,
|
||||||
State->Modes.ActiveModesCount,
|
State->Modes.ActiveModesCount,
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
#include "gs_language.h"
|
#include "gs_language.h"
|
||||||
#include "gs_platform.h"
|
#include "gs_platform.h"
|
||||||
|
#include "gs_array.h"
|
||||||
|
|
||||||
#include "foldhaus_memory.h"
|
#include "foldhaus_memory.h"
|
||||||
#include "gs_string.h"
|
#include "gs_string.h"
|
||||||
|
|
|
@ -0,0 +1,226 @@
|
||||||
|
struct free_list
|
||||||
|
{
|
||||||
|
free_list* Next;
|
||||||
|
s32 Index;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct bucket_index
|
||||||
|
{
|
||||||
|
s32 Bucket;
|
||||||
|
s32 IndexInBucket;
|
||||||
|
};
|
||||||
|
|
||||||
|
inline bucket_index
|
||||||
|
GetBucketIndexForIndex (s32 Index, s32 BucketSize)
|
||||||
|
{
|
||||||
|
bucket_index Result = {};
|
||||||
|
Result.Bucket = Index / BucketSize;
|
||||||
|
Result.IndexInBucket = Index % BucketSize;
|
||||||
|
return Result;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct array_entry_handle
|
||||||
|
{
|
||||||
|
s32 Generation;
|
||||||
|
s32 Index;
|
||||||
|
};
|
||||||
|
|
||||||
|
// NOTE(Peter): This is a total bastardization of the preprocessor but it works and is
|
||||||
|
// easier than writing a metaprogramming system at the moment.
|
||||||
|
// TODO(Peter): Write a metaprogramming version of this that is actually easy to debug
|
||||||
|
|
||||||
|
#define TYPEDEF_ARRAY(element_type) \
|
||||||
|
struct element_type##_array_entry { \
|
||||||
|
s32 Generation; \
|
||||||
|
union \
|
||||||
|
{ \
|
||||||
|
element_type Entry; \
|
||||||
|
free_list Free; \
|
||||||
|
}; \
|
||||||
|
}; \
|
||||||
|
\
|
||||||
|
struct element_type##_array \
|
||||||
|
{ \
|
||||||
|
element_type##_array_entry** Buckets; \
|
||||||
|
s32 BucketSize; \
|
||||||
|
s32 BucketCount; \
|
||||||
|
s32 Used; \
|
||||||
|
free_list FreeList; \
|
||||||
|
}; \
|
||||||
|
\
|
||||||
|
internal void \
|
||||||
|
GrowBuffer(element_type##_array* Buffer) \
|
||||||
|
{ \
|
||||||
|
s32 NewBucketSize = sizeof(element_type##_array_entry) * Buffer->BucketSize; \
|
||||||
|
element_type##_array_entry* NewBucket = (element_type##_array_entry*)malloc(NewBucketSize); \
|
||||||
|
GSZeroMemory((u8*)NewBucket, NewBucketSize); \
|
||||||
|
\
|
||||||
|
s32 NewBucketIndex = Buffer->BucketCount++; \
|
||||||
|
if (!Buffer->Buckets) \
|
||||||
|
{ \
|
||||||
|
Buffer->Buckets = (element_type##_array_entry**)malloc(sizeof(element_type##_array_entry*)); \
|
||||||
|
} \
|
||||||
|
else \
|
||||||
|
{ \
|
||||||
|
Buffer->Buckets = (element_type##_array_entry**)realloc(Buffer->Buckets, sizeof(element_type##_array_entry*) * Buffer->BucketCount); \
|
||||||
|
} \
|
||||||
|
Buffer->Buckets[NewBucketIndex] = NewBucket; \
|
||||||
|
} \
|
||||||
|
\
|
||||||
|
internal element_type##_array_entry* \
|
||||||
|
GetEntryAtIndex (s32 Index, element_type##_array Buffer) \
|
||||||
|
{ \
|
||||||
|
bucket_index BucketIndex = GetBucketIndexForIndex(Index, Buffer.BucketSize); \
|
||||||
|
element_type##_array_entry* Entry = Buffer.Buckets[BucketIndex.Bucket] + BucketIndex.IndexInBucket; \
|
||||||
|
return Entry; \
|
||||||
|
} \
|
||||||
|
\
|
||||||
|
internal array_entry_handle \
|
||||||
|
PushElement (element_type Data, element_type##_array* Buffer) \
|
||||||
|
{ \
|
||||||
|
array_entry_handle Result = {}; \
|
||||||
|
\
|
||||||
|
if (Buffer->FreeList.Next != &Buffer->FreeList) \
|
||||||
|
{ \
|
||||||
|
free_list* FreeList = Buffer->FreeList.Next; \
|
||||||
|
element_type##_array_entry* Entry = GetEntryAtIndex(FreeList->Index, *Buffer); \
|
||||||
|
Buffer->FreeList.Next = Entry->Free.Next; \
|
||||||
|
\
|
||||||
|
Result.Index = Entry->Free.Index; \
|
||||||
|
Result.Generation = Entry->Generation; \
|
||||||
|
Entry->Entry = Data; \
|
||||||
|
\
|
||||||
|
++Buffer->Used; \
|
||||||
|
} \
|
||||||
|
else \
|
||||||
|
{ \
|
||||||
|
if (Buffer->Used >= Buffer->BucketSize * Buffer->BucketCount) \
|
||||||
|
{ \
|
||||||
|
GrowBuffer(Buffer); \
|
||||||
|
} \
|
||||||
|
\
|
||||||
|
s32 Index = Buffer->Used++; \
|
||||||
|
s32 BucketIndex = Index / Buffer->BucketSize; \
|
||||||
|
s32 IndexInBucket = Index % Buffer->BucketSize; \
|
||||||
|
\
|
||||||
|
Buffer->Buckets[BucketIndex][IndexInBucket].Entry = Data; \
|
||||||
|
Result.Index = Index; \
|
||||||
|
Result.Generation = Buffer->Buckets[BucketIndex][IndexInBucket].Generation; \
|
||||||
|
} \
|
||||||
|
\
|
||||||
|
return Result; \
|
||||||
|
} \
|
||||||
|
\
|
||||||
|
internal element_type* \
|
||||||
|
GetElementAtIndex (s32 Index, element_type##_array Buffer) \
|
||||||
|
{ \
|
||||||
|
Assert(Index < Buffer.Used); \
|
||||||
|
element_type##_array_entry* Entry = GetEntryAtIndex(Index, Buffer); \
|
||||||
|
element_type* Result = &Entry->Entry; \
|
||||||
|
return Result; \
|
||||||
|
} \
|
||||||
|
\
|
||||||
|
internal element_type* \
|
||||||
|
GetElementWithHandle (array_entry_handle Handle, element_type##_array Buffer) \
|
||||||
|
{ \
|
||||||
|
element_type* Result = 0; \
|
||||||
|
\
|
||||||
|
element_type##_array_entry* Entry = GetEntryAtIndex(Handle.Index, Buffer); \
|
||||||
|
\
|
||||||
|
if (Entry->Generation == Handle.Generation) \
|
||||||
|
{ \
|
||||||
|
Result = &Entry->Entry; \
|
||||||
|
} \
|
||||||
|
\
|
||||||
|
return Result; \
|
||||||
|
} \
|
||||||
|
\
|
||||||
|
internal void \
|
||||||
|
RemoveElementAtIndex (s32 Index, element_type##_array* Buffer) \
|
||||||
|
{ \
|
||||||
|
Assert(Index < Buffer->Used); \
|
||||||
|
\
|
||||||
|
element_type##_array_entry* Entry = GetEntryAtIndex(Index, *Buffer); \
|
||||||
|
++Entry->Generation; \
|
||||||
|
Entry->Free.Index = Index; \
|
||||||
|
\
|
||||||
|
Entry->Free.Next = Buffer->FreeList.Next; \
|
||||||
|
Buffer->FreeList.Next = &Entry->Free; \
|
||||||
|
\
|
||||||
|
--Buffer->Used; \
|
||||||
|
} \
|
||||||
|
|
||||||
|
// END OF CRAZY MACRO
|
||||||
|
|
||||||
|
|
||||||
|
#define TYPEDEF_CONTIGUOUS_ARRAY(element_type) \
|
||||||
|
struct element_type##_contiguous_array \
|
||||||
|
{ \
|
||||||
|
element_type** Buckets; \
|
||||||
|
s32 BucketSize; \
|
||||||
|
s32 BucketCount; \
|
||||||
|
s32 Used; \
|
||||||
|
}; \
|
||||||
|
\
|
||||||
|
internal void \
|
||||||
|
GrowBuffer(element_type##_contiguous_array* Buffer) \
|
||||||
|
{ \
|
||||||
|
s32 NewBucketSize = sizeof(element_type) * Buffer->BucketSize; \
|
||||||
|
element_type* NewBucket = (element_type*)malloc(NewBucketSize); \
|
||||||
|
GSZeroMemory((u8*)NewBucket, NewBucketSize); \
|
||||||
|
\
|
||||||
|
s32 NewBucketIndex = Buffer->BucketCount++; \
|
||||||
|
if (!Buffer->Buckets) \
|
||||||
|
{ \
|
||||||
|
Buffer->Buckets = (element_type**)malloc(sizeof(element_type*)); \
|
||||||
|
} \
|
||||||
|
else \
|
||||||
|
{ \
|
||||||
|
Buffer->Buckets = (element_type**)realloc(Buffer->Buckets, sizeof(element_type*) * Buffer->BucketCount); \
|
||||||
|
} \
|
||||||
|
Buffer->Buckets[NewBucketIndex] = NewBucket; \
|
||||||
|
} \
|
||||||
|
\
|
||||||
|
internal element_type* \
|
||||||
|
GetElementAtIndex (s32 Index, element_type##_contiguous_array Buffer) \
|
||||||
|
{ \
|
||||||
|
bucket_index BucketIndex = GetBucketIndexForIndex(Index, Buffer.BucketSize); \
|
||||||
|
element_type* Entry = Buffer.Buckets[BucketIndex.Bucket] + BucketIndex.IndexInBucket; \
|
||||||
|
return Entry; \
|
||||||
|
} \
|
||||||
|
\
|
||||||
|
internal s32 \
|
||||||
|
PushElement (element_type Data, element_type##_contiguous_array* Buffer) \
|
||||||
|
{ \
|
||||||
|
s32 Result = -1; \
|
||||||
|
\
|
||||||
|
if (Buffer->Used >= Buffer->BucketSize * Buffer->BucketCount) \
|
||||||
|
{ \
|
||||||
|
GrowBuffer(Buffer); \
|
||||||
|
} \
|
||||||
|
\
|
||||||
|
s32 Index = Buffer->Used++; \
|
||||||
|
s32 BucketIndex = Index / Buffer->BucketSize; \
|
||||||
|
s32 IndexInBucket = Index % Buffer->BucketSize; \
|
||||||
|
\
|
||||||
|
Buffer->Buckets[BucketIndex][IndexInBucket] = Data; \
|
||||||
|
Result = Index; \
|
||||||
|
return Result; \
|
||||||
|
} \
|
||||||
|
\
|
||||||
|
internal void \
|
||||||
|
RemoveElementAtIndex (s32 Index, element_type##_contiguous_array* Buffer) \
|
||||||
|
{ \
|
||||||
|
Assert(Index < Buffer->Used); \
|
||||||
|
\
|
||||||
|
bucket_index IndexToRemove = GetBucketIndexForIndex(Index, Buffer->BucketSize); \
|
||||||
|
bucket_index LastIndex = GetBucketIndexForIndex(Buffer->Used - 1, Buffer->BucketSize); \
|
||||||
|
element_type ValueAtLastIndex = Buffer->Buckets[LastIndex.Bucket][LastIndex.IndexInBucket]; \
|
||||||
|
Buffer->Buckets[IndexToRemove.Bucket][IndexToRemove.IndexInBucket] = ValueAtLastIndex; \
|
||||||
|
--Buffer->Used; \
|
||||||
|
} \
|
||||||
|
|
||||||
|
// END OF CRAZY MACRO
|
||||||
|
|
||||||
|
TYPEDEF_ARRAY(array_entry_handle);
|
||||||
|
TYPEDEF_CONTIGUOUS_ARRAY(array_entry_handle);
|
Loading…
Reference in New Issue