Changeset 7801 for code/trunk/src/libraries/network/packet/Gamestate.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/packet/Gamestate.cc
r7163 r7801 36 36 #include "network/synchronisable/Synchronisable.h" 37 37 #include "network/GamestateHandler.h" 38 #include "network/Host.h" 38 39 39 40 namespace orxonox { … … 43 44 #define GAMESTATE_START(data) (data + GamestateHeader::getSize()) 44 45 45 #define PACKET_FLAG_GAMESTATE PacketFlag::Reliable 46 // #define PACKET_FLAG_GAMESTATE PacketFlag::Reliable 47 #define PACKET_FLAG_GAMESTATE 0 46 48 47 49 inline bool memzero( uint8_t* data, uint32_t datalength) … … 65 67 66 68 Gamestate::Gamestate(): 67 header_( 0)69 header_() 68 70 { 69 71 flags_ = flags_ | PACKET_FLAG_GAMESTATE; … … 72 74 73 75 Gamestate::Gamestate(uint8_t *data, unsigned int clientID): 74 Packet(data, clientID) 76 Packet(data, clientID), header_(data) 75 77 { 76 78 flags_ = flags_ | PACKET_FLAG_GAMESTATE; 77 header_ = new GamestateHeader(data_); 78 } 79 80 81 Gamestate::Gamestate(uint8_t *data)79 } 80 81 82 Gamestate::Gamestate(uint8_t *data): 83 header_(data) 82 84 { 83 85 flags_ = flags_ | PACKET_FLAG_GAMESTATE; 84 86 data_ = data; 85 header_ = new GamestateHeader(data_);86 87 } 87 88 88 89 89 90 Gamestate::Gamestate(const Gamestate& g) : 90 Packet( *(Packet*)&g), nrOfVariables_(0)91 Packet( *(Packet*)&g ), header_(this->data_), nrOfVariables_(0) 91 92 { 92 93 flags_ = flags_ | PACKET_FLAG_GAMESTATE; 93 header_ = new GamestateHeader(data_);94 94 sizes_ = g.sizes_; 95 95 } … … 98 98 Gamestate::~Gamestate() 99 99 { 100 if( header_ )101 delete header_;102 100 } 103 101 … … 105 103 bool Gamestate::collectData(int id, uint8_t mode) 106 104 { 107 assert(this->header_==0); // make sure the header didn't exist before108 105 uint32_t tempsize=0, currentsize=0; 109 106 assert(data_==0); … … 120 117 } 121 118 122 // create the header object 123 assert( header_ == 0 ); 124 header_ = new GamestateHeader(data_); 119 // tell the gamestate header where to store the data 120 header_.setData(this->data_); 125 121 126 122 //start collect data synchronisable by synchronisable … … 142 138 assert(0); // if we don't use multithreading this part shouldn't be neccessary 143 139 // start allocate additional memory 144 COUT(3) << "G .St.Man: need additional memory" << std::endl;140 COUT(3) << "Gamestate: need additional memory" << std::endl; 145 141 ObjectList<Synchronisable>::iterator temp = it; 146 142 uint32_t addsize=tempsize; … … 161 157 162 158 //start write gamestate header 163 header_ ->setDataSize( currentsize );164 header_ ->setID( id );165 header_ ->setBaseID( GAMESTATEID_INITIAL );166 header_ ->setDiffed( false );167 header_ ->setComplete( true );168 header_ ->setCompressed( false );159 header_.setDataSize( currentsize ); 160 header_.setID( id ); 161 header_.setBaseID( GAMESTATEID_INITIAL ); 162 header_.setDiffed( false ); 163 header_.setComplete( true ); 164 header_.setCompressed( false ); 169 165 //stop write gamestate header 170 166 171 COUT(5) << "G .ST.Man: Gamestate size: " << currentsize << std::endl;172 COUT(5) << "G .ST.Man: 'estimated' (and corrected) Gamestate size: " << size << std::endl;167 COUT(5) << "Gamestate: Gamestate size: " << currentsize << std::endl; 168 COUT(5) << "Gamestate: 'estimated' (and corrected) Gamestate size: " << size << std::endl; 173 169 return true; 174 170 } … … 177 173 bool Gamestate::spreadData(uint8_t mode) 178 174 { 179 COUT( 4) << "processing gamestate with id " << header_->getID() << endl;175 COUT(5) << "processing gamestate with id " << header_.getID() << endl; 180 176 assert(data_); 181 assert(!header_ ->isCompressed());177 assert(!header_.isCompressed()); 182 178 uint8_t *mem=data_+GamestateHeader::getSize(); 183 179 Synchronisable *s; 184 180 185 181 // update the data of the objects we received 186 while(mem < data_+GamestateHeader::getSize()+header_ ->getDataSize())182 while(mem < data_+GamestateHeader::getSize()+header_.getDataSize()) 187 183 { 188 184 SynchronisableHeader objectheader(mem); … … 197 193 else 198 194 { 195 // COUT(4) << "not creating object of classid " << objectheader.getClassID() << endl; 199 196 mem += objectheader.getDataSize() + ( objectheader.isDiffed() ? SynchronisableHeaderLight::getSize() : SynchronisableHeader::getSize() ); 200 197 } … … 202 199 else 203 200 { 201 // COUT(4) << "updating object of classid " << objectheader.getClassID() << endl; 204 202 bool b = s->updateData(mem, mode); 205 203 assert(b); 206 204 } 207 205 } 206 assert(mem-data_ == GamestateHeader::getSize()+header_.getDataSize()); 207 208 208 // In debug mode, check first, whether there are no duplicate objectIDs 209 209 #ifndef NDEBUG … … 249 249 { 250 250 assert(data_); 251 if(header_ ->isCompressed())252 return header_ ->getCompSize()+GamestateHeader::getSize();251 if(header_.isCompressed()) 252 return header_.getCompSize()+GamestateHeader::getSize(); 253 253 else 254 254 { 255 return header_ ->getDataSize()+GamestateHeader::getSize();255 return header_.getDataSize()+GamestateHeader::getSize(); 256 256 } 257 257 } … … 271 271 272 272 273 bool Gamestate::process( )274 { 275 return GamestateHandler::addGamestate(this, getClientID());273 bool Gamestate::process(orxonox::Host* host) 274 { 275 return host->addGamestate(this, getPeerID()); 276 276 } 277 277 … … 280 280 { 281 281 assert(data_); 282 assert(!header_ ->isCompressed());283 uLongf buffer = (uLongf)(((header_ ->getDataSize() + 12)*1.01)+1);282 assert(!header_.isCompressed()); 283 uLongf buffer = (uLongf)(((header_.getDataSize() + 12)*1.01)+1); 284 284 if(buffer==0) 285 285 return false; … … 289 289 uint8_t *source = data_ + GamestateHeader::getSize(); 290 290 int retval; 291 retval = compress( dest, &buffer, source, (uLong)(header_ ->getDataSize()) );291 retval = compress( dest, &buffer, source, (uLong)(header_.getDataSize()) ); 292 292 switch ( retval ) 293 293 { … … 299 299 300 300 //copy and modify header 301 GamestateHeader *temp = header_; 302 header_ = new GamestateHeader(ndata, temp); 301 GamestateHeader *temp = new GamestateHeader(data_); 302 header_.setData(ndata); 303 header_ = *temp; 303 304 delete temp; 304 305 //delete old data … … 306 307 //save new data 307 308 data_ = ndata; 308 header_ ->setCompSize( buffer );309 header_ ->setCompressed( true );310 COUT( 0) << "gamestate compress datasize: " << header_->getDataSize() << " compsize: " << header_->getCompSize() << std::endl;309 header_.setCompSize( buffer ); 310 header_.setCompressed( true ); 311 COUT(4) << "gamestate compress datasize: " << header_.getDataSize() << " compsize: " << header_.getCompSize() << std::endl; 311 312 return true; 312 313 } … … 316 317 { 317 318 assert(data_); 318 assert(header_ ->isCompressed());319 COUT(4) << "GameStateClient: uncompressing gamestate. id: " << header_ ->getID() << ", baseid: " << header_->getBaseID() << ", datasize: " << header_->getDataSize() << ", compsize: " << header_->getCompSize() << std::endl;320 uint32_t datasize = header_ ->getDataSize();321 uint32_t compsize = header_ ->getCompSize();319 assert(header_.isCompressed()); 320 COUT(4) << "GameStateClient: uncompressing gamestate. id: " << header_.getID() << ", baseid: " << header_.getBaseID() << ", datasize: " << header_.getDataSize() << ", compsize: " << header_.getCompSize() << std::endl; 321 uint32_t datasize = header_.getDataSize(); 322 uint32_t compsize = header_.getCompSize(); 322 323 uint32_t bufsize; 323 324 bufsize = datasize; … … 338 339 339 340 //copy over the header 340 GamestateHeader *temp = header_; 341 header_ = new GamestateHeader( data_, header_ ); 341 GamestateHeader* temp = new GamestateHeader( data_ ); 342 header_.setData(ndata); 343 header_ = *temp; 342 344 delete temp; 343 345 … … 357 359 //set new pointers 358 360 data_ = ndata; 359 header_ ->setCompressed( false );360 assert(header_ ->getDataSize()==datasize);361 assert(header_ ->getCompSize()==compsize);361 header_.setCompressed( false ); 362 assert(header_.getDataSize()==datasize); 363 assert(header_.getCompSize()==compsize); 362 364 return true; 363 365 } 364 366 365 367 368 inline void /*Gamestate::*/diffObject( uint8_t*& newDataPtr, uint8_t*& origDataPtr, uint8_t*& baseDataPtr, SynchronisableHeader& objectHeader, std::vector<uint32_t>::iterator& sizes ) 369 { 370 assert( objectHeader.getDataSize() == SynchronisableHeader(baseDataPtr).getDataSize() ); 371 372 uint32_t objectOffset = SynchronisableHeader::getSize(); // offset inside the object in the origData and baseData 373 // Check whether the whole object stayed the same 374 if( memcmp( origDataPtr+objectOffset, baseDataPtr+objectOffset, objectHeader.getDataSize()) == 0 ) 375 { 376 // COUT(4) << "skip object " << Synchronisable::getSynchronisable(objectHeader.getObjectID())->getIdentifier()->getName() << endl; 377 origDataPtr += objectOffset + objectHeader.getDataSize(); // skip the whole object 378 baseDataPtr += objectOffset + objectHeader.getDataSize(); 379 sizes += Synchronisable::getSynchronisable(objectHeader.getObjectID())->getNrOfVariables(); 380 } 381 else 382 { 383 // Now start to diff the Object 384 SynchronisableHeaderLight newObjectHeader(newDataPtr); 385 newObjectHeader = objectHeader; // copy over the objectheader 386 VariableID variableID = 0; 387 uint32_t diffedObjectOffset = SynchronisableHeaderLight::getSize(); 388 // iterate through all variables 389 while( objectOffset < objectHeader.getDataSize()+SynchronisableHeader::getSize() ) 390 { 391 // check whether variable changed and write id and copy over variable to the new stream 392 // otherwise skip variable 393 uint32_t varSize = *sizes; 394 assert( varSize == Synchronisable::getSynchronisable(objectHeader.getObjectID())->getVarSize(variableID) ); 395 if ( varSize != 0 ) 396 { 397 if ( memcmp(origDataPtr+objectOffset, baseDataPtr+objectOffset, varSize) != 0 ) 398 { 399 *(VariableID*)(newDataPtr+diffedObjectOffset) = variableID; // copy over the variableID 400 diffedObjectOffset += sizeof(VariableID); 401 memcpy( newDataPtr+diffedObjectOffset, origDataPtr+objectOffset, varSize ); 402 diffedObjectOffset += varSize; 403 objectOffset += varSize; 404 } 405 else 406 { 407 objectOffset += varSize; 408 } 409 } 410 411 ++variableID; 412 ++sizes; 413 } 414 415 // if there are variables from this object with 0 size left in sizes 416 if( Synchronisable::getSynchronisable(objectHeader.getObjectID())->getNrOfVariables() != variableID ) 417 sizes += Synchronisable::getSynchronisable(objectHeader.getObjectID())->getNrOfVariables() - variableID; 418 419 newObjectHeader.setDiffed(true); 420 newObjectHeader.setDataSize(diffedObjectOffset-SynchronisableHeaderLight::getSize()); 421 assert(objectOffset == objectHeader.getDataSize()+SynchronisableHeader::getSize()); 422 assert(newObjectHeader.getDataSize()>0); 423 424 origDataPtr += objectOffset; 425 baseDataPtr += objectOffset; 426 newDataPtr += diffedObjectOffset; 427 } 428 } 429 430 inline void /*Gamestate::*/copyObject( uint8_t*& newData, uint8_t*& origData, uint8_t*& baseData, SynchronisableHeader& objectHeader, std::vector<uint32_t>::iterator& sizes ) 431 { 432 // COUT(4) << "docopy" << endl; 433 // Just copy over the whole Object 434 memcpy( newData, origData, objectHeader.getDataSize()+SynchronisableHeader::getSize() ); 435 SynchronisableHeader(newData).setDiffed(false); 436 437 newData += objectHeader.getDataSize()+SynchronisableHeader::getSize(); 438 origData += objectHeader.getDataSize()+SynchronisableHeader::getSize(); 439 // SynchronisableHeader baseHeader( baseData ); 440 // baseData += baseHeader.getDataSize()+SynchronisableHeader::getSize(); 441 // COUT(4) << "copy " << h.getObjectID() << endl; 442 // COUT(4) << "copy " << h.getObjectID() << ":"; 443 sizes += Synchronisable::getSynchronisable(objectHeader.getObjectID())->getNrOfVariables(); 444 // for( unsigned int i = 0; i < Synchronisable::getSynchronisable(objectHeader.getObjectID())->getNrOfVariables(); ++i ) 445 // { 446 // // COUT(4) << " " << *sizes; 447 // ++sizes; 448 // } 449 // COUT(4) << endl; 450 } 451 452 inline bool findObject(uint8_t*& dataPtr, uint8_t* endPtr, SynchronisableHeader& objectHeader) 453 { 454 // Some assertions to make sure the dataPtr is valid (pointing to a SynchronisableHeader) 455 { 456 SynchronisableHeader htemp2(dataPtr); 457 assert(htemp2.getClassID()<500); 458 assert(htemp2.getDataSize()!=0 && htemp2.getDataSize()<1000); 459 assert(htemp2.isDiffed()==false); 460 } 461 uint32_t objectID = objectHeader.getObjectID(); 462 while ( dataPtr < endPtr ) 463 { 464 SynchronisableHeader htemp(dataPtr); 465 assert( htemp.getDataSize()!=0 ); 466 if ( htemp.getObjectID() == objectID ) 467 { 468 assert( objectHeader.getClassID() == htemp.getClassID() ); 469 assert( objectHeader.getCreatorID() == htemp.getCreatorID() ); 470 return true; 471 } 472 { 473 if( dataPtr+htemp.getDataSize()+SynchronisableHeader::getSize() < endPtr ) 474 { 475 SynchronisableHeader htemp2(dataPtr+htemp.getDataSize()+SynchronisableHeader::getSize()); 476 assert(htemp2.getClassID()<500); 477 assert(htemp2.getDataSize()!=0 && htemp2.getDataSize()<1000); 478 assert(htemp2.isDiffed()==false); 479 } 480 } 481 dataPtr += htemp.getDataSize()+SynchronisableHeader::getSize(); 482 483 } 484 assert(dataPtr == endPtr); 485 486 return false; 487 } 488 366 489 Gamestate* Gamestate::diffVariables(Gamestate *base) 367 490 { 368 491 assert(this && base); assert(data_ && base->data_); 369 assert(!header_->isCompressed() && !base->header_->isCompressed()); 370 assert(!header_->isDiffed()); 492 assert(!header_.isCompressed() && !base->header_.isCompressed()); 493 assert(!header_.isDiffed()); 494 assert( header_.getDataSize() && base->header_.getDataSize() ); 371 495 372 496 373 497 // *** first do a raw diff of the two gamestates 374 498 375 uint8_t *baseData = GAMESTATE_START(base->data_);376 uint8_t *origData = GAMESTATE_START(this->data_);377 uint 32_t origLength = header_->getDataSize();378 uint 32_t baseLength = base->header_->getDataSize();379 380 assert( origLength && baseLength);381 382 uint8_t *nData = new uint8_t[origLength + GamestateHeader::getSize() + sizeof(uint32_t)*this->nrOfVariables_]; // this is the maximum size needed in the worst case383 uint 8_t *dest = GAMESTATE_START(nData);384 385 uint 32_t baseOffset = 0; //offset in the diffed stream386 uint32_t origOffset = 0; //offset in the new stream with removed 0's 387 std::vector<uint32_t>::iterator sizes = this->sizes_.begin();388 389 while( orig Offset < origLength)499 uint8_t *baseDataPtr = GAMESTATE_START(base->data_); 500 uint8_t *origDataPtr = GAMESTATE_START(this->data_); 501 uint8_t *origDataEnd = origDataPtr + header_.getDataSize(); 502 uint8_t *baseDataEnd = baseDataPtr + base->header_.getDataSize(); 503 // uint32_t origLength = header_.getDataSize(); 504 // uint32_t baseLength = base->header_.getDataSize(); 505 506 // Allocate new space for diffed gamestate 507 uint32_t newDataSize = header_.getDataSize() + GamestateHeader::getSize() + sizeof(uint32_t)*this->nrOfVariables_; 508 uint8_t *newData = new uint8_t[newDataSize]; // this is the maximum size needed in the worst case 509 uint8_t *destDataPtr = GAMESTATE_START(newData); 510 511 std::vector<uint32_t>::iterator sizesIt = this->sizes_.begin(); 512 513 while( origDataPtr < origDataEnd ) 390 514 { 391 515 //iterate through all objects 392 516 393 SynchronisableHeader h(origData+origOffset);517 SynchronisableHeader origHeader(origDataPtr); 394 518 395 519 // Find (if possible) the current object in the datastream of the old gamestate 396 520 // Start at the current offset position 397 if(baseOffset >= baseLength) 398 baseOffset = 0; 399 uint8_t* temp = baseData + baseOffset; 400 uint32_t objectID = h.getObjectID(); 401 assert(temp < baseData+baseLength); 402 assert(dest < nData + origLength + GamestateHeader::getSize() + sizeof(uint32_t)*this->nrOfVariables_); 403 assert(sizes != this->sizes_.end()); 404 while ( temp < baseData+baseLength ) 405 { 406 SynchronisableHeader htemp(temp); 407 assert( htemp.getDataSize()!=0 ); 408 if ( htemp.getObjectID() == objectID ) 409 { 410 assert( h.getClassID() == htemp.getClassID() ); 411 goto DODIFF; 412 } 413 // { 414 // SynchronisableHeader htemp2(temp+htemp.getDataSize()+SynchronisableHeader::getSize()); 415 // if( temp+htemp.getDataSize()+SynchronisableHeader::getSize() < baseData+baseLength ) 416 // { 417 // assert(htemp2.getClassID()<500); 418 // assert(htemp2.getDataSize()!=0 && htemp2.getDataSize()<1000); 419 // assert(htemp2.isDiffed()==false); 420 // } 421 // } 422 temp += htemp.getDataSize()+SynchronisableHeader::getSize(); 521 if(baseDataPtr == baseDataEnd) 522 baseDataPtr = GAMESTATE_START(base->data_); 523 uint8_t* oldBaseDataPtr = baseDataPtr; 524 525 assert(baseDataPtr < baseDataEnd); 526 assert(destDataPtr < newData + newDataSize); 527 assert(sizesIt != this->sizes_.end()); 528 529 assert(Synchronisable::getSynchronisable(origHeader.getObjectID())); 530 assert(ClassByID(origHeader.getClassID())); 531 assert(origHeader.getDataSize() < 500); 532 533 bool diffedObject = false; 534 if( findObject(baseDataPtr, baseDataEnd, origHeader) ) 535 { 536 SynchronisableHeader baseHeader(baseDataPtr); 537 assert(Synchronisable::getSynchronisable(baseHeader.getObjectID())); 538 assert(ClassByID(baseHeader.getClassID())); 539 assert(baseHeader.getDataSize() < 500); 540 if( SynchronisableHeader(baseDataPtr).getDataSize()==origHeader.getDataSize() ) 541 { 542 // COUT(4) << "diffing object in order: " << Synchronisable::getSynchronisable(origHeader.getObjectID())->getIdentifier()->getName() << endl; 543 diffObject(destDataPtr, origDataPtr, baseDataPtr, origHeader, sizesIt); 544 diffedObject = true; 545 } 546 else 547 { 548 // COUT(4) << "copy object because of different data sizes (1): " << Synchronisable::getSynchronisable(origHeader.getObjectID())->getIdentifier()->getName() << endl; 549 copyObject(destDataPtr, origDataPtr, baseDataPtr, origHeader, sizesIt); 550 assert(sizesIt != this->sizes_.end() || origDataPtr==origDataEnd); 551 } 423 552 424 553 } 425 // If not found start looking at the beginning 426 assert( temp==baseData+baseLength ); 427 temp = baseData; 428 // { 429 // SynchronisableHeader htemp2(temp); 430 // if( temp < baseData+baseLength ) 431 // { 432 // assert(htemp2.getClassID()<500); 433 // assert(htemp2.getDataSize()!=0 && htemp2.getDataSize()<1000); 434 // assert(htemp2.isDiffed()==false); 435 // } 436 // } 437 while ( temp < baseData+baseOffset ) 438 { 439 SynchronisableHeader htemp(temp); 440 if ( htemp.getObjectID() == objectID ) 441 { 442 assert( h.getClassID() == htemp.getClassID() ); 443 goto DODIFF; 444 } 445 // { 446 // SynchronisableHeader htemp2(temp+htemp.getDataSize()+SynchronisableHeader::getSize()); 447 // if( temp+htemp.getDataSize()+SynchronisableHeader::getSize() < baseData+baseLength ) 448 // { 449 // assert(htemp2.getClassID()<500); 450 // assert(htemp2.getDataSize()!=0 && htemp2.getDataSize()<1000); 451 // assert(htemp2.isDiffed()==false); 452 // } 453 // } 454 temp += htemp.getDataSize()+SynchronisableHeader::getSize(); 455 } 456 // Object is new, thus never transmitted -> just copy over 457 goto DOCOPY; 458 459 460 DODIFF: 461 { 462 // COUT(4) << "dodiff" << endl; 463 // if(baseOffset==0) 464 // { 465 // assert(origOffset==0); 466 // } 467 uint32_t objectOffset = SynchronisableHeader::getSize(); // offset inside the object in the origData and baseData 468 // Check whether the whole object stayed the same 469 if( memcmp( origData+origOffset+objectOffset, temp+objectOffset, h.getDataSize()) == 0 ) 470 { 471 // COUT(4) << "skip object" << Synchronisable::getSynchronisable(h.getObjectID())->getIdentifier()->getName() << endl; 472 origOffset += objectOffset+ h.getDataSize(); // skip the whole object 473 baseOffset = temp + h.getDataSize()+SynchronisableHeader::getSize() - baseData; 474 sizes += Synchronisable::getSynchronisable(h.getObjectID())->getNrOfVariables(); 554 else 555 { 556 assert( baseDataPtr == baseDataEnd ); 557 baseDataPtr = GAMESTATE_START(base->data_); 558 if( findObject(baseDataPtr, oldBaseDataPtr, origHeader) ) 559 { 560 SynchronisableHeader baseHeader(baseDataPtr); 561 assert(Synchronisable::getSynchronisable(baseHeader.getObjectID())); 562 assert(ClassByID(baseHeader.getClassID())); 563 assert(baseHeader.getDataSize() < 500); 564 if( SynchronisableHeader(baseDataPtr).getDataSize()==origHeader.getDataSize() ) 565 { 566 // COUT(4) << "diffing object out of order: " << Synchronisable::getSynchronisable(origHeader.getObjectID())->getIdentifier()->getName() << endl; 567 diffObject(destDataPtr, origDataPtr, baseDataPtr, origHeader, sizesIt); 568 diffedObject = true; 569 } 570 else 571 { 572 // COUT(4) << "copy object because of different data sizes (2): " << Synchronisable::getSynchronisable(origHeader.getObjectID())->getIdentifier()->getName() << endl; 573 copyObject(destDataPtr, origDataPtr, baseDataPtr, origHeader, sizesIt); 574 assert(sizesIt != this->sizes_.end() || origDataPtr==origDataEnd); 575 } 475 576 } 476 577 else 477 578 { 478 // if( Synchronisable::getSynchronisable(h.getObjectID())->getIdentifier()->getName() == "Bot" ) 479 // COUT(0) << "blub" << endl; 480 // COUT(4) << "object diff: " << Synchronisable::getSynchronisable(h.getObjectID())->getIdentifier()->getName() << endl; 481 // COUT(4) << "diff " << h.getObjectID() << ":"; 482 // Now start to diff the Object 483 SynchronisableHeaderLight h2(dest); 484 h2 = h; // copy over the objectheader 485 VariableID variableID = 0; 486 uint32_t newObjectOffset = SynchronisableHeaderLight::getSize(); 487 // iterate through all variables 488 while( objectOffset < h.getDataSize()+SynchronisableHeader::getSize() ) 489 { 490 // check whether variable changed and write id and copy over variable to the new stream 491 // otherwise skip variable 492 assert(sizes != this->sizes_.end()); 493 uint32_t varSize = *sizes; 494 assert( varSize == Synchronisable::getSynchronisable(h.getObjectID())->getVarSize(variableID) ); 495 if ( varSize != 0 ) 496 { 497 if ( memcmp(origData+origOffset+objectOffset, temp+objectOffset, varSize) != 0 ) 498 { 499 // COUT(4) << "copy variable" << endl; 500 *(VariableID*)(dest+newObjectOffset) = variableID; // copy over the variableID 501 newObjectOffset += sizeof(VariableID); 502 memcpy( dest+newObjectOffset, origData+origOffset+objectOffset, varSize ); 503 newObjectOffset += varSize; 504 objectOffset += varSize; 505 } 506 else 507 { 508 // COUT(4) << "skip variable" << endl; 509 objectOffset += varSize; 510 } 511 } 512 // else 513 // COUT(4) << "varsize 0" << endl; 514 515 ++variableID; 516 ++sizes; 517 } 518 519 if( Synchronisable::getSynchronisable(h.getObjectID())->getNrOfVariables() != variableID ) 520 sizes += Synchronisable::getSynchronisable(h.getObjectID())->getNrOfVariables() - variableID; 521 // COUT(4) << endl; 522 h2.setDiffed(true); 523 h2.setDataSize(newObjectOffset-SynchronisableHeaderLight::getSize()); 524 assert(objectOffset == h.getDataSize()+SynchronisableHeader::getSize()); 525 origOffset += objectOffset; 526 // baseOffset += temp + h.getDataSize()+SynchronisableHeader::getSize() - baseData; 527 //baseOffset += objectOffset; 528 // SynchronisableHeader htemp(temp); 529 // baseOffset += SynchronisableHeader::getSize() + htemp.getDataSize(); 530 // { 531 // SynchronisableHeader htemp2( baseData+(temp-baseData+objectOffset) ); 532 // if( baseData+(temp-baseData+objectOffset) < baseData+baseLength ) 533 // { 534 // assert(htemp2.getClassID()<500); 535 // assert(htemp2.getDataSize()!=0 && htemp2.getDataSize()<1000); 536 // assert(htemp2.isDiffed()==false); 537 // } 538 // } 539 baseOffset = temp-baseData + objectOffset; 540 dest += newObjectOffset; 541 } 542 543 continue; 544 } 545 546 DOCOPY: 547 { 548 // COUT(4) << "docopy" << endl; 549 // Just copy over the whole Object 550 memcpy( dest, origData+origOffset, h.getDataSize()+SynchronisableHeader::getSize() ); 551 dest += h.getDataSize()+SynchronisableHeader::getSize(); 552 origOffset += h.getDataSize()+SynchronisableHeader::getSize(); 553 assert( Synchronisable::getSynchronisable(h.getObjectID()) ); 554 // COUT(4) << "copy " << h.getObjectID() << endl; 555 // COUT(4) << "copy " << h.getObjectID() << ":"; 556 //sizes += Synchronisable::getSynchronisable(h.getObjectID())->getNrOfVariables(); 557 for( unsigned int i = 0; i < Synchronisable::getSynchronisable(h.getObjectID())->getNrOfVariables(); ++i ) 558 { 559 // COUT(4) << " " << *sizes; 560 ++sizes; 561 } 562 // COUT(4) << endl; 563 assert(sizes != this->sizes_.end() || origOffset>=origLength); 564 continue; 565 } 566 } 567 568 569 Gamestate *g = new Gamestate(nData, getClientID()); 570 assert(g->header_); 571 *(g->header_) = *header_; 572 g->header_->setBaseID( base->getID() ); 573 g->header_->setDataSize(dest - nData - GamestateHeader::getSize()); 579 // COUT(4) << "copy object: " << Synchronisable::getSynchronisable(origHeader.getObjectID())->getIdentifier()->getName() << endl; 580 assert(baseDataPtr == oldBaseDataPtr); 581 copyObject(destDataPtr, origDataPtr, baseDataPtr, origHeader, sizesIt); 582 assert(sizesIt != this->sizes_.end() || origDataPtr==origDataEnd); 583 } 584 } 585 } 586 assert(sizesIt==this->sizes_.end()); 587 588 589 Gamestate *g = new Gamestate(newData, getPeerID()); 590 (g->header_) = header_; 591 g->header_.setBaseID( base->getID() ); 592 g->header_.setDataSize(destDataPtr - newData - GamestateHeader::getSize()); 574 593 g->flags_=flags_; 575 594 g->packetDirection_ = packetDirection_; … … 579 598 580 599 581 Gamestate* Gamestate::diffData(Gamestate *base)600 /*Gamestate* Gamestate::diffData(Gamestate *base) 582 601 { 583 602 assert(this && base); assert(data_ && base->data_); 584 assert(!header_ ->isCompressed() && !base->header_->isCompressed());585 assert(!header_ ->isDiffed());603 assert(!header_.isCompressed() && !base->header_.isCompressed()); 604 assert(!header_.isDiffed()); 586 605 587 606 uint8_t *basep = GAMESTATE_START(base->data_); 588 607 uint8_t *gs = GAMESTATE_START(this->data_); 589 uint32_t dest_length = header_ ->getDataSize();608 uint32_t dest_length = header_.getDataSize(); 590 609 591 610 if(dest_length==0) … … 595 614 uint8_t *dest = GAMESTATE_START(ndata); 596 615 597 rawDiff( dest, gs, basep, header_ ->getDataSize(), base->header_->getDataSize() );616 rawDiff( dest, gs, basep, header_.getDataSize(), base->header_.getDataSize() ); 598 617 #ifndef NDEBUG 599 618 uint8_t *dest2 = new uint8_t[dest_length]; 600 rawDiff( dest2, dest, basep, header_ ->getDataSize(), base->header_->getDataSize() );619 rawDiff( dest2, dest, basep, header_.getDataSize(), base->header_.getDataSize() ); 601 620 assert( memcmp( dest2, gs, dest_length) == 0 ); 602 621 delete dest2; … … 606 625 assert(g->header_); 607 626 *(g->header_) = *header_; 608 g->header_ ->setDiffed( true );609 g->header_ ->setBaseID( base->getID() );627 g->header_.setDiffed( true ); 628 g->header_.setBaseID( base->getID() ); 610 629 g->flags_=flags_; 611 630 g->packetDirection_ = packetDirection_; … … 619 638 { 620 639 assert(this && base); assert(data_ && base->data_); 621 assert(!header_ ->isCompressed() && !base->header_->isCompressed());622 assert(header_ ->isDiffed());640 assert(!header_.isCompressed() && !base->header_.isCompressed()); 641 assert(header_.isDiffed()); 623 642 624 643 uint8_t *basep = GAMESTATE_START(base->data_); 625 644 uint8_t *gs = GAMESTATE_START(this->data_); 626 uint32_t dest_length = header_ ->getDataSize();645 uint32_t dest_length = header_.getDataSize(); 627 646 628 647 if(dest_length==0) … … 632 651 uint8_t *dest = ndata + GamestateHeader::getSize(); 633 652 634 rawDiff( dest, gs, basep, header_ ->getDataSize(), base->header_->getDataSize() );653 rawDiff( dest, gs, basep, header_.getDataSize(), base->header_.getDataSize() ); 635 654 636 655 Gamestate *g = new Gamestate(ndata, getClientID()); 637 656 assert(g->header_); 638 657 *(g->header_) = *header_; 639 g->header_ ->setDiffed( false );658 g->header_.setDiffed( false ); 640 659 g->flags_=flags_; 641 660 g->packetDirection_ = packetDirection_; … … 670 689 } 671 690 assert(j==datalength); 672 } 673 674 675 Gamestate* Gamestate::doSelection(unsigned int clientID, unsigned int targetSize){691 }*/ 692 693 694 /*Gamestate* Gamestate::doSelection(unsigned int clientID, unsigned int targetSize){ 676 695 assert(data_); 677 696 std::list<obj>::iterator it; 678 697 679 698 // allocate memory for new data 680 uint8_t *gdata = new uint8_t[header_ ->getDataSize()+GamestateHeader::getSize()];699 uint8_t *gdata = new uint8_t[header_.getDataSize()+GamestateHeader::getSize()]; 681 700 // create a gamestate out of it 682 701 Gamestate *gs = new Gamestate(gdata); … … 694 713 695 714 //call TrafficControl 696 TrafficControl::getInstance()->processObjectList( clientID, header_ ->getID(), dataVector_ );715 TrafficControl::getInstance()->processObjectList( clientID, header_.getID(), dataVector_ ); 697 716 698 717 //copy in the zeros … … 725 744 #ifndef NDEBUG 726 745 uint32_t origsize = destsize; 727 while ( origsize < header_ ->getDataSize() )746 while ( origsize < header_.getDataSize() ) 728 747 { 729 748 SynchronisableHeader oldobjectheader(origdata); … … 732 751 origsize += objectsize; 733 752 } 734 assert(origsize==header_ ->getDataSize());753 assert(origsize==header_.getDataSize()); 735 754 assert(destsize!=0); 736 755 #endif 737 gs->header_ ->setDataSize( destsize );756 gs->header_.setDataSize( destsize ); 738 757 return gs; 739 } 740 741 742 uint32_t Gamestate::calcGamestateSize( int32_t id, uint8_t mode)758 }*/ 759 760 761 uint32_t Gamestate::calcGamestateSize(uint32_t id, uint8_t mode) 743 762 { 744 763 uint32_t size = 0;
Note: See TracChangeset
for help on using the changeset viewer.