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

Tools/MessageQueue/MessageQueue.cpp

Go to the documentation of this file.
00001 /**
00002 * @file MessageQueue.cpp
00003 *
00004 * Implementation of class MessageQueue and helper classes
00005 * 
00006 * @author Martin Lötzsch
00007 */
00008 
00009 #include "MessageQueue.h"
00010 #include "Platform/GTAssert.h"
00011 
00012 MessageQueue::MessageQueue()
00013 : in(queue), out(queue)
00014 {
00015   ASSERT(idJPEGImage == 37); // otherwise log files will not work anymore
00016 }
00017 
00018 void MessageQueue::setSize(int size)
00019 {
00020   queue.setSize(size);
00021 }
00022 
00023 void MessageQueue::setPlayerForNewMessages(const Player& player)
00024 {
00025   out.teamColorForNewMessages = player.getTeamColor();
00026   out.playerNumberForNewMessages = player.getPlayerNumber();
00027 }
00028 
00029 void MessageQueue::handleSpecificMessages(MessageID id, MessageHandler& handler)
00030 {
00031   for (int i=0; i<queue.getNumberOfMessages(); i++)
00032   {
00033     queue.setSelectedMessageForReading(i);
00034     if (in.getMessageID()==id)
00035     {
00036       in.config.reset();
00037       in.text.reset();
00038       handler.handleMessage(in);
00039     }
00040   }
00041 }
00042 
00043 void MessageQueue::handleAllMessages(MessageHandler& handler)
00044 {
00045   for (int i=0; i<queue.getNumberOfMessages(); i++)
00046   {
00047     queue.setSelectedMessageForReading(i);
00048     in.config.reset();
00049     in.text.reset();
00050     handler.handleMessage(in);
00051   }
00052 }
00053 
00054 void MessageQueue::copyAllMessages(MessageQueue& other)
00055 {
00056   for (int i=0; i<queue.getNumberOfMessages(); i++)
00057   {
00058     copyMessage(i,other);
00059   }
00060 }
00061 
00062 void MessageQueue::moveAllMessages(MessageQueue& other)
00063 {
00064   copyAllMessages(other);
00065   clear();
00066 }
00067 
00068 void MessageQueue::clear()
00069 {
00070   queue.clear();
00071 }
00072 
00073 bool MessageQueue::isEmpty() const
00074 {
00075   return queue.getNumberOfMessages() == 0;
00076 }
00077 
00078 void MessageQueue::copyMessage(int message, MessageQueue& other)
00079 {
00080   queue.setSelectedMessageForReading(message);
00081   other.out.bin.write(queue.getData(),queue.getMessageSize());
00082   other.out.finishMessage(
00083     queue.getMessageID(),
00084     queue.getTimeStamp(),
00085     queue.getTeamColor(),
00086     queue.getPlayerNumber(),
00087     queue.getMessageWasSentFromAPhysicalRobot());
00088 }
00089 
00090 //
00091 // Format of a message in a log file:
00092 //
00093 // byte
00094 // 0     Bit 0: if 1, then this is the last message in the queue
00095 //       Bit 1-2: the team color. 0:undef, 1: red, 2:blue, 3:undef
00096 //       Bit 2-5: the player number: 0:undef, 1:0, 2:1, 3:2, 4:3, 5:undef
00097 //       Bit 6  : where the message is from: 0:physical robot, 1:simulated robot
00098 // 1-4   Size of the message (without header) in bytes
00099 // 5     id of the message
00100 // 6-9  timestamp
00101 // 10-?  content
00102 //
00103 
00104 In& operator>>(In& stream,MessageQueue& messageQueue)
00105 {
00106   unsigned int messageSize;
00107   char id,c;
00108   unsigned long timeStamp;
00109   bool last=false;
00110   char buffer[100000];
00111   while (!last)
00112   {
00113     stream >> c >> messageSize >> id >> timeStamp;
00114     ASSERT(messageSize<10*1024*1024);
00115     while(messageSize > 0)
00116     {
00117       unsigned int blockSize = messageSize > sizeof(buffer) ? sizeof(buffer) : messageSize;
00118       stream.read(buffer,blockSize); 
00119       messageQueue.out.bin.write(buffer,blockSize);
00120       messageSize -= blockSize;
00121     }
00122 
00123     // This might look strange but is needed for compability with old log files
00124     last = (c%2==1);
00125     messageQueue.out.finishMessage((MessageID)id,timeStamp,
00126       ((c>>1)%4==0? Player::undefinedTeamColor : (Player::teamColor)(((c>>1)%4)-1)),
00127       ((c>>3)%8==0? Player::undefinedPlayerNumber : (Player::playerNumber)(((c>>3)%8)-1)),
00128       (c>>6)==0);
00129 
00130 #ifdef _WIN32
00131     //its only the last message, if message marker *and* stream claim that
00132     //this way we can read appended log files *and* find last message in memory
00133     last &= stream.eof();
00134     //this only works on PC, because on robots memory of known size (different
00135     //from length of messages in it) is used in Receiver
00136 #endif
00137   }
00138   return stream;
00139 }
00140 
00141 int MessageQueue::getStreamedSize()
00142 {
00143   int size = 0;
00144 
00145   for (int i=0; i< queue.getNumberOfMessages(); i++)
00146   {
00147     queue.setSelectedMessageForReading(i);
00148     size += in.getMessageSize() + 10;
00149   }
00150   return size;
00151 }
00152 
00153 Out& operator<<(Out& stream, const MessageQueue& messageQueue)
00154 {
00155   for (int i=0; i< messageQueue.queue.getNumberOfMessages(); i++)
00156   {
00157     // check if the message is the last streamed message
00158     bool last = (i == messageQueue.queue.getNumberOfMessages()-1);
00159 
00160     ((MessageQueue&)messageQueue).queue.setSelectedMessageForReading(i);
00161 
00162     // This might look strange but is needed for compability with old log files
00163     char c = (char)(last)
00164       + (((char)messageQueue.in.getTeamColor()+1) << 1)
00165       + (((char)messageQueue.in.getPlayerNumber()+1) << 3)
00166       + (((char)!messageQueue.in.getMessageWasSentFromAPhysicalRobot()) << 6);
00167 
00168     // write message parameters to the stream
00169     stream << c
00170       << messageQueue.in.getMessageSize() 
00171       << (char)messageQueue.in.getMessageID()
00172       << messageQueue.in.getTimeStamp();
00173 
00174     // write message content
00175     stream.write(messageQueue.in.getData(),messageQueue.in.getMessageSize());
00176   }
00177   return stream;
00178 }
00179 
00180 void operator >> (InMessage& message, MessageQueue& queue)
00181 {
00182   queue.out.bin.write(message.getData(),message.getMessageSize());
00183   queue.out.finishMessage(message.getMessageID(),
00184     message.getTimeStamp(),
00185     message.getTeamColor(),
00186     message.getPlayerNumber(),
00187     message.getMessageWasSentFromAPhysicalRobot());
00188 }
00189 
00190 /*
00191 * Change Log:
00192 *
00193 * $Log: MessageQueue.cpp,v $
00194 * Revision 1.2  2004/06/21 18:05:41  dueffert
00195 * support for appended log files added
00196 *
00197 * Revision 1.1.1.1  2004/05/22 17:37:18  cvsadm
00198 * created new repository GT2004_WM
00199 *
00200 * Revision 1.5  2004/03/18 18:04:25  roefer
00201 * idJPEGImage repaired
00202 *
00203 * Revision 1.4  2004/01/17 20:55:34  loetzsch
00204 * bug fix in getStreamedSize()
00205 *
00206 * Revision 1.3  2004/01/10 18:04:58  loetzsch
00207 * added MessageQueue::getStreamedSize()
00208 *
00209 * Revision 1.2  2003/12/06 23:23:55  loetzsch
00210 * messages in a MessageQueue now contain
00211 * - the team color of the robot which sent the message
00212 * - the player number of the robot which sent the message
00213 * - if the message was sent from a physical robot or not
00214 *
00215 * Revision 1.1  2003/10/07 10:13:24  cvsadm
00216 * Created GT2004 (M.J.)
00217 *
00218 * Revision 1.1.1.1  2003/07/02 09:40:28  cvsadm
00219 * created new repository for the competitions in Padova from the 
00220 * tamara CVS (Tuesday 2:00 pm)
00221 *
00222 * removed unused solutions
00223 *
00224 * Revision 1.6  2003/05/09 11:40:50  goehring
00225 * Assertion for >10MByte messages implemented
00226 *
00227 * Revision 1.5  2003/03/06 11:56:46  dueffert
00228 * signed comparison warnings removed
00229 *
00230 * Revision 1.4  2003/02/05 13:31:44  loetzsch
00231 * added
00232 *       in.config.reset();
00233 *       in.text.reset();
00234 * to MessageQueue::handleSpecificMessages()
00235 *
00236 * Revision 1.3  2003/02/05 12:37:14  dueffert
00237 * handleSpecificMessage added
00238 *
00239 * Revision 1.2  2003/01/26 19:37:16  loetzsch
00240 * In ::handleMessage() now for every message
00241 *     in.config.reset();
00242 *     in.text.reset();
00243 * is called.
00244 *
00245 * Revision 1.1  2002/09/10 15:53:59  cvsadm
00246 * Created new project GT2003 (M.L.)
00247 * - Cleaned up the /Src/DataTypes directory
00248 * - Removed challenge related source code
00249 * - Removed processing of incoming audio data
00250 * - Renamed AcousticMessage to SoundRequest
00251 *
00252 * Revision 1.3  2002/08/08 16:38:47  loetzsch
00253 * moved some members to the derived class LogPlayer because they are not
00254 * needed in the normal MessageQueue
00255 *
00256 * Revision 1.2  2002/07/27 19:07:50  roefer
00257 * Streaming operator is more efficient now
00258 *
00259 * Revision 1.1  2002/07/23 13:47:14  loetzsch
00260 * - new streaming classes
00261 * - new debug message handling
00262 * - exchanged StaticQueue by MessageQueue
00263 *
00264 */
00265 

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