CHaMUE_2 Coding Guidelines
Author: Young Shon
Date: 11/6/03
This document covers CHaMUE_2 coding policies, coding standard and useful tips. If you have any questions, feel free to contact Young Shon
Sections
Adding your library to the CHaMUE_2 project
Writing your own code (coding standards)
Reporting your work to team members
If you have just joined the lab, your account in kingkong has been setup, you need to check out the CHaMUE_2 code, which is being under CVS. For setting up CVS, see the CVS section of the lab orientation page. After finishing CVS setup, run "cvs checkout CHaMUE_2" or "cvs co CHaMUE_2". If you have already checked out CHaMUE_2 before and want to get the latest code, run "cvs update -d -P".The options "-d" and "-P" cause cvs update to 'P'rune empty directories and create new 'd'irectories.
Tip: After downloading the CHaMUE_2 code from CVS to your kingking account, copy all the files to a local machine you are working in. Modifying and compiling codes stored on kingkong is really slow.
Adding your library to the CHaMUE_2 project
Add a new library to CHaMUE_2
Set directories for new source files and output files
Link your library to CHaMUE_2
Check-in to CVS
CHaMUE_2 is broken down into a set of libraries and the main project based on MFC (Microsoft Foundation Classes), each of which has a unified concept. Some of them naturally build on others, some of them stand alone. For example, the "CHaMUE_2" main project is a module controlling and providing basic functionality associated with the creation of windows, drawing on the windows and MFC message handling. The "CHaMUEBary" project deals with generation of poly-lines, which are used to annotate CAD models. The "Math" project provides basic math functions such as matrix multiplication and vector operations. The "HCollide" project handles a different data structure of meshes for fast collision detection.
To keep such modularity, if your work does not fall clearly under any existing
projects, make a new project for your work and add it to the CHaMUE_2 main workspace.
In order to add your new project to the CHaMUE_2 main project, go to the "project"
menu on the main pull-down menu bar and then "Add to Project->New"
and choose either "Win32 Static Library" or "Win32 Dynamic Linking
Library" on "project" tab. Make sure that you choose "add
to current workspace" radio button on the tab and set "dependency
of" to the CHaMUE_2 main project. (By this you can save your effort of
switching back and forth between the projects when you make a change in your
project and compile the whole CHaMUE_2 project). If your project needs two or
more modules to depend on, see set dependencies. Don't
change the default location.

When you click "OK", the next dialog box will ask whether you will use "Pre-compiled header" and "MFC". If you would like to use MFCs and functions based on them, check "MFC support". For quick compiling, check " use Pre-compiled header".

Set directories for new source files and output files
Our policies on file locations are the following.
To confirm to the policies, you need to make "src" and "include" folder under CHaMUE_2\project_name and copy or add .cpp and .h files to the corresponding directory. To locate .lib, which is the output of your project (mostly), in the CHaMUE_2\lib folder, go to "project"-> "settings" and select your project on the left pane. On the right pane, go to "Libraries" tab and put "..\lib\new_project.lib" in the "output file name" edit box.

Select "CHaMUE_2" on the left pane of the Project settings dialog box. Go to "link" tab on the right pane and put your lib name in the "object/library modules" edit box.
If your library needs two or more other libraries for compiling, you need to set the dependencies. Go to "project" menu ->"dependencies" and check every libraries you need for your library. For example, if your library needs math and H-Collide, you need to check math and HCollide in the "depend on the following project(s)" box in the project dependecies dialog window.

