Changeset 7758 for code/branches/network5/src/libraries
- Timestamp:
- Dec 12, 2010, 11:13:01 PM (14 years ago)
- Location:
- code/branches/network5
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
code/branches/network5
- Property svn:mergeinfo changed
/code/branches/network3 (added) merged: 7333,7336-7337,7344 /code/branches/network4 (added) merged: 7497,7718,7753-7755
- Property svn:mergeinfo changed
-
code/branches/network5/src/libraries/network/GamestateManager.cc
r7284 r7758 219 219 assert(b); 220 220 clock.capture(); 221 COUT( 0) << "difftime: " << clock.getDeltaTime() << endl;221 COUT(4) << "diff and compress time: " << clock.getDeltaTime() << endl; 222 222 // COUT(5) << "sending gamestate with id " << gs->getID(); 223 223 // if(gamestate->isDiffed()) -
code/branches/network5/src/libraries/network/packet/Gamestate.cc
r7163 r7758 43 43 #define GAMESTATE_START(data) (data + GamestateHeader::getSize()) 44 44 45 #define PACKET_FLAG_GAMESTATE PacketFlag::Reliable45 #define PACKET_FLAG_GAMESTATE 0 //PacketFlag::Reliable 46 46 47 47 inline bool memzero( uint8_t* data, uint32_t datalength) … … 65 65 66 66 Gamestate::Gamestate(): 67 header_( 0)67 header_() 68 68 { 69 69 flags_ = flags_ | PACKET_FLAG_GAMESTATE; … … 72 72 73 73 Gamestate::Gamestate(uint8_t *data, unsigned int clientID): 74 Packet(data, clientID) 74 Packet(data, clientID), header_(data) 75 75 { 76 76 flags_ = flags_ | PACKET_FLAG_GAMESTATE; 77 header_ = new GamestateHeader(data_); 78 } 79 80 81 Gamestate::Gamestate(uint8_t *data)77 } 78 79 80 Gamestate::Gamestate(uint8_t *data): 81 header_(data) 82 82 { 83 83 flags_ = flags_ | PACKET_FLAG_GAMESTATE; 84 84 data_ = data; 85 header_ = new GamestateHeader(data_);86 85 } 87 86 88 87 89 88 Gamestate::Gamestate(const Gamestate& g) : 90 Packet( *(Packet*)&g), nrOfVariables_(0)89 Packet( *(Packet*)&g ), header_(this->data_), nrOfVariables_(0) 91 90 { 92 91 flags_ = flags_ | PACKET_FLAG_GAMESTATE; 93 header_ = new GamestateHeader(data_);94 92 sizes_ = g.sizes_; 95 93 } … … 98 96 Gamestate::~Gamestate() 99 97 { 100 if( header_ )101 delete header_;102 98 } 103 99 … … 105 101 bool Gamestate::collectData(int id, uint8_t mode) 106 102 { 107 assert(this->header_==0); // make sure the header didn't exist before108 103 uint32_t tempsize=0, currentsize=0; 109 104 assert(data_==0); … … 120 115 } 121 116 122 // create the header object 123 assert( header_ == 0 ); 124 header_ = new GamestateHeader(data_); 117 // tell the gamestate header where to store the data 118 header_.setData(this->data_); 125 119 126 120 //start collect data synchronisable by synchronisable … … 161 155 162 156 //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 );157 header_.setDataSize( currentsize ); 158 header_.setID( id ); 159 header_.setBaseID( GAMESTATEID_INITIAL ); 160 header_.setDiffed( false ); 161 header_.setComplete( true ); 162 header_.setCompressed( false ); 169 163 //stop write gamestate header 170 164 … … 177 171 bool Gamestate::spreadData(uint8_t mode) 178 172 { 179 COUT(4) << "processing gamestate with id " << header_ ->getID() << endl;173 COUT(4) << "processing gamestate with id " << header_.getID() << endl; 180 174 assert(data_); 181 assert(!header_ ->isCompressed());175 assert(!header_.isCompressed()); 182 176 uint8_t *mem=data_+GamestateHeader::getSize(); 183 177 Synchronisable *s; 184 178 185 179 // update the data of the objects we received 186 while(mem < data_+GamestateHeader::getSize()+header_ ->getDataSize())180 while(mem < data_+GamestateHeader::getSize()+header_.getDataSize()) 187 181 { 188 182 SynchronisableHeader objectheader(mem); … … 197 191 else 198 192 { 193 // COUT(4) << "not creating object of classid " << objectheader.getClassID() << endl; 199 194 mem += objectheader.getDataSize() + ( objectheader.isDiffed() ? SynchronisableHeaderLight::getSize() : SynchronisableHeader::getSize() ); 200 195 } … … 202 197 else 203 198 { 199 // COUT(4) << "updating object of classid " << objectheader.getClassID() << endl; 204 200 bool b = s->updateData(mem, mode); 205 201 assert(b); … … 249 245 { 250 246 assert(data_); 251 if(header_ ->isCompressed())252 return header_ ->getCompSize()+GamestateHeader::getSize();247 if(header_.isCompressed()) 248 return header_.getCompSize()+GamestateHeader::getSize(); 253 249 else 254 250 { 255 return header_ ->getDataSize()+GamestateHeader::getSize();251 return header_.getDataSize()+GamestateHeader::getSize(); 256 252 } 257 253 } … … 280 276 { 281 277 assert(data_); 282 assert(!header_ ->isCompressed());283 uLongf buffer = (uLongf)(((header_ ->getDataSize() + 12)*1.01)+1);278 assert(!header_.isCompressed()); 279 uLongf buffer = (uLongf)(((header_.getDataSize() + 12)*1.01)+1); 284 280 if(buffer==0) 285 281 return false; … … 289 285 uint8_t *source = data_ + GamestateHeader::getSize(); 290 286 int retval; 291 retval = compress( dest, &buffer, source, (uLong)(header_ ->getDataSize()) );287 retval = compress( dest, &buffer, source, (uLong)(header_.getDataSize()) ); 292 288 switch ( retval ) 293 289 { … … 299 295 300 296 //copy and modify header 301 GamestateHeader *temp = header_; 302 header_ = new GamestateHeader(ndata, temp); 297 GamestateHeader *temp = new GamestateHeader(data_); 298 header_.setData(ndata); 299 header_ = *temp; 303 300 delete temp; 304 301 //delete old data … … 306 303 //save new data 307 304 data_ = ndata; 308 header_ ->setCompSize( buffer );309 header_ ->setCompressed( true );310 COUT( 0) << "gamestate compress datasize: " << header_->getDataSize() << " compsize: " << header_->getCompSize() << std::endl;305 header_.setCompSize( buffer ); 306 header_.setCompressed( true ); 307 COUT(4) << "gamestate compress datasize: " << header_.getDataSize() << " compsize: " << header_.getCompSize() << std::endl; 311 308 return true; 312 309 } … … 316 313 { 317 314 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();315 assert(header_.isCompressed()); 316 COUT(4) << "GameStateClient: uncompressing gamestate. id: " << header_.getID() << ", baseid: " << header_.getBaseID() << ", datasize: " << header_.getDataSize() << ", compsize: " << header_.getCompSize() << std::endl; 317 uint32_t datasize = header_.getDataSize(); 318 uint32_t compsize = header_.getCompSize(); 322 319 uint32_t bufsize; 323 320 bufsize = datasize; … … 338 335 339 336 //copy over the header 340 GamestateHeader *temp = header_; 341 header_ = new GamestateHeader( data_, header_ ); 337 GamestateHeader* temp = new GamestateHeader( data_ ); 338 header_.setData(ndata); 339 header_ = *temp; 342 340 delete temp; 343 341 … … 357 355 //set new pointers 358 356 data_ = ndata; 359 header_ ->setCompressed( false );360 assert(header_ ->getDataSize()==datasize);361 assert(header_ ->getCompSize()==compsize);357 header_.setCompressed( false ); 358 assert(header_.getDataSize()==datasize); 359 assert(header_.getCompSize()==compsize); 362 360 return true; 363 361 } 364 362 365 363 364 inline void /*Gamestate::*/diffObject( uint8_t*& newDataPtr, uint8_t*& origDataPtr, uint8_t*& baseDataPtr, SynchronisableHeader& objectHeader, std::vector<uint32_t>::iterator& sizes ) 365 { 366 // COUT(4) << "dodiff" << endl; 367 // if(baseOffset==0) 368 // { 369 // assert(origOffset==0); 370 // } 371 assert( objectHeader.getDataSize() == SynchronisableHeader(baseDataPtr).getDataSize() ); 372 373 uint32_t objectOffset = SynchronisableHeader::getSize(); // offset inside the object in the origData and baseData 374 // Check whether the whole object stayed the same 375 if( memcmp( origDataPtr+objectOffset, baseDataPtr+objectOffset, objectHeader.getDataSize()) == 0 ) 376 { 377 // COUT(4) << "skip object " << Synchronisable::getSynchronisable(objectHeader.getObjectID())->getIdentifier()->getName() << endl; 378 origDataPtr += objectOffset + objectHeader.getDataSize(); // skip the whole object 379 baseDataPtr += objectOffset + objectHeader.getDataSize(); 380 sizes += Synchronisable::getSynchronisable(objectHeader.getObjectID())->getNrOfVariables(); 381 } 382 else 383 { 384 // if( Synchronisable::getSynchronisable(origHeader.getObjectID())->getIdentifier()->getName() == "Bot" ) 385 // COUT(0) << "blub" << endl; 386 // COUT(4) << "object diff: " << Synchronisable::getSynchronisable(h.getObjectID())->getIdentifier()->getName() << endl; 387 // COUT(4) << "diff " << h.getObjectID() << ":"; 388 // Now start to diff the Object 389 SynchronisableHeaderLight newObjectHeader(newDataPtr); 390 newObjectHeader = objectHeader; // copy over the objectheader 391 VariableID variableID = 0; 392 uint32_t diffedObjectOffset = SynchronisableHeaderLight::getSize(); 393 // iterate through all variables 394 while( objectOffset < objectHeader.getDataSize()+SynchronisableHeader::getSize() ) 395 { 396 // check whether variable changed and write id and copy over variable to the new stream 397 // otherwise skip variable 398 // assert(sizes != this->sizes_.end()); 399 uint32_t varSize = *sizes; 400 assert( varSize == Synchronisable::getSynchronisable(objectHeader.getObjectID())->getVarSize(variableID) ); 401 if ( varSize != 0 ) 402 { 403 if ( memcmp(origDataPtr+objectOffset, baseDataPtr+objectOffset, varSize) != 0 ) 404 { 405 // COUT(4) << "copy variable" << endl; 406 *(VariableID*)(newDataPtr+diffedObjectOffset) = variableID; // copy over the variableID 407 diffedObjectOffset += sizeof(VariableID); 408 memcpy( newDataPtr+diffedObjectOffset, origDataPtr+objectOffset, varSize ); 409 diffedObjectOffset += varSize; 410 objectOffset += varSize; 411 } 412 else 413 { 414 // COUT(4) << "skip variable" << endl; 415 objectOffset += varSize; 416 } 417 } 418 // else 419 // COUT(4) << "varsize 0" << endl; 420 421 ++variableID; 422 ++sizes; 423 } 424 425 if( Synchronisable::getSynchronisable(objectHeader.getObjectID())->getNrOfVariables() != variableID ) 426 sizes += Synchronisable::getSynchronisable(objectHeader.getObjectID())->getNrOfVariables() - variableID; 427 // COUT(4) << endl; 428 429 newObjectHeader.setDiffed(true); 430 newObjectHeader.setDataSize(diffedObjectOffset-SynchronisableHeaderLight::getSize()); 431 assert(objectOffset == objectHeader.getDataSize()+SynchronisableHeader::getSize()); 432 assert(newObjectHeader.getDataSize()>0); 433 origDataPtr += objectOffset; 434 // baseOffset += temp + h.getDataSize()+SynchronisableHeader::getSize() - baseData; 435 //baseOffset += objectOffset; 436 // SynchronisableHeader htemp(temp); 437 // baseOffset += SynchronisableHeader::getSize() + htemp.getDataSize(); 438 // { 439 // SynchronisableHeader htemp2( baseData+(temp-baseData+objectOffset) ); 440 // if( baseData+(temp-baseData+objectOffset) < baseData+baseLength ) 441 // { 442 // assert(htemp2.getClassID()<500); 443 // assert(htemp2.getDataSize()!=0 && htemp2.getDataSize()<1000); 444 // assert(htemp2.isDiffed()==false); 445 // } 446 // } 447 baseDataPtr += objectOffset; 448 newDataPtr += diffedObjectOffset; 449 } 450 } 451 452 inline void /*Gamestate::*/copyObject( uint8_t*& newData, uint8_t*& origData, uint8_t*& baseData, SynchronisableHeader& objectHeader, std::vector<uint32_t>::iterator& sizes ) 453 { 454 // COUT(4) << "docopy" << endl; 455 // Just copy over the whole Object 456 memcpy( newData, origData, objectHeader.getDataSize()+SynchronisableHeader::getSize() ); 457 newData += objectHeader.getDataSize()+SynchronisableHeader::getSize(); 458 origData += objectHeader.getDataSize()+SynchronisableHeader::getSize(); 459 // SynchronisableHeader baseHeader( baseData ); 460 // baseData += baseHeader.getDataSize()+SynchronisableHeader::getSize(); 461 // COUT(4) << "copy " << h.getObjectID() << endl; 462 // COUT(4) << "copy " << h.getObjectID() << ":"; 463 sizes += Synchronisable::getSynchronisable(objectHeader.getObjectID())->getNrOfVariables(); 464 // for( unsigned int i = 0; i < Synchronisable::getSynchronisable(objectHeader.getObjectID())->getNrOfVariables(); ++i ) 465 // { 466 // // COUT(4) << " " << *sizes; 467 // ++sizes; 468 // } 469 // COUT(4) << endl; 470 } 471 472 inline bool findObject(uint8_t*& dataPtr, uint8_t* endPtr, SynchronisableHeader& objectHeader) 473 { 474 // Some assertions to make sure the dataPtr is valid (pointing to a SynchronisableHeader) 475 { 476 SynchronisableHeader htemp2(dataPtr); 477 assert(htemp2.getClassID()<500); 478 assert(htemp2.getDataSize()!=0 && htemp2.getDataSize()<1000); 479 assert(htemp2.isDiffed()==false); 480 } 481 uint32_t objectID = objectHeader.getObjectID(); 482 while ( dataPtr < endPtr ) 483 { 484 SynchronisableHeader htemp(dataPtr); 485 assert( htemp.getDataSize()!=0 ); 486 if ( htemp.getObjectID() == objectID ) 487 { 488 assert( objectHeader.getClassID() == htemp.getClassID() ); 489 assert( objectHeader.getCreatorID() == htemp.getCreatorID() ); 490 return true; 491 } 492 { 493 if( dataPtr+htemp.getDataSize()+SynchronisableHeader::getSize() < endPtr ) 494 { 495 SynchronisableHeader htemp2(dataPtr+htemp.getDataSize()+SynchronisableHeader::getSize()); 496 assert(htemp2.getClassID()<500); 497 assert(htemp2.getDataSize()!=0 && htemp2.getDataSize()<1000); 498 assert(htemp2.isDiffed()==false); 499 } 500 } 501 dataPtr += htemp.getDataSize()+SynchronisableHeader::getSize(); 502 503 } 504 assert(dataPtr == endPtr); 505 506 return false; 507 } 508 366 509 Gamestate* Gamestate::diffVariables(Gamestate *base) 367 510 { 368 511 assert(this && base); assert(data_ && base->data_); 369 assert(!header_->isCompressed() && !base->header_->isCompressed()); 370 assert(!header_->isDiffed()); 512 assert(!header_.isCompressed() && !base->header_.isCompressed()); 513 assert(!header_.isDiffed()); 514 assert( header_.getDataSize() && base->header_.getDataSize() ); 371 515 372 516 373 517 // *** first do a raw diff of the two gamestates 374 518 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)519 uint8_t *baseDataPtr = GAMESTATE_START(base->data_); 520 uint8_t *origDataPtr = GAMESTATE_START(this->data_); 521 uint8_t *origDataEnd = origDataPtr + header_.getDataSize(); 522 uint8_t *baseDataEnd = baseDataPtr + base->header_.getDataSize(); 523 // uint32_t origLength = header_.getDataSize(); 524 // uint32_t baseLength = base->header_.getDataSize(); 525 526 // Allocate new space for diffed gamestate 527 uint32_t newDataSize = header_.getDataSize() + GamestateHeader::getSize() + sizeof(uint32_t)*this->nrOfVariables_; 528 uint8_t *newData = new uint8_t[newDataSize]; // this is the maximum size needed in the worst case 529 uint8_t *destDataPtr = GAMESTATE_START(newData); 530 531 std::vector<uint32_t>::iterator sizesIt = this->sizes_.begin(); 532 533 while( origDataPtr < origDataEnd ) 390 534 { 391 535 //iterate through all objects 392 536 393 SynchronisableHeader h(origData+origOffset);537 SynchronisableHeader origHeader(origDataPtr); 394 538 395 539 // Find (if possible) the current object in the datastream of the old gamestate 396 540 // 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(); 541 if(baseDataPtr == baseDataEnd) 542 baseDataPtr = GAMESTATE_START(base->data_); 543 uint8_t* oldBaseDataPtr = baseDataPtr; 544 545 assert(baseDataPtr < baseDataEnd); 546 assert(destDataPtr < newData + newDataSize); 547 assert(sizesIt != this->sizes_.end()); 548 549 bool diffedObject = false; 550 if( findObject(baseDataPtr, baseDataEnd, origHeader) ) 551 { 552 if( SynchronisableHeader(baseDataPtr).getDataSize()==origHeader.getDataSize() ) 553 { 554 // COUT(4) << "diffing object in order: " << Synchronisable::getSynchronisable(origHeader.getObjectID())->getIdentifier()->getName() << endl; 555 diffObject(destDataPtr, origDataPtr, baseDataPtr, origHeader, sizesIt); 556 diffedObject = true; 557 } 558 else 559 { 560 // COUT(4) << "copy object because of different data sizes (1): " << Synchronisable::getSynchronisable(origHeader.getObjectID())->getIdentifier()->getName() << endl; 561 copyObject(destDataPtr, origDataPtr, baseDataPtr, origHeader, sizesIt); 562 assert(sizesIt != this->sizes_.end() || origDataPtr==origDataEnd); 563 } 423 564 424 565 } 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(); 566 else 567 { 568 assert( baseDataPtr == baseDataEnd ); 569 baseDataPtr = GAMESTATE_START(base->data_); 570 if( findObject(baseDataPtr, oldBaseDataPtr, origHeader) ) 571 { 572 if( SynchronisableHeader(baseDataPtr).getDataSize()==origHeader.getDataSize() ) 573 { 574 // COUT(4) << "diffing object out of order: " << Synchronisable::getSynchronisable(origHeader.getObjectID())->getIdentifier()->getName() << endl; 575 diffObject(destDataPtr, origDataPtr, baseDataPtr, origHeader, sizesIt); 576 diffedObject = true; 577 } 578 else 579 { 580 // COUT(4) << "copy object because of different data sizes (2): " << Synchronisable::getSynchronisable(origHeader.getObjectID())->getIdentifier()->getName() << endl; 581 copyObject(destDataPtr, origDataPtr, baseDataPtr, origHeader, sizesIt); 582 assert(sizesIt != this->sizes_.end() || origDataPtr==origDataEnd); 583 } 475 584 } 476 585 else 477 586 { 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()); 587 // COUT(4) << "copy object: " << Synchronisable::getSynchronisable(origHeader.getObjectID())->getIdentifier()->getName() << endl; 588 assert(baseDataPtr == oldBaseDataPtr); 589 copyObject(destDataPtr, origDataPtr, baseDataPtr, origHeader, sizesIt); 590 assert(sizesIt != this->sizes_.end() || origDataPtr==origDataEnd); 591 } 592 } 593 } 594 assert(sizesIt==this->sizes_.end()); 595 596 597 Gamestate *g = new Gamestate(newData, getClientID()); 598 (g->header_) = header_; 599 g->header_.setBaseID( base->getID() ); 600 g->header_.setDataSize(destDataPtr - newData - GamestateHeader::getSize()); 574 601 g->flags_=flags_; 575 602 g->packetDirection_ = packetDirection_; … … 579 606 580 607 581 Gamestate* Gamestate::diffData(Gamestate *base)608 /*Gamestate* Gamestate::diffData(Gamestate *base) 582 609 { 583 610 assert(this && base); assert(data_ && base->data_); 584 assert(!header_ ->isCompressed() && !base->header_->isCompressed());585 assert(!header_ ->isDiffed());611 assert(!header_.isCompressed() && !base->header_.isCompressed()); 612 assert(!header_.isDiffed()); 586 613 587 614 uint8_t *basep = GAMESTATE_START(base->data_); 588 615 uint8_t *gs = GAMESTATE_START(this->data_); 589 uint32_t dest_length = header_ ->getDataSize();616 uint32_t dest_length = header_.getDataSize(); 590 617 591 618 if(dest_length==0) … … 595 622 uint8_t *dest = GAMESTATE_START(ndata); 596 623 597 rawDiff( dest, gs, basep, header_ ->getDataSize(), base->header_->getDataSize() );624 rawDiff( dest, gs, basep, header_.getDataSize(), base->header_.getDataSize() ); 598 625 #ifndef NDEBUG 599 626 uint8_t *dest2 = new uint8_t[dest_length]; 600 rawDiff( dest2, dest, basep, header_ ->getDataSize(), base->header_->getDataSize() );627 rawDiff( dest2, dest, basep, header_.getDataSize(), base->header_.getDataSize() ); 601 628 assert( memcmp( dest2, gs, dest_length) == 0 ); 602 629 delete dest2; … … 606 633 assert(g->header_); 607 634 *(g->header_) = *header_; 608 g->header_ ->setDiffed( true );609 g->header_ ->setBaseID( base->getID() );635 g->header_.setDiffed( true ); 636 g->header_.setBaseID( base->getID() ); 610 637 g->flags_=flags_; 611 638 g->packetDirection_ = packetDirection_; … … 619 646 { 620 647 assert(this && base); assert(data_ && base->data_); 621 assert(!header_ ->isCompressed() && !base->header_->isCompressed());622 assert(header_ ->isDiffed());648 assert(!header_.isCompressed() && !base->header_.isCompressed()); 649 assert(header_.isDiffed()); 623 650 624 651 uint8_t *basep = GAMESTATE_START(base->data_); 625 652 uint8_t *gs = GAMESTATE_START(this->data_); 626 uint32_t dest_length = header_ ->getDataSize();653 uint32_t dest_length = header_.getDataSize(); 627 654 628 655 if(dest_length==0) … … 632 659 uint8_t *dest = ndata + GamestateHeader::getSize(); 633 660 634 rawDiff( dest, gs, basep, header_ ->getDataSize(), base->header_->getDataSize() );661 rawDiff( dest, gs, basep, header_.getDataSize(), base->header_.getDataSize() ); 635 662 636 663 Gamestate *g = new Gamestate(ndata, getClientID()); 637 664 assert(g->header_); 638 665 *(g->header_) = *header_; 639 g->header_ ->setDiffed( false );666 g->header_.setDiffed( false ); 640 667 g->flags_=flags_; 641 668 g->packetDirection_ = packetDirection_; … … 670 697 } 671 698 assert(j==datalength); 672 } 673 674 675 Gamestate* Gamestate::doSelection(unsigned int clientID, unsigned int targetSize){699 }*/ 700 701 702 /*Gamestate* Gamestate::doSelection(unsigned int clientID, unsigned int targetSize){ 676 703 assert(data_); 677 704 std::list<obj>::iterator it; 678 705 679 706 // allocate memory for new data 680 uint8_t *gdata = new uint8_t[header_ ->getDataSize()+GamestateHeader::getSize()];707 uint8_t *gdata = new uint8_t[header_.getDataSize()+GamestateHeader::getSize()]; 681 708 // create a gamestate out of it 682 709 Gamestate *gs = new Gamestate(gdata); … … 694 721 695 722 //call TrafficControl 696 TrafficControl::getInstance()->processObjectList( clientID, header_ ->getID(), dataVector_ );723 TrafficControl::getInstance()->processObjectList( clientID, header_.getID(), dataVector_ ); 697 724 698 725 //copy in the zeros … … 725 752 #ifndef NDEBUG 726 753 uint32_t origsize = destsize; 727 while ( origsize < header_ ->getDataSize() )754 while ( origsize < header_.getDataSize() ) 728 755 { 729 756 SynchronisableHeader oldobjectheader(origdata); … … 732 759 origsize += objectsize; 733 760 } 734 assert(origsize==header_ ->getDataSize());761 assert(origsize==header_.getDataSize()); 735 762 assert(destsize!=0); 736 763 #endif 737 gs->header_ ->setDataSize( destsize );764 gs->header_.setDataSize( destsize ); 738 765 return gs; 739 } 766 }*/ 740 767 741 768 -
code/branches/network5/src/libraries/network/packet/Gamestate.h
r7163 r7758 48 48 class _NetworkExport GamestateHeader{ 49 49 public: 50 GamestateHeader(uint8_t *data){ assert(data); data_ = data; *(uint32_t*)data_ = Type::Gamestate; } 51 GamestateHeader(uint8_t *data, GamestateHeader* h) 52 { assert(data); data_=data; memcpy(data_, h->data_, getSize()); } 50 GamestateHeader(){ data_=0; } 51 GamestateHeader(uint8_t* data) 52 { assert(data); data_ = data; *(uint32_t*)data_ = Type::Gamestate; } 53 /*GamestateHeader(uint8_t* data, GamestateHeader* h) 54 { assert(data); data_=data; memcpy(data_, h->data_, getSize()); }*/ 55 void setData(uint8_t* data) 56 { assert(data); data_ = data; *(uint32_t*)data_ = Type::Gamestate; } 53 57 static inline uint32_t getSize() 54 { return 21; }58 { return 21; } 55 59 56 60 inline int32_t getID() const 57 { assert(data_); return *(int32_t*)(data_+4); }61 { assert(data_); return *(int32_t*)(data_+4); } 58 62 inline void setID(int32_t id) 59 { assert(data_); *(int32_t*)(data_+4) = id; }63 { assert(data_); *(int32_t*)(data_+4) = id; } 60 64 61 65 inline int32_t getBaseID() const 62 { assert(data_); return *(int32_t*)(data_+8); }66 { assert(data_); return *(int32_t*)(data_+8); } 63 67 inline void setBaseID(int32_t id) 64 { assert(data_); *(int32_t*)(data_+8) = id; }68 { assert(data_); *(int32_t*)(data_+8) = id; } 65 69 66 70 inline uint32_t getDataSize() const 67 { assert(data_); return *(uint32_t*)(data_+12); }71 { assert(data_); return *(uint32_t*)(data_+12); } 68 72 inline void setDataSize(uint32_t size) 69 { assert(data_); *(uint32_t*)(data_+12) = size; }73 { assert(data_); *(uint32_t*)(data_+12) = size; } 70 74 71 75 inline uint32_t getCompSize() const … … 75 79 76 80 inline bool isDiffed() const 77 { assert(data_); return *(int8_t*)(data_+20) & 0x1; }81 { assert(data_); return *(int8_t*)(data_+20) & 0x1; } 78 82 inline void setDiffed(bool b) 79 { assert(data_); *(int8_t*)(data_+20) = (b<<0) | (*(int8_t*)(data_+20) & 0x6 ); }83 { assert(data_); *(int8_t*)(data_+20) = (b<<0) | (*(int8_t*)(data_+20) & 0x6 ); } 80 84 81 85 inline bool isComplete() const 82 { assert(data_); return *(int8_t*)(data_+20) & 0x2; }86 { assert(data_); return *(int8_t*)(data_+20) & 0x2; } 83 87 inline void setComplete(bool b) 84 { assert(data_); *(int8_t*)(data_+20) = (b<<1) | (*(int8_t*)(data_+20) & 0x5 ); }88 { assert(data_); *(int8_t*)(data_+20) = (b<<1) | (*(int8_t*)(data_+20) & 0x5 ); } 85 89 86 90 inline bool isCompressed() const 87 { assert(data_); return *(int8_t*)(data_+20) & 0x4; }91 { assert(data_); return *(int8_t*)(data_+20) & 0x4; } 88 92 inline void setCompressed(bool b) 89 { assert(data_); *(int8_t*)(data_+20) = (b<<2) | (*(int8_t*)(data_+20) & 0x3 ); }93 { assert(data_); *(int8_t*)(data_+20) = (b<<2) | (*(int8_t*)(data_+20) & 0x3 ); } 90 94 91 95 inline void operator=(GamestateHeader& h) 92 { assert(data_); assert(h.data_); memcpy( data_, h.data_, getSize()); }96 { assert(data_); assert(h.data_); memcpy( data_, h.data_, getSize()); } 93 97 private: 94 uint8_t *data_;98 uint8_t* data_; 95 99 96 100 }; … … 110 114 bool collectData(int id, uint8_t mode=0x0); 111 115 bool spreadData( uint8_t mode=0x0); 112 inline int32_t getID() const { return header_ ->getID(); }113 inline bool isDiffed() const { return header_ ->isDiffed(); }114 inline bool isCompressed() const { return header_ ->isCompressed(); }115 inline int32_t getBaseID() const { return header_ ->getBaseID(); }116 inline uint32_t getDataSize() const { return header_ ->getDataSize(); }116 inline int32_t getID() const { return header_.getID(); } 117 inline bool isDiffed() const { return header_.isDiffed(); } 118 inline bool isCompressed() const { return header_.isCompressed(); } 119 inline int32_t getBaseID() const { return header_.getBaseID(); } 120 inline uint32_t getDataSize() const { return header_.getDataSize(); } 117 121 Gamestate* diffVariables(Gamestate *base); 118 Gamestate* diffData(Gamestate *base);119 Gamestate *undiff(Gamestate *base);120 Gamestate* doSelection(unsigned int clientID, unsigned int targetSize);122 // Gamestate* diffData(Gamestate *base); 123 // Gamestate *undiff(Gamestate *base); 124 // Gamestate* doSelection(unsigned int clientID, unsigned int targetSize); 121 125 bool compressData(); 122 126 bool decompressData(); … … 125 129 // Packet functions 126 130 private: 127 void rawDiff( uint8_t* newdata, uint8_t* data, uint8_t* basedata, uint32_t datalength, uint32_t baselength);128 inline uint32_t findObject( const SynchronisableHeader& header, uint8_t* mem, uint32_t dataLength, uint32_t startPosition = 0 );131 // void rawDiff( uint8_t* newdata, uint8_t* data, uint8_t* basedata, uint32_t datalength, uint32_t baselength); 132 // inline uint32_t findObject( const SynchronisableHeader& header, uint8_t* mem, uint32_t dataLength, uint32_t startPosition = 0 ); 129 133 virtual uint32_t getSize() const; 130 134 virtual inline bool process(); 131 135 uint32_t calcGamestateSize(int32_t id, uint8_t mode=0x0); 136 // inline void diffObject( uint8_t*& newData, uint8_t*& origData, uint8_t*& baseData, SynchronisableHeader& objectHeader, std::vector<uint32_t>::iterator& sizes ); 137 // inline void copyObject( uint8_t*& newData, uint8_t*& origData, uint8_t*& baseData, SynchronisableHeader& objectHeader, std::vector<uint32_t>::iterator& sizes ); 132 138 133 139 std::list<obj> dataVector_; 134 GamestateHeader *header_;140 GamestateHeader header_; 135 141 std::vector<uint32_t> sizes_; 136 142 uint32_t nrOfVariables_; -
code/branches/network5/src/libraries/network/synchronisable/Synchronisable.cc
r7401 r7758 123 123 { 124 124 SynchronisableHeader header(mem); 125 assert( !header.isDiffed() ); 125 if( header.isDiffed() ) 126 { 127 mem += header.getDataSize() + header.getSize(); 128 return 0; 129 } 130 // assert( !header.isDiffed() ); 126 131 127 132 COUT(4) << "fabricating object with id: " << header.getObjectID() << std::endl; … … 217 222 * length of varx: size saved int syncvarlist 218 223 * @param mem pointer to allocated memory with enough size 219 * @param sizes FIXME - add doc!224 * @param sizes vector containing sizes of all objects in gamestate (to be appended) 220 225 * @param id gamestateid of the gamestate to be saved (important for priorities) 221 226 * @param mode defines the direction in which the data will be send/received 222 227 * 0x1: server->client 223 * 0x2: client->server (not recommended)228 * 0x2: client->server 224 229 * 0x3: bidirectional 225 230 * @return true: if !doSync or if everything was successfully saved … … 265 270 //tempsize += (*i)->getSize( mode ); 266 271 } 272 assert(tempsize!=0); // if this happens an empty object (with no variables) would be transmitted 267 273 // COUT(4) << endl; 268 274 … … 316 322 mem += SynchronisableHeader::getSize(); 317 323 std::vector<SynchronisableVariableBase *>::iterator i; 318 for(i=syncList_.begin(); i!=syncList_.end(); i++)324 for(i=syncList_.begin(); i!=syncList_.end(); ++i) 319 325 { 320 326 assert( mem <= data+syncHeader2.getDataSize()+SynchronisableHeader::getSize() ); // always make sure we don't exceed the datasize in our stream
Note: See TracChangeset
for help on using the changeset viewer.