4coder/non-source/test_data/lots_of_files/handmade_debug_interface.h

341 lines
9.6 KiB
C

#if !defined(HANDMADE_DEBUG_INTERFACE_H)
/* ========================================================================
$File: $
$Date: $
$Revision: $
$Creator: Casey Muratori $
$Notice: (C) Copyright 2015 by Molly Rocket, Inc. All Rights Reserved. $
======================================================================== */
struct debug_table;
#define DEBUG_GAME_FRAME_END(name) debug_table *name(game_memory *Memory, game_input *Input, game_offscreen_buffer *Buffer)
typedef DEBUG_GAME_FRAME_END(debug_game_frame_end);
struct debug_id
{
void *Value[2];
};
#if HANDMADE_INTERNAL
enum debug_type
{
DebugType_Unknown,
DebugType_FrameMarker,
DebugType_BeginBlock,
DebugType_EndBlock,
DebugType_OpenDataBlock,
DebugType_CloseDataBlock,
DebugType_MarkDebugValue,
DebugType_b32,
DebugType_r32,
DebugType_u32,
DebugType_s32,
DebugType_v2,
DebugType_v3,
DebugType_v4,
DebugType_rectangle2,
DebugType_rectangle3,
DebugType_bitmap_id,
DebugType_sound_id,
DebugType_font_id,
DebugType_CounterThreadList,
// DebugVariableType_CounterFunctionList,
};
struct debug_event
{
u64 Clock;
// TODO(casey): To save space, we could put these two strings back-to-back with a null terminator in the middle
char *FileName;
char *BlockName;
u32 LineNumber;
u16 ThreadID;
u16 CoreIndex;
u8 Type;
union
{
debug_id DebugID;
debug_event *Value_debug_event;
b32 Value_b32;
s32 Value_s32;
u32 Value_u32;
r32 Value_r32;
v2 Value_v2;
v3 Value_v3;
v4 Value_v4;
rectangle2 Value_rectangle2;
rectangle3 Value_rectangle3;
bitmap_id Value_bitmap_id;
sound_id Value_sound_id;
font_id Value_font_id;
};
};
struct debug_table
{
// TODO(casey): No attempt is currently made to ensure that the final
// debug records being written to the event array actually complete
// their output prior to the swap of the event array index.
u32 CurrentEventArrayIndex;
// TODO(casey): This could actually be a u32 atomic now, since we
// only need 1 bit to store which array we're using...
u64 volatile EventArrayIndex_EventIndex;
debug_event Events[2][16*65536];
};
extern debug_table *GlobalDebugTable;
#define RecordDebugEvent(EventType, Block) \
u64 ArrayIndex_EventIndex = AtomicAddU64(&GlobalDebugTable->EventArrayIndex_EventIndex, 1); \
u32 EventIndex = ArrayIndex_EventIndex & 0xFFFFFFFF; \
Assert(EventIndex < ArrayCount(GlobalDebugTable->Events[0])); \
debug_event *Event = GlobalDebugTable->Events[ArrayIndex_EventIndex >> 32] + EventIndex; \
Event->Clock = __rdtsc(); \
Event->Type = (u8)EventType; \
Event->CoreIndex = 0; \
Event->ThreadID = (u16)GetThreadID(); \
Event->FileName = __FILE__; \
Event->LineNumber = __LINE__; \
Event->BlockName = Block; \
#define FRAME_MARKER(SecondsElapsedInit) \
{ \
int Counter = __COUNTER__; \
RecordDebugEvent(DebugType_FrameMarker, "Frame Marker"); \
Event->Value_r32 = SecondsElapsedInit; \
}
#define TIMED_BLOCK__(BlockName, Number, ...) timed_block TimedBlock_##Number(__COUNTER__, __FILE__, __LINE__, BlockName, ## __VA_ARGS__)
#define TIMED_BLOCK_(BlockName, Number, ...) TIMED_BLOCK__(BlockName, Number, ## __VA_ARGS__)
#define TIMED_BLOCK(BlockName, ...) TIMED_BLOCK_(#BlockName, __LINE__, ## __VA_ARGS__)
#define TIMED_FUNCTION(...) TIMED_BLOCK_((char *)__FUNCTION__, __LINE__, ## __VA_ARGS__)
#define BEGIN_BLOCK_(Counter, FileNameInit, LineNumberInit, BlockNameInit) \
{RecordDebugEvent(DebugType_BeginBlock, BlockNameInit);}
#define END_BLOCK_(Counter) \
{ \
RecordDebugEvent(DebugType_EndBlock, "End Block"); \
}
#define BEGIN_BLOCK(Name) \
int Counter_##Name = __COUNTER__; \
BEGIN_BLOCK_(Counter_##Name, __FILE__, __LINE__, #Name);
#define END_BLOCK(Name) \
END_BLOCK_(Counter_##Name);
struct timed_block
{
int Counter;
timed_block(int CounterInit, char *FileName, int LineNumber, char *BlockName, u32 HitCountInit = 1)
{
// TODO(casey): Record the hit count value here?
Counter = CounterInit;
BEGIN_BLOCK_(Counter, FileName, LineNumber, BlockName);
}
~timed_block()
{
END_BLOCK_(Counter);
}
};
#else
#define TIMED_BLOCK(...)
#define TIMED_FUNCTION(...)
#define BEGIN_BLOCK(...)
#define END_BLOCK(...)
#define FRAME_MARKER(...)
#endif
//
// NOTE(casey): Shared utils
//
inline u32
StringLength(char *String)
{
u32 Count = 0;
while(*String++)
{
++Count;
}
return(Count);
}
#ifdef __cplusplus
}
#endif
#if defined(__cplusplus) && HANDMADE_INTERNAL
inline void
DEBUGValueSetEventData(debug_event *Event, r32 Value)
{
Event->Type = DebugType_r32;
Event->Value_r32 = Value;
}
inline void
DEBUGValueSetEventData(debug_event *Event, u32 Value)
{
Event->Type = DebugType_u32;
Event->Value_u32 = Value;
}
inline void
DEBUGValueSetEventData(debug_event *Event, s32 Value)
{
Event->Type = DebugType_s32;
Event->Value_s32 = Value;
}
inline void
DEBUGValueSetEventData(debug_event *Event, v2 Value)
{
Event->Type = DebugType_v2;
Event->Value_v2 = Value;
}
inline void
DEBUGValueSetEventData(debug_event *Event, v3 Value)
{
Event->Type = DebugType_v3;
Event->Value_v3 = Value;
}
inline void
DEBUGValueSetEventData(debug_event *Event, v4 Value)
{
Event->Type = DebugType_v4;
Event->Value_v4 = Value;
}
inline void
DEBUGValueSetEventData(debug_event *Event, rectangle2 Value)
{
Event->Type = DebugType_rectangle2;
Event->Value_rectangle2 = Value;
}
inline void
DEBUGValueSetEventData(debug_event *Event, rectangle3 Value)
{
Event->Type = DebugType_rectangle3;
Event->Value_rectangle3 = Value;
}
inline void
DEBUGValueSetEventData(debug_event *Event, bitmap_id Value)
{
Event->Type = DebugType_bitmap_id;
Event->Value_bitmap_id = Value;
}
inline void
DEBUGValueSetEventData(debug_event *Event, sound_id Value)
{
Event->Type = DebugType_sound_id;
Event->Value_sound_id = Value;
}
inline void
DEBUGValueSetEventData(debug_event *Event, font_id Value)
{
Event->Type = DebugType_font_id;
Event->Value_font_id = Value;
}
#define DEBUG_BEGIN_DATA_BLOCK(Name, ID) \
{ \
RecordDebugEvent(DebugType_OpenDataBlock, #Name); \
Event->DebugID = ID; \
}
#define DEBUG_END_DATA_BLOCK() \
{ \
RecordDebugEvent(DebugType_CloseDataBlock, "End Data Block"); \
}
#define DEBUG_VALUE(Value) \
{ \
RecordDebugEvent(DebugType_Unknown, #Value); \
DEBUGValueSetEventData(Event, Value); \
}
#define DEBUG_BEGIN_ARRAY(...)
#define DEBUG_END_ARRAY(...)
inline debug_id DEBUG_POINTER_ID(void *Pointer)
{
debug_id ID = {Pointer};
return(ID);
}
#define DEBUG_UI_ENABLED 1
internal void DEBUG_HIT(debug_id ID, r32 ZValue);
internal b32 DEBUG_HIGHLIGHTED(debug_id ID, v4 *Color);
internal b32 DEBUG_REQUESTED(debug_id ID);
inline debug_event DEBUGInitializeValue(debug_type Type, debug_event *SubEvent, char *Name, char *FileName, u32 LineNumber)
{
RecordDebugEvent(DebugType_MarkDebugValue, "");
Event->Value_debug_event = SubEvent;
SubEvent->Clock = 0;
SubEvent->FileName = FileName;
SubEvent->BlockName = Name;
SubEvent->LineNumber = LineNumber;
SubEvent->ThreadID = 0;
SubEvent->CoreIndex = 0;
SubEvent->Type = (u8)Type;
return(*SubEvent);
}
#define DEBUG_IF__(Path) \
local_persist debug_event DebugValue##Path = DEBUGInitializeValue((DebugValue##Path.Value_b32 = GlobalConstants_##Path, DebugType_b32), &DebugValue##Path, #Path, __FILE__, __LINE__); \
if(DebugValue##Path.Value_b32)
#define DEBUG_VARIABLE__(type, Path, Variable) \
local_persist debug_event DebugValue##Variable = DEBUGInitializeValue((DebugValue##Variable.Value_##type = GlobalConstants_##Path##_##Variable, DebugType_##type), &DebugValue##Variable, #Path "_" #Variable, __FILE__, __LINE__); \
type Variable = DebugValue##Variable.Value_##type;
#else
inline debug_id DEBUG_POINTER_ID(void *Pointer) {debug_id NullID = {}; return(NullID);}
#define DEBUG_BEGIN_DATA_BLOCK(...)
#define DEBUG_END_DATA_BLOCK(...)
#define DEBUG_VALUE(...)
#define DEBUG_BEGIN_ARRAY(...)
#define DEBUG_END_ARRAY(...)
#define DEBUG_UI_ENABLED 0
#define DEBUG_HIT(...)
#define DEBUG_HIGHLIGHTED(...) 0
#define DEBUG_REQUESTED(...) 0
#define DEBUG_IF__(Path) if(GlobalConstants_##Path)
#define DEBUG_VARIABLE__(type, Path, Variable) type Variable = GlobalConstants_##Path##_##Variable;
#endif
#define DEBUG_IF_(Path) DEBUG_IF__(Path)
#define DEBUG_IF(Path) DEBUG_IF_(Path)
#define DEBUG_VARIABLE_(type, Path, Variable) DEBUG_VARIABLE__(type, Path, Variable)
#define DEBUG_VARIABLE(type, Path, Variable) DEBUG_VARIABLE_(type, Path, Variable)
#define HANDMADE_DEBUG_INTERFACE_H
#endif