SimpleGameClient Class Reference

#include <SimpleGameClient.h>

Inheritance diagram for SimpleGameClient:

BaseApp BaseRpc RpcListener

List of all members.


Detailed Description

SimpleGameClient class.

A simple test application, which simulates node movement based on different movement generators.

Public Member Functions

virtual ~SimpleGameClient ()
virtual void initializeApp (int stage)
 initializes derived class-attributes
virtual void handleTimerEvent (cMessage *msg)
 processes self-messages
virtual void handleLowerMessage (cMessage *msg)
 method to handle non-commonAPI messages from the overlay
virtual void handleReadyMessage (CompReadyMessage *msg)
 method to handle ready messages from the overlay

Protected Member Functions

void updateNeighbors (GameAPIListMessage *sgcMsg)
void updatePosition ()
void handleRealworldPacket (char *buf, uint32_t len)

Protected Attributes

GlobalCoordinatorcoordinator
CollisionList CollisionRect
double movementDelay
double areaDimension
double movementSpeed
double movementRate
double AOIWidth
bool useScenery
bool overlayReady
Vector2D position
MovementGeneratorGenerator
NeighborMap Neighbors
NeighborMap::iterator itNeighbors
std::string GeneratorType
timeval startTime
cMessage * move_timer
cMessage * packetNotification
RealtimeScheduler::PacketBuffer packetBuffer
RealtimeSchedulerscheduler
unsigned int mtu
int appFd
bool doRealworld
bool frozen


Constructor & Destructor Documentation

SimpleGameClient::~SimpleGameClient (  )  [virtual]

00393 {
00394     // destroy self timer messages
00395     cancelAndDelete(move_timer);
00396     cancelAndDelete(packetNotification);
00397 }


Member Function Documentation

void SimpleGameClient::initializeApp ( int  stage  )  [virtual]

initializes derived class-attributes

Parameters:
stage the init stage

Reimplemented from BaseApp.

00029 {
00030     // all initialization is done in the first stage
00031     if (stage != MIN_STAGE_APP) {
00032         return;
00033     }
00034 
00035     // fetch parameters
00036     areaDimension = par("areaDimension");
00037     useScenery = par("useScenery");
00038     movementRate = par("movementRate");
00039     movementSpeed = par("movementSpeed");
00040     movementDelay= 1.0 / movementRate;
00041     AOIWidth = 0.0;
00042     int groupSize = (int)par("groupSize");
00043     if(groupSize < 1) {
00044         groupSize = 1;
00045     }
00046     GeneratorType = (std::string)par("movementGenerator");
00047 
00048     WATCH_MAP(Neighbors);
00049     WATCH_LIST(CollisionRect);
00050     WATCH(position);
00051     WATCH(GeneratorType);
00052     WATCH(overlayReady);
00053 
00054     doRealworld = false;
00055     coordinator = check_and_cast<GlobalCoordinator*>(simulation.moduleByPath("globalObserver.globalFunctions[0].coordinator"));
00056     scheduler = NULL;
00057     packetNotification = NULL;
00058 
00059     frozen = false;
00060 
00061     CollisionList* listPtr = NULL;
00062     if(useScenery == true) {
00063         listPtr = &CollisionRect;
00064     }
00065 
00066     double speed = movementDelay * movementSpeed;
00067     if(strcmp(GeneratorType.c_str(), "greatGathering") == 0) {
00068         if(debugOutput) {
00069             EV << "SIMPLECLIENT: Movement generator: greatGathering" << endl;
00070         }
00071         Generator = new greatGathering(areaDimension, speed, &Neighbors, coordinator, listPtr);
00072     }
00073     else if(strcmp(GeneratorType.c_str(), "groupRoaming") == 0) {
00074         if(debugOutput) {
00075             EV << "SIMPLECLIENT: Movement generator: groupRoaming" << endl;
00076         }
00077         Generator = new groupRoaming(areaDimension, speed, &Neighbors, coordinator, listPtr, groupSize);
00078     }
00079     else if(strcmp(GeneratorType.c_str(), "realWorldRoaming") == 0) {
00080         if(debugOutput) {
00081             EV << "SIMPLECLIENT: Movement generator: realWorldRoaming" << endl;
00082         }
00083         Generator = new realWorldRoaming(areaDimension, movementSpeed, &Neighbors, coordinator, listPtr);
00084         mtu = par("mtu");
00085         packetNotification = new cMessage("packetNotification");
00086         scheduler = check_and_cast<RealtimeScheduler*>(simulation.scheduler());
00087         scheduler->setInterfaceModule(this, packetNotification, &packetBuffer, mtu, true);
00088         appFd = -1;
00089     }
00090     else {
00091         // debug output
00092         if(debugOutput) {
00093             if(strcmp(GeneratorType.c_str(), "randomRoaming") == 0) {
00094                 EV << "SIMPLECLIENT: Movement generator: randomRoaming" << endl;
00095             }
00096             else {
00097                 EV << "SIMPLECLIENT: Movement generator: <unknown>. Defaulting to: randomRoaming" << endl;
00098             }
00099         }
00100         Generator = new randomRoaming(areaDimension, speed, &Neighbors, coordinator, listPtr);
00101     }
00102 
00103     // self-messages
00104     move_timer = new cMessage("move_timer");
00105     overlayReady = false;
00106 }

