FARSIGHT DevelopersGuide

From FarsightWiki
(Difference between revisions)
Jump to: navigation, search
(add wiki, bugtracker, cdash links to developer's guide)
(Naming Modules)
 
(28 intermediate revisions by 3 users not shown)
Line 7: Line 7:
 
= Document Overview =  
 
= Document Overview =  
 
This document is organized into the following sections.
 
This document is organized into the following sections.
* System Overview \& Philosophy --- coding methodologies and motivation for the resulting style.
+
* 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.
 
* Copyright --- the copyright header to be included in all files and other copyright issues.
 
* File organization --- how to organize source code.
 
* File organization --- how to organize source code.
Line 67: Line 67:
 
demonstrated its ability to create efficient, flexible code.  Use of the STL
 
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  
 
(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 {\em used} by a class,  
+
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.  
+
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 ===
 
=== Portability ===
 
Most FARSIGHT applications as well as the core of the toolkit are designed to  
 
Most FARSIGHT applications as well as the core of the toolkit are designed to  
Line 153: 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
\texttt{FARSIGHT}. Please consult the FARSIGHT team before creating any new
+
''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:
Line 193: Line 197:
  
 
=== Naming Classes ===
 
=== Naming Classes ===
Classes are named beginning with a capital letter. Classes are placed in the
+
Classes are named beginning with a capital letter. Classes are
appropriate namespace, typically mav:: (see namespaces below). Classes are
+
 
named according to the following general rule:
 
named according to the following general rule:
  
Line 201: Line 204:
 
In this formula, the name of the algorithm or process (possibly with an
 
In this formula, the name of the algorithm or process (possibly with an
 
associated adjective or adverb) comes first, followed by an input type,  
 
associated adjective or adverb) comes first, followed by an input type,  
and completed by a {\em concept} name. A concept is an informal classification  
+
and completed by a ''concept'' name. A concept is an informal classification  
 
describing what a class does. There are many concepts in FARSIGHT, here are a  
 
describing what a class does. There are many concepts in FARSIGHT, here are a  
 
few of them:
 
few of them:
Line 232: Line 235:
 
* DefaultImageTraits
 
* DefaultImageTraits
 
* BackwardDifferenceOperator
 
* BackwardDifferenceOperator
 
  
 
=== Naming Modules ===
 
=== Naming Modules ===
 
Modules created within the FARSIGHT toolkit be named in the same manner
 
Modules created within the FARSIGHT toolkit be named in the same manner
 
ascribed to other FARSIGHT classes. The directories that the modules are  
 
ascribed to other FARSIGHT classes. The directories that the modules are  
constructed in should end in \texttt{Module} as well as the shared library
+
constructed in should end in ''Module'' as well as the shared library
 
build of the module. However, the standalone version of the module should omit
 
build of the module. However, the standalone version of the module should omit
 
<em>Module</em> from its name.
 
<em>Module</em> from its name.
Line 263: Line 265:
  
 
=== Naming Methods and Functions ===
 
=== Naming Methods and Functions ===
Global functions and class methods, either static or class members, are named
+
Class methods, either static or class members, are named
 
beginning with a capital letter. The biggest challenge when naming methods
 
beginning with a capital letter. The biggest challenge when naming methods
 
and functions is to be consistent with existing names. For example, given the
 
and functions is to be consistent with existing names. For example, given the
Line 277: Line 279:
 
is being invoked. Similarly the ``::'' global namespace should be used when
 
is being invoked. Similarly the ``::'' global namespace should be used when
 
referring to a global function.
 
referring to a global function.
+
 
 
=== Naming Methods and Functions in Qt-Based Classes ===
 
=== Naming Methods and Functions in Qt-Based Classes ===
 
Qt-Based classes within FARSIGHT present a particular challenge when naming  
 
Qt-Based classes within FARSIGHT present a particular challenge when naming  
Line 338: Line 340:
  
 
=== Using Underscores ===
 
=== Using Underscores ===
Don't use them. The only exception is when defining preprocessor variables
+
namesLikeThisAreHardToRead. Use underscores. names_like_this_are_easy_to_read. Better yet is: easy_name.
and macros (which are discouraged). In this case, underscores are allowed
+
to separate words.
+
  
 
=== Preprocessor Directives ===
 
=== Preprocessor Directives ===
Line 347: Line 347:
 
compilers or operating systems). If a method makes extensive use of preprocessor
 
compilers or operating systems). If a method makes extensive use of preprocessor
 
directives, it is a candidate for separation into its own class.
 
directives, it is a candidate for separation into its own class.
 
== Namespaces ==
 
All classes that do not inherit from VTK, ITK, or Qt classes should be placed in
 
the mav:: namespace.
 
  
 
== Const Correctness ==
 
== Const Correctness ==
Line 359: Line 355:
 
Indicate that methods throw exceptions in the method declaration as in:
 
Indicate that methods throw exceptions in the method declaration as in:
  
   const float* foo() const throws std::exception
+
   const float *foo() const throws std::exception
  
 
== Code Layout and Indentation ==
 
== Code Layout and Indentation ==
Line 372: Line 368:
 
structure of code directly expresses its implementation.
 
