-----------------
Coding Guidelines
-----------------

----------
Introduction
----------

Coding guidelines make it easier to work with other persons code as the code 
will look similar independent of the author.

The most basic rule is "Make it look like existing code". So if you modify a file, just look
on the used style and use the same. 

Note that libraries used in a project can have a different style than the project itself. The most 
basic rule also applies for those. So do not impose the project style on the libraries, but try
to keep the original style of the corresponding library whenever you have to write patches for them.

Also in general - just make it readable. Readability is more important than fast typing.

----------
Computer Languages
----------
This guideline expect application code to be written in C++.
If you use another language you will need another guideline.

Note that there _are_ other languages in use, but usually not for
application code. Websites, tools and the build-system all might use different
languages.

Also libraries are often written in c instead of c++.

----------
File format
----------
Encoding is UTF-8.
TAB size is: 4 
TAB characters are used
End-of-line mode: CR LR (...also on unix! Your editor can do that...)
Expect that trailing blanks will be stripped
All files must end with a blank line.

----------
File names
----------
c source files end in .c
c header files end in .h
c++ source files end in .cpp
c++ header files end in .h

Filennames must be telling what they contain.

Filenames must use lower-case throughout.
(NOTE: right now there are a few exceptions, but only for historical reasons)
Filename example: gui_menu_main.cpp

Filenames must be in english.

----------
Architecture
----------
Prefer enums to constants.
Prefer constants to defines.
Prefer defines to magic numbers.
Don't use magic numbers without comment.

Also always consider using enums instead of 'int' or 'bool' parameters.

Prefer to use one file per class. This is not an absolute rule, so
it is OK to put small helper classes into the same file as a larger class
needing those helpers. But never put independent classes into the same source or header files.

Never pollute the global namespace. So if you see a "using namespace" line in a header then someone did it wrong.

Do not use globals unless absolutely necessary. Right now there should only be 2 globals - one for logging 
and one for the application class. The latter is actually already one too much and wouldn't really be needed.

Functions should be short. 
Classes should be small.
There is no too short or too small.

Do not optimize before you profile.
Be afraid of micro-optimizations, they are nearly never worth it.
But also be aware that games have hard realtime constrains and should run with at least 30 frames per second.

Headers only contain includes they need themself.
Always prefer forward declarations to using includes even if it's not strictly necessary in a case.
Project includes should be before library includes which should be before standard library includes.
Use the c++ standard library headers not the c-lib headers.
For example <cstdlib and <cmath> instead of <stdlib.h> and <math.h>

Care about const correctness. 
This is still far from perfect in existing code. Changing existing code to improve const-correctness is fine.

And just mentioned here because c++ guys tend to overshoot sometimes on that: 
Be wary of replacing signed types with unsigned types. It is not that much cleaner as you might think it is and
you really don't get that much more of a number range. If X is not enough then usually 2X is also not enough. 
So often it is better use a larger signed type. Signed types are better in catching overflows, easier to use for
error-handling and might even be your only choice in communicating with modules written in other computer languages.

Text-strings that are displayed to the user have to use string-tables for internationalization.

Configuration by file is better than configuration in code.
Configuration by an external class is better than configuration within the class.

All headers must use header guards. Adding #pragma once is not sufficient (sorry), although adding it additionally is acceptable.
The reason is that the main compiler used is g++ which for whatever reason still works faster with header guards.

----------
Class-, function and variable names 
----------
Names should be telling. Which means whole words and rather descriptive than short.
If you have the choice between a short word and a long word you should prefer the short one.
The exception are counters used in loops, which can be single characters, typically 'i' is used.
Also obvious local helper variables can be single character.

All names are using camelcase. 
Example: ThisIsCamelCase, thisAlsoIsCamelCase, mAndAlsoThisOne

Do _not_ use hungarian notation (99% of coders used it wrong anyway).
Examples for a wrong names: pObjectWithInvalidName, bFlagWithInvalidName

Struct/class names, function names and member function names all start with an upper-case letter. 
(The reason is that this is commmonly used c++ practice to distinguish own 
classes from the standard library classes and functions)
Example: IrrlichtManager, HelperFunction, Config::Init

Interface classes should use an additional I as first character.
Example: IEntity, IComponent

Do _not_ start all other classes with C. Also no need to start structs with S.
Example for a wrong names: CCanYouStopThatPlease, SStopDoingThatPlease

