===================================
|Coding Guide Lines for Planeshift|
===================================

(a) Coding Precautions: Please follow these simple precautions to make sure
    that your code is safe.
=============================================================================


1. Test for NULL pointers:

    If you are using some function that returns a pointer to some object, 
    then make sure that the pointer returned is not NULL, before using it.

    Example:

    Don't do this:
     psserver->GetConnectionSet()->FindClient(29)->GetCharData();

    Do this:
     ConnectionSet* connSet = psserver->GetConnectionSet();
     if (!connSet)
     {
        Error1("ConnSet doesn't exist yet!");
        return;
     }
     Client* client29 = connSet->FindClient(29);
     if (client29)
        .... ... ..
    
    If a pointer must exist, and it's a serious error for it to be NULL
    at this point, use an assert instead of a regular NULL check.  The
    program will stop and the stack can be examined to find the error.

    Example:

    void class::function(gemItem * obj)
    {
        if (!obj) return;

        psItem* item = obj->GetItem();
        CS_ASSERT(item != NULL);  // All gemItems must have a psItem
        .... ... ..


2. Keep track of scope:

    // This won't do anything to obj outside of this scope
    void class::function(gemItem * obj) { obj = newptr; }

    // This will change what obj is pointed to after it's called
    void class::function(gemItem * & obj) { obj = newptr; }

    Make sure you use the one you need for each situation.  For example,
    if you delete the passed object then set the pointer to NULL, don't
    forget the '&' in the function prototype!
    

3. Avoid including many Header files:

    Please avoid using any header file into other files if there's no need 
    of it, as including many header files will considerably increase the 
    re-build time even if you change little code.

(b) Coding Convention:
======================

1. Introduction:
    Every programmer has his own coding style, however when multiple programmers are
    working on the same project it's a good idea to use a common coding style.
    Before starting with planeshift style. Like most of other coding standard
    documents I present some links to other docs at the end.
 

2. The Planeshift style:

  a) Indentation:

    -4 chars are used for indentation.
    -Tab characters are forbidden!

    -Brackets are used in the following format:

    if (foo == bar)
    {
        bar++;
    }
    PLEASE, use them also when if/else/whatever is followed just by one line of code.
    Don't using them makes the code hard to read and it is easier to create errors.

    -Lines are no longer than 78 chars unless it makes sense to keep them long
     If you have to break a line in a strange place to get it in 78 characters
     then leave it as a long line.
 

  b) Comments:

    First of all: USE THEM!! Especially when introducing new functions, code that
    is not clear, but also in every step that for you is trivial and for others might
    not be.

    -1 line comments are //

    -Multiline comments are  /* */ 

    -We use doxygen (http://www.stack.nl/~dimitri/doxygen/ ) for documenting
    classes and functions, so inside the header files you should use /// and /**
    before commenting classes/functions. (doxygen has more feature you can use
    of course, read the documentation on doxygen page for it). 
    
    Doxygen uses a system of tags to comment the code. Here is a brief example of 
    some of the more common tags.

   /** Your brief class description here, should be about 1 line and end in a period.
    * Your more detailed description is placed here where you describe the class in full
    * detail.
    */
  class MyTestClass
  {
  public:
     
  	  bool MyTestFunction( int x, int y, int& val );

      /** A simple description of the function ending in a period.
       * A more detailed description here. Can be on multiple lines. 
	   * Following we have information on the parameters and return values. 
       * Empty line between detailed description and start of param statements
       * just makes it easier to read.
	   *
	   * @param x:  Description of x
	   * @param y: Description of y
       * @param val: [CHANGES] Is set to be equal to some value.
       * @return bool Describe return state.
	   * 
	   * Additional tags for more detail.
	   * @remark Key remarks about this function.
       * @see MyTestFunction2()
       */
 
      /// A one line comment.
      void Set();

	  /** Multiline comments should look like this.
	   * 
	   */
  };

    You can also use some HTML code in the comments to do lists if needed. Lists 
	are also handled by doxygen easily using - or -# for example:

    /**

     * Following this will be a list.
     *     - List element 1
     *     - List element 2
     *         -# Numbered list 1
     *         -# Numbered list 2
     *         -# Numbered list 3
     *         .
     *         This is more text added to List element 2.
     *     - List element 3
     *     .
     */  


  c) File Organization:

    Each file should start with the following header to make licensing clear:
    (things in [] brackets are optional)

  /** Filename
   *
   * Copyright (C) 200x Atomic Blue (info@planeshift.it, http://www.atomicblue.org)
   * [ - author YourName yourSurname youremail  ]
   *
   * This program is free software; you can redistribute it and/or
   * modify it under the terms of the GNU General Public License
   * as published by the Free Software Foundation (version 2 of the License)
   * This program is distributed in the hope that it will be useful,
   * but WITHOUT ANY WARRANTY; without even the implied warranty of
   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
   * GNU General Public License for more details.
   * You should have received a copy of the GNU General Public License
   * along with this program; if not, write to the Free Software
   * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
   *
   * [short description about what is inside the file]
   */

    -Some people want to separate functions in cpp files, use the following line
    for it:

  //---------------------------------------------------------------------------


  d) Naming style:

  - Classes very tailored to the Planeshift game (not the generic engine)
    should start with a "ps" in front of their name and should use
    uppercase for each new word in them, e.g. psMyClass
  
    An exception are classes/functions that are only used internally in a .cpp
    file. For datatypes it depends, if they are big structs you should use the
    "ps"Name style.

  - Classes that deal with the gui should start with 'paws'
  
  - Functions should have a capital letter at the beginning of each word, e.g.
    MyFunction

  - Variables start with lowercases, e.g. 
    int myVariable;
    psEngine* psengine;

  - To explicitely mention it: We don't use hungarian name convention.

  - Underscores should only be used for constants
  
  - Constants and enums use ONLY capital letters, e.g. CONSTANT, PLAYER_COUNT

  - You should normally put 1 class in 1 file and name the file like the class
    in it. Ee use ONLY lower case letters (and underscores) for filenames and
    extensions are .cpp, .h and .inc, e.g.
    psmyclass.h psmyclass.cpp initcs.inc

  - Multiple classes in one source file are acceptable if the 2ndary classes
    are essentially private to the main class in the file or the data seems like
    it belongs together.


  e) Code in #defines is prohibited if that code is doing meaningful work.
     Things like declaring standard factory classes or logging error message
     expansion are fine.  Doing things with if statements and multiple C
     statements in them is not fine.


  f) Classes which have any form of persistence (db, file, network) should
     in general be responsible for marshaling their own members.  

  g) Portability Issues:
   
     Avoid to use printf or cout. Crystal Space offers several tools for 
     showing errors, therefore use them! For errors, use "ErrorN" where N
     can vary depending from the amount of arguments.
     For debug information, use "DebugN" where N depends from the amount of 
     arguments. You can check the other possible tools in /src/common/util/log.h

     Don't forget libc headers. They could be included inderectly on your
     system, for example I I can include <iostream.h> in linux and <stdio.h> is
     included inderectly by iostream.h so it compiles for me. But on other systems
     this won't work


