Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | File List | Namespace Members | Class Members | File Members | Related Pages

Tools/Process.h

Go to the documentation of this file.
00001 /**
00002 * @file Process.h
00003 *
00004 * Contains the definition of class Process and macros for receivers and senders
00005 */
00006 
00007 #ifndef __Process_h_
00008 #define __Process_h_
00009 
00010 #include "Tools/MessageQueue/MessageQueue.h"
00011 #include "Tools/Streams/StreamHandler.h"
00012 #include "Tools/Debugging/DebugKeyTable.h"
00013 #include "Tools/Debugging/DebugRequest.h"
00014 #include "Tools/Debugging/DebugDataTable.h"
00015 #include "Tools/Module/ModuleHandler.h"
00016 #include "Tools/RobotConfiguration.h"
00017 #ifndef NO_PROCESS_FRAMEWORK
00018 #include "Platform/ProcessFramework.h"
00019 #endif
00020 
00021 #ifdef NO_PROCESS_FRAMEWORK
00022 #define GT_GLOBAL
00023 #endif
00024 
00025 #ifdef NEWDEBUGGING
00026 #include "Tools/Debugging/DebugDrawings.h"
00027 #endif
00028 
00029 /**
00030  * @class Process
00031  *
00032  * System independent base class for Processes.
00033  *
00034  * Process is the common base for processes in the GT2002 Project. 
00035  * The embedding into the system environment is done by system dependent frameworks that use
00036  * derivates of the Process class.
00037  */
00038 class Process : 
00039 #ifndef NO_PROCESS_FRAMEWORK
00040   public PlatformProcess, 
00041 #endif
00042   public MessageHandler
00043 {
00044 public:
00045   
00046   /** 
00047    * Constructor.
00048    * @param debugIn A reference to an incoming debug queue
00049    * @param debugOut A reference to an outgoing debug queue
00050    */
00051   Process(MessageQueue& debugIn, MessageQueue& debugOut);
00052   
00053   /** 
00054    * The main function is called from the process framework once in each frame. 
00055    * It does the debug handling and calls the main function in the derivates.
00056    * @return If 0 is returned, the function main will not be called on a timed basis
00057    *         again. A positive number specifies the minimum number of microseconds to
00058    *         wait before the next frame starts. A negative number specifies a cycle 
00059    *         time, i.e. the time between two activations of the main() function.
00060    */
00061   int processMain();
00062   
00063   /**
00064    * The main funtion is called once in each frame.
00065    * It must be implemented.
00066    * @return If 0 is returned, the function main will not be called on a timed basis
00067    *         again. A positive number specifies the minimum number of microseconds to
00068    *         wait before the next frame starts. A negative number specifies a cycle 
00069    *         time, i.e. the time between two activations of the main() function.
00070    */
00071   virtual int main() = 0;
00072 
00073   /**
00074    * That function is called once before the first main(). It can be used 
00075    * for things that can't be done in the constructor.
00076    */
00077   virtual void init() {}
00078 
00079   /** 
00080    * Is called for every incoming debug message.
00081    * @param message An interface to read the message from the queue
00082    * @return true if message was handled
00083    */
00084   virtual bool handleMessage(InMessage& message);
00085 
00086   /**
00087    * The function returns the current frame number.
00088    * @return The frame number.
00089    */
00090   static unsigned long getFrameNumber();
00091 
00092 private:
00093   /** 
00094    * Determines if the process is already initialized. Becomes true short 
00095    * before the first call of main()
00096    */
00097   bool initialized;
00098 
00099   /**
00100   * The configuration of this robot.
00101   */
00102   RobotConfiguration robotConfiguration;
00103 
00104   /**
00105   * The player configuration of this robot.
00106   */
00107   Player player;
00108 
00109   /** A table of debug keys for runtime debug requests.*/
00110   DebugKeyTable debugKeyTable;
00111 
00112   /** A table wiith the debug requests.*/
00113   DebugRequestTable debugRequestTable;
00114 
00115   /** A datastructure holding information about the streaming of datatypes. */
00116   StreamHandler streamHandler;
00117 
00118 protected:
00119 #ifdef NEWDEBUGGING
00120   /** A datastructure holding information about debug drawing idīs. */
00121   DrawingManager drawingManager;
00122 #endif
00123 
00124   /** A module handler for managing runtime exchangeable modules */
00125   ModuleHandler moduleHandler;
00126 
00127   /** A datastructure for generic streaming of data. */
00128   DebugDataTable debugDataTable;
00129 
00130   /** process wide framenumber */
00131   unsigned long frameNumber;
00132 
00133   /** A queue for incoming debug messages */
00134   MessageQueue& debugIn;
00135   
00136   /** A queue for outgoing debug messages */
00137   MessageQueue& debugOut;
00138 
00139   /** RunTime */
00140   unsigned int frameCounter;
00141   /** RunTime */
00142   double averageRunTime;
00143   /** RunTime */
00144   unsigned long maxRunTime;
00145   /** RunTime */
00146   unsigned long minRunTime;
00147 };
00148 
00149 #ifndef NO_PROCESS_FRAMEWORK
00150 /**
00151  * This template class implements a sender for debug packages.
00152  * It ensures that only a package is sent if it is not empty.
00153  */
00154 template<class T> class MultiDebugSender : public Sender<T>
00155 {
00156   public:
00157     /**
00158      * The constructor.
00159      * @param process The process this sender is associated with.
00160      * @param name The Aperios connection name of the sender without the process name.
00161      * @param blocking Decides whether this sender blocks the execution of the next frame
00162      *                 until all connected receivers have requested a new package.
00163      */
00164     MultiDebugSender(PlatformProcess* process,const char* name,bool blocking)
00165     : Sender<T>(process,name,blocking) {}
00166 
00167     /**
00168      * Marks the package for sending and transmits it to all receivers that already requested for it.
00169      * All other receiver may get it later if they request for it before the package is changed.
00170      * In function will only send a package if it is not empty.
00171      */
00172     virtual void send()
00173     {
00174       if(requestedNew() && !isEmpty())
00175       {
00176         Sender<T>::send();
00177         clear();
00178       }
00179     }
00180 };
00181 
00182 /**
00183  * This class implements a sender for MessageQueues.
00184  * It ensures that only a package is sent if it is not empty.
00185  */
00186 class DebugSender : public MultiDebugSender<MessageQueue>
00187 {
00188   public:
00189     /**
00190      * The constructor.
00191      * @param process The process this sender is associated with.
00192      * @param name The Aperios connection name of the sender without the process name.
00193      * @param blocking Decides whether this sender blocks the execution of the next frame
00194      *                 until all connected receivers have requested a new package.
00195      */
00196     DebugSender(PlatformProcess* process,const char* name,bool blocking)
00197     : MultiDebugSender<MessageQueue>(process,name,blocking) {}
00198 };
00199 
00200 #endif
00201 
00202 /**
00203  * The macro declares two debugging queues.
00204  * The macro shall be the first entry in the declaration of a process.
00205  */
00206 #define DEBUGGING \
00207   Receiver<MessageQueue> theDebugReceiver; \
00208   DebugSender theDebugSender
00209 
00210 /**
00211  * The macro initializes the two debugging queues and the base class.
00212  * The macro shall be the first entry after the colon in constructor
00213  * of the process.
00214  */
00215 #define INIT_DEBUGGING \
00216   Process(theDebugReceiver,theDebugSender), \
00217   theDebugReceiver(this,"Receiver.MessageQueue.O",false), \
00218   theDebugSender(this,"Sender.MessageQueue.S",false)
00219 
00220 /**
00221  * The macro declares a receiver.
00222  * It must be used inside a declaration of a process, after the macro DEBUGGING.
00223  * @param type The type of the package. The variable actually declared has
00224  *             a type compatible to "type" and is called "thetypeReceiver".
00225  */
00226 #define RECEIVER(type) \
00227   Receiver<type> the##type##Receiver
00228 
00229 /**
00230  * The macro initializes a receiver for a certain type. It must be part of the 
00231  * initializer list of the constructor of the process.
00232  * @param type The type of the package. The variable actually declared has
00233  *             a type compatible to "type" and is called "thetypeReceiver".
00234  * @param blocking Decides whether this receiver blocks the execution of the next frame
00235  *                 until it has received a package.
00236  */
00237 #define INIT_RECEIVER(type,blocking) \
00238   the##type##Receiver(this,"Receiver." #type ".O",blocking)
00239 
00240 /**
00241  * The macro declares a sender.
00242  * It must be used inside a declaration of a process, after the macro DEBUGGING.
00243  * @param type The type of the package. The variable actually declared has
00244  *             a type compatible to "type" and is called "thetypeSender".
00245  */
00246 #define SENDER(type) \
00247   Sender<type> the##type##Sender
00248 
00249 /**
00250  * The macro initializes a sender for a certain type. It must be part of the 
00251  * initializer list of the constructor of the process.
00252  * @param type The type of the package. The variable actually declared has
00253  *             a type compatible to "type" and is called "thetypeSender".
00254  * @param blocking Decides whether this sender blocks the execution of the next frame
00255  *                 until all connected receivers have requested a new package.
00256  */
00257 #define INIT_SENDER(type,blocking) \
00258   the##type##Sender(this,"Sender." #type ".S",blocking)
00259 
00260 /**
00261  * The macro declares a receiver for a MessageQueue.
00262  * It must be used inside a declaration of a process, after the macro DEBUGGING.
00263  * It shall only be used in the Debug process.
00264  * @param source The source process of the package. The variable actually declared is
00265  *               of type MessageQueue and is called "thesourceReceiver".
00266  */
00267 #define DEBUG_RECEIVER(source) \
00268   class Receive##source##MessageQueue : public MessageQueue {}; \
00269   Receiver<Receive##source##MessageQueue> the##source##Receiver
00270 
00271 /**
00272  * The macro initializes a receiver for a MessageQueue. It must be part of the 
00273  * initializer list of the constructor of the process.
00274  * @param source The source process of the package. The variable actually declared is
00275  *               of type MessageQueue and is called "thesourceReceiver".
00276  */
00277 #define INIT_DEBUG_RECEIVER(source) \
00278   the##source##Receiver(this,#source "Receiver.MessageQueue.O",false) \
00279 
00280 /**
00281  * The macro declares a sender for a MessageQueue.
00282  * It must be used inside a declaration of a process, after the macro DEBUGGING.
00283  * It shall only be used in the Debug process.
00284  * @param target The target process of the package. The variable actually declared is
00285  *               of type MessageQueue and is called "thetargetReceiver".
00286  */
00287 #define DEBUG_SENDER(target) \
00288   class Send##target##MessageQueue : public MessageQueue {}; \
00289   MultiDebugSender<Send##target##MessageQueue> the##target##Sender
00290 
00291 /**
00292  * The macro initializes a sender for a MessageQueue. It must be part of the 
00293  * initializer list of the constructor of the process.
00294  * @param target The target process of the package. The variable actually declared is
00295  *               of type MessageQueue and is called "thetargetSender".
00296  */
00297 #define INIT_DEBUG_SENDER(target) \
00298   the##target##Sender(this,#target "Sender.MessageQueue.S",false)
00299 
00300 #endif //__Process_h_

Generated on Mon Mar 20 22:00:09 2006 for GT2005 by doxygen 1.3.6