stylesheet - GesielFreitas/CrossRoads-IJE-UnB GitHub Wiki

Stylesheet

This document is the style guide of the crossRoads's project, developed for the discipline of digital games and improved for the discipline of programming techniques, both ministered in Universidade de Brasília.Google C++ Style Guide stylesheet was used as the base, and the needed adaptations were presented on this document.

1. Declarations
2. Indentation
3. Scope
4. Whitespaces
5. Lines 6. Statements
7. Exceptions
8. Comments
9. Documentation
10. Good habits

1. Declarations

Class Name and Enums

Each initial letter of each word should be uppercase. In case of a compound name, the words should be together without underscore between them.

Wrong
class game_object {

}
class button {

}
enum class audiostate {

}
Right
class GameObject {

}
class Button {

}
enum class AudioState {

}

Functions and Variables

Variables and functions names should be lowercase with underscores between words.

Wrong
void MonsterAI::processPos() {
    ...
}
void MonsterAI::Process_pos() {
    ...
}
hasDamage = false;
hasdamage = false;
Right
void MonsterAI::process_pos() {
    ...
}
has_damage = false;

Constants

Constant names should be uppercase with underscores between words.

Wrong
const int player_distance = 850;
const int PlayerDistance = 850;
const int Player_distance = 850;
Right
const int PLAYER_DISTANCE = 850;

2. Indentation

Use 4 spaces per indentation level.

Wrong
void Game::set_properties( std::string name, std::pair<int, int> window_size ) {

main_name = name;
main_window_size = window_size;

}
void Game::set_properties( std::string name, std::pair<int, int> window_size ) {

            main_name = name;
            main_window_size = window_size;

}
Right
void Game::set_properties(std::string name, std::pair<int, int> window_size) {

    main_name = name;
    main_window_size = window_size;

}

3. Scope

Braces

When start a new code block use braces for emulating pure blocks.The opening brace must appear on the same line of the structure who contains it, separated by one whitespace after its end. The closing brace must appear on the line after the block end.

Wrong
bool Game::start_sdl()
{
    ...
}
bool Game::start_sdl() { ... }
bool Game::start_sdl(){
    ...
}
Right
bool Game::start_sdl() {
    ...
}

Code blocks

When starting a new code block, braces must be used to delimit it.

Wrong
if( start_sdl() && create_window() )
    Log::instance.info("Iniciando o jogo");
if( start_sdl() && create_window() ) Log::instance.info("Iniciando o jogo");
Right
if( start_sdl() && create_window() ) {
    Log::instance.info("Iniciando o jogo");
}

4. Whitespaces

Control Structures

If the content within the frame conditions is not empty, a whitespace should be added after opening the parenthesis and another before closing.

Wrong
if(life == 3) {
    ...
}
while(value < max ) {

}
Right
if( life == 3 ) {
    ...
}
while( value < max ) {

}

Parentheses

The opening of the parentheses must be immediately after the sentence calling it not having.

Wrong
if ( life == 3 ) {
    ...
}
Right
if( life == 3 ) {
    ...
}

Empty Parentheses

Empty parentheses should not have whitespaces inside.

Wrong
move_monster(  );
Right
move_monster();

Function Parameters

Parameters of functions should not contain spaces in relation to parenthesis. If there is more than one parameter, a whitespace should be included after each separating comma.

Wrong
m_monster_controler->play_animation("monster_walk",true);
m_monster_controler->play_animation( "monster_walk", true );
m_monster_controler->play_animation( "monster_damage" );
Right
m_monster_controler->play_animation("monster_walk", true);
m_monster_controler->play_animation("monster_damage");

Operators

All the operators must be separated from the operands by a whitespace in both sides.

Wrong
if( life==3 ) {
    ...
}
move_time= Game::instance.timer->getTicks()+900;
Right
if( life == 3 ) {
    ...
}
move_time = Game::instance.timer->getTicks() + 900;

Pointer Operators

The operator accessing a pointer must be adjacent to the referent variable, containing a whitespace before and not after the operator.

Wrong
GameObject * ground;
GameObject* ground;
Player(GameObject & main_game_object);
Right
GameObject *ground;
Player(GameObject &main_game_object);

Dynamic cast

Dynamic cast should not have spaces inside the '<' and '>' operators and should contain a whitespace after the cast is closed.

Wrong
AudioComponent *boss_dash_audio = (dynamic_cast<AudioComponenti*>());
AudioComponent *boss_dash_audio = (dynamic_cast< AudioComponenti* > ());
AudioComponent *boss_dash_audio = (dynamic_cast<AudioComponenti *> ());
Right
AudioComponent *boss_dash_audio = (dynamic_cast<AudioComponenti*> ());

Include statements

Include statements must contain a space between the include and the call library.

