Cleaning up todos, documentation, blumen lumen status, etc.

This commit is contained in:
PS 2021-03-31 02:00:25 -07:00
parent 18bef60ba1
commit bafbcd966a
28 changed files with 294 additions and 207 deletions

View File

@ -7,10 +7,14 @@ Building Lumenarium requires having MSVC installed (sorry, Windows only for now!
2. Run the appropriate build batch file
- for Windows: use `build\build_app_msvc_win32_debug.bat`
- other platforms coming soon
3. Build scripts will output executables into the app_run_tree directory, by platform
## Run Lumenarium
Windows - Debug
1. Just run `win32_msvc\debug\win32_foldhaus.exe`
1. Run `app_run_tree\win32_msvc\debug\win32_foldhaus.exe`
If you want to run in headless mode:
1. Run `app_run_tree\win32_msvc\debug\win32_foldhaus.exe -headless`
## Debug Lumenarium
### Windows

View File

@ -6,7 +6,7 @@ SET MyPath=%MyPath:~0,-1%
call %MyPath%\_prebuild_win32.bat app debug msvc
call %MyPath%\setup_cl.bat
SET CommonCompilerFlags=-nologo -DDEBUG=1 -DPLATFORM_WINDOWS -FC -WX -W4 -Z7 -Oi -GR- -EHsc -EHa- -MTd -fp:fast -fp:except- -IC:\programs-dev\gs_libs\src
SET CommonCompilerFlags=-nologo -DDEBUG=0 -DPLATFORM_WINDOWS -FC -WX -W4 -Z7 -Oi -GR- -EHsc -EHa- -MTd -fp:fast -fp:except- -IC:\programs-dev\gs_libs\src
SET CommonCompilerFlags=-wd4127 -wd4702 -wd4101 -wd4505 -wd4100 -wd4189 -wd4244 -wd4201 -wd4996 -I%CommonLibs% -O2 %CommonCompilerFlags%

View File

@ -128,7 +128,6 @@ Editor_DrawWidget(app_state* State, context* Context, render_command_buffer* Ren
if (ui_WidgetIsFlagSet(Widget, UIWidgetFlag_DrawString) && Widget.String.Length > 0)
{
// TODO(pjs): add this color to the style
v4 TextColor = BlackV4;
Editor_DrawWidgetString(State, Context, RenderBuffer, Widget, ClippedFillBounds, TextColor, -1);
}

View File

@ -40,11 +40,10 @@ OperationModeSystemInit(gs_memory_arena* Storage, gs_thread_context ThreadContex
// TODO(Peter): Do we really need an arena? Can this just operate in constant memory footprint?
Result.Arena.Allocator = ThreadContext.Allocator;
Result.ModeMemoryPagesFreeList.CountMax = 32; // TODO(Peter): Static number of modes that can be active simultaneously
Result.ModeMemoryPagesFreeList.CountMax = 8;
Result.ModeMemoryPagesFreeList.Data = PushArray(Storage, gs_data, Result.ModeMemoryPagesFreeList.CountMax);
for (u32 Page = 0; Page < Result.ModeMemoryPagesFreeList.CountMax; Page++)
{
// TODO(Peter): 4k pages = page size on windows
Result.ModeMemoryPagesFreeList.Data[Page] = PushSizeToData(Storage, KB(4));
}
Result.ModeMemoryPagesFreeList.Count = Result.ModeMemoryPagesFreeList.CountMax;

View File

@ -163,15 +163,42 @@ RenderProfiler_ListVisualization(ui_interface* Interface, ui_widget* Layout, deb
ui_EndList(Interface);
}
struct mem_amt
{
u64 OrigSize;
r64 Size;
char* Units;
};
internal mem_amt
GetMemAmt (u64 BytesCount)
{
mem_amt Result = {};
Result.OrigSize = BytesCount;
Result.Size = (r64)BytesCount;
Result.Units = "bytes";
u32 i = 0;
char* UnitList[] = { "kb", "mb", "gb", "tb" };
while (Result.Size > 1024) {
Result.Size /= 1024.0;
Result.Units = UnitList[i++];
}
return Result;
}
internal void
RenderProfiler_MemoryView(ui_interface* Interface, ui_widget* Layout, app_state* State, context Context, gs_memory_arena* Memory)
{
gs_allocator_debug Debug = *Context.ThreadContext.Allocator.Debug;
gs_string TempString = PushString(State->Transient, 256);
u64 MemFootprint = Debug.TotalAllocSize;
mem_amt MemFootprint = GetMemAmt(Debug.TotalAllocSize);
u64 AllocCount = Debug.AllocationsCount;
PrintF(&TempString, "Total Memory Size: %lld | Allocations: %lld", MemFootprint, AllocCount);
PrintF(&TempString, "Total Memory Size: %.2f %s | Allocations: %lld", MemFootprint.Size, MemFootprint.Units, AllocCount);
ui_Label(Interface, TempString);
ui_column_spec ColumnWidths[] = {
@ -194,7 +221,9 @@ RenderProfiler_MemoryView(ui_interface* Interface, ui_widget* Layout, app_state*
PrintF(&TempString, "%S", A.Location);
ui_Label(Interface, TempString);
PrintF(&TempString, "%lld bytes", A.Size);
mem_amt Amt = GetMemAmt(A.Size);
PrintF(&TempString, "%.2f %s", Amt.Size, Amt.Units);
ui_Label(Interface, TempString);
}
ui_EndRow(Interface);
@ -216,7 +245,10 @@ ProfilerView_Render(panel* Panel, rect2 PanelBounds, render_command_buffer* Rend
RectHSplitAtDistanceFromTop(PanelBounds, FrameListHeight, &FrameListBounds, &ProcListBounds);
rect2 FrameListInner = RectInset(FrameListBounds, 4);
r32 SingleFrameStep = Rect2Width(FrameListInner) / DEBUG_FRAME_COUNT;
s32 FramesToDisplay = DEBUG_FRAME_COUNT;
if (FramesToDisplay != 0)
{
r32 SingleFrameStep = Rect2Width(FrameListInner) / FramesToDisplay;
r32 SingleFrameWidth = (r32)((s32)SingleFrameStep - 2);
ui_OutlineRect(&State->Interface, FrameListBounds, 2, WhiteV4);
@ -226,7 +258,7 @@ ProfilerView_Render(panel* Panel, rect2 PanelBounds, render_command_buffer* Rend
{
v2 LocalMouse = Rect2GetRectLocalPoint(FrameListBounds, Context.Mouse.Pos);
s32 ClosestFrameIndex = (LocalMouse.x / SingleFrameStep);
if (ClosestFrameIndex >= 0 && ClosestFrameIndex < DEBUG_FRAME_COUNT)
if (ClosestFrameIndex >= 0 && ClosestFrameIndex < FramesToDisplay)
{
GlobalDebugServices->RecordFrames = false;
GlobalDebugServices->CurrentDebugFrame = ClosestFrameIndex;
@ -243,11 +275,13 @@ ProfilerView_Render(panel* Panel, rect2 PanelBounds, render_command_buffer* Rend
v4 Color = FrameColors[Clamp(0, FramesAgo, 3)];
ui_FillRect(&State->Interface, PositionedFrameBounds, Color);
}
debug_frame* VisibleFrame = GetLastDebugFrame(GlobalDebugServices);
}
ui_widget* Layout = ui_PushLayout(&State->Interface, ProcListBounds, LayoutDirection_TopDown, MakeString("Profiler Layout"));
debug_frame* VisibleFrame = GetLastDebugFrame(GlobalDebugServices);
if (VisibleFrame)
{
ui_BeginRow(&State->Interface, 4);
{
s64 FrameStartCycles = VisibleFrame->FrameStartCycles;
@ -269,6 +303,7 @@ ProfilerView_Render(panel* Panel, rect2 PanelBounds, render_command_buffer* Rend
}
}
ui_EndRow(&State->Interface);
}
ui_BeginRow(&State->Interface, 8);
{
@ -290,13 +325,19 @@ ProfilerView_Render(panel* Panel, rect2 PanelBounds, render_command_buffer* Rend
switch (GlobalDebugServices->Interface.FrameView)
{
case DebugUI_Profiler:
{
if (VisibleFrame)
{
RenderProfiler_ScopeVisualization(&State->Interface, Layout, VisibleFrame, Memory);
}
}break;
case DebugUI_ScopeList:
{
if (VisibleFrame)
{
RenderProfiler_ListVisualization(&State->Interface, Layout, VisibleFrame, Memory);
}
}break;
case DebugUI_MemoryView:

View File

@ -74,8 +74,6 @@ struct animation
gs_string Name;
anim_layer_array Layers;
// TODO(pjs): Pretty sure Blocks_ should be obsolete and
// Layers should contain their own blocks
animation_block_array Blocks_;
frame_range PlayableRange;
@ -169,6 +167,7 @@ struct animation_system
// panel
animation_fade_group ActiveFadeGroup;
r32 SecondsOnCurrentFrame;
s32 CurrentFrame;
s32 LastUpdatedFrame;
r32 SecondsPerFrame;
@ -762,13 +761,28 @@ AnimationSystem_Update(animation_system* System, r32 DeltaTime)
animation* ActiveAnim = AnimationSystem_GetActiveAnimation(System);
if (ActiveAnim)
{
// TODO(Peter): Revisit this. This implies that the framerate of the animation system
// is tied to the framerate of the simulation. That seems correct to me, but I'm not sure
System->SecondsOnCurrentFrame += DeltaTime;
while (System->SecondsOnCurrentFrame > System->SecondsPerFrame)
{
System->CurrentFrame += 1;
System->SecondsOnCurrentFrame -= System->SecondsPerFrame;
}
// Loop back to the beginning
if (System->CurrentFrame > ActiveAnim->PlayableRange.Max)
{
// NOTE(PS): There's no long term reason why this needs to be true
// but I don't want to implement dealing with PlayableRanges that
// don't start at zero right now becuse there's literally no reason
// I can think of where that's useful.
Assert(ActiveAnim->PlayableRange.Min == 0);
s32 FramesPastEnd = System->CurrentFrame;
while (FramesPastEnd > ActiveAnim->PlayableRange.Max)
{
FramesPastEnd -= ActiveAnim->PlayableRange.Max;
}
switch (System->RepeatMode)
{
case AnimationRepeat_Single:

View File

@ -81,8 +81,6 @@ INITIALIZE_APPLICATION(InitializeApplication)
ReloadStaticData(*Context, GlobalDebugServices, true);
US_CustomInit(&State->UserSpaceDesc, State, *Context);
GlobalDebugServices->Interface.RenderSculpture = true;
if (!Context->Headless)
{
// NOTE(pjs): This just sets up the default panel layout

View File

@ -75,11 +75,6 @@ enum debug_ui_view
struct debug_interface
{
b32 ShowCameraMouse;
b32 ShowTrackedScopes;
b32 RenderSculpture;
b32 SendSACNData;
s32 FrameView;
};
@ -105,34 +100,39 @@ struct debug_histogram_entry
u32 Total_CallCount;
};
#define DEBUG_FRAME_COUNT 128
#if DEBUG
# define DEBUG_FRAME_COUNT 128
#else
# define DEBUG_FRAME_COUNT 0
#endif
struct debug_services
{
s64 PerformanceCountFrequency;
b32 RecordFrames;
s32 CurrentDebugFrame;
debug_frame Frames[DEBUG_FRAME_COUNT];
debug_frame* Frames;
debug_interface Interface;
gs_thread_context Ctx;
debug_get_thread_id* GetThreadId;
debug_timing_proc* GetWallClock;
debug_alloc* Alloc;
debug_realloc* Realloc;
};
internal void
InitializeDebugFrame (debug_frame* Frame, s32 NameHashMax, s32 ThreadCount, s32 ScopeCallsMax, debug_services* Services)
{
Frame->ScopeNamesMax = NameHashMax;
Frame->ScopeNamesHash = (scope_name*)Services->Alloc(sizeof(scope_name), NameHashMax);
Frame->ScopeNamesHash = AllocatorAllocArray(Services->Ctx.Allocator, scope_name, NameHashMax);
// NOTE(Peter): We use the same size as scope names because we're only storing a single instance
// per scope. If ScopeNamesMax can't hold all the scopes, this will never get filled and
// we should assert and recompile with a resized NameHashMax
Frame->CollatedScopesMax = NameHashMax;
Frame->CollatedScopes = (collated_scope_record*)Services->Alloc(sizeof(collated_scope_record), NameHashMax);
Frame->CollatedScopes = AllocatorAllocArray(Services->Ctx.Allocator, collated_scope_record, NameHashMax);
for (s32 i = 0; i < Frame->ScopeNamesMax; i++)
{
@ -141,14 +141,13 @@ InitializeDebugFrame (debug_frame* Frame, s32 NameHashMax, s32 ThreadCount, s32
}
Frame->ThreadCount = ThreadCount;
Frame->ThreadCalls = (debug_scope_record_list*)Services->Alloc(sizeof(debug_scope_record_list),
ThreadCount);
Frame->ThreadCalls = AllocatorAllocArray(Services->Ctx.Allocator, debug_scope_record_list, ThreadCount);
for (s32 i = 0; i < ThreadCount; i++)
{
Frame->ThreadCalls[i].Max = ScopeCallsMax;
Frame->ThreadCalls[i].Count = 0;
Frame->ThreadCalls[i].Calls = (scope_record*)Services->Alloc(sizeof(scope_record), ScopeCallsMax);
Frame->ThreadCalls[i].Calls = AllocatorAllocArray(Services->Ctx.Allocator, scope_record, ScopeCallsMax);
Frame->ThreadCalls[i].CurrentScopeCallDepth = 0;
Frame->ThreadCalls[i].ThreadId = 0;
}
@ -178,16 +177,34 @@ StartDebugFrame(debug_frame* Frame, debug_services* Services)
}
internal void
InitDebugServices (debug_services* Services,
InitDebugServices_OffMode (debug_services* Services,
s64 PerformanceCountFrequency,
debug_alloc* Alloc,
debug_realloc* Realloc,
debug_timing_proc* GetWallClock,
debug_get_thread_id* GetThreadId,
gs_thread_context Ctx,
s32 ThreadCount)
{
Services->Alloc = Alloc;
Services->Realloc = Realloc;
Services->Ctx = Ctx;
Services->GetWallClock = GetWallClock;
Services->GetThreadId = GetThreadId;
Services->RecordFrames = false;
Services->Frames = 0;
Services->CurrentDebugFrame = 0;
Services->PerformanceCountFrequency = PerformanceCountFrequency;
}
internal void
InitDebugServices_DebugMode (debug_services* Services,
s64 PerformanceCountFrequency,
debug_timing_proc* GetWallClock,
debug_get_thread_id* GetThreadId,
gs_thread_context Ctx,
s32 ThreadCount)
{
Services->Ctx = Ctx;
Services->GetWallClock = GetWallClock;
Services->GetThreadId = GetThreadId;
@ -196,19 +213,13 @@ InitDebugServices (debug_services* Services,
Services->CurrentDebugFrame = 0;
s32 NameHashMax = 4096;
s32 ScopeCallsMax = 4096;
Services->Frames = AllocatorAllocArray(Ctx.Allocator, debug_frame, DEBUG_FRAME_COUNT);
for (s32 i = 0; i < DEBUG_FRAME_COUNT; i++)
{
InitializeDebugFrame(&Services->Frames[i], NameHashMax, ThreadCount, ScopeCallsMax, Services);
}
Services->Interface.RenderSculpture = true;
Services->PerformanceCountFrequency = PerformanceCountFrequency;
Services->Interface.ShowCameraMouse = false;
Services->Interface.ShowTrackedScopes = false;
Services->Interface.RenderSculpture = true;
Services->Interface.SendSACNData = false;
}
internal debug_frame*
@ -221,6 +232,8 @@ GetCurrentDebugFrame (debug_services* Services)
internal debug_frame*
GetLastDebugFrame(debug_services* Services)
{
if (!Services->Frames) return 0;
s32 Index = (Services->CurrentDebugFrame - 1);
if (Index < 0) { Index += DEBUG_FRAME_COUNT; }
debug_frame* Result = Services->Frames + Index;
@ -323,7 +336,11 @@ EndDebugFrame (debug_services* Services)
}
ClosingFrame->ScopeNamesCount = ScopeNamesCount;
Services->CurrentDebugFrame = (Services->CurrentDebugFrame + 1) % DEBUG_FRAME_COUNT;
s32 FramesCount = DEBUG_FRAME_COUNT;
if (FramesCount > 0)
{
Services->CurrentDebugFrame = (Services->CurrentDebugFrame + 1) % FramesCount;
}
StartDebugFrame(&Services->Frames[Services->CurrentDebugFrame], Services);
}
@ -388,10 +405,9 @@ PushScopeTimeOnFrame (debug_services* Services, s32 NameHash, u64 StartCycles, u
if (ThreadList->Count >= ThreadList->Max)
{
s32 CurrentSize = ThreadList->Max * sizeof(scope_record);
s32 NewMax = (ThreadList->Max + DEBUG_FRAME_GROW_SIZE);
s32 NewSize = NewMax * sizeof(scope_record);
ThreadList->Calls = (scope_record*)Services->Realloc((u8*)ThreadList->Calls, CurrentSize, NewSize);
AllocatorFreeArray(Services->Ctx.Allocator, ThreadList->Calls, scope_record, ThreadList->Max);
ThreadList->Calls = AllocatorAllocArray(Services->Ctx.Allocator, scope_record, NewMax);
ThreadList->Max = NewMax;
}
@ -411,7 +427,7 @@ internal r32 DEBUGGetSecondsElapsed (s64 Start, s64 End, r32 PerformanceCountFre
return Result;
}
#ifdef DEBUG
#if DEBUG
#define DEBUG_TRACK_FUNCTION scope_tracker ScopeTracker ((char*)__func__, GlobalDebugServices)
#define DEBUG_TRACK_SCOPE(name) scope_tracker ScopeTracker_##name (#name, GlobalDebugServices)
#else

View File

@ -202,8 +202,6 @@ typedef struct system_time
s32 Second;
} system_time;
#define STATUS_PACKET_FREQ_SECONDS 2
struct context
{
gs_thread_context ThreadContext;

View File

@ -6,22 +6,22 @@
#ifndef FOLDHAUS_RENDERER_CPP
internal render_command_buffer
AllocateRenderCommandBuffer (u8* Memory, s32 Size, renderer_realloc* Realloc)
AllocateRenderCommandBuffer (u8* Memory, s32 Size, gs_thread_context Ctx)
{
render_command_buffer Result = {};
Result.CommandMemory = Memory;
Result.CommandMemorySize = Size;
Result.CommandMemoryUsed = 0;
Result.Realloc = Realloc;
Result.Ctx = Ctx;
return Result;
}
internal render_command_buffer
AllocateRenderCommandBuffer(u32 MemorySize,
gs_memory_arena* Arena,
renderer_realloc* Realloc)
gs_thread_context Ctx)
{
u8* Memory = PushSize(Arena, MemorySize);
return AllocateRenderCommandBuffer(Memory, MemorySize, Realloc);
return AllocateRenderCommandBuffer(Memory, MemorySize, Ctx);
}
internal void

View File

@ -124,7 +124,6 @@ struct render_quad_3d
struct render_texture
{
// TODO(Peter): Is all this necessary?
u8* Memory;
s32 Handle;
s32 Width;
@ -214,7 +213,7 @@ struct render_command_buffer
s32 CommandMemoryUsed;
s32 CommandMemorySize;
renderer_realloc* Realloc;
gs_thread_context Ctx;
s32 ViewWidth;
s32 ViewHeight;
@ -265,9 +264,9 @@ ResizeBufferIfNecessary(render_command_buffer* Buffer, s32 DataSize)
s32 SpaceNeeded = DataSize - SpaceAvailable; // This is known to be positive at this point
s32 AdditionSize = Max(SpaceNeeded, COMMAND_BUFFER_MIN_GROW_SIZE);
s32 NewSize = Buffer->CommandMemorySize + AdditionSize;
Buffer->CommandMemory = Buffer->Realloc(Buffer->CommandMemory,
Buffer->CommandMemorySize,
NewSize);
AllocatorFree(Buffer->Ctx.Allocator, Buffer->CommandMemory, Buffer->CommandMemorySize);
Buffer->CommandMemory = AllocatorAlloc(Buffer->Ctx.Allocator, NewSize).Memory;
Buffer->CommandMemorySize = NewSize;
}
}

View File

@ -356,22 +356,6 @@ SetApplicationLinks (context* Context, win32_dll_refresh DLL, gs_work_queue* Wor
}
}
// TODO(Peter): :Redundant remove
internal u8*
DEBUGAlloc(s32 ElementSize, s32 ElementCount)
{
return (u8*)Win32Alloc(ElementSize * ElementCount, 0);
}
// TODO(Peter): :Redundant remove
internal u8*
Win32Realloc(u8* Buf, s32 OldSize, s32 NewSize)
{
u8* NewMemory = (u8*)Win32Alloc(NewSize, 0);
CopyMemoryTo(Buf, NewMemory, OldSize);
return NewMemory;
}
internal void
Win32_SendAddressedDataBuffer(gs_thread_context Context, addressed_data_buffer* BufferAt)
{
@ -604,7 +588,7 @@ WinMain (
gs_allocator_debug AllocDebug = {};
AllocDebug.AllocationsCountMax = 4096;
AllocDebug.Allocations = (gs_debug_allocation*)Win32Alloc(sizeof(gs_debug_allocation) * AllocDebug.AllocationsCountMax, 0);
AllocDebug.Allocations = AllocatorAllocArray(ThreadContext.Allocator, gs_debug_allocation, AllocDebug.AllocationsCountMax);
ThreadContext.Allocator.Debug = &AllocDebug;
@ -636,17 +620,25 @@ WinMain (
s64 PerformanceCountFrequency = GetPerformanceFrequency();
s64 LastFrameEnd = GetWallClock();
r32 TargetSecondsPerFrame = 1 / 60.0f;
r32 TargetSecondsPerFrame = 1 / 30.0f;
r32 LastFrameSecondsElapsed = 0.0f;
GlobalDebugServices = PushStruct(&PlatformPermanent, debug_services);
InitDebugServices(GlobalDebugServices,
#if DEBUG
InitDebugServices_DebugMode(GlobalDebugServices,
PerformanceCountFrequency,
DEBUGAlloc,
Win32Realloc,
GetWallClock,
Win32GetThreadId,
Context.ThreadContext,
PLATFORM_THREAD_COUNT + 1);
#else
InitDebugServices_OffMode(GlobalDebugServices,
PerformanceCountFrequency,
GetWallClock,
Win32GetThreadId,
Context.ThreadContext,
PLATFORM_THREAD_COUNT + 1);
#endif
input_queue InputQueue = InputQueue_Create(&PlatformPermanent, 32);
@ -674,7 +666,11 @@ WinMain (
Win32SerialArray_Create(ThreadContext);
render_command_buffer RenderBuffer = AllocateRenderCommandBuffer(MB(12), &PlatformPermanent, Win32Realloc);
render_command_buffer RenderBuffer = {};
if (!Context.Headless)
{
RenderBuffer = AllocateRenderCommandBuffer(MB(12), &PlatformPermanent, ThreadContext);
}
addressed_data_buffer_list OutputData = AddressedDataBufferList_Create(ThreadContext);
@ -690,6 +686,7 @@ WinMain (
{
EndDebugFrame(GlobalDebugServices);
}
DEBUG_TRACK_SCOPE(MainLoop);
{

View File

@ -251,7 +251,6 @@ Win32SocketPeek(platform_socket_manager* Manager, platform_socket* Socket)
}
else
{
// TODO(pjs): Error handling
s32 Error = WSAGetLastError();
switch (Error)
{

View File

@ -63,7 +63,7 @@ Win32CreateThreadContext(gs_memory_arena* Transient = 0)
PUSH_WORK_ON_QUEUE(Win32PushWorkOnQueue)
{
#ifdef DEBUG
#if DEBUG
// NOTE(Peter): Just prints out the names of all the pending jobs if we end up
// overflowing the buffer
if (Queue->JobsCount >= Queue->JobsMax)
@ -82,7 +82,7 @@ PUSH_WORK_ON_QUEUE(Win32PushWorkOnQueue)
gs_threaded_job* Job = Queue->Jobs + Queue->JobsCount;
Job->WorkProc = WorkProc;
Job->Data = Data;
#ifdef DEBUG
#if DEBUG
Job->JobName = JobName;
#endif
@ -184,7 +184,7 @@ CREATE_THREAD(Win32CreateThread)
Thread->UserData = UserData;
// TODO(pjs): ugh, allocation out in the middle of nowhere
HANDLE* ThreadHandle = (HANDLE*)Win32Alloc(sizeof(HANDLE), 0);
HANDLE* ThreadHandle = AllocatorAllocStruct(Ctx.Allocator, HANDLE);
*ThreadHandle = CreateThread(0, 0, Win32ThreadProcWrapper, (void*)Thread, 0, 0);
// TODO(pjs): Error checking on the created thread

View File

@ -149,7 +149,6 @@ BlumenLumen_MicListenJob(gs_thread_context* Ctx, u8* UserData)
{
if (SocketPeek(Data->SocketManager, ListenSocket))
{
// TODO(pjs): Make this a peek operation
Msg = SocketRecieve(Data->SocketManager, ListenSocket, Ctx->Transient);
if (Msg.Size > 0)
{
@ -233,7 +232,7 @@ BlumenLumen_CustomInit(app_state* State, context Context)
BLState->PatternSpeed = GlobalAnimSpeed;
#if 1
BLState->MicListenThread = CreateThread(Context.ThreadManager, BlumenLumen_MicListenJob, (u8*)&BLState->MicListenJobData);
BLState->MicListenThread = CreateThread(Context.ThreadManager, BlumenLumen_MicListenJob, (u8*)&BLState->MicListenJobData, Context.ThreadContext);
#endif
assembly* Flower0 = LoadAssembly(Flower0AssemblyPath, State, Context);
@ -276,10 +275,54 @@ BlumenLumen_CustomInit(app_state* State, context Context)
return Result;
}
internal void
BlumenLumen_UpdateLog(app_state* State, blumen_lumen_state* BLState, context Context)
{
if (!BLState->ShouldUpdateLog) return;
gs_string FileStr = PushString(State->Transient, 1024);
AppendPrintF(&FileStr, "Lumenarium Status\n\n");
animation* CurrAnim = AnimationSystem_GetActiveAnimation(&State->AnimationSystem);
AppendPrintF(&FileStr, "Curr Animation: %S\n", CurrAnim->Name);
char* Connected = BLState->MicListenJobData.IsConnected ? "Connected" : "Disconnected";
AppendPrintF(&FileStr, "Connected to Python: %s\n", Connected);
u8 MP0 = BLState->LastKnownMotorState.FlowerPositions[0];
u8 MP1 = BLState->LastKnownMotorState.FlowerPositions[1];
u8 MP2 = BLState->LastKnownMotorState.FlowerPositions[2];
AppendPrintF(&FileStr, "Last Known Motor State: %d %d %d\n", MP0, MP1, MP2);
char* PatternMode = 0;
switch (BLState->PatternMode)
{
case BlumenPattern_Standard: { PatternMode = "Standard"; } break;
case BlumenPattern_VoiceCommand: { PatternMode = "Voice Command"; } break;
}
AppendPrintF(&FileStr, "Pattern Mode: %s\n", PatternMode);
phrase_hue LastHuePhrase = BLState->LastHuePhrase;
AppendPrintF(&FileStr, "Last Mic Phrase: %S\n", LastHuePhrase.Phrase);
AppendPrintF(&FileStr, "Pattern Speed: %f\n", BLState->PatternSpeed);
AppendPrintF(&FileStr, "Pattern Brightness: %f\n", BLState->BrightnessPercent);
AppendPrintF(&FileStr, "Last Temp Received: %d\n", BLState->LastTemperatureReceived);
gs_data LogMem = StringToData(FileStr);
if (!WriteEntireFile(Context.ThreadContext.FileHandler, ConstString("lumenarium_status.log"), LogMem))
{
InvalidCodePath;
}
}
internal void
BlumenLumen_CustomUpdate(gs_data UserData, app_state* State, context* Context)
{
blumen_lumen_state* BLState = (blumen_lumen_state*)UserData.Memory;
BLState->ShouldUpdateLog = false;
bool SendMotorCommand = false;
blumen_packet MotorCommand = {};
@ -314,7 +357,9 @@ BlumenLumen_CustomUpdate(gs_data UserData, app_state* State, context* Context)
BlumenLumen_SetPatternMode(BlumenPattern_VoiceCommand, 5, &State->AnimationSystem, BLState);
BLState->TimeLastSetToVoiceMode = Context->SystemTime_Current;
BLState->LastHuePhrase = NewHue;
}
BLState->ShouldUpdateLog = true;
}break;
case PacketType_MotorState:
@ -340,14 +385,14 @@ BlumenLumen_CustomUpdate(gs_data UserData, app_state* State, context* Context)
}
BLState->LastKnownMotorState = Motor.Pos;
BLState->ShouldUpdateLog = true;
}break;
case PacketType_Temperature:
{
temp_packet Temp = Packet.TempPacket;
if (Temp.Temperature > 0)
if (Temp.Temperature > MinHighTemperature)
{
BLState->BrightnessPercent = HighTemperatureBrightnessPercent;
}
@ -355,8 +400,10 @@ BlumenLumen_CustomUpdate(gs_data UserData, app_state* State, context* Context)
{
BLState->BrightnessPercent = FullBrightnessPercent;
}
BLState->LastTemperatureReceived = Temp.Temperature;
DEBUG_ReceivedTemperature(Temp, Context->ThreadContext);
BLState->ShouldUpdateLog = true;
}break;
InvalidDefaultCase;
@ -392,6 +439,7 @@ BlumenLumen_CustomUpdate(gs_data UserData, app_state* State, context* Context)
AnimationFadeGroup_FadeTo(&State->AnimationSystem.ActiveFadeGroup,
NewAnim,
VoiceCommandFadeDuration);
BLState->ShouldUpdateLog = true;
}
}
@ -517,7 +565,7 @@ BlumenLumen_CustomUpdate(gs_data UserData, app_state* State, context* Context)
{
system_time LastSendTime = BLState->LastStatusUpdateTime;
r64 NanosSinceLastSend = ((r64)Context->SystemTime_Current.NanosSinceEpoch - (r64)LastSendTime.NanosSinceEpoch);
r64 SecondsSinceLastSend = NanosSinceLastSend / PowR32(10, 8);
r64 SecondsSinceLastSend = NanosSinceLastSend * NanosToSeconds;
if (SecondsSinceLastSend >= STATUS_PACKET_FREQ_SECONDS)
{
BLState->LastStatusUpdateTime = Context->SystemTime_Current;
@ -538,8 +586,15 @@ BlumenLumen_CustomUpdate(gs_data UserData, app_state* State, context* Context)
gs_data Msg = StructToData(&Packet, blumen_packet);
MessageQueue_Write(&BLState->OutgoingMsgQueue, Msg);
// there's no new information here, but by updating the log here,
// we're updating it at some infrequent but regular period that isnt
// every single frame
BLState->ShouldUpdateLog = true;
}
}
BlumenLumen_UpdateLog(State, BLState, *Context);
}
US_CUSTOM_DEBUG_UI(BlumenLumen_DebugUI)

View File

@ -109,6 +109,9 @@ struct mic_listen_job_data
blumen_network_msg_queue* IncomingMsgQueue;
blumen_network_msg_queue* OutgoingMsgQueue;
// Status
bool IsConnected;
};
typedef struct time_range
@ -151,6 +154,7 @@ struct blumen_lumen_state
// NOTE(pjs): Based on temperature data from weatherman
// dim the leds.
r32 BrightnessPercent;
s8 LastTemperatureReceived;
system_time LastStatusUpdateTime;
system_time LastSendTime;
@ -172,11 +176,15 @@ struct blumen_lumen_state
phrase_hue_map PhraseHueMap;
system_time TimeLastSetToVoiceMode;
phrase_hue LastHuePhrase;
r32 PatternSpeed;
// Debug
motor_packet DEBUG_PendingMotorPacket;
bool DEBUG_IgnoreWeatherDimmingLeds;
bool ShouldUpdateLog;
};
#include "message_queue.cpp"

View File

@ -111,8 +111,17 @@ r64 VoiceCommandSustainDuration = 30.0; // in seconds
// to have been on the whole time.
r64 TurnUpperLedsOffAfterMotorCloseCommandDelay = 5.0; // in seconds
// NOTE: Temperature & Time of Day Based Led Brightness Settings
// The temperature above which we dim the leds to
// HighTemperatureBrightnessPercent (below)
//
// NOTE: this is an 8bit signed integer so its range is
// -128 to 127, not that we should need either of those extremes for
// this, but just a note that you can't just put anything in here.
s8 MinHighTemperature = 0;
// The percent brightness we set leds to during high temperatures.
// A value in the range 0:1 inclusive
// This is multiplied by each pixels R, G, & B channels before being
@ -128,6 +137,12 @@ r32 FullBrightnessPercent = 1.0f;
// A global modifier so Joerg can just slow all the patterns right down
// XD
// This is a percent - so 1 is full speed, 0.1f is 1/10 full speed and
// 2 is 2x as fast.
r32 GlobalAnimSpeed = 1.0f;
// How often should Lumenarium send its status to the python server?
//
#define STATUS_PACKET_FREQ_SECONDS 2 // in seconds
#endif //BLUMEN_LUMEN_SETTINGS_H

View File

@ -85,7 +85,7 @@ typedef double r64;
#endif
#ifdef DEBUG
#if DEBUG
static void DebugPrint(char* Format, ...);
@ -95,8 +95,8 @@ static void DebugPrint(char* Format, ...);
if((expression)) \
{ \
}else{ \
volatile int* p = 0; \
*p = 5; \
volatile int* p = 0; \
*p = 5; \
}
#endif
@ -319,9 +319,9 @@ GSIntDivideRoundUpDef(s64);
#define GSRemapDef(type) \
static type GSRemap(type Value, type OldMin, type OldMax, type NewMin, type NewMax) { \
type Result = (Value - OldMin) / (OldMax - OldMin); \
Result = (Result * (NewMax - NewMin)) + NewMin; \
return Result; \
type Result = (Value - OldMin) / (OldMax - OldMin); \
Result = (Result * (NewMax - NewMin)) + NewMin; \
return Result; \
}
GSRemapDef(u8);
GSRemapDef(u16);

View File

@ -153,13 +153,13 @@ typedef unsigned int gs_mem_u32;
typedef unsigned long long int gs_mem_u64;
#ifdef DEBUG
#if DEBUG
#if !defined(GSMem_Assert)
#define GSMem_Assert(expression) \
if((expression)) { \
}else{ \
volatile int* p = 0; \
*p = 5; \
volatile int* p = 0; \
*p = 5; \
}
#endif

View File

@ -1,12 +1,11 @@
/*
gs_radix_sort.h - An implementation of radix sort for fixed size unsigned 32bit integer buffers
TODO
*/
#ifndef GS_RADIX_SORT_H
#ifdef DEBUG
#if DEBUG
#if !defined(GSRad_Assert)
#define GSRad_Assert(expression) \
if(!(expression)) { \

View File

@ -2474,7 +2474,6 @@ AllocatorDebug_PushAlloc(gs_allocator_debug* Debug, u64 Size, char* Location)
internal gs_data
AllocatorAlloc_(gs_allocator Allocator, u64 Size, char* Location)
{
// TODO(Peter): Memory Profiling with Location
u64 SizeResult = 0;
void* Memory = Allocator.Alloc(Size, &SizeResult);
if (Allocator.Debug)
@ -2486,7 +2485,6 @@ AllocatorAlloc_(gs_allocator Allocator, u64 Size, char* Location)
internal void
AllocatorFree_(gs_allocator Allocator, void* Base, u64 Size, char* Location)
{
// TODO(Peter): Memory Profiling with Location
if (Base != 0 && Size != 0)
{
Allocator.Free(Base, Size);
@ -3498,7 +3496,7 @@ CreatePlatformThreadManager(platform_create_thread* CreateThreadProc,
}
internal platform_thread_handle
CreateThread(platform_thread_manager* Manager, thread_proc_* Proc, u8* Arg)
CreateThread(platform_thread_manager* Manager, thread_proc_* Proc, u8* Arg, gs_thread_context Ctx)
{
platform_thread_handle Result = {};
@ -3513,7 +3511,7 @@ CreateThread(platform_thread_manager* Manager, thread_proc_* Proc, u8* Arg)
Assert(Result.Index != 0);
Manager->ThreadsUsed[Result.Index] = true;
Manager->CreateThreadProc(&Manager->Threads[Result.Index], Proc, Arg);
Manager->CreateThreadProc(&Manager->Threads[Result.Index], Proc, Arg, Ctx);
return Result;
}
@ -3719,7 +3717,6 @@ CloseSocket(platform_socket_manager* Manager, platform_socket_handle_ Handle)
}
// NOTE(pjs): returns true if the socket is connected
// TODO(pjs): make this more descriptive?
internal bool
SocketQueryStatus(platform_socket_manager* Manager, platform_socket_handle_ SocketHandle)
{

View File

@ -140,8 +140,6 @@ global_const r64 EpsilonR64 = 1.11022302462515650e-16;
global_const r64 NanosToSeconds = 1 / 10000000.0;
global_const r64 SecondsToNanos = 10000000.0;
// TODO: va_start and va_arg replacements
internal r32
DegToRadR32(r32 Degrees)
{
@ -1090,10 +1088,9 @@ typedef struct platform_thread
u8* PlatformHandle;
thread_proc_* Proc;
u8* UserData;
// TODO(pjs): Some kind of platform thread handle
} platform_thread;
#define CREATE_THREAD(name) bool name(platform_thread* Thread, thread_proc_* Proc, u8* UserData)
#define CREATE_THREAD(name) bool name(platform_thread* Thread, thread_proc_* Proc, u8* UserData, gs_thread_context Ctx)
typedef CREATE_THREAD(platform_create_thread);
#define KILL_THREAD(name) bool name(platform_thread* Thread)

View File

@ -40,7 +40,7 @@ struct window
struct handle_window_msg_result
{
b32 NeedsUpdate;
#ifdef DEBUG
#if DEBUG
char MessageType[128];
#endif
};

View File

@ -1,19 +0,0 @@
//
// File: test_motor_header.h
// Author: Peter Slattery
// Creation Date: 2021-01-14
//
#ifndef TEST_MOTOR_HEADER_H
struct
{
u8 MotorOnePos;
u8 MotorTwoPos;
u8 MotorThreePos;
} typedef packet;
static packet
UnpackPacket
#define TEST_MOTOR_HEADER_H
#endif // TEST_MOTOR_HEADER_H

View File

@ -1,29 +0,0 @@
//
// File: test_sound_interface_packet.h
// Author: Peter Slattery
// Creation Date: 2021-01-14
//
#ifndef TEST_SOUND_INTERFACE_PACKET_H
enum selectable_patterns
{
};
typedef struct
{
u8 PrimaryColor[3];
u8 SecondaryColor[3];
u32 PatternIndex; // Set via selectable_patterns
u8 Speed; //
} sound_interface_packet;
// expects V to be in the range -1:1
u8 FloatToSpeed (float V)
{
u8 Result = (u8)(((V + 1) / 2) * 255);
return Result;
}
#define TEST_SOUND_INTERFACE_PACKET_H
#endif // TEST_SOUND_INTERFACE_PACKET_H