structure of code directly expresses its implementation.
  
The appropriate indentation level is two spaces for each level of
+
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.
indentation. DO NOT USE TABS. Set up your editor to insert spaces. Using tabs
+
may look good in your editor but will wreak havoc in someone else's.
+
  
 
The declaration of variables within classes, methods, and functions should
 
The declaration of variables within classes, methods, and functions should
Line 381: Line 375:
 
   int    i;
 
   int    i;
 
   int    j;
 
   int    j;
   char * stringname;
+
   char   *stringname;
  
 
=== Spaces (USE THEM!) ===
 
=== 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:
 
FARSIGHT, like ITK, makes liberal use of spaces to improve the readability of code.  When in doubt, use a space.  Common examples:
* Separate expressions from their enclosing paren:
+
* Separate arguments from other args (there should be a space after every comma:
if( a < b )
+
  foo(int a)
  {
+
{
  a = ( 1 + 1 ) / 2;
+
   foofoo(a);
  }
+
   foofoofoo(a, b);
* Separate arguments from their enclosing paran and 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:
 
* Favor right-flush for lines that are continuations of previous lines:
 
   this->IsMyReallyLong()->ITK()
 
   this->IsMyReallyLong()->ITK()
 
                         ->FunctionCall()
 
                         ->FunctionCall()
* Use ( void ) when declaring a function that takes no arguments:
+
 
   int DoesNothing( void )
+
* Use a space before a pointer-type declaration:
    {
+
   int *a, *b;  //most precise
    }
+
   int* a, *b  //confusing
* Use spaces before and after raw pointer declarations:
+
 
   int * a;
+
** Do not use space around structure accessing members.
** You do not need to use spaces when accessing raw pointers:
+
 
   a->b;
 
   a->b;
 
   *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 ===
 
=== KISS ===
Line 415: Line 422:
 
Break complex methods into multiple lines - program in a way that makes it easy for your code to be debugged by others.   
 
Break complex methods into multiple lines - program in a way that makes it easy for your code to be debugged by others.   
 
Examples:
 
Examples:
* ?: statements should not be used instead of if...then statements
+
* ?: 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
 
* Limit the variety of operators that appear in any one line of code
 
  
 
=== Class Layout ===
 
=== Class Layout ===
Line 442: Line 448:
 
   namespace far
 
   namespace far
 
   {
 
   {
  template < class TPixel, unsigned int VImageDimension=2,
+
    template < class TPixel, unsigned int VImageDimension=2,
            class TImageTraits=DefaultImageTraits< TPixel, VImageDimension > >
+
              class TImageTraits=DefaultImageTraits< TPixel, VImageDimension > >
  class FARSIGHT_EXPORT Image : public itk::ImageBase< VImageDimension >
+
              class FARSIGHT_EXPORT Image : public itk::ImageBase< VImageDimension >
 
     {
 
     {
 
     public:
 
     public:
Line 469: Line 475:
 
   Image< TPixel, VImageDimension, TImageTraits >
 
   Image< TPixel, VImageDimension, TImageTraits >
 
   ::GetSpacing( ) const
 
   ::GetSpacing( ) const
    {
+
  {
 
     ...
 
     ...
    }
+
  }
  
 
The first line is the template declaration. The second line is the method
 
The first line is the template declaration. The second line is the method
Line 484: Line 490:
 
   int i;
 
   int i;
 
   for( i=0; i<3; i++ )
 
   for( i=0; i<3; i++ )
    {
+
  {
 
     ...
 
     ...
    }
+
  }
  
  
Line 493: Line 499:
  
 
   if( condition )
 
   if( condition )
    {
+
  {
 
     ...
 
     ...
    }
+
  }
 
   else if( other condition )
 
   else if( other condition )
    {
+
  {
 
     ...
 
     ...
    }
+
  }
 
   else
 
   else
    {
+
  {
 
     ....
 
     ....
    }
+
  }
  
 
== Doxygen Documentation System ==
 
== Doxygen Documentation System ==
Line 534: Line 540:
 
   */
 
   */
 
   TPixel & operator[]( const IndexType & index )
 
   TPixel & operator[]( const IndexType & index )
    {  
+
  {  
    return this->GetPixel( index );  
+
    return this->GetPixel( index );  
    }
+
  }
  
 
The key here is that the comment starts with <em>/**</em>, each subsequent
 
The key here is that the comment starts with <em>/**</em>, each subsequent
Line 559: Line 565:
 
== Dashboards ==
 
== Dashboards ==
 
* Dashboards shall be maintained for all platforms
 
* 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
 
* Warnings will not be tolerated
 
* Failing tests are preferred over disabling tests or using case/system-specific hacks for solutions
 
* Failing tests are preferred over disabling tests or using case/system-specific hacks for solutions
 
** Best answer is to fix the code
 
** Best answer is to fix the code
+
 
 
== Releases ==
 
== Releases ==
 
Before each product release, a battery of testing (specified on the project
 
Before each product release, a battery of testing (specified on the project

Latest revision as of 17:56, 17 January 2012

Back to FARSIGHT_Tutorials

Contents

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 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 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...

Personal tools