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

Platform/Aperios1.3.2/MessageQueueBase.cpp

Go to the documentation of this file.
00001 /**
00002 * @file Platform/Aperios1.3.2/MessageQueueBase.cpp
00003 * 
00004 * Implementation of class MessageQueueBase for Aperios.
00005 *
00006 * @author Martin Lötzsch
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); // write the size of the message
00072     memcpy(buf + nextMessagePosition + 4, (char*)&id, 1); // write the id of the message
00073     memcpy(buf + nextMessagePosition + 5, &timeStamp, 4); // write the timeStamp
00074     memcpy(buf + nextMessagePosition + 9, (char*)&teamColor, 1); // write the team color 
00075     memcpy(buf + nextMessagePosition + 10,(char*)&playerNumber, 1); // write the player number
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       //allow up to 20 idTexts in realtime mode, because several of that kind may be send simultaneously:
00137       copy = --messagesPerType[getMessageID()] <= 20;
00138       break;
00139     default:
00140       copy = --messagesPerType[getMessageID()] == 0;
00141     }
00142     if(copy)
00143     {
00144       //this message is important, it is the last of its type, it shall be copied
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 * Change log :
00248 * 
00249 * $Log: MessageQueueBase.cpp,v $
00250 * Revision 1.1.1.1  2004/05/22 17:23:26  cvsadm
00251 * created new repository GT2004_WM
00252 *
00253 * Revision 1.4  2004/04/14 14:48:56  roefer
00254 * Fixing replaceRepetitions for idStopwatch, 3rd try
00255 *
00256 * Revision 1.3  2004/03/05 15:49:47  dueffert
00257 * 20 idTexts in realtime mode
00258 *
00259 * Revision 1.2  2003/12/06 23:23:55  loetzsch
00260 * messages in a MessageQueue now contain
00261 * - the team color of the robot which sent the message
00262 * - the player number of the robot which sent the message
00263 * - if the message was sent from a physical robot or not
00264 *
00265 * Revision 1.1  2003/10/07 10:06:59  cvsadm
00266 * Created GT2004 (M.J.)
00267 *
00268 * Revision 1.2  2003/09/26 11:36:26  juengel
00269 * - sorted tools
00270 * - clean-up in DataTypes
00271 *
00272 * Revision 1.1.1.1  2003/07/02 09:40:24  cvsadm
00273 * created new repository for the competitions in Padova from the 
00274 * tamara CVS (Tuesday 2:00 pm)
00275 *
00276 * removed unused solutions
00277 *
00278 * Revision 1.8  2003/06/22 12:55:24  roefer
00279 * Stopwatch RT compatible (2nd try)
00280 *
00281 * Revision 1.7  2003/06/13 21:46:47  roefer
00282 * Real time mode now supports debug drawings
00283 *
00284 * Revision 1.6  2003/03/06 11:56:25  dueffert
00285 * re-order warning removed
00286 *
00287 * Revision 1.5  2002/12/19 11:48:34  roefer
00288 * ASSERT moved
00289 *
00290 * Revision 1.4  2002/12/16 23:49:44  roefer
00291 * removeRepetitions sets nextMessagePosition
00292 *
00293 * Revision 1.3  2002/12/06 16:28:45  dueffert
00294 * bug fixed: real time mode works now
00295 *
00296 * Revision 1.2  2002/12/05 16:13:07  dueffert
00297 * started implementing realtime sending
00298 *
00299 * Revision 1.1  2002/09/10 15:40:04  cvsadm
00300 * Created new project GT2003 (M.L.)
00301 * - Cleaned up the /Src/DataTypes directory
00302 * - Removed challenge related source code
00303 * - Removed processing of incoming audio data
00304 * - Renamed AcousticMessage to SoundRequest
00305 *
00306 * Revision 1.4  2002/09/03 14:43:06  dueffert
00307 * bug fixed
00308 *
00309 * Revision 1.3  2002/08/30 17:10:57  dueffert
00310 * removed unused includes
00311 *
00312 * Revision 1.2  2002/08/10 17:09:24  roefer
00313 * ASSERT bug fixed
00314 *
00315 * Revision 1.1  2002/07/23 13:36:39  loetzsch
00316 * - exchanged StaticQueue by MessageQueue with platform dependend
00317 *   base classes
00318 *
00319 */

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