This manual is about implementing Graphlet applications. A Graphlet application is typically a graph algorithm or a graph drawing algorithm which is implemented in C++ and Graphscript. This manual desc
Graphlet is a rather complex program which is based on STL, GTL and Tcl/Tk. Knowledge in the following fields is essential before starting to programming Graphlet in C++:
A Graphlet application typically consists of a set of algorithms which are implemented in C++, Graphscript commands for those algorithms and a user interface written in Graphscript. The following steps are neccessary to implement a Graphscript application:
Algorithms are either implemented in pure GTL or in a mixture of GTL and the Graphlet C++ toolbox. As a rule of thumb, Graphlet's structures are needed if the graphical appearance of nodes, edges or and labels is relevant, or Graphlet's tool box is used. Especially graph drawing algorithms or algorithms which support algorithm animation need the Graphlet toolbox.
This step is described in Chapters Toolbox, GT_Graph, and Algorithms.
Generally, there should a Graphscript command for each algorithm. A family of algorithms may be converged into a single command. The top level of a complex algorithm should always be implemented in Graphscript. This allows easier customization than a C++ implementation, and helps to add a user interface or algorithm animation.
This step is described in the Tcl Interface chapter.
To do this, write a main routine, and link your code with
Graphlet, GTL and Tcl/Tk. Alternatively, create a shared library that can
be loaded at runtime.
Each algorithm should at least provide a window for the parameter settings. This window should be implemented with Tcl/Tk/Graphscript.
This step is described in the Graphscript manual.
The following example illustrates the coding standards for C++ classes in Graphlet:
class GT_Sample_Class : public GT_Sample_Base_Class {
// Alias for the base class of this class.
typedef GT_Sample_Base_Class baseclass;
// Member variables; the prefix the_ is mandatory.
int the_sample;
GT_Graph& the_sample_graph;
public:
// Constructor and virtual destructor.
GT_Sample_Class ();
virtual ~GT_Sample_Class ();
// Accessor to read the value of the_sample.
inline int sample();
// Accessor to change the value of the_sample.
virtual void sample (int s);
// Accessor to read the value of the_sample_graph.
inline const GT_Graph& sample_Graph() const;
// Accessor to change the value of the_sample_graph.
virtual void sample (const GT_Graph& g);
// Sample method declaration.
void sample_method ();
}
All global declarations within Graphlet, especially class names, use the
prefix GT_. It is vital to avoid name clashes with other
modules.
All class names (omitting the GT_ prefix) must start with a
capital letter.
Member variables must start with the prefix the_. All member
variables must be private or protected.
All classes must provides a constructor and a destructor. The destructor one must be virtual if virtual methods are used within the class, or in a class which is derived from it. That is, unless you dont know exactly how a class will be used in your module, use a virtual destructor.
The local type declaration baseclass provides a convenient and
transparent way to access the base class. Inspead of
GT_Sample_Base_Class::sample_method, write
baseclass::sample_method.
Member variables in Graphlet always follow a fixed scheme. First, the actual member variable is private or protected, but never public. accessor methods must be provided if a member variable is meant to be accessed from outside the class.
Graphlet does never export non-const references to member
variables. One reason for this is that Graphlet often needs to react to a
change, and a change can only be recognized if it is done through a
dedicated method to change the member variable.
In C++, simple data types are builtin data types such as
char, int or double. Accessors for
simple data types should have the following form:
private:
type the_name;public:
type name() constpublic:
virtual void name (type)
All data types which are not simple data types are called comples data
types. For example, data types defined by class,
struct or union are complex.
The accessor methods of complex data types need special consideration because they must work through references. If references were not used, then all parameters or return values would copied. That is, the method would not use or return the actual object, but a copy of it.
Accessors for complex data types should have the following form:
private:
type the_name;public:
const type& name() constname. This method is usually inlined for speed.
public:
virtual void name (const type&)name.