Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

Ignore:
Timestamp:
Jan 6, 2009, 9:39:41 PM (15 years ago)
Author:
scheusso
Message:

-performance/memory optimisations in gamestate and synchronisable
-enhancement of portability (gcc↔msvc)

File:
1 edited

Legend:

Unmodified
Added
Removed
  • code/branches/presentation/src/network/packet/Gamestate.cc

    r2501 r2575  
    3636
    3737#include <zlib.h>
    38 #include <assert.h>
     38#include <cassert>
    3939
    4040
     
    4343
    4444namespace packet {
    45 
    46 #define GAMESTATE_START(data) (data + sizeof(GamestateHeader))
    47 #define GAMESTATE_HEADER(data) ((GamestateHeader *)data)
    48 #define HEADER GAMESTATE_HEADER(data_)
    4945
    5046
     
    9389  ObjectList<Synchronisable>::iterator it;
    9490  for(it = ObjectList<Synchronisable>::begin(); it; ++it){
     91   
     92#ifndef NDEBUG
    9593    tempsize=it->getSize(id, mode);
    96 
    9794    if(currentsize+tempsize > size){
    9895      assert(0); // if we don't use multithreading this part shouldn't be neccessary
     
    108105      size = currentsize+addsize;
    109106    }// stop allocate additional memory
    110 
     107#endif
    111108
    112109    //if(it->doSelection(id))
    113     if(tempsize!=0)
     110    if ( it->doSync( id, mode ) )
    114111      dataMap_.push_back( obj(it->getObjectID(), it->getCreatorID(), tempsize, mem-data_) );
    115112//     dataMap_[mem-data_]=(*it);  // save the mem location of the synchronisable data
     
    196193}
    197194
    198 
    199 
    200 int Gamestate::getID(){
    201   return HEADER->id;
    202 }
    203 
    204195uint32_t Gamestate::getSize() const
    205196{
     
    255246    case Z_DATA_ERROR: COUT(2) << "G.St.Man: compress: data corrupted in gamestate.compress" << std::endl; return false;
    256247  }
    257 #ifndef NDEBUG
    258   //decompress and compare the start and the decompressed data
    259   uint8_t *rdata = new uint8_t[HEADER->datasize+sizeof(GamestateHeader)];
    260   uint8_t *d2 = GAMESTATE_START(rdata);
    261   uLongf length2 = HEADER->datasize;
    262   uncompress(d2, &length2, dest, buffer);
    263   for(unsigned int i=0; i<HEADER->datasize; i++){
    264     assert(*(source+i)==*(d2+i));
    265   }
    266   delete[] rdata;
    267 #endif
    268248
    269249  //copy and modify header
    270 #ifndef NDEBUG
    271   HEADER->crc32 = calcCRC(data_+sizeof(GamestateHeader), HEADER->datasize);
    272 #endif
    273250  *GAMESTATE_HEADER(ndata) = *HEADER;
    274251  //delete old data
     
    305282    case Z_DATA_ERROR: COUT(2) << "data corrupted (zlib)" << std::endl; return false;
    306283  }
    307 #ifndef NDEBUG
    308   assert(HEADER->crc32==calcCRC(ndata+sizeof(GamestateHeader), HEADER->datasize));
    309 #endif
    310284
    311285  //copy over the header
     
    420394    origdata += objectsize;
    421395    destsize += objectsize;
    422 //     origdata += objectsize;
    423396  }
    424397#ifndef NDEBUG
     
    438411}
    439412
    440 
    441 Gamestate* Gamestate::intelligentDiff(Gamestate *base, unsigned int clientID){
    442   // asserts
    443   assert(data_);
    444   assert(base->data_);
    445   assert(!GAMESTATE_HEADER(base->data_)->diffed);
    446   assert(!GAMESTATE_HEADER(base->data_)->compressed);
    447   assert(!HEADER->compressed);
    448   assert(!HEADER->diffed);
    449 
    450   //preparations
    451   std::list<obj>::iterator it;
    452   uint8_t *origdata, *basedata, *destdata, *ndata;
    453   uint32_t objectOffset, streamOffset=0;    //data offset
    454   uint32_t minsize = (HEADER->datasize < GAMESTATE_HEADER(base->data_)->datasize) ? HEADER->datasize : GAMESTATE_HEADER(base->data_)->datasize;
    455   synchronisableHeader *origheader;
    456   synchronisableHeader *destheader;
    457   Synchronisable *object;
    458 
    459   origdata = GAMESTATE_START(this->data_);
    460   basedata = GAMESTATE_START(base->data_);
    461   ndata = new uint8_t[HEADER->datasize + sizeof(GamestateHeader)];
    462   destdata = ndata + sizeof(GamestateHeader);
    463 
    464   // do the diff
    465   for(it=dataMap_.begin(); it!=dataMap_.end(); it++){
    466     assert(streamOffset<HEADER->datasize);
    467     origheader = (synchronisableHeader *)(origdata+streamOffset);
    468     destheader = (synchronisableHeader *)(destdata+streamOffset);
    469     object = Synchronisable::getSynchronisable(origheader->objectID);
    470     bool sendData = object->doSelection(HEADER->id);
    471 
    472     //copy and partially diff the object header
    473     assert(sizeof(synchronisableHeader)==3*sizeof(uint32_t)+sizeof(bool));
    474     *(uint32_t*)destdata = *(uint32_t*)origdata; //size (do not diff)
    475     *(bool*)(destdata+sizeof(uint32_t)) = sendData;
    476     if(sendData){
    477       *(uint32_t*)(destdata+sizeof(uint32_t)+sizeof(bool)) = *(uint32_t*)(basedata+sizeof(uint32_t)+sizeof(bool)) ^ *(uint32_t*)(origdata+sizeof(uint32_t)+sizeof(bool)); //objectid (diff it)
    478       *(uint32_t*)(destdata+2*sizeof(uint32_t)+sizeof(bool)) = *(uint32_t*)(basedata+2*sizeof(uint32_t)+sizeof(bool)) ^ *(uint32_t*)(origdata+2*sizeof(uint32_t)+sizeof(bool)); //classid (diff it)
    479     }else{
    480       *(uint32_t*)(destdata+sizeof(uint32_t)+sizeof(bool)) = 0;
    481       *(uint32_t*)(destdata+2*sizeof(uint32_t)+sizeof(bool)) = 0;
    482     }
    483     objectOffset=sizeof(synchronisableHeader);
    484     streamOffset+=sizeof(synchronisableHeader);
    485 
    486     //now handle the object data or fill with zeros
    487     while(objectOffset<origheader->size ){
    488 
    489       if(sendData && streamOffset<minsize)
    490         *(destdata+objectOffset)=*(basedata+objectOffset)^*(origdata+objectOffset); // do the xor
    491       else if(sendData)
    492         *(destdata+objectOffset)=((uint8_t)0)^*(origdata+objectOffset); // xor with 0 (basestream is too short)
    493       else
    494         *(destdata+objectOffset)=0; // set to 0 because this object should not be transfered
    495 
    496       objectOffset++;
    497       streamOffset++;
    498     }
    499     destdata+=objectOffset;
    500     origdata+=objectOffset;
    501     basedata+=objectOffset;
    502   }
    503 
    504   //copy over the gamestate header and set the diffed flag
    505   *(GamestateHeader *)ndata = *HEADER; //copy over the header
    506   Gamestate *gs = new Gamestate(ndata);
    507   GAMESTATE_HEADER(ndata)->diffed=true;
    508   return gs;
    509 }
    510 
    511 Gamestate* Gamestate::intelligentUnDiff(Gamestate *base){
    512   // asserts
    513   assert(data_);
    514   assert(base->data_);
    515   assert(!GAMESTATE_HEADER(base->data_)->diffed);
    516   assert(!GAMESTATE_HEADER(base->data_)->compressed);
    517   assert(!HEADER->compressed);
    518   assert(HEADER->diffed);
    519 
    520   //preparations
    521   std::list<obj>::iterator it;
    522   uint8_t *origdata, *basedata, *destdata, *ndata;
    523   uint32_t objectOffset, streamOffset=0;    //data offset
    524   uint32_t minsize = (HEADER->datasize < GAMESTATE_HEADER(base->data_)->datasize) ? HEADER->datasize : GAMESTATE_HEADER(base->data_)->datasize;
    525   synchronisableHeader *origheader;
    526   synchronisableHeader *destheader;
    527   Synchronisable *object;
    528 
    529   origdata = GAMESTATE_START(this->data_);
    530   basedata = GAMESTATE_START(base->data_);
    531   ndata = new uint8_t[HEADER->datasize + sizeof(GamestateHeader)];
    532   destdata = ndata + sizeof(GamestateHeader);
    533 
    534   // do the undiff
    535   for(it=dataMap_.begin(); it!=dataMap_.end(); it++){
    536     assert(streamOffset<HEADER->datasize);
    537     origheader = (synchronisableHeader *)(origdata+streamOffset);
    538     destheader = (synchronisableHeader *)(destdata+streamOffset);
    539     object = Synchronisable::getSynchronisable( origheader->objectID );
    540     bool sendData;
    541 
    542     //copy and partially diff the object header
    543     assert(sizeof(synchronisableHeader)==3*sizeof(uint32_t)+sizeof(bool));
    544     *(uint32_t*)destdata = *(uint32_t*)origdata; //size (do not diff)
    545     *(bool*)(destdata+sizeof(uint32_t)) = *(bool*)(origdata+sizeof(uint32_t));
    546     sendData = *(bool*)(origdata+sizeof(uint32_t));
    547     if(sendData){
    548       *(uint32_t*)(destdata+sizeof(uint32_t)+sizeof(bool)) = *(uint32_t*)(basedata+sizeof(uint32_t)+sizeof(bool)) ^ *(uint32_t*)(origdata+sizeof(uint32_t)+sizeof(bool)); //objectid (diff it)
    549       *(uint32_t*)(destdata+2*sizeof(uint32_t)+sizeof(bool)) = *(uint32_t*)(basedata+2*sizeof(uint32_t)+sizeof(bool)) ^ *(uint32_t*)(origdata+2*sizeof(uint32_t)+sizeof(bool)); //classid (diff it)
    550     }else{
    551       *(uint32_t*)(destdata+sizeof(uint32_t)+sizeof(bool)) = 0;
    552       *(uint32_t*)(destdata+2*sizeof(uint32_t)+sizeof(bool)) = 0;
    553     }
    554     objectOffset=sizeof(synchronisableHeader);
    555     streamOffset+=sizeof(synchronisableHeader);
    556 
    557     //now handle the object data or fill with zeros
    558     while(objectOffset<origheader->size ){
    559 
    560       if(sendData && streamOffset<minsize)
    561         *(destdata+objectOffset)=*(basedata+objectOffset)^*(origdata+objectOffset); // do the xor
    562       else if(sendData)
    563         *(destdata+objectOffset)=((unsigned char)0)^*(origdata+objectOffset); // xor with 0 (basestream is too short)
    564       else
    565         *(destdata+objectOffset)=0; // set to 0 because this object should not be transfered
    566 
    567       objectOffset++;
    568       streamOffset++;
    569     }
    570     destdata+=objectOffset;
    571     origdata+=objectOffset;
    572     basedata+=objectOffset;
    573   }
    574 
    575   //copy over the gamestate header and set the diffed flag
    576   *(GamestateHeader *)ndata = *HEADER; //copy over the header
    577   Gamestate *gs = new Gamestate(ndata);
    578   GAMESTATE_HEADER(ndata)->diffed=false;
    579   return gs;
    580 }
    581413
    582414Gamestate *Gamestate::undiff(Gamestate *base)
     
    627459  for(it = ObjectList<Synchronisable>::begin(); it; ++it)
    628460    size+=it->getSize(id, mode); // size of the actual data of the synchronisable
    629 //  size+=sizeof(GamestateHeader);
    630461  return size;
    631462}
    632463
    633 /**
    634  * This function removes a Synchronisable out of the universe
    635  * @param it iterator of the list pointing to the object
    636  * @return iterator pointing to the next object in the list
    637  */
    638   void Gamestate::removeObject(ObjectList<Synchronisable>::iterator &it) {
    639     ObjectList<Synchronisable>::iterator temp=it;
    640     ++it;
    641     delete  *temp;
    642   }
    643 
    644   bool Gamestate::isDiffed(){
    645     return HEADER->diffed;
    646   }
    647 
    648   bool Gamestate::isCompressed(){
    649     return HEADER->compressed;
    650   }
    651 
    652   int Gamestate::getBaseID(){
    653     return HEADER->base_id;
    654   }
    655 }
    656 
    657 }
     464} //namespace packet
     465
     466} //namespace orxonox
Note: See TracChangeset for help on using the changeset viewer.