00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #include "Aria.h"
00027 #include "ArExport.h"
00028 #include "ArServerHandlerMap.h"
00029 #ifdef WIN32
00030 #include <sys/types.h>
00031 #include <sys/stat.h>
00032 #endif
00033
00034
00045 AREXPORT ArServerHandlerMap::ArServerHandlerMap(ArServerBase *server,
00046 ArMap *arMap,
00047 DataToSend dataToSend) :
00048 myGetMapNameCB(this, &ArServerHandlerMap::serverGetMapName),
00049 myGetMapCB(this, &ArServerHandlerMap::serverGetMap),
00050 myGetMapBinaryCB(this, &ArServerHandlerMap::serverGetMapBinary),
00051 myGetGoalsCB(this, &ArServerHandlerMap::serverGetGoals),
00052 myProcessFileCB(this, &ArServerHandlerMap::processFile),
00053 myMapChangedCB(this, &ArServerHandlerMap::mapChanged)
00054 {
00055 myServer = server;
00056 myOwnMap = false;
00057 myMap = arMap;
00058 setDataToSend(dataToSend);
00059 myMapChangedCB.setName("ArServerHandlerMap");
00060 myProcessFileCB.setName("ArServerHandlerMap");
00061 if (myMap != NULL)
00062 {
00063 strcpy(myMapFileName, myMap->getFileName());
00064 myAlreadyLoaded = false;
00065 myOwnMap = false;
00066 myMap->addMapChangedCB(&myMapChangedCB, ArListPos::FIRST);
00067 }
00068 else
00069 {
00070 myMapFileName[0] = '\0';
00071 Aria::getConfig()->addParam(ArConfigArg("Map", myMapFileName,
00072 "map file to load",
00073 sizeof(myMapFileName)),
00074 "Files",
00075 ArPriority::IMPORTANT);
00076 Aria::getConfig()->setSectionComment("Files",
00077 "The files where important data is stored");
00078 Aria::getConfig()->addProcessFileCB(&myProcessFileCB, 95);
00079 }
00080
00081
00082 if (myServer != NULL)
00083 {
00084 myServer->addData("getMapName", "gets the name of the map being used",
00085 &myGetMapNameCB, "none", "string: map name (empty string if no maps)", "Map", "RETURN_SINGLE");
00086
00087
00088 myServer->addData("getMapBinary", "gets the map objects as ascii and the data points as binary",
00089 &myGetMapBinaryCB,
00090 "none",
00091 "packets of '<string>: line' for header, followed by packets of '<byte4>: numPtsInPacket, (<double>:x, <double>:y)*' until numPtsInPacket == 0",
00092 "Map", "RETURN_UNTIL_EMPTY");
00093 myServer->addData("getMap", "gets the map as a set of ascii lines",
00094 &myGetMapCB, "none",
00095 "packets of '<string>: line' followed by a packet with an empty string to denote end (if only empty string then no map)",
00096 "Map", "RETURN_UNTIL_EMPTY");
00097 myServer->addData("mapUpdated", "a single packet is sent to this when the map is updated and this denotes a new getMap and getMapName should be requested",
00098 NULL, "none", "none",
00099 "Map", "RETURN_SINGLE");
00100 myServer->addData("getGoals", "gets the list of goals",
00101 &myGetGoalsCB, "none",
00102 "<repeat> string: goal", "Map", "RETURN_SINGLE");
00103 myServer->addData("goalsUpdated", "a single packet is sent to this when the goals are updated and this denotes a new getGoals should be requested",
00104 NULL, "none", "none",
00105 "Map", "RETURN_SINGLE");
00106
00107 }
00108 }
00109
00110 AREXPORT ArServerHandlerMap::~ArServerHandlerMap()
00111 {
00112
00113 }
00114
00115 AREXPORT bool ArServerHandlerMap::loadMap(const char *mapFile)
00116 {
00117 bool ret;
00118 ArNetPacket emptyPacket;
00119 if (myMap != NULL)
00120 {
00121 if (myOwnMap)
00122 delete myMap;
00123 myMap = NULL;
00124 }
00125 myMap = new ArMap(NULL, false);
00126 myMapName = mapFile;
00127 myOwnMap = true;
00128 ret = myMap->readFile(mapFile);
00129 myServer->broadcastPacketTcp(&emptyPacket, "mapUpdated");
00130 myServer->broadcastPacketTcp(&emptyPacket, "goalsUpdated");
00131 return ret;
00132 }
00133
00137 AREXPORT void ArServerHandlerMap::useMap(ArMap *mapObj,
00138 bool takeOwnershipOfMap)
00139 {
00140 ArNetPacket emptyPacket;
00141 if (myMap != NULL)
00142 {
00143 if (myOwnMap)
00144 delete myMap;
00145 myMap = NULL;
00146 }
00147 myMap = mapObj;
00148 myMapName = myMap->getFileName();
00149 myOwnMap = takeOwnershipOfMap;
00150 myServer->broadcastPacketTcp(&emptyPacket, "mapUpdated");
00151 myServer->broadcastPacketTcp(&emptyPacket, "goalsUpdated");
00152 }
00153
00154 AREXPORT ArMap *ArServerHandlerMap::getMap(void)
00155 {
00156 return myMap;
00157 }
00158
00160 AREXPORT void ArServerHandlerMap::serverGetMapName(ArServerClient *client,
00161 ArNetPacket *packet)
00162 {
00163 ArNetPacket sendPacket;
00164 if (myMap == NULL)
00165 {
00166 sendPacket.strToBuf("");
00167 client->sendPacketTcp(&sendPacket);
00168 }
00169 else
00170 {
00171 sendPacket.strToBuf(myMap->getFileName());
00172 client->sendPacketTcp(&sendPacket);
00173 }
00174 }
00175
00177 AREXPORT void ArServerHandlerMap::writeMapToClient(const char *line,
00178 ArServerClient *client)
00179 {
00180 ArNetPacket sendPacket;
00181 sendPacket.strToBuf(line);
00182 client->sendPacketTcp(&sendPacket);
00183 }
00184
00186 AREXPORT void ArServerHandlerMap::writePointsToClient(
00187 int pointCount,
00188 std::vector<ArPose> *points,
00189 ArServerClient *client)
00190 {
00191 ArNetPacket sendPacket;
00192
00193
00194 if (points == NULL) {
00195
00196 sendPacket.byte4ToBuf(0);
00197 client->sendPacketTcp(&sendPacket);
00198 return;
00199 }
00200
00201 ArLog::log(ArLog::Verbose,
00202 "ArServerHandlerMap::writePointsToClient() pointCount = %i, vector size = %i",
00203 pointCount, (int) points->size());
00204
00205
00206 if (pointCount > (int) points->size()) {
00207 pointCount = points->size();
00208 }
00209
00210 int maxInPacketCount = 1000;
00211 int currentCount = 0;
00212 int remainingCount = pointCount;
00213 bool isStartPacket = true;
00214
00215 int totalCount = 0;
00216
00217 for (std::vector<ArPose>::iterator pointIt = points->begin();
00218 pointIt != points->end();
00219 pointIt++) {
00220
00221
00222
00223 if (isStartPacket) {
00224
00225 isStartPacket = false;
00226
00227 sendPacket.empty();
00228 currentCount = 0;
00229
00230
00231 if (maxInPacketCount > remainingCount) {
00232 maxInPacketCount = remainingCount;
00233 }
00234
00235
00236 sendPacket.byte4ToBuf(maxInPacketCount);
00237
00238 }
00239
00240
00241
00242 if (currentCount < maxInPacketCount) {
00243
00244 currentCount++;
00245 remainingCount--;
00246
00247 sendPacket.byte4ToBuf(
00248 ArMath::roundInt((*pointIt).getX()));
00249 sendPacket.byte4ToBuf(
00250 ArMath::roundInt((*pointIt).getY()));
00251 }
00252
00253
00254 if (currentCount == maxInPacketCount) {
00255
00256 totalCount += currentCount;
00257
00258 client->sendPacketTcp(&sendPacket);
00259
00260
00261 isStartPacket = true;
00262 }
00263
00264 }
00265
00266 ArLog::log(ArLog::Verbose,
00267 "ArServerHandlerMap::writePointsToClient() totalCount = %i",
00268 totalCount);
00269
00270
00271 sendPacket.empty();
00272 sendPacket.byte4ToBuf(0);
00273 client->sendPacketTcp(&sendPacket);
00274
00275 }
00276
00278 AREXPORT void ArServerHandlerMap::writeLinesToClient(
00279 int lineCount,
00280 std::vector<ArLineSegment> *lines,
00281 ArServerClient *client)
00282 {
00283 ArNetPacket sendPacket;
00284
00285
00286 if (lines == NULL) {
00287
00288 sendPacket.byte4ToBuf(0);
00289 client->sendPacketTcp(&sendPacket);
00290 return;
00291 }
00292
00293 ArLog::log(ArLog::Verbose,
00294 "ArServerHandlerMap::writeLinesToClient() pointCount = %i, vector size = %i",
00295 lineCount, (int) lines->size());
00296
00297
00298 if (lineCount > (int) lines->size()) {
00299 lineCount = lines->size();
00300 }
00301
00302 int maxInPacketCount = 1000;
00303 int currentCount = 0;
00304 int remainingCount = lineCount;
00305 bool isStartPacket = true;
00306
00307 int totalCount = 0;
00308
00309 for (std::vector<ArLineSegment>::iterator lineIt = lines->begin();
00310 lineIt != lines->end();
00311 lineIt++)
00312 {
00313
00314
00315
00316 if (isStartPacket) {
00317
00318 isStartPacket = false;
00319
00320 sendPacket.empty();
00321 currentCount = 0;
00322
00323
00324 if (maxInPacketCount > remainingCount) {
00325 maxInPacketCount = remainingCount;
00326 }
00327
00328
00329 sendPacket.byte4ToBuf(maxInPacketCount);
00330
00331 }
00332
00333
00334
00335 if (currentCount < maxInPacketCount) {
00336
00337 currentCount++;
00338 remainingCount--;
00339
00340 sendPacket.byte4ToBuf(
00341 ArMath::roundInt((*lineIt).getX1()));
00342 sendPacket.byte4ToBuf(
00343 ArMath::roundInt((*lineIt).getY1()));
00344 sendPacket.byte4ToBuf(
00345 ArMath::roundInt((*lineIt).getX2()));
00346 sendPacket.byte4ToBuf(
00347 ArMath::roundInt((*lineIt).getY2()));
00348 }
00349
00350
00351 if (currentCount == maxInPacketCount) {
00352
00353 totalCount += currentCount;
00354
00355 client->sendPacketTcp(&sendPacket);
00356
00357
00358 isStartPacket = true;
00359 }
00360
00361 }
00362
00363 ArLog::log(ArLog::Verbose,
00364 "ArServerHandlerMap::writePointsToClient() totalCount = %i",
00365 totalCount);
00366
00367
00368 sendPacket.empty();
00369 sendPacket.byte4ToBuf(0);
00370 client->sendPacketTcp(&sendPacket);
00371
00372 }
00373
00374
00376 AREXPORT void ArServerHandlerMap::serverGetMap(ArServerClient *client,
00377 ArNetPacket *packet)
00378 {
00379 ArLog::log(ArLog::Verbose, "Starting sending map to client");
00380 if (myMap == NULL)
00381 {
00382 writeMapToClient("", client);
00383 return;
00384 }
00385
00386 myMap->lock();
00387
00388 ArFunctor1<const char *> *functor =
00389 new ArFunctor2C<ArServerHandlerMap, const char *, ArServerClient *>
00390 (this,
00391 &ArServerHandlerMap::writeMapToClient,
00392 NULL,
00393 client);
00394
00395 myMap->writeToFunctor(functor, "");
00396
00397 delete functor;
00398
00399 writeMapToClient("", client);
00400
00401
00402 ArNetPacket emptyPacket;
00403 client->sendPacketTcp(&emptyPacket);
00404
00405 myMap->unlock();
00406 ArLog::log(ArLog::Verbose, "Finished sending map to client");
00407
00408 }
00409
00410 AREXPORT void ArServerHandlerMap::serverGetMapBinary(ArServerClient *client,
00411 ArNetPacket *packet)
00412 {
00413 ArLog::log(ArLog::Verbose, "Starting sending map (binary) to client");
00414 if (myMap == NULL)
00415 {
00416 writeMapToClient("", client);
00417 return;
00418 }
00419
00420 myMap->lock();
00421
00422 ArFunctor1<const char *> *textFunctor =
00423 new ArFunctor2C<ArServerHandlerMap, const char *, ArServerClient *>
00424 (this,
00425 &ArServerHandlerMap::writeMapToClient,
00426 NULL,
00427 client);
00428
00429
00430
00431 ArFunctor2<int, std::vector<ArLineSegment> *> *linesFunctor =
00432 new ArFunctor3C<ArServerHandlerMap, int, std::vector<ArLineSegment> *, ArServerClient *>
00433 (this,
00434 &ArServerHandlerMap::writeLinesToClient,
00435 0,
00436 NULL,
00437 client);
00438
00439
00440
00441 ArFunctor2<int, std::vector<ArPose> *> *pointsFunctor =
00442 new ArFunctor3C<ArServerHandlerMap, int, std::vector<ArPose> *, ArServerClient *>
00443 (this,
00444 &ArServerHandlerMap::writePointsToClient,
00445 0,
00446 NULL,
00447 client);
00448
00449
00450 myMap->writeObjectsToFunctor(textFunctor, "");
00451
00452
00453 if ((myDataToSend == LINES || myDataToSend == BOTH) &&
00454 myMap->getLines()->begin() != myMap->getLines()->end())
00455 {
00456 writeMapToClient("LINES", client);
00457 myMap->writeLinesToFunctor(linesFunctor);
00458 }
00459
00460
00461
00462
00463
00464 writeMapToClient("DATA", client);
00465
00466 if (myDataToSend == POINTS || myDataToSend == BOTH)
00467 myMap->writePointsToFunctor(pointsFunctor);
00468
00469 else
00470 writeMapToClient("", client);
00471
00472
00473
00474 ArNetPacket emptyPacket;
00475 client->sendPacketTcp(&emptyPacket);
00476
00477 myMap->unlock();
00478 ArLog::log(ArLog::Verbose, "Finished sending map (binary) to client");
00479
00480 }
00481
00482
00484 AREXPORT void ArServerHandlerMap::serverGetGoals(ArServerClient *client,
00485 ArNetPacket *packet)
00486 {
00487 std::list<ArMapObject *>::iterator objIt;
00488 ArMapObject* obj;
00489 ArPose goal;
00490 ArNetPacket sendPacket;
00491
00492 for (objIt = myMap->getMapObjects()->begin();
00493 objIt != myMap->getMapObjects()->end();
00494 objIt++)
00495 {
00496
00497
00498
00499 obj = (*objIt);
00500 if (obj == NULL)
00501 break;
00502 if (strcasecmp(obj->getType(), "GoalWithHeading") == 0 ||
00503 strcasecmp(obj->getType(), "Goal") == 0)
00504 {
00505 sendPacket.strToBuf(obj->getName());
00506 }
00507 }
00508 client->sendPacketTcp(&sendPacket);
00509 }
00510
00511 AREXPORT void ArServerHandlerMap::mapChanged(void)
00512 {
00513 ArNetPacket emptyPacket;
00514 strcpy(myMapFileName, myMap->getFileName());
00515 myServer->broadcastPacketTcp(&emptyPacket, "mapUpdated");
00516 myServer->broadcastPacketTcp(&emptyPacket, "goalsUpdated");
00517 }
00518
00520 AREXPORT bool ArServerHandlerMap::processFile(void)
00521 {
00522 struct stat mapFileStat;
00523
00524 if (myMapFileName[0] == '\0')
00525 {
00526 ArLog::log(ArLog::Verbose, "ArServerHandlerMap::processFile: No map file");
00527 return true;
00528 }
00529
00530 if (stat(myMapFileName, &mapFileStat) != 0)
00531 {
00532 ArLog::log(ArLog::Terse, "Cannot stat file");
00533 return false;
00534 }
00535
00536 if (!myAlreadyLoaded || strcmp(myMapFileName, myLastMapFile) != 0 ||
00537 mapFileStat.st_mtime != myLastMapFileStat.st_mtime ||
00538 mapFileStat.st_ctime != myLastMapFileStat.st_ctime)
00539 {
00540 myAlreadyLoaded = true;
00541 strcpy(myLastMapFile, myMapFileName);
00542 memcpy(&myLastMapFileStat, &mapFileStat, sizeof(mapFileStat));
00543
00544 ArLog::log(ArLog::Terse, "Loading map %s", myMapFileName);
00545 if (!loadMap(myMapFileName))
00546 {
00547 ArLog::log(ArLog::Terse, "Failed loading map %s", myMapFileName);
00548 return false;
00549 }
00550 ArLog::log(ArLog::Terse, "Loaded map %s", myMapFileName);
00551 return true;
00552 }
00553 myAlreadyLoaded = true;
00554 ArLog::log(ArLog::Normal, "ArServerHandlerMapConfig: File did not need reloading");
00555 return true;
00556 }
00557