#include <SimMud.h>
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 |
SimMud::SimMud | ( | ) |
00031 { 00032 currentRegionX = currentRegionY = INT_MIN; 00033 currentRegionID = OverlayKey::UNSPECIFIED_KEY; 00034 playerTimer = new cMessage("playerTimeout"); 00035 }
SimMud::~SimMud | ( | ) |
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
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)
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
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
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.
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.
msg | The response message. | |
rpcId | The RPC id. | |
rtt | The Round-Trip-Time of this RPC |
Reimplemented from RpcListener.
void SimMud::finishApp | ( | ) | [virtual] |
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 }
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] |