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_