SimMud Class Reference

#include <SimMud.h>

Inheritance diagram for SimMud:
BaseApp BaseRpc RpcListener

List of all members.

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< OverlayKeysubscribedRegions
int fieldSize
int numSubspaces
int regionSize
int AOIWidth
int receivedMovementLists
int lostMovementLists
simtime_t maxMoveDelay
int playerTimeout
cMessage * playerTimer
std::map< NodeHandle, PlayerInfoplayerMap

Detailed Description

Definition at line 33 of file SimMud.h.


Constructor & Destructor Documentation

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 }


Member Function Documentation

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

Parameters:
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

Parameters:
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.

Returns:
true, if rpc has been handled

Reimplemented from BaseRpc.

Definition at line 80 of file SimMud.cc.

00081 {
00082 //    RPC_SWITCH_START(msg);
00083 //    RPC_SWITCH_END( );
00084 //    return RPC_HANDLED;
00085       return false;
00086 }

void SimMud::handleRpcResponse ( BaseResponseMessage *  msg,
cPolymorphic *  context,
int  rpcId,
simtime_t  rtt 
) [virtual]

This method is called if an RPC response has been received.

Parameters:
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.

Definition at line 88 of file SimMud.cc.

00091 {
00092 //    RPC_SWITCH_START(msg);
00093 //    RPC_SWITCH_END( );
00094 }

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)

Parameters:
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 }


Member Data Documentation

int SimMud::AOIWidth [private]

Definition at line 44 of file SimMud.h.

Referenced by handleMove(), handleReadyMessage(), and initializeApp().

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().

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().

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().

Definition at line 39 of file SimMud.h.

Referenced by handleMove().


The documentation for this class was generated from the following files:
Generated on Wed May 26 16:21:19 2010 for OverSim by  doxygen 1.6.3