void SimpleGameClient::handleTimerEvent ( cMessage *  msg  )  [virtual]

processes self-messages

method to handle self-messages should be overwritten in derived application if needed

Parameters:
msg self-message

Reimplemented from BaseApp.

00109 {
00110     if(msg->isName("move_timer")) {
00111         //reset timer
00112         cancelEvent(move_timer);
00113         if(overlayReady) {
00114             scheduleAt(simulation.simTime() + movementDelay, msg);
00115         }
00116         // handle event
00117         updatePosition();
00118     }
00119     else if(msg->isName("packetNotification")) {
00120         while(packetBuffer.size() > 0) {
00121             // get packet from buffer and parse it
00122             RealtimeScheduler::PacketBufferEntry packet = *(packetBuffer.begin());
00123             packetBuffer.pop_front();
00124             switch (packet.func) {
00125                 case RealtimeScheduler::PacketBufferEntry::DATA: {
00126                     if(packet.fd != appFd) {
00127                         error("SimpleClient::handleMessage(): Received packet from unknown socket!");
00128                     }
00129                     handleRealworldPacket(packet.data, packet.length);
00130                 } break;
00131                 case RealtimeScheduler::PacketBufferEntry::FD_NEW: {
00132                     if(appFd != -1) {
00133                         error("SimpleClient::handleMessage(): Multiple connections not supported yet!");
00134                     }
00135                     appFd = packet.fd;
00136                 } break;
00137                 case RealtimeScheduler::PacketBufferEntry::FD_CLOSE: {
00138                     if(packet.fd != appFd) {
00139                         error("SimpleClient::handleMessage(): Trying to close unknown connection!");
00140                     }
00141                     appFd = -1;
00142                 } break;
00143             }
00144             delete packet.data;
00145         }
00146     }
00147     else if(msg->isName("Snowball landing")) {
00148         SCSnowTimer* snowTimer = check_and_cast<SCSnowTimer*>(msg);
00149         if(position.distanceSqr(snowTimer->getPosition() / 32 ) < 2) {
00150             // freeze me!
00151             frozen = true;
00152             cMessage* unfreeze = new cMessage("unfreeze me");
00153             scheduleAt(simulation.simTime() + 5, unfreeze);
00154 
00155             timeval now;
00156             gettimeofday(&now, NULL);
00157             GameAPIFrozenMessage* freeze = new GameAPIFrozenMessage("I'm frozen");
00158             freeze->setCommand(GAMEEVENT_FROZEN);
00159             freeze->setSrc(overlay->getThisNode());
00160             freeze->setTimeSec(now.tv_sec + 5);
00161             freeze->setTimeUsec(now.tv_usec);
00162             sendMessageToLowerTier(freeze);
00163 
00164             if(doRealworld) {
00165                 SCFrozenPacket scfreeze;
00166                 scfreeze.packetType = SC_EV_FROZEN;
00167                 scfreeze.ip = overlay->getThisNode().ip.get4().getInt();
00168                 scfreeze.time_sec = now.tv_sec + 5;
00169                 scfreeze.time_usec = now.tv_usec;
00170                 int packetlen = sizeof(scfreeze);
00171                 scheduler->sendBytes((const char*)&packetlen, sizeof(int), 0, 0, true, appFd);
00172                 scheduler->sendBytes((const char*)&scfreeze, packetlen, 0, 0, true, appFd);
00173             }
00174         }
00175         delete msg;
00176     }
00177     else if(msg->isName("unfreeze me")) {
00178         frozen = false;
00179         delete msg;
00180     }
00181 }

