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