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

Platform/Aperios1.3.2/Sender.h

Go to the documentation of this file.
00001 /**
00002  * @file Platform/Aperios1.3.2/Sender.h
00003  * This file contains classes related to senders.
00004  * @author Thomas Röfer
00005  */
00006 #ifndef __SENDER_H__
00007 #define __SENDER_H__
00008 
00009 #ifndef __ProcessFramework_h__
00010 #error Never include this file directly. Include ProcessFramework.h instead.
00011 #endif
00012 
00013 #include "Tools/MessageQueue/MessageQueue.h"
00014 #include "Platform/GTAssert.h"
00015 
00016 const int RECEIVERS_MAX = 20; /**< The maximum number of receivers connected to a single sender */
00017 
00018 /**
00019  * The class is the base class for senders.
00020  * A sender is an object that sends packages to an Aperios queue.
00021  * The class manages a global list of all senders in an Aperios process.
00022  */
00023 class SenderList : public OSubject
00024 {
00025   private:
00026     PlatformProcess* process;   /**< The process this sender is associated with. */
00027     SenderList* next;           /**< The successor of the current sender. */
00028     char name[NAME_LENGTH_MAX]; /**< The name of a sender without the module's name. */
00029   
00030   protected:
00031     int eventId;                /**< The id of the current sender in the range [0..30]. */
00032     bool blocking;              /**< Stores whether this is a blocking sender. */
00033 
00034     /**
00035      * The function sends a package to all receivers that requested it.
00036      */
00037     virtual void sendPackage() = 0;
00038 
00039   public:
00040     /**
00041      * The constructor.
00042      * @param process The process this sender is associated with.
00043      * @param senderName The Aperios connection name of the sender without the process name.
00044      * @param blocking Decides whether this sender blocks the execution of the next frame
00045      *                 until all connected receivers have requested a new package.
00046      */
00047     SenderList(PlatformProcess* process,const char* senderName,bool blocking);
00048 
00049     /**
00050      * Returns the begin of the list of all senders.
00051      * @return The first sender in the list, or 0 if the list ist empty.
00052      */
00053     SenderList*& getFirst();
00054 
00055     /**
00056      * Returns the next sender in the list.
00057      * @return The next sender in the list, or 0 if this sender is the last one.
00058      */
00059     SenderList* getNext() const {return next;}
00060 
00061     /**
00062      * Returns the Aperios connection name of the sender.
00063      * @return The Aperios connection name without the process name ("Sender.type.O")
00064      */
00065     const char* getName() const {return name;}
00066 
00067     /**
00068      * Fills the Aperios entry table for global functions.
00069      * The function will write two entries into the table.
00070      * @param entryTable The Aperios entry table.
00071      * @param id The first empty id in the entry table.
00072      * @return The new first empty id in the entry table.
00073      */
00074     virtual int fillEntryTable(ObjectEntry* entryTable,int id) = 0;
00075 
00076     /**
00077      * The function must be called to finish the current frame.
00078      */
00079     void finishFrame();
00080 
00081     /**
00082      * The functions sets or resets a bit in the blocking mask.
00083      * After a bit is set in the blocking mask for a certain 
00084      * sender or receiver, a new frame will not be started before
00085      * this sender or receiver received an event.
00086      * @param id The id of the sender or receiver.
00087      * @param block Should it block or not?
00088      */
00089     static void setBlockingId(int id,bool block = true);
00090 
00091     /**
00092      * The function is called when an event was received. 
00093      * If this was the last event the process was waiting for, the next
00094      * frame is started, i.e. NextFrame() is called.
00095      * @param id The id of the sender or receiver that received an event.
00096      */
00097     static void setEventId(int id);
00098 };
00099 
00100 /**
00101  * The class implements a the base class for senders.
00102  * A sender is an object that sends packages to an Aperios queue.
00103  * Note that the template parameter is required to force a different
00104  * instantiation of the static members for each package type.
00105  */
00106 template<class T> class SenderBase : public SenderList, public T
00107 {
00108   private:
00109     static SenderBase<T>* theInstance;         /**< The only instance of SenderBase<T>. */
00110     ObserverID receiver[RECEIVERS_MAX],        /**< A list of all receivers that are ready to receive a package. */
00111                alreadyReceived[RECEIVERS_MAX]; /**< A list of all receivers that have already received the current package. */
00112     int numOfReceivers,                        /**< The number of entries in the receiver list. */
00113         numOfAlreadyReceived;                  /**< The number of entries in the alreadyReceived list. */
00114 
00115   private:
00116     /**
00117      * The function is called when a receiver announces that it is ready to receive a package.
00118      * @param msg An Open-R message that contains the object id of the receiver.
00119      */    
00120     void handleMessage(OReadyMessage& msg)
00121     {
00122       ReadyHandler(msg);
00123       /** 
00124        * @todo Currently, assert fails in conjunction with wlan, so avoid crash! 
00125        * However, it may work correctly, because TCPGateway will be the only 
00126        * receiver. 
00127        */
00128       ASSERT(numOfReceivers < RECEIVERS_MAX);
00129       int i = 0;
00130       while(i < numOfReceivers && !(receiver[i] == msg.observerID))
00131         ++i;
00132       if(i == numOfReceivers && numOfReceivers < NumberOfObservers())
00133         numOfReceivers++;
00134       receiver[i] = msg.observerID;
00135       if(numOfReceivers == NumberOfObservers())
00136         setEventId(eventId);
00137     }
00138 
00139     /**
00140      * The Aperios control handler.
00141      * @param msg A message provided by Aperios.
00142      */
00143     static void aperiosControl(OControlMessage* msg)
00144     {
00145       theInstance->ControlHandler(*msg);
00146       Return();
00147     }
00148 
00149     /**
00150      * The Aperios handler that is called when a receiver announces that it is ready to receive a package.
00151      * @param msg An Open-R message that contains the object id of the receiver.
00152      */
00153     static void aperiosReady(OReadyMessage* msg)
00154     {
00155       theInstance->handleMessage(*msg);
00156       Return();
00157     }
00158 
00159   protected:
00160     /**
00161      * The function prepares a package.
00162      * The function should be pure virtual, but GreenHills does not like that.
00163      */
00164     virtual void preparePackage() {}
00165 
00166     /**
00167      * The functions sets a package for a receiver.
00168      * The function should be pure virtual, but GreenHills does not like that.
00169      * @param receiver The receive the package will be sent to.
00170      */
00171     virtual void setPackage(const ObserverID& receiver) {}
00172 
00173     /**
00174      * The function frees the package.
00175      * The function should be pure virtual, but GreenHills does not like that.
00176      */
00177     virtual void freePackage() {}
00178 
00179   private:
00180     /**
00181      * The function sends a package to all receivers that requested it.
00182      */
00183     void sendPackage()
00184     {
00185       if(numOfAlreadyReceived != -1)
00186       { // send() has been called at least once
00187         int i;
00188         for(i = 0; i < numOfReceivers; ++i)
00189         {
00190           int j;
00191           for(j = 0; j < numOfAlreadyReceived; ++j)
00192             if(receiver[i] == alreadyReceived[j])
00193               break;
00194           if(j == numOfAlreadyReceived)
00195             break; // receiver[i] has not received its requested package yet
00196         }
00197         if(i < numOfReceivers)
00198         { // at least one receiver has not received its requested package, so prepare one
00199           preparePackage();
00200           // Send this package to all the receivers that requested it and that have not received it yet
00201           i = 0;
00202           while(i < numOfReceivers)
00203           {
00204             int j;
00205             for(j = 0; j < numOfAlreadyReceived; ++j)
00206               if(receiver[i] == alreadyReceived[j])
00207                 break;
00208             if(j == numOfAlreadyReceived)
00209             { // receiver[i] has not received its requested package yet
00210               setPackage(receiver[i]);
00211               VERIFY(NotifyObserver(receiver[i]) == oSUCCESS);
00212               // note that receiver[i] has received the current package
00213               ASSERT(numOfAlreadyReceived < RECEIVERS_MAX);
00214               alreadyReceived[numOfAlreadyReceived++] = receiver[i];
00215               // remove receiver[i] from the list 
00216               receiver[i] = receiver[--numOfReceivers];
00217             }
00218             else 
00219               ++i;
00220           }
00221           // The sender does not need the package anymore
00222           freePackage();
00223         }
00224       }
00225     }
00226 
00227     
00228   public:
00229     /**
00230      * The constructor.
00231      * @param process The process this sender is associated with.
00232      * @param senderName The Aperios connection name of the sender without the process name.
00233      * @param blocking Decides whether this sender blocks the execution of the next frame
00234      *                 until all connected receivers have requested a new package.
00235      */
00236     SenderBase(PlatformProcess* process,const char* senderName,bool blocking)
00237     : SenderList(process,senderName,blocking)
00238     {
00239       theInstance = this;
00240       numOfReceivers = 0;
00241       numOfAlreadyReceived = -1;
00242     }
00243 
00244     /**
00245      * Fills the Aperios entry table for global functions.
00246      * The function will write two entries into the table.
00247      * @param entryTable The Aperios entry table.
00248      * @param id The first empty id in the entry table.
00249      * @return The new first empty id in the entry table.
00250      */
00251     int fillEntryTable(ObjectEntry* entryTable,int id)
00252     {
00253       eventId = (id - ENTRY_TABLE_MIN) / 2;
00254       ASSERT(eventId <= 31); // should test on < 31
00255       setBlockingId(eventId,blocking);
00256       entryTable[id].selector = id;
00257       entryTable[id++].entry = (Entry) aperiosControl;
00258       entryTable[id].selector = id;
00259       entryTable[id++].entry = (Entry) aperiosReady;
00260       return id;
00261     }
00262 
00263     /**
00264      * Returns whether a new package was requested from the sender.
00265      * This is always true if this is a blocking sender.
00266      * @return Has a new package been requested?
00267      */
00268     bool requestedNew() const {return numOfReceivers > 0;}
00269 
00270     /**
00271      * Marks the package for sending and transmits it to all receivers that already requested for it.
00272      * All other receiver may get it later if they request for it before the package is changed.
00273      */
00274     void send()
00275     {
00276       setBlockingId(eventId,blocking);
00277       numOfAlreadyReceived = 0;
00278       sendPackage();
00279     }
00280 };
00281 
00282 template<class T> SenderBase<T>* SenderBase<T>::theInstance = 0;
00283 
00284 /**
00285  * The class implements the default sender for packages.
00286  */
00287 template<class T> class Sender : public SenderBase<T>
00288 {
00289   private:
00290     RCRegion* package; /**< A pointer to the package. */
00291 
00292   protected:
00293     /**
00294      * The function prepares a package.
00295      */
00296     virtual void preparePackage()
00297     {
00298       const T& data = *static_cast<const T*>(this);
00299       OutBinarySize size;
00300       size << data;
00301       package = new RCRegion(size.getSize());
00302       ASSERT(package);
00303       OutBinaryMemory memory(package->Base());
00304       memory << data;
00305     }
00306 
00307     /**
00308      * The functions sets a package for a receiver.
00309      * @param receiver The receive the package will be sent to.
00310      */
00311     virtual void setPackage(const ObserverID& receiver)
00312     {
00313       VERIFY(SetData(receiver,package) == oSUCCESS);
00314     }
00315 
00316     /**
00317      * The function frees the package.
00318      */
00319     virtual void freePackage()
00320     {
00321       package->RemoveReference();
00322     }
00323 
00324   public:
00325     /**
00326      * The constructor.
00327      * @param process The process this sender is associated with.
00328      * @param senderName The Aperios connection name of the sender without the process name.
00329      * @param blocking Decides whether this sender blocks the execution of the next frame
00330      *                 until all connected receivers have requested a new package.
00331      */
00332     Sender(PlatformProcess* process,const char* senderName,bool blocking)
00333     : SenderBase<T>(process,senderName,blocking)
00334     {
00335     }
00336 };
00337 
00338 #endif
00339 
00340 /*
00341  * Change log :
00342  * 
00343  * $Log: Sender.h,v $
00344  * Revision 1.1.1.1  2004/05/22 17:23:35  cvsadm
00345  * created new repository GT2004_WM
00346  *
00347  * Revision 1.2  2003/11/21 20:27:43  kerdels
00348  * Kommentare hinzugefügt
00349  *
00350  * Revision 1.1  2003/10/07 10:06:59  cvsadm
00351  * Created GT2004 (M.J.)
00352  *
00353  * Revision 1.1.1.1  2003/07/02 09:40:24  cvsadm
00354  * created new repository for the competitions in Padova from the 
00355  * tamara CVS (Tuesday 2:00 pm)
00356  *
00357  * removed unused solutions
00358  *
00359  * Revision 1.3  2003/04/04 21:28:35  roefer
00360  * Communication protocol changed
00361  *
00362  * Revision 1.2  2002/12/02 11:00:13  dueffert
00363  * doxygen docu corrected
00364  *
00365  * Revision 1.1  2002/09/10 15:40:04  cvsadm
00366  * Created new project GT2003 (M.L.)
00367  * - Cleaned up the /Src/DataTypes directory
00368  * - Removed challenge related source code
00369  * - Removed processing of incoming audio data
00370  * - Renamed AcousticMessage to SoundRequest
00371  *
00372  * Revision 1.7  2002/08/14 17:11:00  dueffert
00373  * adapted by Thomas Roefer to OPENR_SDK-1.1.3-r1 and OPENR_SYS-007
00374  *
00375  * Revision 1.6  2002/07/23 13:39:39  loetzsch
00376  * - new streaming classes
00377  * - removed many #include statements
00378  * - new design of debugging architecture
00379  * - exchanged StaticQueue with MessageQueue
00380  *
00381  * Revision 1.5  2002/07/13 10:54:58  roefer
00382  * New command and sound sender
00383  *
00384  * Revision 1.4  2002/07/06 20:08:10  roefer
00385  * Advances towards gcc
00386  *
00387  * Revision 1.3  2002/07/06 15:28:28  roefer
00388  * Prologue function removed
00389  *
00390  * Revision 1.2  2002/05/25 22:52:18  roefer
00391  * WLan, first working approach
00392  *
00393  * Revision 1.1.1.1  2002/05/10 12:40:18  cvsadm
00394  * Moved GT2002 Project from ute to tamara.
00395  *
00396  * Revision 1.11  2002/05/06 16:01:44  hebbel
00397  * Added buffered Sender
00398  *
00399  * Revision 1.10  2002/04/28 19:18:18  giese
00400  * SoundPlay added...
00401  *
00402  * Revision 1.9  2002/04/21 16:09:02  roefer
00403  * Anchor removed
00404  *
00405  * Revision 1.8  2001/12/15 20:32:08  roefer
00406  * Senders and receivers are now part of the processes
00407  *
00408  * Revision 1.7  2001/12/12 13:25:02  roefer
00409  * Blocking sender fixed
00410  *
00411  * Revision 1.6  2001/12/10 17:47:08  risler
00412  * change log added
00413  *
00414  */

Generated on Thu Sep 23 19:57:34 2004 for GT2004 by doxygen 1.3.6