3. Using cvs early and often:

   - For those of you with write access, if you are not committing code to
     cvs at least every day or so (on the days you work on PS), you are
     probably defining your task too broadly.  Don't interpret your task
     as "Implement new GUI system for Spells" but as "Make button which
     displays icon", "Make Spellbook Parent window", etc.

   - PLEASE, TEST YOUR CODE as much as possible before committing! At least
     test that the client can STILL connect to the server and that there are 
     no major problems!

   - After completing each step, re-update your cvs to merge everyone else's
     changes into yours, rebuild, make sure there are no problems and commit
     your step with a note in the history about the step and what the next
     steps are until you are finished your task.  If something is partially
     completed and will not work right if someone tries it, don't let that
     stop you from committing the part that does work.  Just note in history.txt
     what NOT to try.
  
   - If what are you committing is a fix for a bug in the bugtracker, specify
     in the history.txt the number of the bug and briefly, what was the bug about.

   - Write as many comments as possibile: what it is obvious to you might be
     unclear for some body else and it can become really hard to solve problems
     if you are not available if the code is hard to understand!


4. Implementing coding style in Vim:

   Here are some tips to automate some things from the coding style above:

  a) unix with vim
  - make 2 template files with the general header in them
  - Setup your vimrc to automate indentation (this is only a part of my vim
    configuration that covers indentation and syntax highlighting)

set nocompatible  
autocmd FileType cpp	call PSStyle()
autocmd FileType h	call PSStyle()
autocmd FileType inc	call PSStyle()
  
function PSStyle()
    set cindent
    set shiftwidth=4
    set tabstop=8
    set softtabstop=4
    set textwith=78
    so ${VIMRUNTIME}/syntax/syntax.vim
endfunction

filetype on


5 Some other coding styles:

    http://pcroot.cern.ch/TaligentDocs/TaligentOnline/DocumentRoot/1.0/Docs/books/WM/WM_3.html
        This is a complicated document, while some general advises are good, the
        naming convention are just another braindamaged thing like the old
        hungarian name conventions...

    http://www.gnu.org/prep/standards_toc.html
        This also covers more than indentation and naming. I personally like the
        this style as it's succesfull used in LOTS of projects howevere the
        authors don't like c++ :(, and the document enforces you a bit too lot I
        think (style for a changelog?!?)

    http://developer.gnome.org/doc/guides/programming-guidelines/book1.html
        Some more general advices and nearly some indentation/naming style as
        gnu uses

    http://purists.org/linux/
        To present something different to gnu, here's linus view of coding style
        , also a good read, you should especially look at the "functions" and
        "commenting" sections.

    http://crystal.sourceforge.net/docs/online/manual/cs_263.html#SEC619
        The style of Crystal Space our 3d engine. We're using their naming
        conventions as it's the only way not to end up with 2 naming styles in
        our application. Howevere we use another indentation style and change
        some other things.

    Compared with all these docs the planeshift coding convention is poor and lets
    you much room, if you have more questions/additions feel free to contact Planeshift
    team on IRC:
    
    irc.freenode.net, channel #planeshift-build

