Coding Style
This is our preferred coding style. It was inspired by googles coding style at http://google-styleguide.googlecode.com/svn/trunk/cppguide.xml, but this set is only a small subset of it. Currently, not all our sources are following this style, and we welcome any patches that improves this.
Most of the sources follow this coding style, and the rest is being re-styled as we continue development.
Contents |
File names and directories
- All include files should end in .hpp, all sources are .cpp (this allows shell commands to easily specify all sources: *.?pp).
- All file names are in lower case, with _ as a word separator, e.g.: grand_prix_ending.hpp.
- Files should be grouped in appropriate subdirectories (work in progress). Avoid having more than one level of subdirectories, i.e.
*.?pp */*.?pp
will find all STK source files. - The file names should represent the name of the classes it contains, e.g. grand_prix_ending.hpp contains the class GrandPrixEnding (see #Coding below). Not more than one class should be declared inside a single file.
Including files
- In file XX.cpp first include the corresponding XX.hpp file if available (this guarantees that the header has no hidden dependencies). Then include:
- system files and STL,
- external libraries used by STK (plib, openal, ...),
- libraries that are included with the STK source code (bullet, enet),
- STK header files.
- Sort the STK specific header files alphabetically - first files in src, then the files from the different subdirs. This makes it much easier to spot if a file is included more than once.
- Use a #ifdef header guard in the following form to protect against multiple include: HEADER_FILE_NAME_HPP. I.e. HEADER_ followed by the filename in all caps, with "." replaced by "_".
- Even when including a .hpp file that is in the same subdir (say gui/menu_manager.hpp in gui/char_sel.cpp), use the path including the subdir, i.e.:
#include "gui/menu_manager.hpp"
and not#include "menu_manager.hpp"
This makes it easier to move files into different directories. - If possible, use a simple 'class XYZ' forward declarations instead of including the header file. This will reduce the amount of recompilation necessary when modifying files (see http://google-styleguide.googlecode.com/svn/trunk/cppguide.xml#Header_File_Dependencies for more details).
Layout
- 4 spaces, no tabs
- Both the opening and the closing braces should be on a line of their own. That means:
int main()
{
return 0;
}
Exceptions to this are one line functions in header files: float getValue() const { return m_my_value; }
- In header files try to align declaration and definitions in columns (e.g. first column type, 2nd column function name). This might not always be possible, but a more structured header file is easier to read and understand). Example:
NetworkMode getMode() const {return m_mode; }
void becomeServer();
void becomeClient();
void setState(NetworkState s) {m_state = s; }
NetworkState getState() const {return m_state; }
int getMyHostId() const {return m_host_id; }
void setHostId(int host_id) {m_host_id = host_id; }
unsigned int getNumClients() const {return m_num_clients; }
const std::string&
getClientName(int i) const {return m_client_names[i];}
bool initialiseConnections();
void update(float dt);
- Start with private declarations, then the public ones (this might be a bit unusual: the idea is that the doxygen output is sorted with public declarations first, which is what people studying the code should look like. If you are actually looking at the sources, you are more likely interested in the implementation, so having this come first saves scrolling down time).
- Try not to use more than 80 characters in a line.
- Have a line "// ------------------------" (up to 80th column) separate each function definition (see #Doxygen for an example)
- If the closing } is more than a few lines away from the opening {, or if there are multiple curly braces in-between, add a comment indicating what this } closes. This comment can be an informal comment, or just be the corresponding opening statement. E.g:
} // for i in all karts
or} // for(int i=0; i<m_num_karts; i++)
- It should be avoided to have more than one class in a file
Doxygen
Use Doxygen comments (this is work in progress). The comments should be before the definition of the function/class/variable/... abd be in the following format (Doxyfile is set up to use the first sentence as a brief description):
// -----------------------------------------------------------------------------
/** Searches recursively through the model for any branches representing
* wheels. It looks for any branches having the name
* WheelFront.L, WheelFront.R, WheelRear.L, WheelRear.R. If a wheel is found,
* a new transform node will be inserted 'above' the branch.
* \param branch This is the branch in which the wheels are searched.
* \return true if found.
*/
bool Kart::load_wheels(ssgBranch* branch)
{
}
//----------------------------------------------------------------------------
/** Updates the physics for a kart. */
Kart::handlePhysics()
Coding
- Use const instead of #define if possible.
- References should only be used as const: const Kart &k . If an object is modified, pass it in as a pointer. This makes it more obvious which values are modified.
- If possible, all parameters of functions should be const correct (i.e. if it's not modified, it should be declared const).
- Try to sort parameters with input first, then output parameters.
- Compile time constant values should be all uppercase, e.g. const float PI=3.1415 .
- Member variables start with m_ , e.g. m_kart .
- Variable names are lower case separated by '_'. Example: sun_position (member variable: m_kart_pointer).
- Function names should be capitalized, except the first word. Example: getWidth().
- Type(including classes/struct/enum) names have all their words capitalized. Example: KartControl.
- Use true/false instead of TRUE/FALSE. In [1] it's written that uppercase booleans are used only for older compilers, so we should try to avoid this inconsistency.
- Use std::string instead of char*. If you need a C-style string, use the function std::string.c_str(). However, there are cases when this cannot be avoided(like when using strings with gettext).
- Instead of using ulList or other plib container classes, use stl containers like vector (or once we switched to irrlicht the corresponding irrlicht classes, which can have better performance than STL classes).
- Use std::min() / std::max() instead of a #define (windows needs NOMINMAX to be defined before including windows.h).