After your work is done, you need to commit your work to CVS. Before committing your libraries or codes, you always should do "cvs update" to make sure that you have all the latest changes and compile and test after the update. Also you should always test your code on both types of PHANToMs (PHANToM Premium 3.0L, the big arm mounted on Immersadesk, PHANToM Desktop, two small ones on the desks).
Only .cpp, .h, .dsp and .txt (for documentation of your work and the configuration file-only when you add new entries, for more info see the "avoid hardcoding" section in the coding standards) files need to be committed. Without executing "cvs add", your work is not to be committed to CVS by simply doing"cvs commit". Therefore, follow the procedure described below.
After you put your directory and files under CHaMUE_2 in your kingkong account, you need to let CVS know that you have new directories by "cvs add project_name", "cvs add project_name/src", "cvs add project_name/include" and other directories you created. After creating all necessary directories, add your files by "cvs add filename" from the directories. If you have plenty of files to check in, use wildcard *, like "cvs add project_name/src/*.cpp". Finally do "cvs commit" to check in. While you are committing, CVS will invoke the editor that you have set for log files. Always add a descriptive comment about your changes in the log files with the editor. You need to report your changes to other team members via e-mail in the same format as the log files. For more intruction on reporting, see reporting your work to team members
For more information about CVS, see http://www.me.berkeley.edu/~mcmains/cvs.txt
Writing your code (CHaMUE_2 coding standards)
About this Standard - This standard was primarily composed from http://www.possibility.com/Cpp/CppCodingStandard.html and due credit is given.
One Statement Per Line
There should be only one statement per line.
Don't Over Use Operators
C++ allows the overloading of all kinds of weird operators. Unless you are building a class directly related to math there are very few operators you should override. Only override an operator when the semantics will be clear to users.
Justification:
· Very few people will have the same intuition as you about what a particular operator will do.
No Magic Numbers
A magic number is a bare-naked number used in source code. It's magic because no one has a clue what it means including the author inside 3 months.
Example:
from old CHaMUE
camera.setScreenParams(820.0, 630.0);
camera.setEyeSep(63);
In the above example what does 820.0, 630.0 and 63 mean? If there was a number change or the numbers were just plain wrong how would you know? Instead of magic numbers use a real name that means something. You can use constants, enums, and variables as names. Which one is a design choice.
Example
const float immersadeskScreenWidth= 820;
const float immersadeskScreenHeight= 630;
const float averageHumanIPD= 63;
A Line Should Not Exceed 80 Characters
· Lines should not exceed 80 characters.
Justification:
· Even though with big monitors we stretch windows wide our printers can only print so wide. And we still need to print code.
· The wider the window the fewer windows we can have on a screen. More windows == better than wider windows.
Usually Avoid Embedded Assignments
Using embedded assignment statements to improve run-time performance is possible. However, one should consider the tradeoff between increased speed and decreased maintainability that results when embedded assignments are used in artificial places.
Example:
a = b + c;
d = a + r;
should not be replaced by,
d = (a = b + c) + r;
even though the latter may save one cycle. In the long run the time difference between the two will decrease as the optimizer gains maturity, while the difference in ease of maintenance will increase as the human memory of what's going on in the latter piece of code begins to fade.
Initialize all Variables
· You shall always initialize variables. Always. Every time.
· You shall initialize structs before use.
Justification:
· More problems than you can believe are eventually traced back to a pointer, variable, or struct left uninitialized.
Global Variables
In general, you shouldnt be using globals. One of the design principles of CHaMUE_2 is that it should have as small number of global variables as possible: there are only handful of global variables in CHaMUE_2. But when you really need to use global variables follow the guideline below:
· Global variables prefixed with 'g' in Hungarian notation.
Example:
int giBadGlobalBadBadBad;
Justification:
· It's important to know the scope of a variable.
In order to to make the program more flexible to different hardware configurations and modification easier, avoid hardcoding as much as possible. Varibables associated with hardware setting such as the size of the bounding box, the location of the transmitter for head tracking and the type of the current coordinate system, should not be hardcoded. If you decide to add such hardware dependent variables or some variables that should not be hardcoded, you need to add entries to Config1.txt file (under the config directory) and write additional code to read the new entries (usually reading is done by CConfigInfo::ReadInformation() in CConfigInfo.cpp). Unless you are adding new entries and values to the config file, don't check in changes to it.
Example:
The following entries
TRANSMITTER: LEFT
CONSOLE: ON
(in config1.txt)
are read in
else if (strcmp(buffer2, "TRANSMITTER:") == 0) {
if (strcmp(inputValue, "RIGHT") == 0) {
TransmitterOnLeft = FALSE;
} else {
TransmitterOnLeft = TRUE;
}
in CConfigInfo::ReadInformation()
Use Header File Guards
Include files should protect against multiple inclusion through the use of guards:
#ifndef __CLASSNAME_H__
#define CLASSNAME_H__
#endif // CLASSNAME_H__
· Replace ClassName with the name of the class contained in the file. Use the exact class name.
· Most standards put a leading _ and trailing _. This is no longer valid as the C++ standard reserves leading _ to compiler writers.
· When the include file is not for a class then the file name should be used as the guard name.
Macros
Don't use macros that can be replaced by inline functions. The only situation we need macros is when we want conditional compiling. For example, if you want to compile the whole program with H-Collide, define a macro "#define USING_HCOLLIDE" in CHaMUE2define.h file in CHaMUE2/include directory. The macros for conditional compiling should be defined in CHaMUE2define.h file (under CHaMUE2/include) whatever project you are working on. Consequently if you are using macros for projects other than CHaMUE_2 main project, you need to include the CHaMUE2define.h file by adding #include "..\..\include\CHaMUE2define.h" in the Stdafx.h file of the project. Note that "..\..\include\CHaMUE2define.h" can be different depending on the location of stdafx.h. (However, if you followed all the standard and guidelines, the path should be "..\..\include\CHaMUE2define.h")
Always Put #ifdef/#endif Directives before/after Printing Functions
Printing to the console window is an expensive operation. Unless you want to watch the values of variables, you may not need the printing function. In order to turn off printing function by undefining "PRINT_TO_CONSOLE", you need to put #ifdef PRINT_TO_CONSOLE and #endif before and after the printing functions respectively. Note that you can also turn off all the printing by setting "CONSOLE" to "OFF" in config1.txt file.
Reporting your work to team members
After committing your changes to CVS, you must report your changes
to other team members via e-mail. Our group mail address is
.
The report should contain the following:
The date and time of check-in
The description of changes
The name of files where you made changes
The file version info.
Tip: One way of doing this easily is, after you are adding descriptive comments on log files on committing you codes, to copy the comments, version, date and time info from the log files and paste them to the e-mail.
Example:
CHaMUE_2View.cpp
revision 1.19
date: 2003/11/01 23:43:51; author: koz; state: Exp; lines: +62 -51
Added Extension of Phantom and expanded the configuration file to include viewing
parameters
----------------------------
CExtPhantom.cpp
revision 1.1
date: 2003/11/01 23:43:51; author: koz; state: Exp;
Added Extension of Phantom and expanded the configuration file to include viewing
parameters
=============================================================================