
{"id":1313,"date":"2014-12-15T22:12:20","date_gmt":"2014-12-15T22:12:20","guid":{"rendered":"http:\/\/www.codergears.com\/Blog\/?p=1313"},"modified":"2014-12-18T20:40:02","modified_gmt":"2014-12-18T20:40:02","slug":"lessons-to-learn-from-john-carmack-and-oculus-developement-team-when-using-the-modern-c-approach","status":"publish","type":"post","link":"https:\/\/codergears.com\/Blog\/?p=1313","title":{"rendered":"Lessons to learn from Oculus development team when using the &#8220;Modern C++&#8221; approach."},"content":{"rendered":"<p>In the previous post about <a href=\"http:\/\/www.codergears.com\/Blog\/?p=1103\">Doom3<\/a>, we discovered that it was developed using the &#8220;C with Classes&#8221; approach. John Carmack is\u00a0the main developer and it was between 2000 and 2004, what explains why &#8220;Modern C++&#8221; approach was not adopted. And, even if &#8220;C with Classes&#8221; is not recommended, he made some good decisions to have clean code.<\/p>\n<p>John Carmack is now the <a href=\"https:\/\/www.oculus.com\/\">oculus VR<\/a> CTO, Oculus VR\u00a0is an American virtual reality\u00a0technology company founded by Palmer Luckey and Brendan Iribe. Their first product, still in development, is the\u00a0Oculus Rift, a\u00a0head-mounted display\u00a0for immersive virtual reality\u00a0(VR).<!--more--><\/p>\n<p>Oculus provides an SDK\u00a0which includes its source code, it&#8217;s developed using C++. \u00a0For this project the Modern C++ approach was adopted. Let&#8217;s discover some design and implementation choices of <span style=\"color: #333333;\">its primary architect<\/span>\u00a0Michael Antonov.<\/p>\n<p><strong>1- Use namespaces to modularize\u00a0the SDK<\/strong><\/p>\n<p>Namespaces were introduced to the C++ Standard in 1995\u00a0and usually they are most often used to avoid\u00a0naming collisions. Although namespaces are used extensively in recent C++ code, most older code does not use this artifact.<br \/>\nNamespaces are useful to modularize your projects, to make it more readable and maintainable. Here&#8217;s the list of all namespaces defined in the oculus SDK:<br \/>\n<a href=\"http:\/\/www.codergears.com\/Blog\/wp-content\/uploads\/ovr1.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-1327\" src=\"http:\/\/www.codergears.com\/Blog\/wp-content\/uploads\/ovr1.png\" alt=\"ovr1\" width=\"281\" height=\"289\" \/><\/a><\/p>\n<p><strong>2-\u00a0Minimize the use of global variables and functions<\/strong><\/p>\n<p>The SDK defines few global functions; most of them are the exported ones. Even if a function is just an utility, it&#8217;s better to add it in a \u00a0class as static to group utilities by category.<\/p>\n<p><strong>3- Modern C++ doesn&#8217;t imply necessarly the overuse of templates<\/strong><\/p>\n<p>Andrei Alexandrescu says about the Modern C++ design:<\/p>\n<blockquote style=\"color: #111111;\">\n<p style=\"color: #111111;\"><span style=\"color: #000000;\">Modern C++ Design defines and systematically uses\u00a0<\/span><i style=\"color: #000000;\">generic components<\/i><span style=\"color: #000000;\">\u00a0&#8211; highly flexible design artifacts that are mixable and matchable to obtain rich behaviors with a small, orthogonal body of code.<\/span><\/p>\n<\/blockquote>\n<p>Modern C++ has a close relation with generic programming; probably it\u2019s the reason that makes many developers neglect the modern C++ approach. They think that the code will be mostly implemented as templates, which makes the code difficult to read and maintain.<\/p>\n<p>In the SDK, the templates represent only 20% of all types defined and most of them are related to the technical layer.<\/p>\n<p>The following <a href=\"http:\/\/www.cppdepend.com\/cqlinq.aspx\">CQLinq <\/a>query give us the types defined by the SDK:<\/p>\n<p><a href=\"http:\/\/www.codergears.com\/Blog\/wp-content\/uploads\/ovr3.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-1329\" src=\"http:\/\/www.codergears.com\/Blog\/wp-content\/uploads\/ovr3.png\" alt=\"ovr3\" width=\"420\" height=\"282\" \/><\/a><\/p>\n<p>&nbsp;<\/p>\n<p>It&#8217;s true that some Modern C++ libraries like Boost mainly define their classes as templates to be as the most generic as possible. However, in many other applications it&#8217;s not necessarily the case. You could use templates when the genericity is suitable and needed.<\/p>\n<p><strong>4- Don&#8217;t repeat yourself<\/strong><\/p>\n<p>Repeating boilerplate code makes maintenance difficult, and allows all kinds of mistakes. With generic programming you can avoid harmful repetition. Think about using generic everywhere, the code is similar and differs only in types manipulated.<\/p>\n<p>The SDK defines a templated singleton, to avoid the same singleton code in many places:<\/p>\n<p><a href=\"http:\/\/www.codergears.com\/Blog\/wp-content\/uploads\/ovr5.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-1330\" src=\"http:\/\/www.codergears.com\/Blog\/wp-content\/uploads\/ovr5.png\" alt=\"ovr5\" width=\"724\" height=\"401\" \/><\/a><\/p>\n<p><span style=\"color: #000000;\"><b>5- Allocation and RAII<\/b><\/span><\/p>\n<p>RAII is a C++ idiom\u00a0which binds the life cycle of a resource \u00a0to the lifetime of an object with automatic storage duration, which guarantees that all resources are cleaned up when the object goes out of scope, in reverse order of acquisition. This leverages the language to eliminate resource leaks and guarantee exception safety.<\/p>\n<p>To manage allocation, the oculus development team defines its reference counted class OVR::RefCountBase which is a base class for classes that require thread-safe reference counting; it also overrides the new and delete operators to use MemoryHeap.<\/p>\n<p>Many classes inherit from it to manage their life cycle.<\/p>\n<p><a href=\"http:\/\/www.codergears.com\/Blog\/wp-content\/uploads\/ovr8.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-1331\" src=\"http:\/\/www.codergears.com\/Blog\/wp-content\/uploads\/ovr8.png\" alt=\"ovr8\" width=\"400\" height=\"494\" \/><\/a><\/p>\n<p>These ref counted classes are used through the\u00a0Reference Counted template pointer OVR::Ptr&lt;C&gt; which contains the logic of AddRef and Release methods.<\/p>\n<p>With these allocation utility classes, the SDK users will not care about releasing the pointers used, or spending time to resolve memory management problems due to the use of multithreading. The classes implemented by the SDK free the developers from the memory management problems.<\/p>\n<p><strong>6- Prefer static polymorphism to dynamic polymorphism<\/strong><\/p>\n<p>In classic C++, the dynamic polymorphism is generally overused, which implies the use of inheritance, and the use of the virtual table at runtime to know the method of each child class to invoke. On the other side, static polymorphism is completely resolved at compile time.<\/p>\n<p>For example the SDK defines the Shader class for Direct 3D version 10, Direct3D version 11 and OpenGL.<\/p>\n<p><a href=\"http:\/\/www.codergears.com\/Blog\/wp-content\/uploads\/ovr9.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-1332\" src=\"http:\/\/www.codergears.com\/Blog\/wp-content\/uploads\/ovr9.png\" alt=\"ovr9\" width=\"397\" height=\"304\" \/><\/a><\/p>\n<p>In contrast to\u00a0\u00a0classic C++ \u00a0they do not have a\u00a0common base class, so the RTTI could not be used to decide the\u00a0methods of which one will be used at runtime.<\/p>\n<p>Here&#8217;s a snippet of the implementation of SharedImpl class. This class has two template parameters and \u00a0the decision of which Shader to use is done at compile time\u00a0by specifying the D3DShaderType when an instance is created.<\/p>\n<p><a href=\"http:\/\/www.codergears.com\/Blog\/wp-content\/uploads\/ovr17.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-1338\" src=\"http:\/\/www.codergears.com\/Blog\/wp-content\/uploads\/ovr17.png\" alt=\"ovr17\" width=\"812\" height=\"258\" \/><\/a><\/p>\n<p>In Modern C++, static polymorphism is preferred to the dynamic one, it makes the code more flexible, no need to have an inheritance relation between classes, which enforce the low coupling.<\/p>\n<p><strong>7- Separate\u00a0data model from treatments<\/strong><\/p>\n<p>The oculus SDK defines many structs for its data model, here is the CppDepend <a href=\"http:\/\/www.cppdepend.com\/Doc_Treemap.aspx\">metric view<\/a> which shows in blue all of them.<\/p>\n<p><a href=\"http:\/\/www.codergears.com\/Blog\/wp-content\/uploads\/ovr2.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-1328\" src=\"http:\/\/www.codergears.com\/Blog\/wp-content\/uploads\/ovr2.png\" alt=\"ovr2\" width=\"835\" height=\"498\" \/><\/a><\/p>\n<p>Let&#8217;s take as example ovrSensorData struct from the SDK, and suppose it was defined as class containing also the treatments. If we need to use these data in another context that we need to add other methods, we will have a not cohesive class after few evolutions.<\/p>\n<p><strong>8- Use some most common modern C++ techniques\u00a0<\/strong><\/p>\n<p>The Modern C++ design introduced many idioms, some of them are easy to understand and implement, others are difficult and makes the code not easy to read and maintain.<\/p>\n<p>You can focus only on the most common used ones; the oculus SDK uses mainly <a href=\"http:\/\/accu.org\/index.php\/journals\/442\">Traits <\/a>and <a href=\"http:\/\/en.wikipedia.org\/wiki\/Policy-based_design\">Policy-based design<\/a> techniques. Here&#8217;s an example of a class from the SDK using them:<\/p>\n<p><a href=\"http:\/\/www.codergears.com\/Blog\/wp-content\/uploads\/ovr10.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-1333\" src=\"http:\/\/www.codergears.com\/Blog\/wp-content\/uploads\/ovr10.png\" alt=\"ovr10\" width=\"724\" height=\"231\" \/><\/a><\/p>\n<p>Don&#8217;t force yourself to use all the Modern C++ idioms like <a href=\"http:\/\/en.wikipedia.org\/wiki\/Substitution_failure_is_not_an_error\">SFINAE <\/a>or other advanced ones, unless you really need to.<\/p>\n<p><strong>9- It&#8217;s not mandatory to use Exception handling<\/strong><\/p>\n<p>Even if many Modern C++ resources recommend the use of exceptions they are not used in many known open source projects. The exceptions provide a powerful mechanism to report errors. However, it\u2019s not easy to write an exception safety code.<\/p>\n<p>The oculus SDK developers prefer to not use them.<\/p>\n<p><strong>10- And specially don&#8217;t forget to provide recurrent technical layer needs<\/strong><\/p>\n<p>The classes related to the technical layer are generally the most used ones as shown by this following CQLinq query:<\/p>\n<p><a href=\"http:\/\/www.codergears.com\/Blog\/wp-content\/uploads\/ovr18.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-1353\" src=\"http:\/\/www.codergears.com\/Blog\/wp-content\/uploads\/ovr18.png\" alt=\"ovr18\" width=\"528\" height=\"493\" \/><\/a><\/p>\n<p>In some projects\u00a0the C++ developers\u00a0\u00a0spend most of their development time fighting with the technical layer.<\/p>\n<p>As the decision taken for Doom3, the oculus SDK provides all needed low level classes, powerful String and StringBuilder classes are\u00a0implemented, many useful classes concerning multithreading, memory management, containers are provided, which makes the task very easy for the SDK users.<\/p>\n<p><strong>Summary:<\/strong><\/p>\n<p>In the oculus SDK source code and as Doom3, \u00a0the priority is to make the life easy for developers by:<\/p>\n<ul>\n<li>Providing a pragmatic and complete framework for technical layer.<\/li>\n<li>Leting the developers focus more on the application logic.<\/li>\n<li>Having a compact and very clean code.<\/li>\n<\/ul>\n<p>To resume it&#8217;s better to study a source code using the\u00a0Modern C++ approach instead of reading only books and articles. The oculus SDK is a good candidate; it&#8217;s not a big project and it provides some useful Modern C++ best practices.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>In the previous post about Doom3, we discovered that it was developed using the &#8220;C with Classes&#8221; approach. John Carmack is\u00a0the main developer and it was between 2000 and 2004, what explains why &#8220;Modern C++&#8221; approach was not adopted. And, even if &#8220;C with Classes&#8221; is not recommended, he made some good decisions to have &hellip; <a href=\"https:\/\/codergears.com\/Blog\/?p=1313\" class=\"more-link\">Continue reading<span class=\"screen-reader-text\"> &#8220;Lessons to learn from Oculus development team when using the &#8220;Modern C++&#8221; approach.&#8221;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[],"tags":[],"class_list":["post-1313","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/codergears.com\/Blog\/index.php?rest_route=\/wp\/v2\/posts\/1313","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/codergears.com\/Blog\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/codergears.com\/Blog\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/codergears.com\/Blog\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/codergears.com\/Blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=1313"}],"version-history":[{"count":45,"href":"https:\/\/codergears.com\/Blog\/index.php?rest_route=\/wp\/v2\/posts\/1313\/revisions"}],"predecessor-version":[{"id":1412,"href":"https:\/\/codergears.com\/Blog\/index.php?rest_route=\/wp\/v2\/posts\/1313\/revisions\/1412"}],"wp:attachment":[{"href":"https:\/\/codergears.com\/Blog\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=1313"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/codergears.com\/Blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=1313"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/codergears.com\/Blog\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=1313"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}