[video 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]