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

Location:
code/branches/network/src/network
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • code/branches/network/src/network/GamestateClient.cc

    r1775 r1827  
    189189        return 0;
    190190      }
    191 //      assert(base); //TODO: fix this
     191//       assert(base); //TODO: fix this
    192192      packet::Gamestate *undiffed = gs->undiff(base);
    193193      delete gs;
  • code/branches/network/src/network/GamestateManager.cc

    r1800 r1827  
    133133    gs = reference->doSelection(clientID);
    134134//     gs = new packet::Gamestate(*reference);
     135//     gs = new packet::Gamestate(*reference);
    135136    // save the (undiffed) gamestate in the clients gamestate map
    136137    gamestateMap_[clientID].insert(std::pair<int, packet::Gamestate*>(gs->getID(), gs));
  • code/branches/network/src/network/Synchronisable.cc

    r1800 r1827  
    120120  Synchronisable *Synchronisable::fabricate(unsigned char*& mem, int mode)
    121121  {
    122     unsigned int size, objectID, classID;
    123     size = *(unsigned int *)mem;
    124     objectID = *(unsigned int*)(mem+sizeof(unsigned int));
    125     classID = *(unsigned int*)(mem+2*sizeof(unsigned int));
    126    
    127     orxonox::Identifier* id = GetIdentifier(classID);
     122    synchronisableHeader *header = (synchronisableHeader *)mem;
     123   
     124    orxonox::Identifier* id = GetIdentifier(header->classID);
    128125    assert(id);
    129126    orxonox::BaseObject *bo = id->fabricate();
    130127    Synchronisable *no = dynamic_cast<Synchronisable *>(bo);
    131128    assert(no);
    132     no->objectID=objectID;
    133     no->classID=classID;
     129    no->objectID=header->objectID;
     130    no->classID=header->classID;
    134131    COUT(3) << "fabricate objectID: " << no->objectID << " classID: " << no->classID << std::endl;
    135132          // update data and create object/entity...
     
    228225   
    229226    // start copy header
    230     memcpy(mem, &size, sizeof(unsigned int));
    231     mem+=sizeof(unsigned int);
    232     memcpy(mem, &(this->objectID), sizeof(unsigned int));
    233     mem+=sizeof(unsigned int);
    234     memcpy(mem, &(this->classID), sizeof(unsigned int));
    235     mem+=sizeof(unsigned int);
    236     tempsize+=12;
     227    synchronisableHeader *header = (synchronisableHeader *)mem;
     228    header->size = size;
     229    header->objectID = this->objectID;
     230    header->classID = this->classID;
     231    header->dataAvailable = true;
     232    tempsize+=sizeof(synchronisableHeader);
     233    mem+=sizeof(synchronisableHeader);
    237234    // end copy header
    238235   
     
    241238    // copy to location
    242239    for(i=syncList->begin(); i!=syncList->end(); ++i){
    243       //(std::memcpy(retVal.data+n, (const void*)(&(i->size)), sizeof(int));
    244240      if( ((*i)->mode & mode) == 0 ){
    245241        COUT(5) << "not getting data: " << std::endl;
     
    284280    unsigned char *data=mem;
    285281    // start extract header
    286     if(!isMyData(mem))
     282    synchronisableHeader *syncHeader = (synchronisableHeader *)mem;
     283    assert(syncHeader->objectID==this->objectID);
     284    if(syncHeader->dataAvailable==false){
     285      mem+=syncHeader->size;
    287286      return true;
    288     unsigned int objectID, classID, size;
    289     size = *(int *)mem;
    290     mem+=sizeof(size);
    291     objectID = *(int *)mem;
    292     mem+=sizeof(objectID);
    293     classID = *(int *)mem;
    294     mem+=sizeof(classID);
     287    }
     288   
     289    mem+=sizeof(synchronisableHeader);
    295290    // stop extract header
    296     assert(this->objectID==objectID);
    297     assert(this->classID==classID);
    298    
    299     COUT(5) << "Synchronisable: objectID " << objectID << ", classID " << classID << " size: " << size << " synchronising data" << std::endl;
    300     for(i=syncList->begin(); i!=syncList->end() && mem <= data+size; i++){
     291    assert(this->objectID==syncHeader->objectID);
     292//    assert(this->classID==syncHeader->classID); //TODO: fix this!!! maybe a problem with the identifier ?
     293   
     294    COUT(5) << "Synchronisable: objectID " << syncHeader->objectID << ", classID " << syncHeader->classID << " size: " << syncHeader->size << " synchronising data" << std::endl;
     295    for(i=syncList->begin(); i!=syncList->end() && mem <= data+syncHeader->size; i++){
    301296      if( ((*i)->mode ^ mode) == 0 ){
    302297        COUT(5) << "synchronisable: not updating variable " << std::endl;
     
    382377  bool Synchronisable::isMyData(unsigned char* mem)
    383378  {
    384     unsigned int objectID, classID, size;
    385     size = *(int *)mem;
    386     mem+=sizeof(size);
    387     objectID = *(int *)mem;
    388     mem+=sizeof(objectID);
    389     classID = *(int *)mem;
    390     mem+=sizeof(classID);
    391    
    392     assert(classID == this->classID);
    393     return (objectID == this->objectID);
     379    synchronisableHeader *header = (synchronisableHeader *)mem;
     380    assert(header->objectID==this->objectID);
     381    return header->dataAvailable;
    394382  }
    395383 
  • code/branches/network/src/network/Synchronisable.h

    r1800 r1827  
    6262  struct synchronisableHeader{
    6363    unsigned int size;
     64    bool dataAvailable;
    6465    unsigned int objectID;
    6566    unsigned int classID;
  • 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}
  • code/branches/network/src/network/packet/Gamestate.h

    r1800 r1827  
    7474    int getBaseID();
    7575    Gamestate *diff(Gamestate *base);
     76    Gamestate* intelligentDiff(Gamestate *base, unsigned int clientID);
     77    Gamestate *undiff(Gamestate *base);
     78    Gamestate* intelligentUnDiff(Gamestate *base);
    7679    Gamestate* doSelection(unsigned int clientID);
    77     Gamestate *undiff(Gamestate *base);
    7880    bool compressData();
    7981    bool decompressData();
     
    8890    unsigned int calcGamestateSize(unsigned int id, int mode=0x0);
    8991    void removeObject(orxonox::ObjectListIterator<Synchronisable> &it);
    90     std::map<Synchronisable *, unsigned char *> dataMap_;
     92    std::map<unsigned int, Synchronisable*> dataMap_;
    9193};
    9294
Note: See TracChangeset for help on using the changeset viewer.