void SimpleGameClient::handleLowerMessage ( cMessage *  msg  )  [virtual]

method to handle non-commonAPI messages from the overlay

Parameters:
msg message to handle

Reimplemented from BaseApp.

00184 {
00185     if(dynamic_cast<GameAPIMessage*>(msg)) {
00186         GameAPIMessage* gameAPIMsg = check_and_cast<GameAPIMessage*>(msg);
00187         if(gameAPIMsg->getCommand() == MOVEMENT_REQUEST) {
00188             updatePosition();
00189         }
00190         else if(gameAPIMsg->getCommand() == NEIGHBOR_UPDATE) {
00191             GameAPIListMessage* gameAPIListMsg = check_and_cast<GameAPIListMessage*>(msg);
00192             updateNeighbors(gameAPIListMsg);
00193         }
00194         else if(gameAPIMsg->getCommand() == RESIZE_AOI) {
00195             GameAPIResizeAOIMessage* gameAPIResizeMsg = check_and_cast<GameAPIResizeAOIMessage*>(msg);
00196             AOIWidth = gameAPIResizeMsg->getAOIsize();
00197             if(doRealworld) {
00198                 SCAOIPacket packet;
00199                 packet.packetType = SC_RESIZE_AOI;
00200                 packet.AOI = AOIWidth;
00201                 int packetlen = sizeof(SCAOIPacket);
00202                 scheduler->sendBytes((const char*)&packetlen, sizeof(int), 0, 0, true, appFd);
00203                 scheduler->sendBytes((const char*)&packet, packetlen, 0, 0, true, appFd);
00204             }
00205         }
00206         else if(gameAPIMsg->getCommand() == GAMEEVENT_CHAT) {
00207             if(doRealworld) {
00208                 GameAPIChatMessage* chatMsg = check_and_cast<GameAPIChatMessage*>(msg);
00209                 const char* msg = chatMsg->getMsg();
00210                 int packetlen = sizeof(SCChatPacket) + strlen(msg) + 1;
00211                 SCChatPacket* pack = (SCChatPacket*)malloc(packetlen);
00212                 pack->packetType = SC_EV_CHAT;
00213                 pack->ip = chatMsg->getSrc().ip.get4().getInt();
00214                 strcpy(pack->msg, msg);
00215                 scheduler->sendBytes((const char*)&packetlen, sizeof(int), 0, 0, true, appFd);
00216                 scheduler->sendBytes((const char*)pack, packetlen, 0, 0, true, appFd);
00217                 free(pack);
00218             }
00219         }
00220         else if(gameAPIMsg->getCommand() == GAMEEVENT_SNOW) {
00221             GameAPISnowMessage* snowMsg = check_and_cast<GameAPISnowMessage*>(gameAPIMsg);
00222             if(doRealworld) {
00223                 SCSnowPacket packet;
00224                 packet.packetType = SC_EV_SNOWBALL;
00225                 packet.ip = snowMsg->getSrc().ip.get4().getInt();
00226                 packet.startX = snowMsg->getStart().x;
00227                 packet.startY = snowMsg->getStart().y;
00228                 packet.endX = snowMsg->getEnd().x;
00229                 packet.endY = snowMsg->getEnd().y;
00230                 packet.time_sec = snowMsg->getTimeSec();
00231                 packet.time_usec = snowMsg->getTimeUsec();
00232                 int packetlen = sizeof(SCSnowPacket);
00233                 scheduler->sendBytes((const char*)&packetlen, sizeof(int), 0, 0, true, appFd);
00234                 scheduler->sendBytes((const char*)&packet, packetlen, 0, 0, true, appFd);
00235             }
00236             SCSnowTimer* snowTimer = new SCSnowTimer("Snowball landing");
00237             snowTimer->setPosition(snowMsg->getEnd());
00238             timeval snowTime;
00239             snowTime.tv_sec = snowMsg->getTimeSec();
00240             snowTime.tv_usec = snowMsg->getTimeUsec();
00241             snowTime = timeval_substract(snowTime, startTime);
00242             simtime_t snow_t = snowTime.tv_sec + snowTime.tv_usec / 1000000.0;
00243             if(snow_t < simulation.simTime()) {
00244                 snow_t = simulation.simTime();
00245             }
00246             scheduleAt(snow_t, snowTimer);
00247         }
00248         else if(gameAPIMsg->getCommand() == GAMEEVENT_FROZEN) {
00249             if(doRealworld) {
00250                 GameAPIFrozenMessage* frozen = check_and_cast<GameAPIFrozenMessage*>(gameAPIMsg);
00251                 SCFrozenPacket scfreeze;
00252                 scfreeze.packetType = SC_EV_FROZEN;
00253                 scfreeze.ip = frozen->getSrc().ip.get4().getInt();
00254                 scfreeze.time_sec = frozen->getTimeSec();
00255                 scfreeze.time_usec = frozen->getTimeUsec();
00256                 int packetlen = sizeof(scfreeze);
00257                 scheduler->sendBytes((const char*)&packetlen, sizeof(int), 0, 0, true, appFd);
00258                 scheduler->sendBytes((const char*)&scfreeze, packetlen, 0, 0, true, appFd);
00259             }
00260         }
00261     }
00262     delete msg;
00263 }

