- Timestamp:
- May 30, 2018, 2:56:24 PM (6 years ago)
- Location:
- code/branches/PresentationFS18
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
code/branches/PresentationFS18
- Property svn:mergeinfo changed
/code/branches/Masterserver_FS18 (added) merged: 11816,11829,11842,11856,11858,11880,11889,11905,11907,11910,11929-11930,11937,11962-11963,11973,11983,11990
- Property svn:mergeinfo changed
-
code/branches/PresentationFS18/src/libraries/network/GamestateManager.cc
r11071 r12020 43 43 #include <cassert> 44 44 #include <queue> 45 // #include <boost/thread/mutex.hpp>46 45 47 46 #include "packet/Acknowledgement.h" … … 55 54 #include "util/Clock.h" 56 55 #include "util/OrxAssert.h" 57 // #include "TrafficControl.h"58 56 59 57 namespace orxonox … … 62 60 currentGamestate_(nullptr), id_(0) 63 61 { 64 // trafficControl_ = new TrafficControl();65 // threadMutex_ = new boost::mutex();66 // threadPool_ = new ThreadPool();67 62 } 68 63 69 64 GamestateManager::~GamestateManager() 70 65 { 71 if( this->currentGamestate_ ) 72 delete this->currentGamestate_; 73 for( const auto& mapEntry : gamestateQueue ) 74 delete mapEntry.second; 75 for( const auto& mapEntryPeer : peerMap_ ) 76 { 77 for( const auto& mapEntryGamestate : mapEntryPeer.second.gamestates ) 78 delete mapEntryGamestate.second; 79 } 80 // this->trafficControl_->destroy(); 81 // delete this->threadMutex_; 82 // delete this->threadPool_; 83 } 84 85 bool GamestateManager::update(){ 86 // cleanup(); 87 return getSnapshot(); 66 if(this->currentGamestate_) 67 { 68 delete this->currentGamestate_; 69 this->currentGamestate_ = nullptr; 70 } 71 72 for(const auto& gsPair : this->gamestateQueue) 73 { 74 delete gsPair.second; 75 } 76 77 for(const auto& peerPair : this->peerMap_) 78 { 79 for(const auto& gsPair : peerPair.second.gamestates) 80 { 81 delete gsPair.second; 82 } 83 } 84 } 85 86 bool GamestateManager::update() 87 { 88 return this->getSnapshot(); 88 89 } 89 90 … … 91 92 { 92 93 assert(gs); 93 std::map<unsigned int, packet::Gamestate*>::iterator it = gamestateQueue.find(clientID); 94 if(it!=gamestateQueue.end()) 94 // Search the queue for a gamestate for the client 95 std::map<unsigned int, packet::Gamestate*>::iterator it = this->gamestateQueue.find(clientID); 96 if(it != this->gamestateQueue.end()) 95 97 { 96 98 // delete obsolete gamestate 97 99 delete it->second; 98 100 } 99 gamestateQueue[clientID] = gs; 101 // update the client's gamestate 102 this->gamestateQueue[clientID] = gs; 103 100 104 return true; 101 105 } 102 106 107 /** 108 * Process the queued gamestates. 109 */ 103 110 bool GamestateManager::processGamestates() 104 111 { 105 if( this->gamestateQueue.empty() ) 112 // Queue is empty, nothing to do 113 if(this->gamestateQueue.empty()) 114 { 106 115 return true; 116 } 117 107 118 // now push only the most recent gamestates we received (ignore obsolete ones) 108 for(const auto& mapEntry :gamestateQueue)109 { 110 OrxVerify( processGamestate(mapEntry.second), "ERROR: could not process Gamestate");111 sendAck( mapEntry.second->getID(), mapEntry.second->getPeerID());112 delete mapEntry.second;119 for(const auto& gsPair : this->gamestateQueue) 120 { 121 OrxVerify(this->processGamestate(gsPair.second), "ERROR: could not process Gamestate"); 122 this->sendAck(gsPair.second->getID(), gsPair.second->getPeerID()); 123 delete gsPair.second; 113 124 } 114 125 // now clear the queue 115 gamestateQueue.clear(); 126 this->gamestateQueue.clear(); 127 116 128 //and call all queued callbacks 117 129 NetworkCallbackManager::callCallbacks(); 130 118 131 return true; 119 132 } 120 133 134 /** 135 * Send Acknowledgement packet. 136 * @param gamestateId The gamestate ID we want to acknowledge 137 * @param peerID The ID of the peer we want to send the Acknowledgement to 138 */ 121 139 bool GamestateManager::sendAck(unsigned int gamestateID, uint32_t peerID) 122 140 { 123 assert( gamestateID != ACKID_NACK);141 assert(gamestateID != ACKID_NACK); 124 142 packet::Acknowledgement *ack = new packet::Acknowledgement(gamestateID, peerID); 125 if( 143 if(!this->sendPacket(ack)) 126 144 { 127 145 orxout(internal_warning, context::network) << "could not ack gamestate: " << gamestateID << endl; … … 135 153 } 136 154 137 138 bool GamestateManager::getSnapshot(){ 139 if ( currentGamestate_ != nullptr ) 140 delete currentGamestate_; 155 /** 156 * Update the current gamestate. 157 */ 158 bool GamestateManager::getSnapshot() 159 { 160 // Delete current gamestate 161 if (this->currentGamestate_) 162 { 163 delete this->currentGamestate_; 164 this->currentGamestate_ = nullptr; 165 } 166 141 167 uint8_t gsMode; 142 if( GameMode::isMaster() ) 168 if(GameMode::isMaster()) 169 { 143 170 gsMode = packet::GAMESTATE_MODE_SERVER; 144 else 171 } 172 else 173 { 145 174 gsMode = packet::GAMESTATE_MODE_CLIENT; 175 } 176 146 177 uint32_t newID; 147 if( GameMode::isMaster() ) 148 newID = ++id_; 149 else 150 { 151 assert(peerMap_.size()!=0); 152 newID = peerMap_[NETWORK_PEER_ID_SERVER].lastReceivedGamestateID; 153 if( newID == GAMESTATEID_INITIAL ) 178 if(GameMode::isMaster()) 179 { 180 newID = ++this->id_; 181 } 182 else 183 { 184 assert(this->peerMap_.size() != 0); 185 newID = this->peerMap_[NETWORK_PEER_ID_SERVER].lastReceivedGamestateID; 186 if(newID == GAMESTATEID_INITIAL) 154 187 { 155 188 return false; … … 157 190 } 158 191 159 currentGamestate_ = new packet::Gamestate(); 160 161 if(!currentGamestate_->collectData(newID, gsMode)) 162 { //we have no data to send 163 delete currentGamestate_; 164 currentGamestate_=nullptr; 192 // Create a new gamestate 193 this->currentGamestate_ = new packet::Gamestate(); 194 if(!this->currentGamestate_->collectData(newID, gsMode)) 195 { 196 // we have no data to send 197 delete this->currentGamestate_; 198 this->currentGamestate_ = nullptr; 165 199 return false; 166 200 } 201 167 202 return true; 168 203 } 169 204 205 /** 206 * Return a vector with the gamestates of all peers. 207 */ 170 208 std::vector<packet::Gamestate*> GamestateManager::getGamestates() 171 209 { 172 if(!currentGamestate_) 210 // Current gamestate is empty 211 if(!this->currentGamestate_){ 173 212 return std::vector<packet::Gamestate*>(); 213 } 214 174 215 std::vector<packet::Gamestate*> peerGamestates; 175 176 for( const auto& mapEntry : peerMap_ ) 177 { 178 if( !mapEntry.second.isSynched ) 216 for(const auto& mapEntry : this->peerMap_) 217 { 218 if(!mapEntry.second.isSynched) 179 219 { 180 220 orxout(verbose_more, context::network) << "Server: not sending gamestate" << endl; … … 198 238 peerGamestates.push_back(nullptr); // insert an empty gamestate* to be changed 199 239 finishGamestate( peerID, peerGamestates.back(), baseGamestate, currentGamestate_ ); 200 if( peerGamestates.back()==nullptr ) 240 if(peerGamestates.back() == nullptr) 241 { 201 242 // nothing to send to remove pointer from vector 202 243 peerGamestates.pop_back(); 203 //FunctorMember<GamestateManager>* functor = 204 // ExecutorMember<GamestateManager>* executor = createExecutor( createFunctor(&GamestateManager::finishGamestate, this) ); 205 // executor->setDefaultValues( cid, &clientGamestates.back(), client, currentGamestate_ ); 206 // (*static_cast<Executor*>(executor))(); 207 // this->threadPool_->passFunction( executor, true ); 208 // (*functor)( cid, &(clientGamestates.back()), client, currentGamestate_ ); 209 } 210 211 // threadPool_->synchronise(); 244 } 245 } 212 246 213 247 return peerGamestates; … … 215 249 216 250 217 void GamestateManager::finishGamestate( unsigned int peerID, packet::Gamestate*& destgamestate, packet::Gamestate* base, packet::Gamestate* gamestate ) { 218 //why are we searching the same client's gamestate id as we searched in 219 //Server::sendGameState? 251 void GamestateManager::finishGamestate(unsigned int peerID, packet::Gamestate*& destgamestate, packet::Gamestate* base, packet::Gamestate* gamestate) 252 { 220 253 // save the (undiffed) gamestate in the clients gamestate map 221 //chose wheather the next gamestate is the first or not 222 223 // packet::Gamestate *gs = gamestate->doSelection(clientID, 20000); 224 // packet::Gamestate* gs = new packet::Gamestate(*gamestate); 225 // packet::Gamestate* gs = gamestate; 254 // choose whether the next gamestate is the first or not 255 256 // Create a copy of the gamestate 226 257 packet::Gamestate *gs = new packet::Gamestate(*gamestate); //this is neccessary because the gamestate are being kept (to diff them later on) for each client seperately 227 // packet::Gamestate *gs = new packet::Gamestate(); 228 // gs->collectData( id_, 0x1 ); 229 // this->threadMutex_->lock(); 230 peerMap_[peerID].gamestates[gamestate->getID()]=gs; 231 // this->threadMutex_->unlock(); 258 this->peerMap_[peerID].gamestates[gamestate->getID()] = gs; 259 260 // Start the clock 232 261 Clock clock; 233 262 clock.capture(); … … 236 265 { 237 266 packet::Gamestate *diffed1 = gs->diffVariables(base); 238 if( diffed1->getDataSize() == 0)267 if(diffed1->getDataSize() == 0) 239 268 { 240 269 delete diffed1; … … 249 278 } 250 279 251 252 // OrxVerify(gs->compressData(), ""); 280 // Stop the clock 253 281 clock.capture(); 254 282 orxout(verbose_more, context::network) << "diff and compress time: " << clock.getDeltaTime() << endl; 255 // orxout(verbose_more, context::network) << "sending gamestate with id " << gs->getID(); 256 // if(gamestate->isDiffed()) 257 // orxout(verbose_more, context::network) << " and baseid " << gs->getBaseID() << endl; 258 // else 259 // orxout(verbose_more, context::network) << endl; 283 284 260 285 gs->setPeerID(peerID); 261 286 destgamestate = gs; … … 263 288 264 289 290 /** 291 * Acknowledge a received gamestate. 292 * @param gamestateID The ID of the gamestate to be acknowledged 293 * @param peerID The ID of the peer to send the Acknowledgement to 294 */ 265 295 bool GamestateManager::ackGamestate(unsigned int gamestateID, unsigned int peerID) 266 296 { 267 // ClientInformation *temp = ClientInformation::findClient(peerID); 268 // assert(temp); 297 // Search for the peer in the peer map 269 298 std::map<uint32_t, peerInfo>::iterator it = this->peerMap_.find(peerID); 270 assert(it!=this->peerMap_.end()); 299 assert(it != this->peerMap_.end()); 300 271 301 unsigned int curid = it->second.lastAckedGamestateID; 272 302 273 303 assert(gamestateID != ACKID_NACK); 274 // if(gamestateID == ACKID_NACK){ 275 // it->second.lastAckedGamestateID = GAMESTATEID_INITIAL; 276 // // temp->setGamestateID(GAMESTATEID_INITIAL); 277 // // now delete all saved gamestates for this client 278 // std::map<uint32_t, packet::Gamestate*>::iterator it2; 279 // for(it2 = it->second.gamestates.begin(); it2!=it->second.gamestates.end(); ++it2 ){ 280 // delete it2->second; 281 // } 282 // it->second.gamestates.clear(); 283 // return true; 284 // } 285 286 // assert(curid==GAMESTATEID_INITIAL || curid<=gamestateID); // this line is commented out because acknowledgements are unreliable and may arrive in distorted order 287 if( gamestateID <= curid && curid != GAMESTATEID_INITIAL ) 304 305 // The gamestate has already been acknowledged, nothing to do 306 if(gamestateID <= curid && curid != GAMESTATEID_INITIAL) 307 { 288 308 return true; 289 orxout(verbose, context::network) << "acking gamestate " << gamestateID << " for peerID: " << peerID << " curid: " << curid << endl; 309 } 310 311 orxout(verbose, context::network) << "acking gamestate " << gamestateID << " for peerID: " << peerID << " curid: " << curid << endl; 290 312 std::map<uint32_t, packet::Gamestate*>::iterator it2; 291 for ( it2=it->second.gamestates.begin(); it2!=it->second.gamestates.end();)292 { 293 if( it2->second->getID() < gamestateID)313 for (it2 = it->second.gamestates.begin(); it2 != it->second.gamestates.end();) 314 { 315 if(it2->second->getID() < gamestateID) 294 316 { 295 317 delete it2->second; … … 297 319 } 298 320 else 321 { 299 322 ++it2; 323 } 300 324 } 301 325 302 // std::map<unsigned int, packet::Gamestate*>::iterator it; 303 // for(it = gamestateMap_[peerID].begin(); it!=gamestateMap_[peerID].end() && it->first<gamestateID; ){ 304 // delete it->second; 305 // gamestateMap_[peerID].erase(it++); 306 // } 326 // update the last acked gamestate 307 327 it->second.lastAckedGamestateID = gamestateID; 308 // temp->setGamestateID(gamestateID); 309 // TrafficControl::processAck(peerID, gamestateID); 328 310 329 return true; 311 330 } 312 331 332 /** 333 * Return the ID of the last received gamestate for a certain peer 334 * @param peerID The ID of the peer\ 335 */ 313 336 uint32_t GamestateManager::getLastReceivedGamestateID(unsigned int peerID) 314 337 { 315 assert( this->peerMap_.find(peerID)!=this->peerMap_.end() );316 if( this->peerMap_.find(peerID) != this->peerMap_.end() )338 if(this->peerMap_.find(peerID) != this->peerMap_.end()) 339 { 317 340 return this->peerMap_[peerID].lastReceivedGamestateID; 318 else 341 } 342 else 343 { 319 344 return GAMESTATEID_INITIAL; 345 } 320 346 } 321 347 322 348 /** 349 * Add a peer to the game. 350 * @param peerID The ID of the peer to add. 351 */ 323 352 void GamestateManager::addPeer(uint32_t peerID) 324 353 { 325 assert(peerMap_.find(peerID)==peerMap_.end()); 326 peerMap_[peerID].peerID = peerID; 327 peerMap_[peerID].lastReceivedGamestateID = GAMESTATEID_INITIAL; 328 peerMap_[peerID].lastAckedGamestateID = GAMESTATEID_INITIAL; 329 if( GameMode::isMaster() ) 330 peerMap_[peerID].isSynched = false; 331 else 332 peerMap_[peerID].isSynched = true; 333 } 334 354 // Ensure that the peer doesn't already exist. 355 assert(this->peerMap_.find(peerID) == this->peerMap_.end()); 356 357 // Create the peerInfo struct for the peer 358 this->peerMap_[peerID].peerID = peerID; 359 this->peerMap_[peerID].lastReceivedGamestateID = GAMESTATEID_INITIAL; 360 this->peerMap_[peerID].lastAckedGamestateID = GAMESTATEID_INITIAL; 361 if(GameMode::isMaster()) 362 { 363 this->peerMap_[peerID].isSynched = false; 364 } 365 else 366 { 367 this->peerMap_[peerID].isSynched = true; 368 } 369 } 370 371 /** 372 * Remove a peer from the game. 373 * @param peerID The ID of the peer to be removed 374 */ 335 375 void GamestateManager::removePeer(uint32_t peerID) 336 376 { 337 assert(peerMap_.find(peerID)!=peerMap_.end()); 338 for( const auto& mapEntry : peerMap_[peerID].gamestates ) 377 // Make sure that the peer exists 378 assert(this->peerMap_.find(peerID) != this->peerMap_.end()); 379 380 for (const auto& mapEntry : this->peerMap_[peerID].gamestates) 339 381 { 340 382 delete mapEntry.second; 341 383 } 342 peerMap_.erase(peerMap_.find(peerID)); 343 } 344 345 346 // void GamestateManager::removeClient(ClientInformation* client){ 347 // assert(client); 348 // std::map<unsigned int, std::map<unsigned int, packet::Gamestate*>>::iterator clientMap = gamestateMap_.find(client->getID()); 349 // // first delete all remained gamestates 350 // std::map<unsigned int, packet::Gamestate*>::iterator it; 351 // for(it=clientMap->second.begin(); it!=clientMap->second.end(); it++) 352 // delete it->second; 353 // // now delete the clients gamestatemap 354 // gamestateMap_.erase(clientMap); 355 // } 356 384 this->peerMap_.erase(this->peerMap_.find(peerID)); 385 } 386 387 /** 388 * Process an incoming Gamestate packet. 389 * @param gs Pointer to the incoming Gamestate packet 390 */ 357 391 bool GamestateManager::processGamestate(packet::Gamestate *gs) 358 392 { 393 // Decompress if necessary 359 394 if(gs->isCompressed()) 360 395 { … … 362 397 } 363 398 assert(!gs->isDiffed()); 399 364 400 uint8_t gsMode; 365 if( GameMode::isMaster() ) 401 if(GameMode::isMaster()) 402 { 366 403 gsMode = packet::GAMESTATE_MODE_SERVER; 367 else 404 } 405 else 406 { 368 407 gsMode = packet::GAMESTATE_MODE_CLIENT; 369 if( gs->spreadData(gsMode) ) 408 } 409 410 if(gs->spreadData(gsMode)) 370 411 { 371 412 this->peerMap_[gs->getPeerID()].lastReceivedGamestateID = gs->getID(); … … 373 414 } 374 415 else 416 { 375 417 return false; 418 } 376 419 } 377 420
Note: See TracChangeset
for help on using the changeset viewer.