Wrong
#include"monsterAI.hpp"
#include<stdio.h>
Right
#include "monsterAI.hpp"
#include <stdio.h>

5. Lines

Logical blocks

The code must be separated into logical paragraphs by a blank line, so as to make clear the identification of parts of the code, such as initialization of variables, execution of a particular procedure, etc.

Wrong
Matrix4x4 matrix = new Matrix4x4();
double cosAngle = Math.cos(angle);
double sinAngle = Math.sin(angle);
matrix.setElement(1, 1, cosAngle);
matrix.setElement(1, 2, sinAngle);
matrix.setElement(2, 1, -sinAngle);
matrix.setElement(2, 2, cosAngle);
multiply(matrix);
Right
Matrix4x4 matrix = new Matrix4x4();

double cosAngle = Math.cos(angle);
double sinAngle = Math.sin(angle);

matrix.setElement(1, 1, cosAngle);
matrix.setElement(1, 2, sinAngle);
matrix.setElement(2, 1, -sinAngle);
matrix.setElement(2, 2, cosAngle);

multiply(matrix);

Functions and Class Declarations

Add one blank line after functions and class declaration and before last key.

Wrong
bool Boss::init(){
  life = 10;
  timestep = 0;
  move_time = 0;
  fireball_time = 0;
  side = false;

  return true;
}
class Button : public GameObject {
    public:
        Button();
        void update(float timer = 0);
        Sprite *button_sprite;
};
Right
bool Boss::init() {

  life = 10;
  timestep = 0;
  move_time = 0;
  fireball_time = 0;
  side = false;

  return true;

}
class Button : public GameObject {

    public:
        Button();
        void update(float timer = 0);
        Sprite *button_sprite;

};

Decision structures and loops

In decision structures and loop, the statements should begin in next line after structure declaration.

Wrong
if( life == 3 ) {

    boss_full_putasso_audio->play(0, -1);
}
while( value < max ) {

    cout << value << endl;
}
Right
if( life == 3 ) {
    boss_full_putasso_audio->play(0, -1);
}
while( value < max ) {
    cout << value << endl;
}

If statements

If statements should always mark the block with keys. In the case of keywords else and else if you should always start them on the next line after the key is closed.

Wrong
if( !has_ground() ) {
    ...
} else {
    ...
}
Right
if( !has_ground() ) {
    ...
}
else {
    ...
}

Character limit

A line can be a maximum of 80 characters. If it is necessary to break the line it must be indented according to its the origin of its sentence.

Wrong
if( _main_game_object->main_positionX<0 || _main_game_object->main_positionX+_main_game_object->main_width>800 )
Right
if( _main_game_object->main_positionX<0 || 
    _main_game_object->main_positionX+_main_game_object->main_width>800 )

Break expressions

A line should break after a binary operator.

Wrong
compound_key = (registration 
                + id);
Right
compound_key = (registration +
                id);

List of parameters

The initialization of variances of a class by passing a list of parameters to the constructor must have a blank before and after the colon - if it fits on a single line. If more than one line is required, the list must start on the next line and be indented according to the parameters of the constructor method.

Wrong
Heart(GameObject &main_game_objecte): Component(main_game_object, id) {}
Heart(GameObject &main_game_objecte) :
  Component(main_game_object, id) {}
Heart(GameObject &main_game_object, std::string id, Player* player, int life):
Component(main_game_object, id), m_player(player), m_life(life) {}
Right
Heart(GameObject &main_game_objecte) : Component(main_game_object, id) {}
Heart(GameObject &main_game_object, std::string id, Player* player, int life) :
      Component(main_game_object, id), m_player(player), m_life(life) {}

Header Style

All header files should have #define guards to prevent multiple inclusion. The format of the symbol name should be H. To guarantee uniqueness, they should be based on the full path in a project's source tree.

Wrong
#define BAZ_H_

...

#endif  // BAZ_H_
Right
#define FOO_BAR_BAZ_H_

...

#endif  // FOO_BAR_BAZ_H_

6. Statements

If Statements

If statements must follow the standard logical flow and must have else statement even if it does not have logical content. If there is no content a comment should be placed with "Do nothing".

Wrong
if( m_life > m_player->life_points ) { 
    _main_game_object->setState(GameObject::State::disabled);
} 
if( m_life > m_player->life_points ) { 
   
}
else {
    _main_game_object->setState(GameObject::State::disabled);
}
Right
if( m_life > m_player->life_points ) { 
    _main_game_object->setState(GameObject::State::disabled);
}
else {
    // Do nothing
}

7. Exceptions

Asserts

Assert liberally to document internal assumptions and invariants.

Wrong
assert(false);
Right
assert( !variable );

Report Errors

Prefer to use exceptions to report errors.

