Changeset 7801 for code/trunk/src/libraries/network/GamestateManager.cc
- Timestamp:
- Dec 22, 2010, 7:24:24 PM (13 years ago)
- Location:
- code/trunk
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
code/trunk
- Property svn:mergeinfo changed
-
code/trunk/src/libraries/network/GamestateManager.cc
r7284 r7801 43 43 #include <cassert> 44 44 #include <queue> 45 #include "util/Clock.h"46 45 // #include <boost/thread/mutex.hpp> 47 46 48 #include "util/Debug.h"49 #include "core/ThreadPool.h"50 #include "core/command/Executor.h"51 #include "ClientInformation.h"52 47 #include "packet/Acknowledgement.h" 53 48 #include "packet/Gamestate.h" 54 49 #include "synchronisable/NetworkCallbackManager.h" 55 #include "TrafficControl.h" 50 51 #include "core/ThreadPool.h" 52 #include "core/command/Executor.h" 53 #include "core/GameMode.h" 54 #include "util/Debug.h" 55 #include "util/Clock.h" 56 // #include "TrafficControl.h" 56 57 57 58 namespace orxonox 58 59 { 59 60 GamestateManager::GamestateManager() : 60 reference(0), id_(0)61 { 62 trafficControl_ = new TrafficControl();61 currentGamestate_(0), id_(0) 62 { 63 // trafficControl_ = new TrafficControl(); 63 64 // threadMutex_ = new boost::mutex(); 64 65 // threadPool_ = new ThreadPool(); … … 67 68 GamestateManager::~GamestateManager() 68 69 { 69 if( this-> reference)70 delete this-> reference;std::map<unsigned int, packet::Gamestate*>::iterator it;70 if( this->currentGamestate_ ) 71 delete this->currentGamestate_;std::map<unsigned int, packet::Gamestate*>::iterator it; 71 72 for( it = gamestateQueue.begin(); it != gamestateQueue.end(); ++it ) 72 73 delete it->second; 73 std::map<u nsigned int, std::map<unsigned int, packet::Gamestate*> >::iterator it1;74 std::map<u nsigned int, packet::Gamestate*>::iterator it2;75 for( it1 = gamestateMap_.begin(); it1 != gamestateMap_.end(); ++it1)76 { 77 for( it2 = it1->second.begin(); it2 != it1->second.end(); ++it2)78 delete it2->second;79 } 80 this->trafficControl_->destroy();74 std::map<uint32_t, peerInfo>::iterator peerIt; 75 std::map<uint32_t, packet::Gamestate*>::iterator gamestateIt; 76 for( peerIt = peerMap_.begin(); peerIt != peerMap_.end(); ++peerIt ) 77 { 78 for( gamestateIt = peerIt->second.gamestates.begin(); gamestateIt != peerIt->second.gamestates.end(); ++gamestateIt ) 79 delete gamestateIt->second; 80 } 81 // this->trafficControl_->destroy(); 81 82 // delete this->threadMutex_; 82 83 // delete this->threadPool_; … … 88 89 } 89 90 90 bool GamestateManager::add(packet::Gamestate *gs, unsigned int clientID){ 91 bool GamestateManager::addGamestate(packet::Gamestate *gs, unsigned int clientID) 92 { 91 93 assert(gs); 92 94 std::map<unsigned int, packet::Gamestate*>::iterator it = gamestateQueue.find(clientID); … … 99 101 } 100 102 101 bool GamestateManager::processGamestates(){ 103 bool GamestateManager::processGamestates() 104 { 102 105 if( this->gamestateQueue.empty() ) 103 106 return true; … … 107 110 bool b = processGamestate(it->second); 108 111 assert(b); 112 sendAck( it->second->getID(), it->second->getPeerID() ); 109 113 delete it->second; 110 114 } … … 115 119 return true; 116 120 } 121 122 bool GamestateManager::sendAck(unsigned int gamestateID, uint32_t peerID) 123 { 124 packet::Acknowledgement *ack = new packet::Acknowledgement(gamestateID, peerID); 125 if( !this->sendPacket(ack)) 126 { 127 COUT(3) << "could not ack gamestate: " << gamestateID << std::endl; 128 return false; 129 } 130 else 131 { 132 COUT(5) << "acked a gamestate: " << gamestateID << std::endl; 133 return true; 134 } 135 } 117 136 118 137 119 138 bool GamestateManager::getSnapshot(){ 120 if ( reference != 0 ) 121 delete reference; 122 reference = new packet::Gamestate(); 123 if(!reference->collectData(++id_, 0x1)){ //we have no data to send 124 delete reference; 125 reference=0; 139 if ( currentGamestate_ != 0 ) 140 delete currentGamestate_; 141 currentGamestate_ = new packet::Gamestate(); 142 uint8_t gsMode; 143 if( GameMode::isMaster() ) 144 gsMode = packet::GAMESTATE_MODE_SERVER; 145 else 146 gsMode = packet::GAMESTATE_MODE_CLIENT; 147 uint32_t newID; 148 if( GameMode::isMaster() ) 149 newID = ++id_; 150 else 151 newID = peerMap_[NETWORK_PEER_ID_SERVER].lastProcessedGamestateID; 152 153 if(!currentGamestate_->collectData(newID, gsMode)){ //we have no data to send 154 delete currentGamestate_; 155 currentGamestate_=0; 126 156 } 127 157 return true; 128 158 } 129 159 130 void GamestateManager::sendGamestates() 131 { 132 ClientInformation *temp = ClientInformation::getBegin(); 133 std::queue<packet::Gamestate*> clientGamestates; 134 while(temp != NULL){ 135 if( !(temp->getSynched()) ){ 160 std::vector<packet::Gamestate*> GamestateManager::getGamestates() 161 { 162 if(!currentGamestate_) 163 return std::vector<packet::Gamestate*>(); 164 std::vector<packet::Gamestate*> peerGamestates; 165 166 std::map<uint32_t, peerInfo>::iterator peerIt; 167 for( peerIt=peerMap_.begin(); peerIt!=peerMap_.end(); ++peerIt ) 168 { 169 if( !peerIt->second.isSynched ) 170 { 136 171 COUT(5) << "Server: not sending gamestate" << std::endl; 137 temp=temp->next();138 if(!temp)139 break;140 172 continue; 141 173 } 142 COUT(4) << "client id: " << temp->getID() << " RTT: " << temp->getRTT() << " loss: " << temp->getPacketLoss()<< std::endl;174 COUT(4) << "client id: " << peerIt->first << std::endl; 143 175 COUT(5) << "Server: doing gamestate gamestate preparation" << std::endl; 144 int cid = temp->getID(); //get client id145 146 unsigned int gID = temp->getGamestateID();147 if(!reference) 148 return;149 150 packet::Gamestate *client=0;151 if(gID != GAMESTATEID_INITIAL){152 assert(gamestateMap_.find(cid)!=gamestateMap_.end());153 std::map<unsigned int, packet::Gamestate*>::iterator it = gamestateMap_[cid].find(gID);154 if(it!=gamestateMap_[cid].end())155 {156 client = it->second; 157 }158 }159 160 clientGamestates.push(0);161 finishGamestate( cid, clientGamestates.back(), client, reference);176 int peerID = peerIt->first; //get client id 177 178 unsigned int lastAckedGamestateID = peerIt->second.lastAckedGamestateID; 179 180 packet::Gamestate* baseGamestate=0; 181 if(lastAckedGamestateID != GAMESTATEID_INITIAL) 182 { 183 assert(peerMap_.find(peerID)!=peerMap_.end()); 184 std::map<uint32_t, packet::Gamestate*>::iterator it = peerMap_[peerID].gamestates.find(lastAckedGamestateID); 185 assert(it!=peerMap_[peerID].gamestates.end()); 186 baseGamestate = it->second; 187 } 188 189 peerGamestates.push_back(0); // insert an empty gamestate* to change 190 finishGamestate( peerID, peerGamestates.back(), baseGamestate, currentGamestate_ ); 191 if( peerGamestates.back()==0 ) 192 // nothing to send to remove pointer from vector 193 peerGamestates.pop_back(); 162 194 //FunctorMember<GamestateManager>* functor = 163 195 // ExecutorMember<GamestateManager>* executor = createExecutor( createFunctor(&GamestateManager::finishGamestate, this) ); 164 // executor->setDefaultValues( cid, &clientGamestates.back(), client, reference);196 // executor->setDefaultValues( cid, &clientGamestates.back(), client, currentGamestate_ ); 165 197 // (*static_cast<Executor*>(executor))(); 166 198 // this->threadPool_->passFunction( executor, true ); 167 // (*functor)( cid, &(clientGamestates.back()), client, reference ); 168 169 temp = temp->next(); 199 // (*functor)( cid, &(clientGamestates.back()), client, currentGamestate_ ); 170 200 } 171 201 172 202 // threadPool_->synchronise(); 173 203 174 while( !clientGamestates.empty() ) 175 { 176 if(clientGamestates.front()) 177 clientGamestates.front()->send(); 178 clientGamestates.pop(); 179 } 180 } 181 182 183 void GamestateManager::finishGamestate( unsigned int clientID, packet::Gamestate*& destgamestate, packet::Gamestate* base, packet::Gamestate* gamestate ) { 204 return peerGamestates; 205 } 206 207 208 void GamestateManager::finishGamestate( unsigned int peerID, packet::Gamestate*& destgamestate, packet::Gamestate* base, packet::Gamestate* gamestate ) { 184 209 //why are we searching the same client's gamestate id as we searched in 185 210 //Server::sendGameState? … … 194 219 // gs->collectData( id_, 0x1 ); 195 220 // this->threadMutex_->lock(); 196 gamestateMap_[clientID][gamestate->getID()]=gs;221 peerMap_[peerID].gamestates[gamestate->getID()]=gs; 197 222 // this->threadMutex_->unlock(); 198 199 223 Clock clock; 224 clock.capture(); 200 225 201 226 if(base) … … 216 241 217 242 218 bool b = gs->compressData();219 assert(b);220 221 COUT(0) << "difftime: " << clock.getDeltaTime() << endl;243 // bool b = gs->compressData(); 244 // assert(b); 245 clock.capture(); 246 COUT(4) << "diff and compress time: " << clock.getDeltaTime() << endl; 222 247 // COUT(5) << "sending gamestate with id " << gs->getID(); 223 248 // if(gamestate->isDiffed()) … … 225 250 // else 226 251 // COUT(5) << endl; 227 gs->set ClientID(clientID);252 gs->setPeerID(peerID); 228 253 destgamestate = gs; 229 254 } 230 255 231 256 232 bool GamestateManager::ack(unsigned int gamestateID, unsigned int clientID) { 233 ClientInformation *temp = ClientInformation::findClient(clientID); 234 assert(temp); 235 unsigned int curid = temp->getGamestateID(); 257 bool GamestateManager::ackGamestate(unsigned int gamestateID, unsigned int peerID) 258 { 259 // ClientInformation *temp = ClientInformation::findClient(peerID); 260 // assert(temp); 261 std::map<uint32_t, peerInfo>::iterator it = this->peerMap_.find(peerID); 262 assert(it!=this->peerMap_.end()); 263 unsigned int curid = it->second.lastAckedGamestateID; 236 264 237 265 if(gamestateID == ACKID_NACK){ 238 temp->setGamestateID(GAMESTATEID_INITIAL); 266 it->second.lastAckedGamestateID = GAMESTATEID_INITIAL; 267 // temp->setGamestateID(GAMESTATEID_INITIAL); 239 268 // now delete all saved gamestates for this client 240 std::map<unsigned int, packet::Gamestate*>::iterator it; 241 for(it = gamestateMap_[clientID].begin(); it!=gamestateMap_[clientID].end(); ){ 242 delete it->second; 243 244 gamestateMap_[clientID].erase(it++); 245 } 269 std::map<uint32_t, packet::Gamestate*>::iterator it2; 270 for(it2 = it->second.gamestates.begin(); it2!=it->second.gamestates.end(); ++it2 ){ 271 delete it2->second; 272 } 273 it->second.gamestates.clear(); 246 274 return true; 247 275 } 248 276 249 assert(curid==GAMESTATEID_INITIAL || curid<gamestateID); 250 COUT(5) << "acking gamestate " << gamestateID << " for clientid: " << clientID << " curid: " << curid << std::endl; 251 std::map<unsigned int, packet::Gamestate*>::iterator it; 252 for(it = gamestateMap_[clientID].begin(); it!=gamestateMap_[clientID].end() && it->first<gamestateID; ){ 253 delete it->second; 254 gamestateMap_[clientID].erase(it++); 255 } 256 temp->setGamestateID(gamestateID); 257 TrafficControl::processAck(clientID, gamestateID); 277 assert(curid==GAMESTATEID_INITIAL || curid<=gamestateID); 278 COUT(5) << "acking gamestate " << gamestateID << " for peerID: " << peerID << " curid: " << curid << std::endl; 279 std::map<uint32_t, packet::Gamestate*>::iterator it2; 280 for( it2=it->second.gamestates.begin(); it2!=it->second.gamestates.end(); ) 281 { 282 if( it2->second->getID() < gamestateID ) 283 { 284 delete it2->second; 285 it->second.gamestates.erase(it2++); 286 } 287 else 288 ++it2; 289 } 290 291 // std::map<unsigned int, packet::Gamestate*>::iterator it; 292 // for(it = gamestateMap_[peerID].begin(); it!=gamestateMap_[peerID].end() && it->first<gamestateID; ){ 293 // delete it->second; 294 // gamestateMap_[peerID].erase(it++); 295 // } 296 it->second.lastAckedGamestateID = gamestateID; 297 // temp->setGamestateID(gamestateID); 298 // TrafficControl::processAck(peerID, gamestateID); 258 299 return true; 259 300 } 260 261 void GamestateManager::removeClient(ClientInformation* client){ 262 assert(client); 263 std::map<unsigned int, std::map<unsigned int, packet::Gamestate*> >::iterator clientMap = gamestateMap_.find(client->getID()); 264 // first delete all remained gamestates 265 std::map<unsigned int, packet::Gamestate*>::iterator it; 266 for(it=clientMap->second.begin(); it!=clientMap->second.end(); it++) 267 delete it->second; 268 // now delete the clients gamestatemap 269 gamestateMap_.erase(clientMap); 270 } 271 272 bool GamestateManager::processGamestate(packet::Gamestate *gs){ 301 302 uint32_t GamestateManager::getLastProcessedGamestateID(unsigned int peerID) 303 { 304 assert( this->peerMap_.find(peerID)!=this->peerMap_.end() ); 305 if( this->peerMap_.find(peerID) != this->peerMap_.end() ) 306 return this->peerMap_[peerID].lastProcessedGamestateID; 307 else 308 return GAMESTATEID_INITIAL; 309 } 310 311 312 void GamestateManager::addPeer(uint32_t peerID) 313 { 314 assert(peerMap_.find(peerID)==peerMap_.end()); 315 peerMap_[peerID].peerID = peerID; 316 peerMap_[peerID].lastProcessedGamestateID = GAMESTATEID_INITIAL; 317 peerMap_[peerID].lastAckedGamestateID = GAMESTATEID_INITIAL; 318 if( GameMode::isMaster() ) 319 peerMap_[peerID].isSynched = false; 320 else 321 peerMap_[peerID].isSynched = true; 322 } 323 324 void GamestateManager::removePeer(uint32_t peerID) 325 { 326 assert(peerMap_.find(peerID)!=peerMap_.end()); 327 std::map<uint32_t, packet::Gamestate*>::iterator peerIt; 328 for( peerIt = peerMap_[peerID].gamestates.begin(); peerIt!=peerMap_[peerID].gamestates.end(); ++peerIt ) 329 { 330 delete peerIt->second; 331 } 332 peerMap_.erase(peerMap_.find(peerID)); 333 } 334 335 336 // void GamestateManager::removeClient(ClientInformation* client){ 337 // assert(client); 338 // std::map<unsigned int, std::map<unsigned int, packet::Gamestate*> >::iterator clientMap = gamestateMap_.find(client->getID()); 339 // // first delete all remained gamestates 340 // std::map<unsigned int, packet::Gamestate*>::iterator it; 341 // for(it=clientMap->second.begin(); it!=clientMap->second.end(); it++) 342 // delete it->second; 343 // // now delete the clients gamestatemap 344 // gamestateMap_.erase(clientMap); 345 // } 346 347 bool GamestateManager::processGamestate(packet::Gamestate *gs) 348 { 273 349 if(gs->isCompressed()) 274 350 { … … 277 353 } 278 354 assert(!gs->isDiffed()); 279 return gs->spreadData(0x1); 355 uint8_t gsMode; 356 if( GameMode::isMaster() ) 357 gsMode = packet::GAMESTATE_MODE_SERVER; 358 else 359 gsMode = packet::GAMESTATE_MODE_CLIENT; 360 if( gs->spreadData(gsMode) ) 361 { 362 this->peerMap_[gs->getPeerID()].lastProcessedGamestateID = gs->getID(); 363 return true; 364 } 365 else 366 return false; 280 367 } 281 368
Note: See TracChangeset
for help on using the changeset viewer.