void SimpleGameClient::handleReadyMessage ( CompReadyMessage *  msg  )  [virtual]

method to handle ready messages from the overlay

Parameters:
msg message to handle

Reimplemented from BaseApp.

00266 {
00267     if(msg->getReady()) {
00268         overlayReady = true;
00269         if(!move_timer->isScheduled()) {
00270             scheduleAt(simulation.simTime() + movementDelay, move_timer);
00271         }
00272         gettimeofday(&startTime, NULL);
00273         startTime = timeval_substract(startTime, simulation.simTime());
00274     }
00275     else {
00276         overlayReady = false;
00277     }
00278 
00279     delete msg;
00280 }

void SimpleGameClient::updateNeighbors ( GameAPIListMessage *  sgcMsg  )  [protected]

Referenced by handleLowerMessage().

00330 {
00331     unsigned int i;
00332 
00333     if(doRealworld) {
00334         int packetSize;
00335 
00336         SCRemovePacket removePacket;
00337         removePacket.packetType = SC_REMOVE_NEIGHBOR;
00338         packetSize = sizeof(removePacket);
00339 
00340         for(i=0; i<sgcMsg->getRemoveNeighborArraySize(); ++i) {
00341             removePacket.ip = sgcMsg->getRemoveNeighbor(i).ip.get4().getInt();
00342             scheduler->sendBytes((const char*)&packetSize, sizeof(int), 0, 0, true, appFd);
00343             scheduler->sendBytes((const char*)&removePacket, packetSize, 0, 0, true, appFd);
00344         }
00345 
00346         SCAddPacket addPacket;
00347         addPacket.packetType = SC_ADD_NEIGHBOR;
00348         packetSize = sizeof(addPacket);
00349 
00350         for(i=0; i<sgcMsg->getAddNeighborArraySize(); ++i) {
00351             addPacket.ip = sgcMsg->getAddNeighbor(i).ip.get4().getInt();
00352             if( addPacket.ip == thisNode.ip.get4().getInt() ) continue;
00353             addPacket.posX = sgcMsg->getNeighborPosition(i).x;
00354             addPacket.posY = sgcMsg->getNeighborPosition(i).y;
00355             scheduler->sendBytes((const char*)&packetSize, sizeof(int), 0, 0, true, appFd);
00356             scheduler->sendBytes((const char*)&addPacket, packetSize, 0, 0, true, appFd);
00357         }
00358     }
00359     for(i=0; i<sgcMsg->getRemoveNeighborArraySize(); ++i)
00360         Neighbors.erase(sgcMsg->getRemoveNeighbor(i));
00361 
00362     for(i=0; i<sgcMsg->getAddNeighborArraySize(); ++i) {
00363         Vector2D newPos;
00364         newPos = sgcMsg->getNeighborPosition(i);
00365         itNeighbors = Neighbors.find(sgcMsg->getAddNeighbor(i));
00366         if(itNeighbors != Neighbors.end()) {
00367             Vector2D temp = newPos - itNeighbors->second.position;
00368             temp.normalize();
00369             itNeighbors->second.direction = temp;
00370             itNeighbors->second.position = newPos;
00371         }
00372         else {
00373             NeighborMapEntry entry;
00374             entry.position = newPos;
00375             Neighbors.insert(std::make_pair(sgcMsg->getAddNeighbor(i), entry));
00376         }
00377     }
00378 }

void SimpleGameClient::updatePosition (  )  [protected]

