I'm a bit surprised this thing can be done like in handmade_debug_interface.h, I've never seen this before !! (ominous nerd laughter)
#define RecordDebugEvent(EventType, GUIDInit, NameInit) \ u64 ArrayIndex_EventIndex = AtomicAddU64(&GlobalDebugTable->EventArrayIndex_EventIndex, GlobalDebugTable->RecordIncrement); \ 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->GUID = GUIDInit; \ Event->Name = NameInit //// #define TIMED_BLOCK__(GUID, Name) timed_block TimedBlock_##Number(GUID, Name) /// #define BEGIN_BLOCK_(GUID, Name) {RecordDebugEvent(DebugType_BeginBlock, GUID, Name);} #define END_BLOCK_(GUID, Name) {RecordDebugEvent(DebugType_EndBlock, GUID, Name);} #define BEGIN_BLOCK(Name) BEGIN_BLOCK_(DEBUG_NAME(Name), Name) #define END_BLOCK() END_BLOCK_(DEBUG_NAME("END_BLOCK_"), "END_BLOCK_") struct timed_block { timed_block(char *GUID, char *Name) { BEGIN_BLOCK_(GUID, Name); } ~timed_block() { END_BLOCK(); } };
This is literally sorcery to me. How exactly TimedBlock_##Number(GUID, Name)
becomes instantiated? I understand that is a trick to create an actual sort of dynamic variable naming on compile time, but how's that thing spitting back the name AND constructing the struct if you are not passing the parameters? Is there any definition of Number(GUID, Name)
elsewhere that does that?
And why putting this as a struct? Won't you need to destruct the object upon exiting the block anyways? Why not just calling END_BLOCK()
?
Ha, I'm asking too many questions in forums recently, sry about that!! 😁