You should start enums with an E as well in the enum itself as in it's members.
As enum members are often in the global namespace it's also useful giving them 
even further prefixes to ensure the names are unique. Using the first characters
of the camel-case name of the enum is a typical used trick for this.
Example: enum ECountThisStuff { ECTS_ZERO, ECTS_ONE };

You may use additional prefixes to group classes sometimes. Although you also should consider
using namespaces in such situations. Separating the prefix with an underscore is appreciated.
Example (for championship classes): CS_RaceType, CS_RaceResult.

Member variables start with a small m and continue with camel-case.
Example: 
struct X { bool mFlaggingSomething; }

Local variables and function parameters start with a lower case character.
Example:
void Foo( int param, bool importantFlag, char * name)
{
    int doingStuff;
}
Note: You will still find many function parameters using an underscore at the end. 
Like: void Foo(int myParam_) {}
This has historical reasons, as I did distinguish function parameters from local parameters
that way in the past. After experimenting with both styles I think it isn't really worth it.
So if you modify a function still using that style, it's up to you if you want to remove 
the underscore or keep it.

Names must be in english.

----------
Other style considerations
----------
Each command should be in an own line. 
So do not put the command after an if in the same line as the if.
The only exception to this rule is when you have a lot of nearly repeating code which obviously 
improves by breaking this rule. To decide if you have such a case is up to your tastes.

Brackets use the Allman style (also sometimes called ANSI style). They start in an own line and with the same 
indention as the code.
Example:
void Foo()
{
    int stuff=99;
    for (int i=0; i < stuff; ++i )
    {
        std::cout << i << std::endl;
    }
}

Prefer using brackets even for single line commands following if's. (Yes, it's not needed, but just do it).

Do not be afraid of white-space and new-lines. Use it to make code more readable.
So use it to align member-variables. Use it to align comments. Use it to break up long formulas into logical chunks. 
Use it to group lines of code. Use it to seperate commands and parameters. 
How exactly you do that is basically up to your tastes.

Don't make lines too long. We don't care about 80 characters anymore and there is no fixed limit. 
But once you get past ~120-140 characters you should really start breaking the line into 2 lines.

Do use at least one space after commas in parameters and also after semicolons in for loops.
Examples: void Foo(int param1, int params2); // <--- good, bad ---> void Foo(int param1,int params2);
          for ( int x=0; x < 10; ++x ) // <--- good, also ok: for(int x=0; x<10; ++x) but bad: for(int x=0;x<10;++x)


----------
Other libraries
----------
Using the standard c++ library is always the primary choice by default.
So even if you have another library offering the same functionality, you should use
the standard library functions in application code when possible.
For example the Irrlicht library will offer string, array and list classes. Do not use
them unless you have to (which is usually only the case if they are used as parameters).

Adding any new libraries always must be discussed first.

Criteria for new libraries are
- cross-platform: Especially Windows, Linux, MacOSC. But also consider consoles and mobile phone platforms.
- openness: Prefered licenses are zlib, boost or public domain. Next come licenses which insist on adding credits
            like BSD or jpeg. Next comes the LGPL (not GPL!) license, but don't use it for critical infrastructure 
            as it can conflict with console development. Using it for features, like for sound, is ok if
            there is some way to exchange such a lib without too much trouble if a port to console comes up. 
            Lastly proprietary licenses might be considered if no alternatives are available.
            GPL may only be used in tools and even there should rather be avoided if possible (sorry).
- standard: Prefer standard libraries to custom solution. Prefer well-known libraries to unknown libraries. 

If you must patch a library, be careful to document the patch.
To do this you use a text-file (usually called patches.txt) which contains a description of each patch.
Preferably also create a patch-file for each patch (using Mercurial it would theoretically be good enough 
to document the change-version, but having the patch file around turned out to be a good reminder of open patches).
This is needed (and very important) to help updating to newer Library versions. Once the patch makes it into 
the corresponding official library sources it can be deleted.

----------
Documentation
----------
All documentation and all sources must be in english.

For now all project documenation is in the "doc" folder.

Source documentation should be helpful not noisy. Good names are the most important part.
If something is not obvious from reading code alone, do add a comment.

Do mention your sources of information. If you start with code from the web, try to figure out it's license.
Mention that. Mention the original author. If you change the file, mention you changed it and that
this is not longer the original code you found. Same if you start with an algorithm you did not 
think up yourself. Document which algorithm it is and if it has an author then do mention that author.
