mirror of https://github.com/mosra/magnum.git
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
387 lines
16 KiB
387 lines
16 KiB
namespace Magnum { |
|
/** @page coding-style Coding style |
|
@brief Coding style and best practices to preserve maintainability and |
|
consistent style across whole project. |
|
|
|
@tableofcontents |
|
|
|
Please note that if you have a good excuse to either break the rules or modify |
|
them, feel free to do it (and update this guide accordingly, if appropriate). |
|
Nothing is worse than rule that hurts productivity instead of improving it. |
|
|
|
@section cpp C++ code |
|
|
|
@subsection cpp-files File naming and directory structure |
|
|
|
All C++ header and source files are named after the class they contain with no |
|
case change. Thus there should be only one class per file, but if the classes |
|
are closely related and small enough, you can make an exception (see Query.h |
|
or TypeTraits.h for example). |
|
|
|
Supporting headers (not relevant to end user), such as various `configure.h`, |
|
`visibility.h` etc., which are used only internally and don't contain any |
|
code, should have first letter of the name lowercased to distinguish them from |
|
API headers. |
|
|
|
Code in the root Magnum namespace is in `src/` directory, each subnamespace is |
|
in its own subdirectory. Unit tests are in `Test` subnamespace (and |
|
subdirectory). Implementation details (helper classes etc.) which shouldn't be |
|
visible to end users should be in `Implementation` subnamespace in the same |
|
file as the class/function for which the implementation is. See @ref documentation |
|
section below for guide how to hide it also from Doxygen documentation. |
|
|
|
@subsection cpp-headers Headers |
|
|
|
Headers have an strict structure. Include guards are basically include path |
|
with slashes replaced with underscores to make refactoring as easy as possible. |
|
Directly after them is license block, blank line, then file documentation, |
|
blank line and after that the contents of the header. Include guard ending is |
|
only `endif`, without any additional comments. |
|
|
|
It's probably common practice, but repeating won't hurt: headers shouldn't |
|
have `using` declarations inside them (unless there is good excuse, see |
|
Magnum.h). |
|
|
|
@subsection cpp-sources Source files |
|
|
|
Source file have similar structure as headers - first license block, then |
|
blank line, then the includes, then contents of the file. |
|
|
|
Unlike headers, it's good to use `using` declaration in source files as much |
|
as needed to make the code less verbose (unless the name is used only once). |
|
|
|
@subsection cpp-format Code format |
|
|
|
@subsubsection cpp-naming Naming |
|
|
|
Namespaces, classes and structs, enums, type template names and static |
|
constants should be named with `CamelCase`, i.e. first letter of the name and |
|
each successive word uppercase, other lowercase. E.g. `%CubeMapTextureArray`. |
|
Classes with pure virtual methods or base classes which are not meant to be |
|
used directly should be prefixed with `Abstract`. If the class is not meant |
|
to be instanced directly and doesn't have any pure virtual methods, consider |
|
using pure virtual destructor (see AbstractTexture source for example). |
|
|
|
Functions, function parameters, non-type template names and variables should |
|
be named with `camelCase`, i.e. first letter of the name lowercase, each |
|
successive word starting with uppercase. E.g. `generateFlatNormals()`. |
|
|
|
Preprocessor macros should be written in uppercase with underscores between |
|
words, e.g. `MAGNUM_EXPORTING`. |
|
|
|
Redundant information and abbrevations in names are not recommended (use |
|
`determinant`, `inverse` and `attribute` instead of `det`, `inv` and `attr`). |
|
Hungarian notation, `I` and `E` prefixes for interfaces and enums are |
|
forbidden and cruelly punished, if found. Acronyms should be written with |
|
first letter uppercase only to avoid visual collision with preprocessor macros |
|
(`Http`, `Collada` and `Bptc` instead of `HTTP`, `COLLADA` and `BPTC`). When |
|
writing wrappers for OpenGL functions and defines, try to match the original |
|
name as closely as possible, although expanding abbrevations (and removing |
|
redundant prefixes) is encouraged. |
|
|
|
Private variables clashing with (mostly getter) function names can have |
|
one underscore before them, don't use two underscores, as they are reserved |
|
for internal usage by the C++ standard. Underscores before the name shouldn't |
|
be used in public API or function parameters, as it looks ugly in the |
|
documentation. |
|
|
|
@subsubsection cpp-namespace Namespace declarations |
|
|
|
Namespace declaration is on one line, separated with blank lines on both |
|
sides. The code inside the declaration is not indented to save horizontal |
|
space. |
|
@code |
|
namespace Magnum { namespace Math { namespace Geometry { |
|
|
|
// ... |
|
|
|
}}} |
|
@endcode |
|
|
|
The only exception is with forward declarations: use indentation where it |
|
improves readability, e.g.: |
|
@code |
|
namespace Corrade { namespace PluginManager { |
|
class AbstractPluginManager; |
|
}} |
|
|
|
namespace Magnum { |
|
|
|
namespace Math { |
|
class Matrix4; |
|
|
|
namespace Geometry { |
|
class Distance; |
|
} |
|
} |
|
|
|
// the actual code... |
|
|
|
} |
|
@endcode |
|
|
|
@subsubsection cpp-classes Class and structure declarations |
|
|
|
Class and structure protection levels are ordered as following: first friend |
|
declarations, then public members, then protected members and finally private |
|
members, so class public interface is easy to spot at the top of the file. |
|
|
|
Members are ordered as following: first classes and enums, then static |
|
functions, then non-static functions, then static variables, then non-static |
|
variables. Again, classes and methods are more important for user than |
|
variables, static members are more important than non-static. |
|
|
|
@subsubsection cpp-style Blocks, whitespace and indentation |
|
|
|
The goal is to preserve readability with minimal amount of wasted vertical |
|
and horizontal space. |
|
|
|
Each file must have one blank line at the end (Git will warn you in the |
|
diff if it's not the case), indentation is done exclusively with spaces (4 |
|
spaces). Trailing whitespaces are not permitted (and you should set up your |
|
Git installation to warn about that). |
|
|
|
The code should be wrapped around 80th column, exceptions for long single-line |
|
statements are allowed unless it hurts readability. |
|
|
|
Indented is everything except namespace declarations (as specified above) - |
|
blocks, class protection levels, `case` statements. Overlong line breaks are |
|
indented also with 4 spaces or better where it makes more sense (e.g. for |
|
aligning similar code), multiline comments are indented with three spaces for |
|
the comment text block to be aligned. |
|
|
|
Whitespace is **not allowed** inside parentheses and between function name or |
|
branch/loop statement and left parenthesis (or between constructed variable |
|
name and left brace) and before semicolon. It **must be** around block braces |
|
if the block is not empty. It **must not** be space before, but after the |
|
comma. |
|
@code |
|
if ( statement ){foo (a ,b) ;} // awful! |
|
if(statement) { foo(a, b); } // good |
|
@endcode |
|
|
|
Whitespace should be around operators with low precedence (namely `+`, `-`, |
|
`<<`, `>>` but not on unary `-`), around all boolean and comparison operators, |
|
around `=` and related operators and around ternary operator. Whitespace is |
|
should be around `/`, `*`, `%` to indicate they have precedence before |
|
addition and substraction. Whitespace can or need not to be around binary |
|
operators, whichever looks better in particular content. |
|
|
|
Block opening braces start on the same line as corresponding statement (class/ |
|
function declaration, branch and loop statement), `else` and `else if` |
|
statements have both braces on the same line too: |
|
@code |
|
if(expression) { |
|
// ... |
|
} else if(another || expression) { |
|
// ... |
|
} else { |
|
// ... |
|
} |
|
@endcode |
|
|
|
If the block is only one statement and short enough, it can be on the same line: |
|
@code |
|
void setClearDepth(GLfloat depth) { clearDepth = depth; } |
|
@endcode |
|
@code |
|
if(!initialized) return false; |
|
@endcode |
|
|
|
@subsubsection cpp-switches Switch statements |
|
|
|
Switch statements are usually very verbose and thus they are often subject of |
|
various shortening and whitespace tricks. The goal is to make them as readable |
|
as possible without wasting too much vertical space, for example: |
|
@code |
|
switch(type) { |
|
case Byte: size = 8; break; |
|
case Short: size = 16; break; |
|
case Int: size = 32; break; |
|
case Long: size = 64; break; |
|
case LongLong: size = 128; break; |
|
|
|
default: size = 0; |
|
} |
|
@endcode |
|
|
|
@subsubsection cpp-virtual Virtual functions |
|
|
|
Only base virtual functions should have `virtual` keyword, not the |
|
reimplementations. |
|
|
|
@subsubsection cpp-includes Includes |
|
|
|
Includes should be organized into separate groups separated with blank line - |
|
first header belonging to the particular source file (if the file is source |
|
file), then system includes, then includes from the engine itself and then |
|
internal includes used only in the particular file (e.g. `configure.h`). |
|
Includes from system libraries and dependencies are in angle brackets, |
|
includes from engine itself are in quotes. Includes should be sorted by |
|
"level" (e.g. C includes (`<cstdlib>`) before C++ includes |
|
(`<string>`) and those before dependencies (`<GL/gl.h>`)), then by |
|
path name. |
|
|
|
@subsubsection cpp-macros Preprocessor macros |
|
|
|
Preprocessor macros should have the same indentation as surrounding code. If |
|
the macro is long or contains code which should be spanned or multiple lines, |
|
it should be wrapped on multiple lines, each successive line indented and the |
|
line wrapping indicator `\` should be aligned around 80th column, preferably |
|
on some tab-stop. |
|
|
|
@section comments Comments |
|
|
|
All comments should be in C-style (i.e. slash and asterisk, not two slashes). |
|
There should always be space after leading asterisk and before trailing |
|
asterisk, this is also the case for C++-style comments, if are used somewhere |
|
(mostly in the documentation, because nesting of C-style comments is |
|
impossible). |
|
|
|
Multi-line comments should be done in a way which preserves block align (so |
|
when first line starts with slash, asterisk and space, the second line should |
|
be indented with three spaces to align the text). |
|
|
|
@section documentation Doxygen documentation |
|
|
|
Doxygen documentation uses C-style comments with two asterisks, each |
|
successive line should start with asterisk and space. However, documentation |
|
block starting at beginning of the line (with no indentation) and spanning |
|
more lines shouldn't have leading asterisks and use whole 80 column width to |
|
avoid wasted space. |
|
|
|
Doxygen commands are prefixed with `@`. |
|
|
|
If the documentation comment is short enough, it can be on one line. If not, |
|
the first line should contain only the slash and two asterisks. However, there |
|
are exceptions for commands that can be on the first line of the multiline |
|
documentation block - namely @c \@page, @c \@name, @c \@file, @c \@namespace |
|
and other commands for "out-of-place" documentation. |
|
|
|
Doxygen documentation is mainly in header files, additional documentation |
|
pages which doesn't belong to any particular class (e.g. namespaces, |
|
overview...) is in `doc/` directory. In source file should be only @c \@todo |
|
items related to particular lines of code. Documentation pages and additional |
|
documentation files should be named in lowercase with dashes between words. |
|
Additional documentation files use `*.dox` extension. |
|
|
|
File documentation block is after license block, it explains only in |
|
@c \@brief what content given header contains. |
|
|
|
Namespace documentation is only in file `namespaces.dox` inside `doc/` |
|
directory. |
|
|
|
Class and function documentation block nearly always starts with an @c \@brief |
|
description (the only exception is enum value documentation). After that is |
|
documentation of template parameters, function parameters and return value. |
|
These are documented only if it's not obvious from the description or |
|
function/parameter name (i.e. it's not needed for setters). |
|
|
|
Trivial function overloads (e.g. const overloads) are marked only with |
|
@c \@overload keyword and are always *after* the original documented function. |
|
|
|
If the documentation is short enough, it can be placed after the documented |
|
element only if it doesn't exceed 80 character limit too much (e.g. enum value |
|
documentation). |
|
|
|
For hiding implementation details from documentation or for working around |
|
Doxygen parsing issues (and false positive warnings), preprocessor define |
|
`DOXYGEN_GENERATING_OUTPUT` can be used. It is defined only when doxygen |
|
generates the documentation. If that works around some Doxygen parsing bug, |
|
don't forget to mark it with @c \@todoc (see below). |
|
|
|
@subsection documentation-commands Special documentation commands |
|
|
|
@subsubsection documentation-commands-todoc Documentation-related TODOs |
|
|
|
TODOs about documentation (or about Doxygen workarounds) should be written |
|
with @c \@todoc instead of @c \@todo. They will appear on @ref todoc |
|
"separate page". |
|
|
|
@subsubsection documentation-commands-debugoperator Debugging operators |
|
|
|
Operators for printing types on Corrade's debug output should be marked with |
|
@c \@debugoperator, e.g.: |
|
@code |
|
// @debugoperator{Matrix4} |
|
template<class T> Corrade::Utility::Debug operator<<(Corrade::Utility::Debug debug, const Matrix4<T>& value) { |
|
// ... |
|
} |
|
@endcode |
|
They will appear as related functions within documentation of class specified |
|
as the parameter. |
|
|
|
@subsubsection documentation-commands-collisionoperator Physics collision operators |
|
|
|
Out-of-class operators for collision in Physics namespace should be marked with |
|
@c \@collisionoperator, e.g.: |
|
@code |
|
// @collisionoperator{Point,Sphere} |
|
inline bool operator%(const Point& a, const Sphere& b) { return b % a; } |
|
@endcode |
|
They will appear as related functions within documentation of class for which |
|
the operator is implemented (not of class in which the operator is |
|
implemented), thus efficiently connecting the two classes together in the |
|
documentation. |
|
|
|
@subsubsection documentation-commands-extension Links to OpenGL extensions |
|
|
|
If an OpenGL extension is referenced in the documentation, it should be done |
|
with @c \@extension command: |
|
@code |
|
@extension{ARB,timer_query} |
|
@endcode |
|
It produces link to the specification of the extension in OpenGL registry, |
|
e.g. @extension{ARB,timer_query}. |
|
|
|
@subsubsection documentation-commands-requires Classes and functions requiring specific OpenGL version or extensions |
|
|
|
If any class or function requires specific OpenGL version above 2.1, it should |
|
be marked with appropriate command @c \@requires_glXX, where `XX` is version |
|
number (e.g. `42` for OpenGL 4.2) or @c \@requires_extension for specific |
|
extension which is not in any core OpenGL version. It should be used in |
|
conjunction with @c \@extension command, if there is an extension providing |
|
the same functionality. For example: |
|
@code |
|
@requires_GL33 Extension @extension{ARB,timer_query} |
|
@endcode |
|
|
|
If class is marked with the command, member and related functions shouldn't be |
|
marked. On the other hand, if the version/extension is needed only by one |
|
function, only the function should be marked. If the extension is needed only |
|
for some functionality (not related to any member function), it should be |
|
noted in the description. |
|
|
|
All classes and functions using those commands are cross-referenced in page |
|
@ref required-extensions. |
|
|
|
@section git Git commit messages, branch and tag format |
|
|
|
It is encouraged to follow best practices of git commit messages as explained |
|
here: http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html |
|
|
|
In short, each commit message should be in this format, each line at most 72 |
|
characters long: |
|
|
|
~~~~ |
|
Capitalized short summary |
|
|
|
More detailed explanation text, if necessary, wrapped on multiple lines. |
|
|
|
- Bullet points, indented with one space before (if there is preceeding |
|
paragraph) and one space after the bullet, indented to have the text |
|
aligned. Colons are allowed too, but not mixed. |
|
- Bullet points are separated from surrounding text with blank lines. |
|
|
|
It is good to use *emphasise*, _underline_ or `code` as in Markdown, if |
|
necessary, but they shouldn't be overused. |
|
|
|
Multi-line code examples are indented with four spaces, as in Markdown |
|
syntax. |
|
~~~~ |
|
|
|
Branches and tags should be named with lowercase names with words separated |
|
with colons (`-`), e.g. `physics-performance-tweaks`. Version tags start with |
|
`v`, followed by version number, e.g. `v1.0.3`. |
|
*/ |
|
}
|
|
|