FARSIGHT DevelopersGuide
m (→Document Overview) |
m (→File organization) |
||
Line 157: | Line 157: | ||
with the rest of the system, and to avoid cyclic dependencies. The | with the rest of the system, and to avoid cyclic dependencies. The | ||
FARSIGHT source directory structure is divided into several directories below | FARSIGHT source directory structure is divided into several directories below | ||
− | + | ''FARSIGHT''. Please consult the FARSIGHT team before creating any new | |
directories with FARSIGHT. Directories containing source are arranged as | directories with FARSIGHT. Directories containing source are arranged as | ||
follows: | follows: |
Revision as of 17:52, 17 January 2012
Back to FARSIGHT_Tutorials
Purpose
The following document is a description of the accepted coding style for the FARSIGHT Toolkit. Developers who wish to contribute code to FARSIGHT should read and adhere to the standards described here.
Document Overview
This document is organized into the following sections.
- System Overview & Philosophy --- coding methodologies and motivation for the resulting style.
- Copyright --- the copyright header to be included in all files and other copyright issues.
- File organization --- how to organize source code.
- Naming conventions --- patterns used to name classes, variables, template parameters, and instance variables.
- Namespaces --- the use of namespaces.
- Code Layout and Indentation --- accepted standards for arranging code including indentation style.
- Exception Handling --- how to add exception handling to the system.
- Documentation Style --- a brief section describing the documentation philosophy used within FARSIGHT.
This style guide is an evolving document. Please confer with the FARSIGHT development team if you wish to add, modify, or delete the rules described in these guidelines.
Sign up to use FARSIGHT communication tools
In addition to having SVN write access to the FARSIGHT repository, all developers should be subscribed to the following FARSIGHT communication tools:
Style Guidelines
The following coding-style guidelines are to be used in development of the FARSIGHT Toolkit. To a large extent these guidelines are a result of the fundamental architectural and implementation decisions made early in the FARSIGHT project. For example, the decision was made to implement FARSIGHT with a C++ core using principles of generic programming, so the rules are oriented towards this style of implementation. Some guidelines are relatively arbitrary, such as indentation levels and style. However, an attempt was made to find coding styles consistent with accepted practices. The point is to adhere to a common style to assist developers and users of the future learn, use, maintain, and extend the FARSIGHT Toolkit.
Please do your best to be a upstanding member of the FARSIGHT team. The rules described here have been developed with the team as a whole in mind. If you consistently violate these rules you will likely be harassed mercilessly, first privately and then publicly. If this does not result in correct code layout, your right to SVN write access (if you are developer and wish to contribute code) may be removed. Similarly, if you wish to contribute code and are not a developer, your code will not be accepted until the style is consistent with these guidelines.
System Overview & Philosophy
The following implementation strategies have been adopted by the FARSIGHT team. These directly and indirectly affect the resulting code style. Understanding these strategies motivate the reasons for many of the style guidelines described in this document.
Implementation Language
The core implementation language is C++. C++ was chosen for its flexibility, performance, and familiarity to team members. The FARSIGHT toolkit uses the full spectrum of C++ features including const and volatile correctness, namespaces, partial template specialization, operator overloading, traits, and iterators.
Generic Programming and the STL
Compile-time binding using methods of generic programming and template instantiation is the preferred implementation style. This approach has demonstrated its ability to create efficient, flexible code. Use of the STL (Standard Template Library) is encouraged. In contrast with many libraries, STL containers are the acceptable for passing collections of data between public and private member functions. The STL is typically use by a class, rather than as serving as a base class for derivation of FARSIGHT classes.
Caveats:
- If you have sections of code that are executed millions of time and you want to parallelize, do not use the STL library functions (std::vector... etc) as they are NOT THREAD-SAFE.
- Do not use a template to write functions in your programs that only ever accept 1 data-type. It is poor form because it results in code that is highly unmaintainable because the person reading the template will now have to read your entire program to figure out what data-types could potentially be passed into the template
Portability
Most FARSIGHT applications as well as the core of the toolkit are designed to compile on a set of target operating system/compiler combinations. These combinations are:
- Windows XP with Microsoft Visual C++ (Released within the past 5 years.)
- Linux with GCC
- Mac OSX 10.4 (Tiger) and 10.5 (Leopard) with GCC
- Other *nix systems with GCC
Some FARSIGHT applications and modules make use of specific GPU configurations to optimize certain calculations. These vary according to system, but there shall always be an unoptimized implementation that will comply to the above portablity standards.
VTK and ITK Based
FARSIGHT makes extensive use of both the Visualization Toolkit (VTK) and the Insight Toolkit (ITK). Image processing features added to FARSIGHT should prefer ITK constructs over those of VTK. When visualization-geared code is written for FARSIGHT, VTK should be favored. All FARSIGHT code is considered proprietary for the duration of the AFRL project at which point all VTK and ITK classes will be reviewed for possible contribution to the community.
Qt as the GUI Framework
Another strength of FARSIGHT is the ease of assembling applications with fully-featured Graphical User Interfaces (GUIs). This is done by using and extending Qt classes to created widgets unique to the FARSIGHT toolkit. Any FARSIGHT widget is expected to have a corresponding plugin such that the majority of the user interface can be built in the Qt Designer.
CMake Build Environment
The FARSIGHT build environment is CMake. CMake is an open-source, advanced cross-platform build system that enables developers to write simple ``makefiles (named CMakeLists.txt) that are processed to generated native build tools for a particular operating system/compiler combinations. See the CMake web pages at http://www.cmake.org for more information.
Tool and Library Versions
Because of the agile nature of FARSIGHT toolkit developement, the FARSIGHT team uses the latest developement versions of VTK, ITK, Slicer3, and CMake along with the latest stable version of Qt. This becomes an unrealistic requirement for outside developers; thus, each FARSIGHT release will require a specific version of the listed libraries and tools.
These are the most important factors influencing the coding style found in Insight. Now we will look at the details.
Copyright
FARSIGHT is an open-source product. This copyright should be placed at the head of every source code file. The current copyright reads as follows:
/*========================================================================= Program: FARSIGHT Module: $RCSfile: config.h,v $ Copyright (c)
FIXME
IN NO EVENT SHALL THE AUTHORS OR DISTRIBUTORS BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OF THIS SOFTWARE, ITS DOCUMENTATION, OR ANY DERIVATIVES THEREOF, EVEN IF THE AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. THE AUTHORS AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT. THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. =========================================================================*/
This header is available at the top level of FARSIGHT in the file Header.txt
File organization
Classes are created and organized into a single class per file set. A file set consists of .h header file, .cxx implementation file, and/or a .txx templated implementation file. Helper classes may also be defined in the file set, typically these are not visible to the system at large, or placed into a special namespace.
Source files must be placed in the correct directory for logical consistency with the rest of the system, and to avoid cyclic dependencies. The FARSIGHT source directory structure is divided into several directories below FARSIGHT. Please consult the FARSIGHT team before creating any new directories with FARSIGHT. Directories containing source are arranged as follows:
FARSIGHT/Application
Applications consists of subdirectories for each FARSIGHT application. Experimental Applications should be placed in the Experimental folder, and no application should depend upon another in any way.
FARSIGHT/Core
Code should contain no Qt-based code and consists of the following sub-directories:
- IO --- Reading/writing files from disk or databases
- Numerics --- core numeric functions and classes (Functions and Calculators)
- Common --- core classes to FARSIGHT including the VisualObject and Scene classes (mav Nodes)
- BasicFilters --- common image processing and mesh algorithms (Filters)
Dependencies
PUT FIGURE HERE
FARSIGHT/Examples
Examples contains subdirectories for various examples. When adding a fairly complex widget or feature to FARSIGHT, you are encouraged to add an example that exhibits its behavior. Examples are a lot more useful than conventional documentation in the eyes of many developers.
FARSIGHT/Libs
Libs consists of the following subdirectories:
. . .
Naming conventions
In general,
- names are constructed by using case change to indicate separate words, as in TimeStamp (versus Time_Stamp). Underscores are not used.
- Variable names are chosen carefully with the intention to convey the meaning behind the code.
- Names are generally spelled out; use of abbreviations is discouraged. (Abbreviation are allowable when in common use, and should be in uppercase as in RGB.) While this does result in long names, it self-documents the code. If you learn how to use name completion in your editor (e.g., vim), this inconvenience can be minimized. Depending on whether the name is a class, file, variable, or other name, variations on this theme are explained in the following subsections.
Naming Classes
Classes are named beginning with a capital letter. Classes are named according to the following general rule:
class name = <algorithm><input><concept>
In this formula, the name of the algorithm or process (possibly with an associated adjective or adverb) comes first, followed by an input type, and completed by a {\em concept} name. A concept is an informal classification describing what a class does. There are many concepts in FARSIGHT, here are a few of them:
- Container
- A container of objects such as points or cells.
- Filter
- A class that participates in the data processing pipeline. Filters typically take one or more inputs and produce one or more outputs.
- Iterator
- Traverse data in various ways (e.g., forward, backward, within a region, etc.)
- Reader
- A class that reads a single data object (e.g., image or mesh).
- Region
- A subset of a data object, such as an image region.
- Source
- A filter that initiates the data processing pipeline such as a reader or a procedural data generator.
- Transform
- Various types of transformations including affine, procedural, and so on.
- Writer
- A filter that terminates the data processing pipeline by writing data to disk or to a communications port.
The naming of classes is an art form; please review existing names to catch the spirit of the naming convention. Example names include:
- ShrinkImageFilter
- TriangleCell
- ScalarImageRegionIterator
- NeighborhoodIterator
- MapContainer
- DefaultImageTraits
- BackwardDifferenceOperator
Naming Modules
Modules created within the FARSIGHT toolkit be named in the same manner ascribed to other FARSIGHT classes. The directories that the modules are constructed in should end in \texttt{Module} as well as the shared library build of the module. However, the standalone version of the module should omit Module from its name.
Naming Qt-Based Classes
Qt-based classes are named a bit differently than classes in the mav:: namespace These classes are named according to the following rules:
- Q(Module Name)ModuleGUI
- Classes that wrap modules for use in the designer.
- Q(Module Name)ModuleGUIPlugin
- Designer plugin definitions for the QmModuleGUI classes.
- QVTK*
- Classes that are Qt widgets and contain VTK Renders, Render Windows, etc. These classes shouldn't be used directly unless they end in Widget
- Q*Widget
- Qt classes written for FARSIGHT. Many of these use widgets defined as QmVTK*Display. These are the only GUI classes that should be used directly.
- Q*WidgetPlugin
- Designer plugin definitions for the Qm*Widget classes.
Naming Files
Files should have the same name as the class, with the 3 letter namespace of the library prepended (e.g., ``far). Header files are named .h, while implementation files are named either .cxx or .txx, depending on whether they are implementations of templated classes. It is important to note that VTK, ITK, and Qt classes fall under their respective namespaces and do not use the mav namespace.
Naming Methods and Functions
Class methods, either static or class members, are named beginning with a capital letter. The biggest challenge when naming methods and functions is to be consistent with existing names. For example, given the choice between ComputeBoundingBox() and CalculateBoundingBox (CalcBoundingBox() is not allowed because it is not spelled out), the choice is ComputeBoundingBox() because ``Compute is used elsewhere in the system for a similar circumstance. (The concepts described previously should be used whenever possible.)
When referring to class methods in code, an explicit ``this-> pointer should be used, as in this->ComputeBoundingBox(). The use of the explicit this-\(>\) pointer helps clarify exactly which method, and where it originates, is being invoked. Similarly the ``:: global namespace should be used when referring to a global function.
Naming Methods and Functions in Qt-Based Classes
Qt-Based classes within FARSIGHT present a particular challenge when naming methods. The above rules apply, but it is very imporant to recognize the few caveats:
- overriding methods
- When overriding methods from a superclass in the Qt library, you are generally forced to name your method accordingly. That's an acceptable variation from the rules. If you stay consistent by otherwise naming methods in uppercase, this can be an invaluable clue to other FARSIGHT developers regarding your intentions.
- FARSIGHT-specific signals
- Signals defined in FARSIGHT must be of the form Send*.
- FARSIGHT-specific slots
- Slots defined in FARSIGHT must be of the form Receive*.
Naming variables in Qt GUIs
- When naming instances of Qt widgets, use the following construct
ui<ParentName><UniqueName><WidgetType>
- Examples
uiSmootherRadiusSlider uiROIVolumeTextBox uiROIComputeWidthButton
Naming Class Data Members
Class data members are prepended with ``m\_ as in m\_Size. This clearly indicates the origin of data members, and differentiates them from all other variables.
Naming Local Variables
Local variables begin in lowercase. There is more flexibility in the naming of local variables; please remember that others will study, maintain, fix, and extend your code. Any bread crumbs that you can drop in the way of explanatory variable names and comments will go a long way towards helping other developers.
Naming Template Parameters
Template parameters follow the usual rules with naming except that they should start with either the capital letter T or V. Type parameters begin with the letter T while value template parameters begin with the letter V.
Naming Typedefs
Typedefs are absolutely essential in generic programming. They significantly improve the readability of code, and facilitate the declaration of complex syntactic combinations. Unfortunately, creation of typedefs is tantamount to creating another programming language. Hence typedefs must be used in a consistent fashion.
The general rule for typedef names is that they end in the word Type. For example
typedef TPixel PixelType;
However, there are many exceptions to this rule that recognize that FARSIGHT has several important {\em concepts} that are expressed partially in the names used to implement the concept. An iterator is a concept, as is a container or pointer. These concepts are used in preference to Type at the end of a typedef as appropriate. For example
typedef typename ImageTraits::PixelContainer PixelContainer;
Here Container is a concept used in place of Type.
Using Underscores
namesLikeThisAreHardToRead. Use underscores. names_like_this_are_easy_to_read. Better yet is: easy_name.
Preprocessor Directives
Some of the worst code contains many preprocessor directives and macros. Do not use them except in a very limited sense (to support minor differences in compilers or operating systems). If a method makes extensive use of preprocessor directives, it is a candidate for separation into its own class.
Const Correctness
Const correctness is important. Please use it as appropriate to your class or method.
Exception Handling
Indicate that methods throw exceptions in the method declaration as in:
const float *foo() const throws std::exception
Code Layout and Indentation
The following are the accepted FARSIGHT code layout rules and indentation style. After reading this section, you may wish to visit many of the source files found in ITK. This will help crystallize the rules described here.
General Layout
Each line of code should take no more than 80 characters. Break the code across multiple lines as necessary. Use lots of whitespace to separate logical blocks of code, intermixed with comments. To a large extent the structure of code directly expresses its implementation.
DO NOT USE SPACES. Tabs can easily be modified by any real editor to display 2, 4 or even 8 spaces. Different style of programmers like to see different levels of indentation.
The declaration of variables within classes, methods, and functions should be one declaration per line.
int i; int j; char *stringname;
Spaces (USE THEM!)
FARSIGHT, like ITK, makes liberal use of spaces to improve the readability of code. When in doubt, use a space. Common examples:
- Separate arguments from other args (there should be a space after every comma:
foo(int a) { foofoo(a); foofoofoo(a, b); }
- Favor right-flush for lines that are continuations of previous lines:
this->IsMyReallyLong()->ITK() ->FunctionCall()
- Use a space before a pointer-type declaration:
int *a, *b; //most precise int* a, *b //confusing
- Do not use space around structure accessing members.
a->b; *a = b; a.b;
Passing by Reference
- Pass by reference by passing the reference in the CALLING function:
** Good: int main(void) { int a, b, c; functionA(a, &b, c); //immediately see that b is passed into functionA and may potentially have its value modified } void functionA(int a, int *b, int c) ** Bad: int main(void) { int a, b, c; functionA(a, b, c); //does b get passed by value? } void functionA(int a, int &b, int c)
KISS
Keep it simple, stupid!
Break complex methods into multiple lines - program in a way that makes it easy for your code to be debugged by others. Examples:
- ?: Most developers have no clue what ? means and you should only use it if it significantly reduces the visual noise to understand the meaning of your code.
- Limit the variety of operators that appear in any one line of code
Class Layout
Classes are defined using the following guidelines.
- Begin with #include guards.
- Follow with the necessary includes. Include only what is necessary to avoid dependency problems.
- Place the class in the correct namespace.
- Public methods come first.
- Protected methods follow.
- Private members come last.
- Public data members are forbidden.
The class layout looks something like this:
#ifndef __mavImage_h #define __mavImage_h #include "itkImageBase.h" #include "itkPixelTraits.h" #include "itkDefaultImageTraits.h" #include "itkDefaultDataAccessor.h" namespace far { template < class TPixel, unsigned int VImageDimension=2, class TImageTraits=DefaultImageTraits< TPixel, VImageDimension > > class FARSIGHT_EXPORT Image : public itk::ImageBase< VImageDimension > { public: ....stuff... protected: ....stuff... private: ....stuff... }; }//end of namespace #endif //end include guard
Method Definition
Methods are defined across multiple lines. This is to accommodate the extremely long definitions possible when using templates. The starting and ending brace should be indented. For example:
template< class TPixel, unsigned int VImageDimension, class TImageTraits > const double * Image< TPixel, VImageDimension, TImageTraits > ::GetSpacing( ) const { ... }
The first line is the template declaration. The second line is the method return type. The third line is the class qualifier. And the fourth line in the example above is the name of the method.
Use of Braces { }
Braces must be used to delimit the scope of an if, for, while, switch, or other control structure. Braces are placed on a line by themselves:
int i; for( i=0; i<3; i++ ) { ... }
or when using an if:
if( condition ) { ... } else if( other condition ) { ... } else { .... }
Doxygen Documentation System
Doxygen is an open-source, powerful system for automatically generating documentation from source code. To use Doxygen effectively, the developer must insert comments, delimited in a special way, that Doxygen extracts to produce the documentation. While there are a large number of options to Doxygen, developers at a minimum should insert the following Doxygen commands. (See more at http://www.stack.nl/~dimitri/doxygen/index.html.)
Documenting a Class
Classes should be documented using the \texttt{\\class} and \texttt{\\brief} Doxygen commands, followed by the detailed class description:
/** \class Object * \brief Base class for most itk classes. * * Object is the second-highest level base class for most itk objects. * It extends the base object functionality of LightObject by * implementing debug flags/methods and modification time tracking. */
Documenting a Method
Methods should be documented using the following comment block style as shown in the following example.
/** * Access a pixel. This version can be an lvalue. */ TPixel & operator[]( const IndexType & index ) { return this->GetPixel( index ); }
The key here is that the comment starts with /**, each subsequent line has an aligned *, and the comment block terminates with a */.
Documentation
The FARSIGHT has adopted the following guidelines for producing supplemental documentation.
- Most documentation should begin as a wiki page
- Documentation for releases should be available as PDF
- Administrative documentation for releases should be available as Word
- Presentations are acceptable in Microsoft PowerPoint format.
Testing
Each developer should do his or her part to aid in testing process. It is generally accepted that each developer should write proper unit tests using CTest and those tests will be run on nightly and continuous dashboards.
Dashboards
- Dashboards shall be maintained for all platforms
- If you have a computer with spare cycles, and you'd like to help test FARSIGHT, please see Setting up automated builds.
- Warnings will not be tolerated
- Failing tests are preferred over disabling tests or using case/system-specific hacks for solutions
- Best answer is to fix the code
Releases
Before each product release, a battery of testing (specified on the project wiki) will be carried out to check for regressions not caught by traditional unit testing.
- Release version naming convention
- MajorReleaseNumber.MinorReleaseNumber.PatchReleaseNumber
- These variables are controlled in the top-level CMakeLists.txt file. They apply to all applications within FARSIGHT
Code Coverage
Code coverage is everyone's responsibility...