00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 #include "MessageQueueBase.h"
00010 #include "GTAssert.h"
00011 #include "SystemCall.h"
00012 #include "Tools/Debugging/DebugDrawings.h"
00013 #include "Tools/Debugging/Stopwatch.h"
00014 #include <stdlib.h>
00015 #include <string.h>
00016 
00017 MessageQueueBase::MessageQueueBase()
00018 : buf(0), queueSize(0)
00019 {
00020   clear();
00021 }
00022 
00023 MessageQueueBase::~MessageQueueBase()
00024 {
00025   if (buf != 0) delete[] buf;
00026 }
00027 
00028 void MessageQueueBase::setSize(int size)
00029 {
00030   ASSERT(buf == 0);
00031   buf = (char*)malloc(size);
00032   queueSize = size;
00033   ASSERT(buf);
00034 }
00035 
00036 void MessageQueueBase::clear()
00037 {
00038   nextMessagePosition = 0;
00039   numOfMessages = 0;
00040   nextMessageSize = 0;
00041   writingOfLastMessageFailed = false;
00042   selectedMessageForReadingPosition = 0;
00043   readPosition = 0;
00044 }
00045 
00046 int MessageQueueBase::getNumberOfMessages() const
00047 {
00048   return numOfMessages;
00049 }
00050 
00051 void MessageQueueBase::write(const void* p,int size)
00052 {
00053   if (nextMessagePosition + 12 + nextMessageSize + size >= queueSize)
00054   {
00055     writingOfLastMessageFailed = true;
00056   }
00057   else
00058   {
00059     memcpy(buf + nextMessagePosition + 12 + nextMessageSize, p, size);
00060     nextMessageSize += size;
00061   }
00062 }
00063 
00064 void MessageQueueBase::finishMessage(MessageID id, unsigned long timeStamp,
00065     Player::teamColor teamColor,Player::playerNumber playerNumber,
00066     bool messageWasSentFromAPhysicalRobot)
00067 {
00068   if (!writingOfLastMessageFailed)
00069   {
00070     ASSERT(nextMessageSize > 0);
00071     memcpy(buf + nextMessagePosition, &nextMessageSize, 4); 
00072     memcpy(buf + nextMessagePosition + 4, (char*)&id, 1); 
00073     memcpy(buf + nextMessagePosition + 5, &timeStamp, 4); 
00074     memcpy(buf + nextMessagePosition + 9, (char*)&teamColor, 1); 
00075     memcpy(buf + nextMessagePosition + 10,(char*)&playerNumber, 1); 
00076     memcpy(buf + nextMessagePosition + 11,(char*)&messageWasSentFromAPhysicalRobot, 1); 
00077     numOfMessages++;
00078     nextMessagePosition += nextMessageSize + 12;
00079   }
00080   nextMessageSize = 0;
00081   writingOfLastMessageFailed = false;
00082 }
00083 
00084 void MessageQueueBase::removeRepetitions()
00085 {
00086   int messagesPerType[numOfMessageIDs],
00087       fieldDrawings[Drawings::numberOfFieldDrawings],
00088       imageDrawings[Drawings::numberOfImageDrawings],
00089       stopWatches[Stopwatch::numberOfStopwatchEventIDs];
00090   memset(messagesPerType,0,sizeof(messagesPerType));
00091   memset(fieldDrawings,0,sizeof(fieldDrawings));
00092   memset(imageDrawings,0,sizeof(imageDrawings));
00093   memset(stopWatches,0,sizeof(stopWatches));
00094   selectedMessageForReadingPosition=0;
00095   int i;
00096   for (i=0;i<numOfMessages;i++)
00097   {
00098     if(getMessageID() == idDebugDrawingFinished)
00099     {
00100       if(Drawings::TypeOfDrawing(getData()[1]) == Drawings::drawingOnField)
00101         fieldDrawings[int(getData()[0])]++;
00102       else
00103         imageDrawings[int(getData()[0])]++;
00104     }
00105     else if(getMessageID() == idStopwatch)
00106       stopWatches[int(getData()[0])]++;
00107     else
00108       messagesPerType[getMessageID()]++;
00109     selectedMessageForReadingPosition += getMessageSize() + 12;
00110   }
00111   selectedMessageForReadingPosition=0;
00112   nextMessagePosition = 0;
00113   int numOfDeleted=0;
00114   for (i=0; i < numOfMessages; i++)
00115   {
00116     int mlength = getMessageSize() + 12;
00117     bool copy;
00118     switch (getMessageID())
00119     {
00120     case idDebugDrawingFinished:
00121       if(Drawings::TypeOfDrawing(getData()[1]) == Drawings::drawingOnField)
00122         copy = --fieldDrawings[int(getData()[0])] == 0;
00123       else 
00124         copy = --imageDrawings[int(getData()[0])] == 0;
00125       break;
00126     case idDebugDrawing2:
00127       if(Drawings::TypeOfDrawing(getData()[2]) == Drawings::drawingOnField)
00128         copy = fieldDrawings[int(getData()[1])] <= 1;
00129       else
00130         copy = imageDrawings[int(getData()[1])] <= 1;
00131       break;
00132     case idStopwatch:
00133       copy = --stopWatches[int(getData()[0])] == 0;
00134       break;
00135     case idText:
00136       
00137       copy = --messagesPerType[getMessageID()] <= 20;
00138       break;
00139     default:
00140       copy = --messagesPerType[getMessageID()] == 0;
00141     }
00142     if(copy)
00143     {
00144       
00145       for (int l=0;l<mlength;l++)
00146       {
00147         buf[nextMessagePosition++] = buf[selectedMessageForReadingPosition++];
00148       }
00149     }
00150     else
00151     {
00152       numOfDeleted++;
00153       selectedMessageForReadingPosition += mlength;
00154     }
00155   }
00156   readPosition=0;
00157   numOfMessages -= numOfDeleted;
00158 }
00159 
00160 void MessageQueueBase::setSelectedMessageForReading(int message)
00161 {
00162   ASSERT(message >= 0);
00163   ASSERT(message < numOfMessages);
00164 
00165   selectedMessageForReadingPosition = 0;
00166   for (int i=0; i < message; i++)
00167   {
00168     selectedMessageForReadingPosition += getMessageSize() + 12;
00169   }
00170   readPosition = 0;
00171 }
00172 
00173 void MessageQueueBase::read(void* p,int size)
00174 {
00175   ASSERT(readPosition + size <= getMessageSize());
00176   memcpy(p,buf + selectedMessageForReadingPosition + 12 + readPosition, size);
00177   readPosition += size;
00178 } 
00179 
00180 const char* MessageQueueBase::getData() const
00181 {
00182   return buf + selectedMessageForReadingPosition + 12;
00183 }
00184 
00185 int MessageQueueBase::getMessageSize() const
00186 {
00187   int size;
00188   memcpy(&size, buf + selectedMessageForReadingPosition, 4);
00189   return size;
00190 }
00191 
00192 
00193 void MessageQueueBase::resetReadPosition()
00194 {
00195   readPosition = 0;
00196 }
00197 
00198 unsigned long MessageQueueBase::getTimeStamp() const
00199 {
00200   unsigned long timeStamp;
00201   memcpy(&timeStamp, buf + selectedMessageForReadingPosition + 5, 4);
00202   return timeStamp;
00203 }
00204 
00205 unsigned long MessageQueueBase::getTimeStamp(int message)
00206 {
00207   setSelectedMessageForReading(message);
00208   return getTimeStamp();
00209 }
00210 
00211 MessageID MessageQueueBase::getMessageID() const
00212 {
00213   char id;
00214   memcpy(&id, buf + selectedMessageForReadingPosition + 4, 1);
00215   return (MessageID)id;
00216 }
00217 
00218 Player::teamColor MessageQueueBase::getTeamColor() const
00219 {
00220   char color;
00221   memcpy(&color, buf + selectedMessageForReadingPosition + 9, 1);
00222   return (Player::teamColor)color;
00223 }
00224 
00225 Player::playerNumber MessageQueueBase::getPlayerNumber() const
00226 {
00227   char number;
00228   memcpy(&number, buf + selectedMessageForReadingPosition + 10, 1);
00229   return (Player::playerNumber)number;
00230 }
00231 
00232 bool MessageQueueBase::getMessageWasSentFromAPhysicalRobot() const
00233 {
00234   char b;
00235   memcpy(&b, buf + selectedMessageForReadingPosition + 11, 1);
00236   return (bool)b;
00237 }
00238 
00239 
00240 bool MessageQueueBase::eof() const
00241 {
00242   return readPosition == getMessageSize();
00243 }
00244 
00245 
00246 
00247 
00248 
00249 
00250 
00251 
00252 
00253 
00254 
00255 
00256 
00257 
00258 
00259 
00260 
00261 
00262 
00263 
00264 
00265 
00266 
00267 
00268 
00269 
00270 
00271 
00272 
00273 
00274 
00275 
00276 
00277 
00278 
00279 
00280 
00281 
00282 
00283 
00284 
00285 
00286 
00287 
00288 
00289 
00290 
00291 
00292 
00293 
00294 
00295 
00296 
00297 
00298 
00299 
00300 
00301 
00302 
00303 
00304 
00305 
00306 
00307 
00308 
00309 
00310 
00311 
00312 
00313 
00314 
00315 
00316 
00317 
00318 
00319