[video output=day177 member=cmuratori stream_platform=twitch stream_username=handmade_hero project=code title="Automatic Performance Counters" vod_platform=youtube id=uHSLHvWFkto annotator=Miblo annotator=debiatan]
[00:11][Plan for today]
[01:40][Recap of work done in the previous episode]
[03:41][TIMED_BLOCK should be easier to use]
[05:09][Timing a block should be an inexpensive operation]
[07:03][Don't be afraid of major changes]
[07:47][Getting rid of the debug counter IDs]
[08:25][Preprocessor directives]
[11:07][The __COUNTER__ preprocessor directive]
[11:47][Consider MSVC's gender][quote 204]
[12:48][Preprocessor directives are frequently used in debug code]
[13:22][Getting rid of the argument to TIMED_BLOCK]
[14:36][Avoiding predefined values while still describing the location of the TIMED_BLOCK call]
[16:49][Mapping filenames and line numbers to IDs]
[17:24][We could use some sort of mapping strategy, but that's too complex for a debug log system]
[19:14][An alternative method: Avoid looking for filenames and line numbers until we need to print them]
[20:47][Depending on the amount of information we log, this method could tax our write bandwidth]
[23:46][We'll try first the alternative method]
[24:48][Have a thought][quote 205]
[24:51][We could resort to __COUNTER__ because of our single compilation unit build!]
[25:47]["Are you thinking what I'm thinking?"][quote 206]
[26:30][Quick test of the __COUNTER__ approach]
[29:25][__COUNTER__ passes the test!]
[29:56][Dealing with two translation units. We will keep one array of debug records for each of them]
[31:44][We could define the DEBUG_PREFIX preprocessor symbol to access the proper array]
[33:22][Forward-declaring the debug record arrays]
[34:56][Accessing debug records]
[36:06][Using the DebugRecordArray preprocessor symbol instead of DEBUG_PREFIX]
[38:00][Defining the fields of the debug record array]
[38:33][Implementing the timed_block constructor and destructor]
[40:32][Using the new TIMED_BLOCK syntax]
[42:48][Adding HitCount as an extra parameter to TIMED_BLOCK]
[44:56][handmade_debug.h: Fuss with the vagaries of C++ preprocessor nonsense][quote 207]
[45:00][Expanding __LINE__ in the presence of the paste operator]
[48:28][Modifying OverlayCycleCounters to work with the debug record arrays]
[50:41][Testing today's changes]
[51:00][Identifying our debug counters using the file names stored in the debug arrays]
[51:40][It works!]
[52:09][What we have accomplished today]
[53:08][Q&A][:speech]
[54:16][@elxenoaizd][There's an alternative way to start / end the counter instead of using constructor / destructor pair, and you don't have to store the data in the struct. Maybe not as convenient but it's worth mentioning. I use it quite often when I have to 'begin X' -- write code -- 'end X'. It's basically a hacked / tweaked version of C#'s 'using' statement. I think you'll find it interesting]
[55:13][Write out elxenoaizd's suggestion]
[56:33][@JamesWidman][I feel like I missed something: why does the array name need to be different between builds?]
[57:20][@twitch_makes_me_itch][How do you move your typing cursor around so fast? Is that an IDE-specific macro?]
[58:07][@graeme7][Could you expand on how you would have done the char *Filename / *FunctionName with uints instead?][quote 208]
[59:14][@andsz_][This is awesome. You have a few minutes left: could you output the results or show them in the debugger?]
[59:34][handmade.cpp: Print out the debug cycle counts]
[1:04:34][@nico3695][Do you recommend taking game-programming as a major or programming in general?]
[1:04:48][@elxenoaizd][What other useful preproc values could we use other than __FILE__, __FUNCTION__ and __LINE__?]
[1:05:47][@elxenoaizd][I'm not sure I fully understand Unity builds. So Unity build is when we compile everything to a single file? I don't think that's the case because we do have multiple source files in HMH...]
[1:07:16][@plain_flavored][Where did the whole weird IInterface CClass style of programming I see everywhere come from?]
[1:07:43][@elxenoaizd][Why do you have both u32 and uint32 typedefs? What's the difference?]
[1:08:18][@elxenoaizd][If exceptions are bad, then what is a good way to handle errors? Just return error codes? A global error value like in errno or GetLastError()? What do you think of the idea of having a central error handling function that we call and pass it the error id and it acts accordingly (switch statement maybe)?][quote 209]
[1:10:39][@nexus_80][Why use Record->FileName instead of Record->FunctionName?]
[1:10:47][@superdude4242564][I am kind of new to the stream. Is there a reason you hate C++ so much?]
[1:12:14][@Eipon][Will this game compile with gcc or only with the Visual Studio compiler?]
[1:13:04][@twitch_makes_me_itch][General Programming Question: Do you see the use of public variables being accessed outside the class bad practice, versus using a "getter / accessor" function?]
[1:14:03][handmade.cpp: Demo bad programming practice]
[1:16:32][@insofaras][How would you handle parsing errors / exceptions in a recursive decent parser?]
[1:16:48][@waterlimon][Internet says __COUNTER__ started on VC++]
[1:17:53][Spin it down][:speech]
[/video]