Referenced by handleLowerMessage(), and handleTimerEvent().

00381 {
00382     if(!frozen) {
00383         Generator->move();
00384     }
00385     position = Generator->getPosition();
00386     GameAPIPositionMessage *posMsg = new GameAPIPositionMessage("MOVEMENT_INDICATION");
00387     posMsg->setCommand(MOVEMENT_INDICATION);
00388     posMsg->setPosition(position);
00389     sendMessageToLowerTier(posMsg);
00390 }

void SimpleGameClient::handleRealworldPacket ( char *  buf,
uint32_t  len 
) [protected]

Referenced by handleTimerEvent().

00283 {
00284     SCBasePacket *type = (SCBasePacket*)buf;
00285     if(type->packetType == SC_PARAM_REQUEST) {
00286         SCParamPacket packet;
00287         packet.packetType = SC_PARAM_RESPONSE;
00288         packet.speed = movementSpeed;
00289         packet.dimension = areaDimension;
00290         packet.AOI = AOIWidth;
00291         packet.delay = movementDelay;
00292         packet.startX = position.x;
00293         packet.startY = position.y;
00294         packet.ip = thisNode.ip.get4().getInt();
00295         packet.seed = coordinator->getSeed();
00296         int packetSize = sizeof(packet);
00297         scheduler->sendBytes((const char*)&packetSize, sizeof(int), 0, 0, true, appFd);
00298         scheduler->sendBytes((const char*)&packet, packetSize, 0, 0, true, appFd);
00299         doRealworld = true;
00300     }
00301     else if(type->packetType == SC_MOVE_INDICATION) {
00302         SCMovePacket *packet = (SCMovePacket*)type;
00303         Vector2D temp;
00304         temp.x = packet->posX;
00305         temp.y = packet->posY;
00306         dynamic_cast<realWorldRoaming*>(Generator)->setPosition(temp);
00307     }
00308     else if(type->packetType == SC_EV_CHAT) {
00309         SCChatPacket* packet = (SCChatPacket*)type;
00310         GameAPIChatMessage* chatMsg = new GameAPIChatMessage("ChatMsg");
00311         chatMsg->setCommand(GAMEEVENT_CHAT);
00312         chatMsg->setSrc(thisNode);
00313         chatMsg->setMsg(packet->msg);
00314         sendMessageToLowerTier(chatMsg);
00315     }
00316     else if(type->packetType == SC_EV_SNOWBALL) {
00317         SCSnowPacket* packet = (SCSnowPacket*)type;
00318         GameAPISnowMessage* snowMsg = new GameAPISnowMessage("Throw Snowball");
00319         snowMsg->setCommand(GAMEEVENT_SNOW);
00320         snowMsg->setSrc(thisNode);
00321         snowMsg->setStart(Vector2D(packet->startX, packet->startY));
00322         snowMsg->setEnd(Vector2D(packet->endX, packet->endY));
00323         snowMsg->setTimeSec(packet->time_sec);
00324         snowMsg->setTimeUsec(packet->time_usec);
00325         sendMessageToLowerTier(snowMsg);
00326     }
00327 }


Member Data Documentation

Referenced by initializeApp().

double SimpleGameClient::movementDelay [protected]

double SimpleGameClient::areaDimension [protected]

double SimpleGameClient::movementSpeed [protected]

double SimpleGameClient::movementRate [protected]

Referenced by initializeApp().

double SimpleGameClient::AOIWidth [protected]

bool SimpleGameClient::useScenery [protected]

Referenced by initializeApp().

Referenced by initializeApp(), and updateNeighbors().

NeighborMap::iterator SimpleGameClient::itNeighbors [protected]

Referenced by updateNeighbors().

std::string SimpleGameClient::GeneratorType [protected]

Referenced by initializeApp().

timeval SimpleGameClient::startTime [protected]

cMessage* SimpleGameClient::move_timer [protected]

cMessage* SimpleGameClient::packetNotification [protected]

Referenced by initializeApp(), and ~SimpleGameClient().

Referenced by handleTimerEvent(), and initializeApp().

unsigned int SimpleGameClient::mtu [protected]

Referenced by initializeApp().

int SimpleGameClient::appFd [protected]

bool SimpleGameClient::frozen [protected]


The documentation for this class was generated from the following files:

Generated on Fri Sep 19 13:05:08 2008 for ITM OverSim by  doxygen 1.5.5