★ wanayoo — archive 1999 http://www.cgsoftware.com/BeOS/Tools/Style.htmlNouvelle recherche | Portail wanayoo

Style Conventions For the Deco Project


Overview


The following is the documentation for the conventions that we are going to be followed as the Deco team. We have scratched our heads for hours trying to come up with compelling reasoning behind why we like our code to have the format it does. So far the reasoning we have come up with is we just like it this way. Nothing more nothing less. We have broken the language (sounds worse that it really is), and the soon to be framework, DCL, into classes, sections each containing a few sub sections. The sub sections include code format, variable-naming conventions

One of our primary goals it to write code that is readable. So if for some reason something is just not readable by using our naming conventions or style then throw out what we say and write readable code. Although I seriousely doubt that code is any more readable any other way, this is the best coding style. I guarantee.

Outline


Naming Conventions


Code Structure


Comment Style



Naming Conventions


All code written in the DCL follows some sort of naming convention. When writing this document we sat down for hours to come up with reasons behind why we code the way we do. And of course we all comprimised to come up with this list.


Classes


The naming convention for classes is to precede the name of your class with a the letter 'T' and use mixed case:

class TMyClass

class TSomeLameClass



Functions/Member Functions


All function names are mixed case and start with a capital letter:

void DoSomething();

void LoadFromFile();

void SaveToFile();

Functions that are not setter/getters should do something, and therefore have verb names, like DecodeAudio() or EatTheVegetables().

Functions that are setter/getters should have noun names and use the single overloaded name convention, i.e.: void Color(rgb_color SetColor), rgb_color Color().

The Exception to this is getter/setters should never be re-named, this usually happens when deriving from a class in the BeOS kits, such as BControl::IsEnabled() and BControl::SetEnabled(). You would not try and create your own Enabled() pair.

Arguments passed into fucntions should be Upper and Lower case mixed names, just like function names, this helps them be differentiated from local variables and 'Fields', ie:

 
void TSpiffyControl::IncreaseSpiffyness(int8 SpiffAmount, char* SpiffMoniker) 
{ 
 ... 
}


Fields


Fields are class variables. They are usually private.

These 'fields' should have descriptive names, use upper and lowercase letters to break up words and must be pre-pended with an 'F' to differentiate them from other variables:



vector<TSomeClass*> FSomeClassVec;
int64               FSomeHugeValue;


It is also advisable to line up the variables for ease of reading.


Properties and Events


The Object Inspector shows what are called Properties and Events.

Properties need to be named with a noun, i.e.: Position, Left or FollowsText.

Event handlers are verbs that happen at a certain time and are usually prefixed with 'On', i.e.: OnOpen, OnAnimate or OnCreate.


Local Variables


Local variables are in all lower case:

int i;
BRect rect;

for (i = 0; i < 1 ; i++)
{
   rect.top = i;
}

There has been a movement among the group to have longer local variables have the logical names be broken up with capitals, ie:

int myLongNamedLocalVariableInteger;
	


Global Variables


Global variables should be use as infrequently as possible, so we have made them as ugly as possible. Global variables begin with an underscore and have mixed underscores between the words that make up the variable:

const int _this_is_my_global_variable = 100

Enumerations


