SimMud Class Reference

#include <SimMud.h>

Inheritance diagram for SimMud:

BaseApp BaseRpc RpcListener

List of all members.

Public Member Functions

 SimMud ()
 ~SimMud ()
virtual void initializeApp (int stage)
 Initialize class attributes.
virtual void handleTimerEvent (cMessage *msg)
 processes self-messages
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)
 method to handle non-commonAPI messages from the overlay
virtual void handleReadyMessage (TierReadyMessage *msg)
 method to handle ready messages from the overlay
virtual bool handleRpc (BaseCallMessage *msg)
 Processes Remote-Procedure-Call invokation messages.
virtual void handleRpcResponse (BaseResponseMessage *msg, 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
int fieldSize
int regionSize
int playerTimeout
cMessage * playerTimer
map< NodeHandle,
PlayerInfo
playerMap

Classes

struct  PlayerInfo


Constructor & Destructor Documentation

SimMud::SimMud (  ) 

00031 {
00032     currentRegionX = currentRegionY = INT_MIN;
00033     currentRegionID = OverlayKey::UNSPECIFIED_KEY;
00034     playerTimer = new cMessage("playerTimeout");
00035 }

SimMud::~SimMud (  ) 

00038 {
00039     cancelAndDelete(playerTimer);
00040 }


Member Function Documentation

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

Initialize class attributes.

Reimplemented from BaseApp.

00047 {
00048     if( stage != (numInitStages()-1)) {
00049         return;
00050     }
00051 
00052     // FIXME: areaDimension is not used consistently between all overlays!
00053     fieldSize = par("areaDimension");
00054     regionSize = par("regionDimension");
00055     playerTimeout = par("playerTimeout");
00056 
00057     WATCH(currentRegionX);
00058     WATCH(currentRegionY);
00059     WATCH(currentRegionID);
00060 //    WATCH_MAP( playerMap );
00061 }

void SimMud::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.

00078 {
00079     if( msg == playerTimer ) {
00080         // Check if any player didn't send any updates since last check
00081         map<NodeHandle, PlayerInfo>::iterator it;
00082         list<NodeHandle> erasePlayers;
00083         for( it = playerMap.begin(); it != playerMap.end(); ++it ) {
00084             if( it->second.update == false ) {
00085                 erasePlayers.push_back( it->first );
00086             }
00087             it->second.update = false;
00088         }
00089         for( list<NodeHandle>::iterator it = erasePlayers.begin(); it != erasePlayers.end(); ++it) {
00090             // Delete all neighbors that didn't update (and inform app)
00091             GameAPIListMessage *scMsg = new GameAPIListMessage("NEIGHBOR_UPDATE");
00092             scMsg->setCommand(NEIGHBOR_UPDATE);
00093             scMsg->setRemoveNeighborArraySize(1);
00094             scMsg->setRemoveNeighbor(0, *it);
00095             send(scMsg, "to_upperTier");
00096 
00097             playerMap.erase( *it );
00098         }
00099         erasePlayers.clear();
00100 
00101         scheduleAt( simulation.simTime() + playerTimeout, msg );
00102     }
00103 }

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.

00139 {
00140     if( GameAPIPositionMessage* moveMsg =
00141         dynamic_cast<GameAPIPositionMessage*>(msg) ) {
00142         handleMove( moveMsg );
00143         delete msg;
00144     }
00145 }

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

method to handle non-commonAPI messages from the overlay

Parameters:
msg message to handle

Reimplemented from BaseApp.

00106 {
00107     if (ALMMulticastMessage* mcastMsg =
00108             dynamic_cast<ALMMulticastMessage*>(msg) ){
00109 
00110         cMessage* innerMsg = mcastMsg->decapsulate();
00111         SimMudMoveMessage* moveMsg = NULL;
00112         if( innerMsg ) {
00113                 moveMsg = dynamic_cast<SimMudMoveMessage*>(innerMsg);
00114         }
00115         if( moveMsg ) {
00116             handleOtherPlayerMove( moveMsg );
00117         }
00118         delete innerMsg;
00119         delete mcastMsg;
00120     }
00121 }

void SimMud::handleReadyMessage ( TierReadyMessage *  msg  )  [virtual]

method to handle ready messages from the overlay

Parameters:
msg message to handle

Reimplemented from BaseApp.

00124 {
00125     if( msg->getReady() ) {
00126         // FIXME/TODO: Should be done by BaseApp
00127         thisNode = msg->getThisNode();
00128         // TODO/FIXME: maybe ugly? send TierReadyMessage directly form BaseApp to SimpleGameClient?
00129         send(msg, "to_upperTier");
00130 
00131         if( playerTimeout > 0 ) {
00132             scheduleAt( simulation.simTime() + playerTimeout, playerTimer );
00133         }
00134     }
00135     //delete msg;
00136 }

bool SimMud::handleRpc ( BaseCallMessage *  msg  )  [virtual]

Processes Remote-Procedure-Call invokation messages.


This method should be overloaded when the overlay provides RPC functionality.

Returns:
true, if rpc has been handled

Reimplemented from BaseRpc.

00064 {
00065 //    RPC_SWITCH_START(msg);
00066 //    RPC_SWITCH_END( );
00067 //    return RPC_HANDLED;
00068       return false;
00069 }

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

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

Parameters:
msg The response message.
rpcId The RPC id.
rtt The Round-Trip-Time of this RPC

Reimplemented from RpcListener.

00072 {
00073 //    RPC_SWITCH_START(msg);
00074 //    RPC_SWITCH_END( );
00075 }

void SimMud::finishApp (  )  [virtual]

collect statistical data

Reimplemented from BaseApp.

00043 {
00044 }

void SimMud::handleMove ( GameAPIPositionMessage *  msg  )  [protected]

00148 {
00149     if( (int) (msg->getPosition().x/regionSize) != currentRegionX ||
00150             (int) (msg->getPosition().y/regionSize) != currentRegionY ) {
00151         // New position is outside of current region; change regions
00152 
00153         if( !currentRegionID.isUnspecified() ){
00154             // leave old region's multicastGroup
00155             ALMLeaveMessage* leaveMsg = new ALMLeaveMessage("LEAVE_REGION_GROUP");
00156             leaveMsg->setGroupId(currentRegionID);
00157             send(leaveMsg, "to_lowerTier");
00158             // TODO: leave old simMud region
00159 
00160             // Inform other players about region leave
00161             SimMudMoveMessage* moveMsg = new SimMudMoveMessage("MOVE/LEAVE_REGION");
00162             moveMsg->setSrc( thisNode );
00163             moveMsg->setPosX( msg->getPosition().x );
00164             moveMsg->setPosY( msg->getPosition().y );
00165             moveMsg->setLeaveRegion( true );
00166             ALMMulticastMessage* mcastMsg = new ALMMulticastMessage("MOVE/LEAVE_REGION");
00167             mcastMsg->setGroupId(currentRegionID);
00168             mcastMsg->encapsulate( moveMsg );
00169 
00170             send(mcastMsg, "to_lowerTier");
00171         }
00172 
00173         // get region ID
00174         currentRegionX = (int) (msg->getPosition().x/regionSize);
00175         currentRegionY = (int) (msg->getPosition().y/regionSize);
00176         std::stringstream regionstr;
00177         regionstr << currentRegionX << ":" << currentRegionY;
00178         OverlayKey region = OverlayKey::sha1( BinaryValue(regionstr.str() ));
00179         currentRegionID = region;
00180 
00181         // join region's multicast group
00182         ALMSubscribeMessage* subMsg = new ALMSubscribeMessage;
00183         subMsg->setGroupId(region);
00184         send( subMsg, "to_lowerTier" );
00185 
00186         // TODO: join simMud region
00187    }
00188 
00189     // publish movement
00190     SimMudMoveMessage* moveMsg = new SimMudMoveMessage("MOVE");
00191     moveMsg->setSrc( thisNode );
00192     moveMsg->setPosX( msg->getPosition().x );
00193     moveMsg->setPosY( msg->getPosition().y );
00194     ALMMulticastMessage* mcastMsg = new ALMMulticastMessage("MOVE");
00195     mcastMsg->setGroupId(currentRegionID);
00196     mcastMsg->encapsulate( moveMsg );
00197 
00198     send(mcastMsg, "to_lowerTier");
00199 }

void SimMud::handleOtherPlayerMove ( SimMudMoveMessage *  msg  )  [protected]

00202 {
00203     GameAPIListMessage *scMsg = new GameAPIListMessage("NEIGHBOR_UPDATE");
00204     scMsg->setCommand(NEIGHBOR_UPDATE);
00205 
00206     NodeHandle& src = msg->getSrc();
00207 
00208     if( msg->getLeaveRegion() ) {
00209         // Player leaves region
00210         scMsg->setRemoveNeighborArraySize(1);
00211         scMsg->setRemoveNeighbor(0, src);
00212         playerMap.erase( src );
00213 
00214     } else {
00215         PlayerInfo player;
00216         player.pos = Vector2D( msg->getPosX(), msg->getPosY() );
00217         player.update = true;
00218 
00219         pair< map<NodeHandle, PlayerInfo>::iterator, bool> inserter =
00220             playerMap.insert( make_pair(src, player) );
00221 
00222         /*    if( inserter.second ) {
00223             // new player
00224 
00225         } else {
00226             // move player
00227         }*/
00228 
00229         // Ordinary move
00230         scMsg->setAddNeighborArraySize(1);
00231         scMsg->setNeighborPositionArraySize(1);
00232         scMsg->setAddNeighbor(0, src);
00233         scMsg->setNeighborPosition(0, Vector2D(msg->getPosX(), msg->getPosY()) );
00234     }
00235     send(scMsg, "to_upperTier");
00236 
00237 }


Member Data Documentation

int SimMud::currentRegionX [private]

int SimMud::currentRegionY [private]

OverlayKey SimMud::currentRegionID [private]

int SimMud::fieldSize [private]

int SimMud::regionSize [private]

int SimMud::playerTimeout [private]

cMessage* SimMud::playerTimer [private]

map<NodeHandle, PlayerInfo> SimMud::playerMap [private]


The documentation for this class was generated from the following files:
Generated on Thu Apr 17 13:19:30 2008 for ITM OverSim by  doxygen 1.5.3