#include <SimpleGameClient.h>
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 | |
GlobalCoordinator * | coordinator |
CollisionList | CollisionRect |
double | movementDelay |
double | areaDimension |
double | movementSpeed |
double | movementRate |
double | AOIWidth |
bool | useScenery |
bool | overlayReady |
Vector2D | position |
MovementGenerator * | Generator |
NeighborMap | Neighbors |
NeighborMap::iterator | itNeighbors |
std::string | GeneratorType |
timeval | startTime |
cMessage * | move_timer |
cMessage * | packetNotification |
RealtimeScheduler::PacketBuffer | packetBuffer |
RealtimeScheduler * | scheduler |
unsigned int | mtu |
int | appFd |
bool | doRealworld |
bool | frozen |
SimpleGameClient::~SimpleGameClient | ( | ) | [virtual] |
00393 { 00394 // destroy self timer messages 00395 cancelAndDelete(move_timer); 00396 cancelAndDelete(packetNotification); 00397 }
void SimpleGameClient::initializeApp | ( | int | stage | ) | [virtual] |
initializes derived class-attributes
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
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
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
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 }
GlobalCoordinator* SimpleGameClient::coordinator [protected] |
Referenced by handleRealworldPacket(), and initializeApp().
CollisionList SimpleGameClient::CollisionRect [protected] |
Referenced by initializeApp().
double SimpleGameClient::movementDelay [protected] |
Referenced by handleReadyMessage(), handleRealworldPacket(), handleTimerEvent(), and initializeApp().
double SimpleGameClient::areaDimension [protected] |
Referenced by handleRealworldPacket(), and initializeApp().
double SimpleGameClient::movementSpeed [protected] |
Referenced by handleRealworldPacket(), and initializeApp().
double SimpleGameClient::movementRate [protected] |
Referenced by initializeApp().
double SimpleGameClient::AOIWidth [protected] |
Referenced by handleLowerMessage(), handleRealworldPacket(), and initializeApp().
bool SimpleGameClient::useScenery [protected] |
Referenced by initializeApp().
bool SimpleGameClient::overlayReady [protected] |
Referenced by handleReadyMessage(), handleTimerEvent(), and initializeApp().
Vector2D SimpleGameClient::position [protected] |
Referenced by handleRealworldPacket(), handleTimerEvent(), initializeApp(), and updatePosition().
MovementGenerator* SimpleGameClient::Generator [protected] |
Referenced by handleRealworldPacket(), initializeApp(), and updatePosition().
NeighborMap SimpleGameClient::Neighbors [protected] |
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] |
Referenced by handleLowerMessage(), and handleReadyMessage().
cMessage* SimpleGameClient::move_timer [protected] |
Referenced by handleReadyMessage(), handleTimerEvent(), initializeApp(), and ~SimpleGameClient().
cMessage* SimpleGameClient::packetNotification [protected] |
Referenced by initializeApp(), and ~SimpleGameClient().
Referenced by handleTimerEvent(), and initializeApp().
RealtimeScheduler* SimpleGameClient::scheduler [protected] |
Referenced by handleLowerMessage(), handleRealworldPacket(), handleTimerEvent(), initializeApp(), and updateNeighbors().
unsigned int SimpleGameClient::mtu [protected] |
Referenced by initializeApp().
int SimpleGameClient::appFd [protected] |
Referenced by handleLowerMessage(), handleRealworldPacket(), handleTimerEvent(), initializeApp(), and updateNeighbors().
bool SimpleGameClient::doRealworld [protected] |
Referenced by handleLowerMessage(), handleRealworldPacket(), handleTimerEvent(), initializeApp(), and updateNeighbors().
bool SimpleGameClient::frozen [protected] |
Referenced by handleLowerMessage(), handleTimerEvent(), initializeApp(), and updatePosition().