Enumeration names are done exactly like classes, after all they are just another type. The data names of an enumerated type have an odd naming convention, They are preceded with the first two capital letters of the type name (excluding the 'T'. We wanted it to be clear what type of enumeration is being used, so that is why we do the following: If I have an enumerated type called TCodeStyle and there are three data names called Keyword, Comment, and Code, then the enumerated type would be defined as:

enum TCodeStyle = {csKeyword, csComment, csCode};

Typedefs


Typedefs follow the rules of the underlying type. For example, if it were a class you were typedefing, your typedef would be identical to the classes naming convention:

typedef TMyClass TCool;

Macros


Macros must be in all capital letters. For example:

#define MYCREATEWINDOW CreateWindow

Defines


Defines are simular to macros, but to distinguish them #defines use underscores between the words making up the define:

#define MY_DEFINE 100

Includes


Includes cover a few different issues. First is the naming convention of files. It has been decided that we like case sensitivity of UNIX based operating systems, so we want to use it to its fullest. Therefore, files should be named MyFile.h and MyFile.cpp. Second, we don't like the new C++ style of naming header files with a .hpp. We much prefere the old way of naming C header files as .h.


Code Structure


This can be a touchy topic for some people. Everyone seems to have their own style, for good reason (usually), and they stick to it. Others could care less and use whatever style they feel like that day. This section is to provide users of Deco a common format. Of course you don't have to use this format, but our tools use it by default. This may change in the future, but currently don't count on it.

#include Structure


#includes should be listed from the top to the bottom in incresingly specific scope, that is:

The top section should be only generic C/C++ header includes.


#include <stdio.h> 
#include <stdlib.h> 
...

Then go with the generic C++ stuff, ie:


#include <cpp/vector> 
#include <cpp/map> 
... 

Then the BeOS "C" type stuff:


#include <be/kernal/fs_attr.h> 
... 

Then the BeOS C++ kits stuff:


#include <be/interface/View.h> 
#include <be/storage/File.h>
...

Then project specific includes:


#include "ProjectDefs.h" 
#include "ThatOtherView.h"
...

Then last, but not least, the header for that .cpp module:


#include "ThisClassesHeader.h" 

The subpath below boot/develop/headers/ should be included in the include as well, this helps to speed up compile times a bit.


Tabbing


Tabs should be 3 spaces, tab characters are to be avoided.

Curly Braces


Curly braces are to be lined up vertically. Asymmetric alignment of curly braces is a no-no.

Do this:


if (0 == something)
{
	if ("dave" == FName)
	{
	
	}
}
else
{

}

Not this:


if (0 == something) {
	if ("dave" == FName) {
	
	}
} else {

}



Case Statements


Case statements are another one of those things that is just religiousely adhered to. The format of case statements in Deco uses is as follows:

//------------------------------------------------------------------------------
String Flop(int Value)
{
   // ToDo: switch according to value.
   switch (Value)
   {
   case FLOP_IT:
      return "To Flop or Not to Flop.";
   case FLOP_ME:
      return "One never Flops.";
   case FLOP_YOU:
      return "That is offensive, please refrain yourself.";
   }

   return "I have nothing to say to you.";
}


Classes


Classes are here it's all at man!

Classes should have the following general form:

class TSuperKeenClass : public TSomething
{
private:
	TAggregate* FThatAggregate;
	int64       FBigNumber;
	
protected:
	bool        FUsefulState;

public:
	                    TSuperKeenClass();
	                    ~TSuperKeenClass();
	
	virtual void        GenerateCoolApplication();
	        TAggregate* Aggregate();
};

This may look up-side down, but it actually seems better after you get used to it.

Variable names should be lined up, as should Function names, but not necessarily with eachother.


Member Functions


Member functions int the header are described in the section above, in the .cpp they should be in the same order as the .h

Member functions should also be separated by comment lines thusly :



#include "SuperKeenClass.h"

//------------------------------------------------------------------------------
TSuperKeenClass::TSuperKeenClass()
{
...
}
//------------------------------------------------------------------------------
TSuperKeenClass::~TSuperKeenClass()
{
...
}
//------------------------------------------------------------------------------
void TSuperKeenClass::GenerateCoolApplication()
{
...
}
//------------------------------------------------------------------------------


Code in the functions should be wrapped so that it fits in the comment line widths, this is usually about 80 characters, but may be more if necessary.


Inline Functions


Inline functions carry a soft place in our hearts. If written poorly they can be very difficult to read. If done correctly they can be very easy to read. We prefere to do them correctly. Here are the rules behind having inline functions in your classes:

1. If the line of code extends beyone 80 characters, then re-think how the code is formated. For example (this might not look very good because some bowseres may wrap the line):

//------------------------------------------------------------------------------
// These two lines are 80 characters
//------------------------------------------------------------------------------
class TFido
{
public:
   void FunctionName(int SomeValue, String Some String, float SomeFloatNumber) { return SomeFunction(); }
};

It is much nicer to see:

//------------------------------------------------------------------------------
class TFido
{
public:
   void FunctionName(int SomeValue, String SomeString,
                     float SomeFloatNumber) { return SomeFunction(); }
};

Or, even better:

//------------------------------------------------------------------------------
class TFido
{
public:
   void FunctionName(int SomeValue, String SomeString, float SomeFloatNumber)
   {
      return SomeFunction();
   }
};
2. If your inline functions become messy after following part (1), then remove your function from being inline, place the declaration in the header file and put the keyword inline in front of it. For example:
//------------------------------------------------------------------------------
class TFido
{
public:
   void FunctionName(int SomeValue, String SomeString
                     float SomeFloatNumber);
};
// ... inline void TFido::FunctionName(int SomeValue, String SomeString, float SomeFloatNumber) { // ... }


Copyright © 1999 Deco Team -- Last Modified August 17, 1999