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

# Platform/Aperios1.3.2/Receiver.h

Go to the documentation of this file.

    00001 /**
    00002  * @file Platform/Aperios1.3.2/Receiver.h
    00003  * This file contains classes related to receivers.
    00004  * @author Thomas Röfer
    00005  */
    00006 #ifndef __RECEIVER_H__
    00007 #define __RECEIVER_H__
    00008
    00009 #ifndef __ProcessFramework_h__
    00010 #error Never include this file directly. Include ProcessFramework.h instead.
    00011 #endif
    00012
    00013 #include "Tools/Streams/InStreams.h"
    00014 #include "Platform/GTAssert.h"
    00015
    00016 /**
    00017  * The class is the base class for receivers.
    00018  * A receiver is an object that reads packages from Aperios queues.
    00019  * The class manages a global list of all receivers in an Aperios process.
    00020  */
    00021 class ReceiverList : public OObserver
    00022 {
    00023   private:
    00024     PlatformProcess* process;   /**< The process this receiver is associated with. */
    00025     ReceiverList* next;         /**< The successor of the current receiver. */
    00026     char name[NAME_LENGTH_MAX]; /**< The name of a receiver without the module's name. */
    00027
    00028   protected:
    00029     int eventId;                /**< The id of the current receiver in the range [0..30]. */
    00030     bool blocking;              /**< Stores whether this is a blocking receiver. */
    00031
    00032   public:
    00033     /**
    00034      * The constructor.
    00035      * @param process The process this receiver is associated with.
    00036      * @param receiverName The Aperios connection name of the receiver without the process name.
    00037      * @param blocking Decides whether this receiver blocks the execution of the next frame
    00038      *                 until it has received a package.
    00039      */
    00040     ReceiverList(PlatformProcess* process,const char* receiverName,bool blocking);
    00041
    00042     /**
    00043      * Returns the begin of the list of all receivers.
    00044      * @return The first receiver in the list, or 0 if the list ist empty.
    00045      */
    00046     ReceiverList*& getFirst();
    00047
    00048     /**
    00049      * Returns the next receiver in the list.
    00050      * @return The next receiver in the list, or 0 if this receiver is the last one.
    00051      */
    00052     ReceiverList* getNext() const {return next;}
    00053
    00054     /**
    00055      * Returns the Aperios connection name of the receiver.
    00056      * @return The Aperios connection name without the process name ("Receiver.type.O")
    00057      */
    00058     const char* getName() const {return name;}
    00059
    00060     /**
    00061      * Fills the Aperios entry table for global functions.
    00062      * The function will write two entries into the table.
    00063      * @param entryTable The Aperios entry table.
    00064      * @param id The first empty id in the entry table.
    00065      * @return The new first empty id in the entry table.
    00066      */
    00067     virtual int fillEntryTable(ObjectEntry* entryTable,int id) = 0;
    00068
    00069     /**
    00070      * Returns whether a new package was received in the current frame.
    00071      * This is always true if this is a blocking receiver.
    00072      * @return Has a new package been received?
    00073      */
    00074     bool receivedNew() const;
    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 receiver.
    00102  * A receiver is an object that reads packages from an Aperios queue.
    00103  */
    00104 template<class T> class Receiver : public ReceiverList, public T
    00105 {
    00106   protected:
    00107     static Receiver<T>* theInstance; /**< The only instance of Receiver<T>. */
    00108
    00109     /**
    00110      * The function is called when a new package arrived.
    00111      * @param msg An Open-R message that contains the package.
    00112      */
    00113     virtual void handleMessage(ONotifyMessage& msg)
    00114     {
    00115       ONotifyEvent event;
    00116       event.SetIndex(eventId);
    00117       NotifyHandler(msg,&event);
    00118       T& data = *static_cast<T*>(this);
    00119       InBinaryMemory memory(event.RCData(0)->Base(),event.RCData(0)->Size());
    00120       memory >> data;
    00121       ASSERT(memory.eof());
    00122       setEventId(eventId);
    00123     }
    00124
    00125     /**
    00126      * The Aperios connection handler.
    00127      * @param msg A message provided by Aperios.
    00128      */
    00129     static void aperiosConnect(OConnectMessage* msg)
    00130     {
    00131       theInstance->ConnectHandler(*msg);
    00132       Return();
    00133     }
    00134
    00135     /**
    00136      * The Aperios handler that is called when a package is received.
    00137      * @param msg A message provided by Aperios that contains the package.
    00138      */
    00139     static void aperiosNotify(ONotifyMessage* msg)
    00140     {
    00141       theInstance->handleMessage(*msg);
    00142       Return();
    00143     }
    00144
    00145   public:
    00146     /**
    00147      * The constructor.
    00148      * @param process The process this receiver is associated with.
    00149      * @param receiverName The Aperios connection name of the receiver without the process name.
    00150      * @param blocking Decides whether this receiver blocks the execution of the next frame
    00151      *                 until it has received a package.
    00152      */
    00153     Receiver(PlatformProcess* process,const char* receiverName,bool blocking)
    00154     : ReceiverList(process,receiverName,blocking)
    00155     {
    00156       theInstance = this;
    00157     }
    00158
    00159     /**
    00160      * Fills the Aperios entry table for global functions.
    00161      * The function will write two entries into the table.
    00162      * @param entryTable The Aperios entry table.
    00163      * @param id The first empty id in the entry table.
    00164      * @return The new first empty id in the entry table.
    00165      */
    00166     virtual int fillEntryTable(ObjectEntry* entryTable,int id)
    00167     {
    00168       eventId = (id - ENTRY_TABLE_MIN) / 2;
    00169       ASSERT(eventId <= 31); // should test < 31
    00170       if(blocking)
    00171         setBlockingId(eventId); // setBlocking(eventId,blocking) should done it too
    00172       entryTable[id].selector = id;
    00173       entryTable[id++].entry = (Entry) aperiosConnect;
    00174       entryTable[id].selector = id;
    00175       entryTable[id++].entry = (Entry) aperiosNotify;
    00176       return id;
    00177     }
    00178 };
    00179
    00180 template<class T> Receiver<T>* Receiver<T>::theInstance = 0;
    00181
    00182 #endif