Reasons why exceptions is better than errors:

  • Exceptions can't be silently ignored;
  • Exceptions propagate automatically;
  • Exception handling removes error handling and recovery from the main line of control flow;
  • Exception handling is better than the alternatives for reporting errors from constructors and operators.

Throw by value, catch by reference

Wrong
catch( MyException& e ) {
    e.AppendContext("Passed through here");
    throw e;
}
Right
catch( MyException& e ) {
    e.AppendContext("Passed through here");
    throw;
}

8. Comments

All comments should follow the following practices:

  1. Comments should be complete sentences
  2. All comments must have a blank line before and after
  3. Comments must have a maximum of 80 characters per line
  4. All comments must be idented with the code
  5. All comments must begin with first letter capitalized
  6. All comments must be written in English
  7. Single line comments must be written with // (space) (comment)
  8. Block comments - two or more lines - shoul d begin / * followed the comment and closed with * / in new line. The content of the comment sho uld be idented in relation to bookmarks /* */.
Wrong
// Loop to iterate in the range of table
  for (i in range 0,10) {
    ...
  };
//Imprimindo a interação
  std::cout << i;
// Returns an iterator for this table.  It is the client's responsibility to delete the iterator when it is done with it, and it must not use the iterator once the GargantuanTable object on which the iterator was created has been deleted.
// Returns an iterator for this table.  It is the client's
// responsibility to delete the iterator when it is done with it,
// and it must not use the iterator once the GargantuanTable object
// on which the iterator was created has been deleted.
/*
Returns an iterator for this table.  It is the client's
responsibility to delete the iterator when it is done with it,
and it must not use the iterator once the GargantuanTable object
on which the iterator was created has been deleted.
*/
Right
  // Loop to iterate in the range of table

  for (i in range 0,10) {
    ...
      };
  // Printing the iterator

  std::cout << i;
/*
    Returns an iterator for this table.  It is the client's
    responsibility to delete the iterator when it is done with it,
    and it must not use the iterator once the GargantuanTable object
    on which the iterator was created has been deleted.
*/

9. Documentation

The documentation of the code will be done using the Doxygen tool, and the documentation of the tool itself will be used as a basis for structuring the comments of classes, methods and files.

Class Comments

All classes should be commented immediately before their declaration, following the following structure:

/// Short description about class
/**
  \class NameClass
  Detailed description of the class.
*/
Example
/// Clase for control of player commands
/**
  \class Button
  Class for communicating the player's input commands with the application
*/
class Button : public GameObject{
  ...
};

Method Comments

The methods should be commented immediately before their implemantation, following the following structure:

/**
  Description of method if necessary
  \param param_name this param is considerations about the parameter
  \param param_name_2 description this param
  \return return this method
*/

If more than one row is required to describe the function parameters, follow the following structure:

/**
  Description of method if necessary
  \param param_name
  \parblock
      First paragraph of the param description.

      Second paragraph of the param description.
  \endparblock
  \param param_name_2 description this param
  \return return this method
*/

Note: Limits, valid values and units of measure of each parameter should be described as necessary.

Example
/**
  \param id
  \parblock
      This value can not be null
  \endparblock
  \return Returns the GameObject relative to id
*/
GameObject &Scene::get_game_object(const std::string &id);

Files comments

All files must contain an initial header following the following structure:

/**
  \file nameFile.ext
  Description
*/
Example
/**
  \file scene.cpp
  Scene class implementation
*/

Variables comments

All variables must contain an description following the following structure:

  /**
    This is the description of a variable
  */
  std::string main_path;

  /**
    This is the description of a second variable
  */
  SDL_Texture *main_texture;

Notes, warnings, bugs and ToDo

Macros can be placed in comments using the \note, \warning \bug, and \tags when necessary to flag some of these situations.

/**
    \note My note about this code
    \warning this is a critical section
    \todo to implement
    \bug problem in project
*/

In the case of milestones in a specific line of code you can follow the following pattern in the comment:

    /// \note My note about this code
    scene_objects[id] = &obj;

10. Good habits

This section aims describe good habits that should be adopted on a daily basis in programmer routine for the purpose of generate code safe, clean and principally easy to maintain.

  • Follow the style sheet;
  • Prioritize clarity rather than conciseness:
  • Prioritize simple resolutions;
  • Break the code into smaller pieces;
  • Break arithmetic expressions;
  • Reduce scope
  • Protect data and internal functions;
  • Avoid using global variables;
  • Never ignore compiler warnings;
  • Use secure data structures;
  • Check all return values;
  • Fix errors received
  • Release the resources(memory, threads, files, locks...) that are no more used;
  • Initialize all variables in declaration;
  • Declare the variables as close to their use as possible;
  • Don't reuse the auxiliary variables name;
  • Don't abbreviate the names of variables, functions, classes, and constants
  • Use standard language sentences and resources.
⚠️ **GitHub.com Fallback** ⚠️