/************************************************************************/
/* Copyright 1998 MBARI							*/
/************************************************************************/
// This header file is used only by the Cocoon documentation utility.
/* ------------------------------------------------------------------
LIBRARY
Tmacs

OVERVIEW
Tiburon Monitor and Control Software (TMACS) provides pilots, scientists 
and engineers with a graphical user interface (GUI) to monitor and control 
the vehicle. 

TMACS incorporates classes of the <a href="http://www.viewkit.com">ViewKit</a>
application framework from <a href="http://www.ics.com">ICS</a>.

A software design overview for TMACS can be found
<a href="http://mww.mbari.org/~oreilly/tmacs/Design/SoftwareReview.html">
here</a>.

Below is the containment hierarchy for major objects in the system.
<pre>
                                many       many              many
               |- RovMainWindow ----> View ----> DmGuiObject ----> DmObject
               |
               |
               |- PeriodicHandler ---> DmGuiObject list
               |
TiburonApp --->|
               |
               |- AperiodicHandler ---> DmGuiObject list
               | 
               |               many        many
               |- SystemAlarms ----> Alarm ----> DmObject


</pre>

DmGuiObject is perhaps the most basic class in the application.
A DmGuiObject contains DataManager objects (DmObject class), as well
as graphical components, such as widgets, XLib drawings, etc. The graphical
components represent the values or states of the DmObjects, and may
also allow those values or states to be modified by the pilot. 
The virtual function DmGuiObject::updateGui() specifies exactly how the 
graphical components reflect values of the contained DmObjects.
DmGuiObject is an abstract class; the actual components displayed by TMACS, 
such as RovCompass and PowerSwitchGui, are subclasses of DmGuiObject.
<a href="DmGuiObject.html#children">Here</a> is a list of all DmGuiObject
subclasses.

In the constructor for each DmGuiObject subclass, the object is specified
as either "periodic" or "aperiodic". A periodic object is registered with
the application's PeriodicHandler, along with the update period (millisec).
An aperiodic object is registered with the AperiodicHandler.

After all objects have been created, the application enters the 
X event loop. Objects which are registered as periodic will have their
updateGui() function called at the requested rate by the PeriodicHandler,
whether or not the values of contained DmObjects have changed.
An object registered as aperiodic will have its updateGui()
function called only when any of its contained DmObjects changes.

The following diagrams illustrate the registration and update process
for a periodic DmGuiObject:

<img src="PeriodicRegistration.gif">
<img src="PeriodicUpdate.gif">

Aperiodic registration and update requires the cooperation of two processes;
the GUI process and the dmonitor process, as shown in the following:

<img src="AperiodicArchitecture.gif">
<img src="AperiodicRegistration.gif">
<img src="AperiodicUpdate.gif">

USE
The most common task for application writers is to develop subclasses
of DmGuiObject. The procedure is as follows:

1. Encapsulate all of object's Widgets in a single-rooted subtree. The top of 
   the tree is typically a container Widget (e.g. Form, RowColumn, etc.). 
   In most cases the base Widget and all descendant's should be created in 
   the class constructor. Assign the base Widget to member _baseWidget 
   inherited from VkComponent. Call VkComponent::installDestroyHandler() 
   immediately after creating _baseWidget. The constructor should manage 
   all Widgets (except perhaps _baseWidget). The constructor must take at 
   least two arguments; the parent Widget of the object instance, and the 
   name of the object instance. 

2. The contained DmObjects are often created in the class constructor, but in 
   some cases can be passed in as arguments to the constructor. In either 
   case, the constructor should call DmGuiObject::addDmObject() for each 
   contained DmObject. 

3. The constructor sets the update method to periodic or aperiodic by calling
   DmGuiObject::setConsumePeriod(). 

4. Override DmGuiObject::updateGui(); updateGui() should read all contained 
   consumed DmObjects and update the corresponding Widgets accordingly. 

5. Define all required callback functions (e.g., for Widgets which get user 
   input) as private static member functions. Pass the "this" pointer as 
   client data, so that object methods and data can be accessed from the
   callback. 

6. Create a new instance of your DmGuiObject subclass in 
   RovMainWindow::createGui(), and add it to the desired View.
   
Note: A DmGuiObject may contain other DmGuiObjects. 

In general, a DmGuiObject's update method should set to periodic if 
its DmObjects are updated periodically by the DmObjects' provider,
and aperiodic when they are aperiodically updated. Alarm Data Manager 
items are the most common aperiodic items. 

It is possible to define a DmGuiObject which displays both periodic 
and aperiodic behavior by containing an aperiodic DmGuiObject within 
a periodic one, or vice versa. In this case, we say that the two 
DmGuiObjects are "peers" of one another. DmGuiObject includes the function
updateFromPeer(), so that peers may communicate. For example,
DmBarGraph updates its displayed value periodically, but aperiodically 
monitors its associated alarm item with a contained DmInputDetector.


------------------------------------------------------------------ */
