Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

Ignore:
Timestamp:
Sep 23, 2008, 12:46:37 AM (16 years ago)
Author:
scheusso
Message:

another new gamestate concept ;)

  • server does an individual object composition (to be sent) for every client
  • atm objects have sync frequencies and are priorized after their frequency (not clienbased yet)
  • after highlevel diff (object composition) a lowlevel diff is done
  • afterwards compression

→ 65 to 80 percent less data to be transmitted

File:
1 edited

Legend:

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

    r1800 r1827  
    101101    }// stop allocate additional memory
    102102
    103     if(it->doSelection(id))
    104       dataMap_[*it]=mem;  // save the mem location of the synchronisable data
     103    //if(it->doSelection(id))
     104    dataMap_[mem-data_]=(*it);  // save the mem location of the synchronisable data
    105105    if(!it->getData(mem, id, mode))
    106106      return false; // mem pointer gets automatically increased because of call by reference
     
    130130  assert(!HEADER->compressed);
    131131  assert(!HEADER->diffed);
    132   unsigned int size, objectID, classID;
    133132  unsigned char *mem=data_+sizeof(GamestateHeader);
    134133    // get the start of the Synchronisable list
     
    138137  // update the data of the objects we received
    139138  while(mem < data_+sizeof(GamestateHeader)+HEADER->datasize){
    140     size = *(unsigned int *)mem;
    141     objectID = *(unsigned int*)(mem+sizeof(unsigned int));
    142     classID = *(unsigned int*)(mem+2*sizeof(unsigned int));
    143 
    144     s = Synchronisable::getSynchronisable( objectID );
     139    synchronisableHeader *objectheader = (synchronisableHeader*)mem;
     140
     141    s = Synchronisable::getSynchronisable( objectheader->objectID );
    145142    if(!s)
    146143    {
     
    195192  return GamestateHandler::addGamestate(this, getClientID());
    196193}
     194
     195
    197196
    198197bool Gamestate::compressData()
     
    321320Gamestate* Gamestate::doSelection(unsigned int clientID){
    322321  assert(data_);
    323   std::map<Synchronisable *, unsigned char *>::iterator it;
    324   unsigned char *ndata, *tdata;
    325   unsigned int nsize=0;
    326   // calculate the size of the new gamestate
     322  std::map<unsigned int, Synchronisable *>::iterator it;
     323 
     324  Gamestate *gs = new Gamestate(*this);
     325  unsigned char *ndata = gs->data_ + sizeof(GamestateHeader);
     326  synchronisableHeader *objectheader;
     327  unsigned int objectOffset;
     328 
     329  //copy in the zeros
    327330  for(it=dataMap_.begin(); it!=dataMap_.end(); it++){
    328     if(it->first->doSelection(HEADER->id))
    329       nsize+=*(unsigned int*)it->second;
    330   }
    331   ndata = new unsigned char[nsize+sizeof(GamestateHeader)];
    332   tdata = ndata;
    333   tdata += sizeof(GamestateHeader);
     331    objectheader = (synchronisableHeader*)ndata;
     332    unsigned int objectsize = objectheader->size;
     333    assert(it->second->objectID==objectheader->objectID);
     334    objectOffset=sizeof(unsigned int)+sizeof(bool); //skip the size and the availableDate variables in the objectheader
     335    if(!it->second->doSelection(HEADER->id)){
     336      while(objectOffset<objectsize){
     337        objectheader->dataAvailable=false;
     338        *(ndata+objectOffset)=0;    // set to 0
     339        objectOffset++;
     340      }
     341      assert(objectOffset==objectsize);
     342    }
     343    ndata+=objectsize;
     344  }
     345  return gs;
     346}
     347
     348
     349Gamestate* Gamestate::intelligentDiff(Gamestate *base, unsigned int clientID){
     350  // asserts
     351  assert(data_);
     352  assert(base->data_);
     353  assert(!GAMESTATE_HEADER(base->data_)->diffed);
     354  assert(!GAMESTATE_HEADER(base->data_)->compressed);
     355  assert(!HEADER->compressed);
     356  assert(!HEADER->diffed);
     357 
     358  //preparations
     359  std::map<unsigned int, Synchronisable *>::iterator it;
     360  unsigned char *origdata, *basedata, *destdata, *ndata;
     361  unsigned int objectOffset, streamOffset=0;    //data offset
     362  unsigned int minsize = (HEADER->datasize < GAMESTATE_HEADER(base->data_)->datasize) ? HEADER->datasize : GAMESTATE_HEADER(base->data_)->datasize;
     363  synchronisableHeader *origheader;
     364  synchronisableHeader *destheader;
     365 
     366  origdata = GAMESTATE_START(this->data_);
     367  basedata = GAMESTATE_START(base->data_);
     368  ndata = new unsigned char[HEADER->datasize + sizeof(GamestateHeader)];
     369  destdata = ndata + sizeof(GamestateHeader);
     370 
     371  // do the diff
    334372  for(it=dataMap_.begin(); it!=dataMap_.end(); it++){
    335     if(it->first->doSelection(HEADER->id)){
    336       memcpy(tdata, it->second, *(unsigned int*)it->second); // copy over the saved data of the synchronisable
    337       tdata += *(unsigned int*)it->second;
    338     }
    339   }
    340   COUT(3) << "oldsize: " << HEADER->datasize << " newsize: " << nsize << std::endl;
     373    assert(streamOffset<HEADER->datasize);
     374    bool sendData = it->second->doSelection(HEADER->id);
     375    origheader = (synchronisableHeader *)(origdata+streamOffset);
     376    destheader = (synchronisableHeader *)(destdata+streamOffset);
     377   
     378    //copy and partially diff the object header
     379    assert(sizeof(synchronisableHeader)==3*sizeof(unsigned int)+sizeof(bool));
     380    *(unsigned int*)destdata = *(unsigned int*)origdata; //size (do not diff)
     381    *(bool*)(destdata+sizeof(unsigned int)) = sendData;
     382    if(sendData){
     383      *(unsigned int*)(destdata+sizeof(unsigned int)+sizeof(bool)) = *(unsigned int*)(basedata+sizeof(unsigned int)+sizeof(bool)) ^ *(unsigned int*)(origdata+sizeof(unsigned int)+sizeof(bool)); //objectid (diff it)
     384      *(unsigned int*)(destdata+2*sizeof(unsigned int)+sizeof(bool)) = *(unsigned int*)(basedata+2*sizeof(unsigned int)+sizeof(bool)) ^ *(unsigned int*)(origdata+2*sizeof(unsigned int)+sizeof(bool)); //classid (diff it)
     385    }else{
     386      *(unsigned int*)(destdata+sizeof(unsigned int)+sizeof(bool)) = 0;
     387      *(unsigned int*)(destdata+2*sizeof(unsigned int)+sizeof(bool)) = 0;
     388    }
     389    objectOffset=sizeof(synchronisableHeader);
     390    streamOffset+=sizeof(synchronisableHeader);
     391   
     392    //now handle the object data or fill with zeros
     393    while(objectOffset<origheader->size ){
     394     
     395      if(sendData && streamOffset<minsize)
     396        *(destdata+objectOffset)=*(basedata+objectOffset)^*(origdata+objectOffset); // do the xor
     397      else if(sendData)
     398        *(destdata+objectOffset)=((unsigned char)0)^*(origdata+objectOffset); // xor with 0 (basestream is too short)
     399      else
     400        *(destdata+objectOffset)=0; // set to 0 because this object should not be transfered
     401     
     402      objectOffset++;
     403      streamOffset++;
     404    }
     405    destdata+=objectOffset;
     406    origdata+=objectOffset;
     407    basedata+=objectOffset;
     408  }
     409 
     410  //copy over the gamestate header and set the diffed flag
    341411  *(GamestateHeader *)ndata = *HEADER; //copy over the header
    342   GAMESTATE_HEADER(ndata)->datasize = nsize;
    343412  Gamestate *gs = new Gamestate(ndata);
    344   assert(HEADER->datasize>=nsize);
     413  GAMESTATE_HEADER(ndata)->diffed=true;
     414  return gs;
     415}
     416
     417Gamestate* Gamestate::intelligentUnDiff(Gamestate *base){
     418  // asserts
     419  assert(data_);
     420  assert(base->data_);
     421  assert(!GAMESTATE_HEADER(base->data_)->diffed);
     422  assert(!GAMESTATE_HEADER(base->data_)->compressed);
     423  assert(!HEADER->compressed);
     424  assert(HEADER->diffed);
     425 
     426  //preparations
     427  std::map<unsigned int, Synchronisable *>::iterator it;
     428  unsigned char *origdata, *basedata, *destdata, *ndata;
     429  unsigned int objectOffset, streamOffset=0;    //data offset
     430  unsigned int minsize = (HEADER->datasize < GAMESTATE_HEADER(base->data_)->datasize) ? HEADER->datasize : GAMESTATE_HEADER(base->data_)->datasize;
     431  synchronisableHeader *origheader;
     432  synchronisableHeader *destheader;
     433 
     434  origdata = GAMESTATE_START(this->data_);
     435  basedata = GAMESTATE_START(base->data_);
     436  ndata = new unsigned char[HEADER->datasize + sizeof(GamestateHeader)];
     437  destdata = ndata + sizeof(GamestateHeader);
     438 
     439  // do the undiff
     440  for(it=dataMap_.begin(); it!=dataMap_.end(); it++){
     441    assert(streamOffset<HEADER->datasize);
     442    origheader = (synchronisableHeader *)(origdata+streamOffset);
     443    destheader = (synchronisableHeader *)(destdata+streamOffset);
     444    bool sendData;
     445   
     446    //copy and partially diff the object header
     447    assert(sizeof(synchronisableHeader)==3*sizeof(unsigned int)+sizeof(bool));
     448    *(unsigned int*)destdata = *(unsigned int*)origdata; //size (do not diff)
     449    *(bool*)(destdata+sizeof(unsigned int)) = *(bool*)(origdata+sizeof(unsigned int));
     450    sendData = *(bool*)(origdata+sizeof(unsigned int));
     451    if(sendData){
     452      *(unsigned int*)(destdata+sizeof(unsigned int)+sizeof(bool)) = *(unsigned int*)(basedata+sizeof(unsigned int)+sizeof(bool)) ^ *(unsigned int*)(origdata+sizeof(unsigned int)+sizeof(bool)); //objectid (diff it)
     453      *(unsigned int*)(destdata+2*sizeof(unsigned int)+sizeof(bool)) = *(unsigned int*)(basedata+2*sizeof(unsigned int)+sizeof(bool)) ^ *(unsigned int*)(origdata+2*sizeof(unsigned int)+sizeof(bool)); //classid (diff it)
     454    }else{
     455      *(unsigned int*)(destdata+sizeof(unsigned int)+sizeof(bool)) = 0;
     456      *(unsigned int*)(destdata+2*sizeof(unsigned int)+sizeof(bool)) = 0;
     457    }
     458    objectOffset=sizeof(synchronisableHeader);
     459    streamOffset+=sizeof(synchronisableHeader);
     460   
     461    //now handle the object data or fill with zeros
     462    while(objectOffset<origheader->size ){
     463     
     464      if(sendData && streamOffset<minsize)
     465        *(destdata+objectOffset)=*(basedata+objectOffset)^*(origdata+objectOffset); // do the xor
     466      else if(sendData)
     467        *(destdata+objectOffset)=((unsigned char)0)^*(origdata+objectOffset); // xor with 0 (basestream is too short)
     468      else
     469        *(destdata+objectOffset)=0; // set to 0 because this object should not be transfered
     470     
     471      objectOffset++;
     472      streamOffset++;
     473    }
     474    destdata+=objectOffset;
     475    origdata+=objectOffset;
     476    basedata+=objectOffset;
     477  }
     478 
     479  //copy over the gamestate header and set the diffed flag
     480  *(GamestateHeader *)ndata = *HEADER; //copy over the header
     481  Gamestate *gs = new Gamestate(ndata);
     482  GAMESTATE_HEADER(ndata)->diffed=false;
    345483  return gs;
    346484}
Note: See TracChangeset for help on using the changeset viewer.