Skip to content

Coding Conventions

Lawrence Love edited this page Jan 12, 2015 · 39 revisions
  • We've not been following any hard rules, but we've evolved some good patterns and heuristics over time. Ultimately, the code either works, is debuggable, readable, and maintainable -- or it's not. After working, code debuggability and readability are probably the most important properties because that's what we wind up spending most of our time doing overall. Also, when in doubt, correctness is the priority, not performance, especially this early in development.

  • We don't ultimately care what the source mechanically looks like because we use ClangFormat to mass-reformat all source code, using this config file. All source has been passed through this tool. So feel free to reformat the code to suit your tastes, just be sure to reformat it back to our config before pushing. Tabs=4 spaces.
    [Note: "ColumnLimit" exception: "ColumnLimit" is currently set to '0' in the vogl clang-format config file and means no limit in column size (e.g., lines of code with 200 characters, 500 characters, etc.); if the column size setting is lowered (say to a preference of, e.g., "80" or "132") and then changed back to vogl's unlimited '0' format (before being pushed), the code is not reset to the lines' original column widths but remains at the last column width setting. I.e. seems you can scale down but not back up]
    [Note2: For vim users accustomed to 80/132 column width, a function key can be set to toggle no-wrap with horizontal scrollbar enabled: nnoremap <silent><expr> <F3> ':set wrap! go'.'-+'[&wrap]."=b\r"] which keeps the code from wrapping at the window width and gives a scrollbar to view extended lines.

  • We use both C and C++03, currently compiled with clang v3.3 or gcc v4.8. clang is our primary compiler. The tracer is mostly C with some C++ helper classes, the replayer is mostly C++, and the UI is completely C++. We avoid, as much as practical, the more extreme aspects of C++, such as abuse of multiple inheritance, template metaprogramming, mixins/policies, and the most bleeding edge developments in C++11. However, we are not afraid of templates at all when they add a significant amount of value, such as with custom containers, or when they can be leveraged to massively reduce code bloat.

  • The tracer, replayer, or code in the voglcore and voglcommon libraries should never directly call plain operator new/delete, or malloc/free, etc. Use vogl_new and vogl_malloc instead (use Find in Files for example patterns). The UI currently uses operator new but this may change once we wrap out heads around the specific needs of Qt. The tracer is a particularly unique case: in 32-bit processes it's under a huge amount of memory pressure in some games (like TF2). So be careful, even a temporary 10MB allocation can kill the traced process.

  • Use VOGL_ASSERT, etc. for assertions, and the other helpers in voglcore for console output, etc.

  • We don't use stuff like Boost, but a couple Loki headers are in there to help us debug GL type issues using its excellent typetraits classes. Don't use STL containers (their perf is just too unpredictable across implementations), or anything that could be impacted by the current locale setting (especially in the tracer!). Use our stuff in voglcore, or roll your own code instead whenever possible. (This rule is targeted at the tracer, replayer, voglcore, and voglcommon. Outside of this you can do whatever is best to get the job done.)

  • C++ exceptions are evil -- do not use them.

  • Some of us are slightly allergic to Python/Perl/etc. scripting. We usually find the scripts to be undebuggable enough to not be worth whatever time savings or productivity enhancements scripting languages can bring to the table. We are C/C++ programmers at heart, so we would rather write our "scripts" in those languages because we have good tools, class libraries, and solid debuggers for C/C++. Also, the runtime dependencies sometimes just cause more trouble than it's worth.

  • We've been doing this as a exclusively Linux project in order to make fast progress, but porting to OSX and Windows is inevitable. Our primary platform will always be Linux.

  • When modifying existing code or adding new code, please make your code look like the code in its immediate neighborhood. voglcore, voglcommon, voglgen, the tracer and replayer use underscores ("my_special_variable") for variable/function names, the "m_" prefix for member variables, the "g_" prefix for globals, and "s_" prefix for static. (We unfortunately haven't been following a single coding standard up to this point, so the UI and some of our tools do their own things.)

GL and tracer specific conventions:

  • The tracer should NEVER crash the traced process, unless the GL call being issued would also always crash the driver. (Even so, the tracer should try to detect cases like this before calling the driver.)

  • Tracer perf: Be VERY careful what you do in the tracer's GL wrapper functions. Remember the app will be calling many of these functions many thousands or tens of thousands of times per frame, sometimes from multiple threads. Some GL entrypoints (such as glActiveTexture) are critical hotspots in many games, so even adding a few lines of code to these wrappers can noticeably slow down the traced app.

  • Synchronously check for GL errors after more or less every GL call (try to follow the existing GL error checking patterns used in nearby parts of the codebase). Do not modify or diverge the traced app's GL state or usage patterns (including GL errors!) unless you know EXACTLY why doing so is important. The replayer has similar requirements - the general rule is to always play back the app's GL calls exactly as they were issued by the original traced process, even glGet's.

  • New GL code must be tested on both NVidia's and AMD's closed source drivers in both compat and core profiles before it is declared to "work". Intel's open source driver will be added soon.

  • Run the regression test before checking in. (Once it's pushed up.. which should be very soon.)