#include <SimMud.h>
Classes | |
struct | PlayerInfo |
Public Member Functions | |
SimMud () | |
~SimMud () | |
virtual void | initializeApp (int stage) |
Initialize class attributes. | |
virtual void | handleTimerEvent (cMessage *msg) |
virtual void | handleUpperMessage (cMessage *msg) |
handleUpperMessage gets called of handleMessage(cMessage* msg) if msg arrivedOn from_upperTier (currently msg gets deleted in this function) | |
virtual void | handleLowerMessage (cMessage *msg) |
processes self-messages | |
virtual void | handleReadyMessage (CompReadyMessage *msg) |
method to handle ready messages from the overlay | |
virtual bool | handleRpcCall (BaseCallMessage *msg) |
Processes Remote-Procedure-Call invocation messages. | |
virtual void | handleRpcResponse (BaseResponseMessage *msg, cPolymorphic *context, int rpcId, simtime_t rtt) |
This method is called if an RPC response has been received. | |
virtual void | finishApp () |
collect statistical data | |
Protected Member Functions | |
void | handleMove (GameAPIPositionMessage *msg) |
void | handleOtherPlayerMove (SimMudMoveMessage *msg) |
Private Attributes | |
int | currentRegionX |
int | currentRegionY |
OverlayKey | currentRegionID |
std::set< OverlayKey > | subscribedRegions |
int | fieldSize |
int | numSubspaces |
int | regionSize |
int | AOIWidth |
int | receivedMovementLists |
int | lostMovementLists |
simtime_t | maxMoveDelay |
int | playerTimeout |
cMessage * | playerTimer |
std::map< NodeHandle, PlayerInfo > | playerMap |
Definition at line 33 of file SimMud.h.
SimMud::SimMud | ( | ) |
Definition at line 33 of file SimMud.cc.
00034 { 00035 currentRegionX = currentRegionY = INT_MIN; 00036 currentRegionID = OverlayKey::UNSPECIFIED_KEY; 00037 playerTimer = new cMessage("playerTimeout"); 00038 }
SimMud::~SimMud | ( | ) |
Definition at line 40 of file SimMud.cc.
00041 { 00042 cancelAndDelete(playerTimer); 00043 }
void SimMud::finishApp | ( | ) | [virtual] |
collect statistical data
Reimplemented from BaseApp.
Definition at line 45 of file SimMud.cc.
00046 { 00047 simtime_t time = globalStatistics->calcMeasuredLifetime(creationTime); 00048 if (time < GlobalStatistics::MIN_MEASURED) return; 00049 00050 globalStatistics->addStdDev("SimMUD: Lost or too long delayed MoveLists/s", 00051 lostMovementLists / time); 00052 globalStatistics->addStdDev("SimMUD: Received valid MoveLists/s", 00053 receivedMovementLists / time); 00054 }
void SimMud::handleLowerMessage | ( | cMessage * | msg | ) | [virtual] |
processes self-messages
method to handle self-messages should be overwritten in derived application if needed
msg | self-message method to handle non-commonAPI messages from the overlay | |
msg | message to handle |
Reimplemented from BaseApp.
Definition at line 124 of file SimMud.cc.
00125 { 00126 if (ALMMulticastMessage* mcastMsg = 00127 dynamic_cast<ALMMulticastMessage*>(msg) ){ 00128 00129 cMessage* innerMsg = mcastMsg->decapsulate(); 00130 SimMudMoveMessage* moveMsg = NULL; 00131 if( innerMsg ) { 00132 moveMsg = dynamic_cast<SimMudMoveMessage*>(innerMsg); 00133 } 00134 if( moveMsg ) { 00135 handleOtherPlayerMove( moveMsg ); 00136 } 00137 delete innerMsg; 00138 delete mcastMsg; 00139 } 00140 }
void SimMud::handleMove | ( | GameAPIPositionMessage * | msg | ) | [protected] |
Definition at line 175 of file SimMud.cc.
Referenced by handleUpperMessage().
00176 { 00177 if( (int) (msg->getPosition().x/regionSize) != currentRegionX || 00178 (int) (msg->getPosition().y/regionSize) != currentRegionY ) { 00179 // New position is outside of current region; change currentRegion 00180 00181 // get region ID 00182 currentRegionX = (int) (msg->getPosition().x/regionSize); 00183 currentRegionY = (int) (msg->getPosition().y/regionSize); 00184 std::stringstream regionstr; 00185 regionstr << currentRegionX << ":" << currentRegionY; 00186 OverlayKey region = OverlayKey::sha1( BinaryValue(regionstr.str() )); 00187 currentRegionID = region; 00188 } 00189 00190 set<OverlayKey> expectedRegions; 00191 set<OverlayKey> allowedRegions; 00192 int minX = (int) ((msg->getPosition().x - AOIWidth)/regionSize); 00193 if( minX < 0 ) minX = 0; 00194 int maxX = (int) ((msg->getPosition().x + AOIWidth)/regionSize); 00195 if( maxX >= numSubspaces ) maxX = numSubspaces -1; 00196 int minY = (int) ((msg->getPosition().y - AOIWidth)/regionSize); 00197 if( minY < 0 ) minY = 0; 00198 int maxY = (int) ((msg->getPosition().y + AOIWidth)/regionSize); 00199 if( maxY >= numSubspaces ) maxY = numSubspaces -1; 00200 00201 // FIXME: make parameter: unsubscription size 00202 int minUnsubX = (int) ((msg->getPosition().x - 1.5*AOIWidth)/regionSize); 00203 if( minUnsubX < 0 ) minUnsubX = 0; 00204 int maxUnsubX = (int) ((msg->getPosition().x + 1.5*AOIWidth)/regionSize); 00205 if( maxUnsubX >= numSubspaces ) maxUnsubX = numSubspaces -1; 00206 int minUnsubY = (int) ((msg->getPosition().y - 1.5*AOIWidth)/regionSize); 00207 if( minUnsubY < 0 ) minUnsubY = 0; 00208 int maxUnsubY = (int) ((msg->getPosition().y + 1.5+AOIWidth)/regionSize); 00209 if( maxUnsubY >= numSubspaces ) maxUnsubY = numSubspaces -1; 00210 00211 for( int x = minUnsubX; x <= maxUnsubX; ++x ){ 00212 for( int y = minUnsubY; y <= maxUnsubY; ++y ){ 00213 std::stringstream regionstr; 00214 regionstr << x << ":" << y; 00215 if( x >= minX && x <=maxX && y >= minY && y <= maxY ){ 00216 expectedRegions.insert( OverlayKey::sha1( BinaryValue(regionstr.str() ))); 00217 } 00218 allowedRegions.insert( OverlayKey::sha1( BinaryValue(regionstr.str() ))); 00219 } 00220 } 00221 00222 set<OverlayKey>::iterator subIt = subscribedRegions.begin(); 00223 while( subIt != subscribedRegions.end() ){ 00224 00225 expectedRegions.erase( *subIt ); 00226 00227 // unsubscribe region if to far away 00228 if( allowedRegions.find( *subIt ) == allowedRegions.end() ){ 00229 // Inform other players about region leave 00230 SimMudMoveMessage* moveMsg = new SimMudMoveMessage("MOVE/LEAVE_REGION"); 00231 moveMsg->setSrc( overlay->getThisNode() ); 00232 moveMsg->setPosX( msg->getPosition().x ); 00233 moveMsg->setPosY( msg->getPosition().y ); 00234 moveMsg->setTimestamp( simTime() ); 00235 moveMsg->setLeaveRegion( true ); 00236 ALMMulticastMessage* mcastMsg = new ALMMulticastMessage("MOVE/LEAVE_REGION"); 00237 mcastMsg->setGroupId(*subIt); 00238 mcastMsg->encapsulate( moveMsg ); 00239 00240 send(mcastMsg, "to_lowerTier"); 00241 00242 // leave old region's multicastGroup 00243 ALMLeaveMessage* leaveMsg = new ALMLeaveMessage("LEAVE_REGION_GROUP"); 00244 leaveMsg->setGroupId(*subIt); 00245 send(leaveMsg, "to_lowerTier"); 00246 // TODO: leave old simMud region 00247 00248 // Erase subspace from subscribedList and increase iterator 00249 subscribedRegions.erase( subIt++ ); 00250 } else { 00251 ++subIt; 00252 } 00253 } 00254 00255 // if any "near" region is not yet subscribed, subscribe 00256 for( set<OverlayKey>::iterator regionIt = expectedRegions.begin(); regionIt != expectedRegions.end(); ++regionIt ){ 00257 // join region's multicast group 00258 ALMSubscribeMessage* subMsg = new ALMSubscribeMessage; 00259 subMsg->setGroupId(*regionIt); 00260 send( subMsg, "to_lowerTier" ); 00261 00262 subscribedRegions.insert( *regionIt ); 00263 // TODO: join simMud region 00264 } 00265 00266 // publish movement 00267 SimMudMoveMessage* moveMsg = new SimMudMoveMessage("MOVE"); 00268 moveMsg->setSrc( overlay->getThisNode() ); 00269 moveMsg->setPosX( msg->getPosition().x ); 00270 moveMsg->setPosY( msg->getPosition().y ); 00271 moveMsg->setTimestamp( simTime() ); 00272 moveMsg->setBitLength( SIMMUD_MOVE_L( moveMsg )); 00273 ALMMulticastMessage* mcastMsg = new ALMMulticastMessage("MOVE"); 00274 mcastMsg->setGroupId(currentRegionID); 00275 mcastMsg->encapsulate( moveMsg ); 00276 00277 send(mcastMsg, "to_lowerTier"); 00278 }
void SimMud::handleOtherPlayerMove | ( | SimMudMoveMessage * | msg | ) | [protected] |
Definition at line 280 of file SimMud.cc.
Referenced by handleLowerMessage().
00281 { 00282 GameAPIListMessage *scMsg = new GameAPIListMessage("NEIGHBOR_UPDATE"); 00283 scMsg->setCommand(NEIGHBOR_UPDATE); 00284 00285 NodeHandle& src = msg->getSrc(); 00286 RECORD_STATS( 00287 if( msg->getTimestamp() < simTime() - maxMoveDelay ){ 00288 ++lostMovementLists; 00289 globalStatistics->addStdDev("SimMUD: LOST MOVE Delay", 00290 SIMTIME_DBL(simTime() - msg->getTimestamp()) ); 00291 } else { 00292 ++receivedMovementLists; 00293 } 00294 00295 if( src != overlay->getThisNode() ){ 00296 globalStatistics->addStdDev("SimMUD: MOVE Delay", 00297 SIMTIME_DBL(simTime() - msg->getTimestamp()) ); 00298 } 00299 ); 00300 00301 if( msg->getLeaveRegion() ) { 00302 // Player leaves region 00303 scMsg->setRemoveNeighborArraySize(1); 00304 scMsg->setRemoveNeighbor(0, src); 00305 playerMap.erase( src ); 00306 00307 } else { 00308 PlayerInfo player; 00309 player.pos = Vector2D( msg->getPosX(), msg->getPosY() ); 00310 player.update = true; 00311 00312 pair< map<NodeHandle, PlayerInfo>::iterator, bool> inserter = 00313 playerMap.insert( make_pair(src, player) ); 00314 00315 /* if( inserter.second ) { 00316 // new player 00317 00318 } else { 00319 // move player 00320 }*/ 00321 00322 // Ordinary move 00323 scMsg->setAddNeighborArraySize(1); 00324 scMsg->setNeighborPositionArraySize(1); 00325 scMsg->setAddNeighbor(0, src); 00326 scMsg->setNeighborPosition(0, Vector2D(msg->getPosX(), msg->getPosY()) ); 00327 } 00328 send(scMsg, "to_upperTier"); 00329 00330 }
void SimMud::handleReadyMessage | ( | CompReadyMessage * | msg | ) | [virtual] |
method to handle ready messages from the overlay
msg | message to handle |
Reimplemented from BaseApp.
Definition at line 142 of file SimMud.cc.
00143 { 00144 // process only ready messages from the tier below 00145 if( getThisCompType() - msg->getComp() == 1 ){ 00146 if( msg->getReady() ) { 00147 // TODO/FIXME: use overlay->sendMessageToAllComp(msg, getThisCompType())? 00148 msg->setComp(getThisCompType()); 00149 send(msg, "to_upperTier"); 00150 // also send AOI size to SimpleGameClient 00151 GameAPIResizeAOIMessage* gameMsg = new GameAPIResizeAOIMessage("RESIZE_AOI"); 00152 gameMsg->setCommand(RESIZE_AOI); 00153 gameMsg->setAOIsize(AOIWidth); 00154 send(gameMsg, "to_upperTier"); 00155 00156 if( playerTimeout > 0 ) { 00157 cancelEvent( playerTimer ); 00158 scheduleAt( simTime() + playerTimeout, playerTimer ); 00159 } 00160 } 00161 } else { 00162 delete msg; 00163 } 00164 }
bool SimMud::handleRpcCall | ( | BaseCallMessage * | msg | ) | [virtual] |
Processes Remote-Procedure-Call invocation messages.
This method should be overloaded when the overlay provides RPC functionality.
Reimplemented from BaseRpc.
void SimMud::handleRpcResponse | ( | BaseResponseMessage * | msg, | |
cPolymorphic * | context, | |||
int | rpcId, | |||
simtime_t | rtt | |||
) | [virtual] |
This method is called if an RPC response has been received.
msg | The response message. | |
context | Pointer to an optional state object. The object has to be handled/deleted by the handleRpcResponse() code | |
rpcId | The RPC id. | |
rtt | The Round-Trip-Time of this RPC |
Reimplemented from RpcListener.
void SimMud::handleTimerEvent | ( | cMessage * | msg | ) | [virtual] |
Reimplemented from BaseRpc.
Definition at line 96 of file SimMud.cc.
00097 { 00098 if( msg == playerTimer ) { 00099 // Check if any player didn't send any updates since last check 00100 map<NodeHandle, PlayerInfo>::iterator it; 00101 list<NodeHandle> erasePlayers; 00102 for( it = playerMap.begin(); it != playerMap.end(); ++it ) { 00103 if( it->second.update == false ) { 00104 erasePlayers.push_back( it->first ); 00105 } 00106 it->second.update = false; 00107 } 00108 for( list<NodeHandle>::iterator it = erasePlayers.begin(); it != erasePlayers.end(); ++it) { 00109 // Delete all neighbors that didn't update (and inform app) 00110 GameAPIListMessage *scMsg = new GameAPIListMessage("NEIGHBOR_UPDATE"); 00111 scMsg->setCommand(NEIGHBOR_UPDATE); 00112 scMsg->setRemoveNeighborArraySize(1); 00113 scMsg->setRemoveNeighbor(0, *it); 00114 send(scMsg, "to_upperTier"); 00115 00116 playerMap.erase( *it ); 00117 } 00118 erasePlayers.clear(); 00119 00120 scheduleAt( simTime() + playerTimeout, msg ); 00121 } 00122 }
void SimMud::handleUpperMessage | ( | cMessage * | msg | ) | [virtual] |
handleUpperMessage gets called of handleMessage(cMessage* msg) if msg arrivedOn from_upperTier (currently msg gets deleted in this function)
msg | the message to handle |
Reimplemented from BaseApp.
Definition at line 166 of file SimMud.cc.
00167 { 00168 if( GameAPIPositionMessage* moveMsg = 00169 dynamic_cast<GameAPIPositionMessage*>(msg) ) { 00170 handleMove( moveMsg ); 00171 delete msg; 00172 } 00173 }
void SimMud::initializeApp | ( | int | stage | ) | [virtual] |
Initialize class attributes.
Reimplemented from BaseApp.
Definition at line 56 of file SimMud.cc.
00057 { 00058 if( stage != (numInitStages()-1)) { 00059 return; 00060 } 00061 00062 // FIXME: areaDimension is not used consistently between all overlays! 00063 fieldSize = par("areaDimension"); 00064 numSubspaces = par("numSubspaces"); 00065 regionSize = fieldSize / numSubspaces; 00066 playerTimeout = par("playerTimeout"); 00067 00068 receivedMovementLists = 0; 00069 lostMovementLists = 0; 00070 00071 maxMoveDelay = par("maxMoveDelay"); 00072 AOIWidth = par("AOIWidth"); 00073 00074 WATCH(currentRegionX); 00075 WATCH(currentRegionY); 00076 WATCH(currentRegionID); 00077 // WATCH_MAP( playerMap ); 00078 }
int SimMud::AOIWidth [private] |
Definition at line 44 of file SimMud.h.
Referenced by handleMove(), handleReadyMessage(), and initializeApp().
OverlayKey SimMud::currentRegionID [private] |
Definition at line 38 of file SimMud.h.
Referenced by handleMove(), initializeApp(), and SimMud().
int SimMud::currentRegionX [private] |
Definition at line 36 of file SimMud.h.
Referenced by handleMove(), initializeApp(), and SimMud().
int SimMud::currentRegionY [private] |
Definition at line 37 of file SimMud.h.
Referenced by handleMove(), initializeApp(), and SimMud().
int SimMud::fieldSize [private] |
Definition at line 41 of file SimMud.h.
Referenced by initializeApp().
int SimMud::lostMovementLists [private] |
Definition at line 47 of file SimMud.h.
Referenced by finishApp(), handleOtherPlayerMove(), and initializeApp().
simtime_t SimMud::maxMoveDelay [private] |
Definition at line 48 of file SimMud.h.
Referenced by handleOtherPlayerMove(), and initializeApp().
int SimMud::numSubspaces [private] |
Definition at line 42 of file SimMud.h.
Referenced by handleMove(), and initializeApp().
std::map<NodeHandle, PlayerInfo> SimMud::playerMap [private] |
Definition at line 58 of file SimMud.h.
Referenced by handleOtherPlayerMove(), and handleTimerEvent().
int SimMud::playerTimeout [private] |
Definition at line 50 of file SimMud.h.
Referenced by handleReadyMessage(), handleTimerEvent(), and initializeApp().
cMessage* SimMud::playerTimer [private] |
Definition at line 51 of file SimMud.h.
Referenced by handleReadyMessage(), handleTimerEvent(), SimMud(), and ~SimMud().
int SimMud::receivedMovementLists [private] |
Definition at line 46 of file SimMud.h.
Referenced by finishApp(), handleOtherPlayerMove(), and initializeApp().
int SimMud::regionSize [private] |
Definition at line 43 of file SimMud.h.
Referenced by handleMove(), and initializeApp().
std::set<OverlayKey> SimMud::subscribedRegions [private] |
Definition at line 39 of file SimMud.h.
Referenced by handleMove().