Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

Ignore:
Timestamp:
Oct 12, 2008, 7:40:47 PM (16 years ago)
Author:
scheusso
Message:

merged network branch back to trunk

File:
1 edited

Legend:

Unmodified
Added
Removed
  • code/trunk/src/network/Synchronisable.cc

    r1856 r1907  
    5151namespace network
    5252{
    53 
     53 
     54
     55  std::map<unsigned int, Synchronisable *> Synchronisable::objectMap_;
     56  std::queue<unsigned int> Synchronisable::deletedObjects_;
    5457
    5558  int Synchronisable::state_=0x1; // detemines wheter we are server (default) or client
     
    5760  /**
    5861  * Constructor:
    59   * calls registarAllVariables, that has to be implemented by the inheriting classID
     62  * Initializes all Variables and sets the right objectID
    6063  */
    6164  Synchronisable::Synchronisable(){
    6265    RegisterRootObject(Synchronisable);
    63     static int idCounter=0;
    64     datasize=0;
     66    static uint32_t idCounter=0;
    6567    objectFrequency_=1;
    66     objectMode_=0x1; // by default do not send data to servere
     68    objectMode_=0x1; // by default do not send data to server
    6769    objectID=idCounter++;
    6870    syncList = new std::list<synchronisableVariable *>;
    69     //registerAllVariables();
    70   }
    71 
     71  }
     72
     73  /**
     74   * Destructor:
     75   * Delete all callback objects and remove objectID from the objectMap_
     76   */
    7277  Synchronisable::~Synchronisable(){
    7378    // delete callback function objects
    74     if(!orxonox::Identifier::isCreatingHierarchy())
     79    if(!orxonox::Identifier::isCreatingHierarchy()){
    7580      for(std::list<synchronisableVariable *>::iterator it = syncList->begin(); it!=syncList->end(); it++)
    7681        delete (*it)->callback;
    77   }
    78 
     82      deletedObjects_.push(objectID);
     83//       COUT(3) << "destruct synchronisable +++" << objectID << " | " << classID << std::endl;
     84//       COUT(3) << " bump ---" << objectID << " | " << &objectMap_ << std::endl;
     85//       assert(objectMap_[objectID]->objectID==objectID);
     86//       objectMap_.erase(objectID);
     87    }
     88  }
     89
     90  /**
     91   * This function gets called after all neccessary data has been passed to the object
     92   * Overload this function and recall the create function of the parent class
     93   * @return true/false
     94   */
    7995  bool Synchronisable::create(){
    8096    this->classID = this->getIdentifier()->getNetworkID();
    81     COUT(4) << "creating synchronisable: setting classid from " << this->getIdentifier()->getName() << " to: " << classID << std::endl;
     97//     COUT(4) << "creating synchronisable: setting classid from " << this->getIdentifier()->getName() << " to: " << classID << std::endl;
     98   
     99//     COUT(3) << "construct synchronisable +++" << objectID << " | " << classID << std::endl;
     100//     objectMap_[objectID]=this;
     101//     assert(objectMap_[objectID]==this);
     102//     assert(objectMap_[objectID]->objectID==objectID);
    82103    return true;
    83104  }
    84105
    85106
     107  /**
     108   * This function sets the internal mode for synchronisation
     109   * @param b true if this object is located on a client or on a server
     110   */
    86111  void Synchronisable::setClient(bool b){
    87112    if(b) // client
     
    91116  }
    92117
    93   bool Synchronisable::fabricate(unsigned char*& mem, int mode)
     118  /**
     119   * This function fabricated a new synchrnisable (and children of it), sets calls updateData and create
     120   * After calling this function the mem pointer will be increased by the size of the needed data
     121   * @param mem pointer to where the appropriate data is located
     122   * @param mode defines the mode, how the data should be loaded
     123   * @return pointer to the newly created synchronisable
     124   */
     125  Synchronisable *Synchronisable::fabricate(uint8_t*& mem, int mode)
    94126  {
    95     unsigned int size, objectID, classID;
    96     size = *(unsigned int *)mem;
    97     objectID = *(unsigned int*)(mem+sizeof(unsigned int));
    98     classID = *(unsigned int*)(mem+2*sizeof(unsigned int));
    99 
    100     if(size==3*sizeof(unsigned int)){ //not our turn, dont do anything
    101       mem+=3*sizeof(unsigned int);
    102       return true;
    103     }
    104 
    105     orxonox::Identifier* id = ClassByID(classID);
    106     if(!id){
    107       COUT(3) << "We could not identify a new object; classid: " << classID << " uint: " << (unsigned int)classID << " objectID: " << objectID << " size: " << size << std::endl;
    108       assert(0);
    109       return false; // most probably the gamestate is corrupted
    110     }
     127    synchronisableHeader *header = (synchronisableHeader *)mem;
     128
     129    COUT(3) << "fabricating object with id: " << header->objectID << std::endl;
     130
     131    orxonox::Identifier* id = ClassByID(header->classID);
     132    assert(id);
    111133    orxonox::BaseObject *bo = id->fabricate();
    112134    Synchronisable *no = dynamic_cast<Synchronisable *>(bo);
    113135    assert(no);
    114     no->objectID=objectID;
    115     no->classID=classID;
     136    no->objectID=header->objectID;
     137    no->classID=header->classID;
    116138    COUT(3) << "fabricate objectID: " << no->objectID << " classID: " << no->classID << std::endl;
    117139          // update data and create object/entity...
    118     if( !no->updateData(mem, mode) ){
    119       COUT(1) << "We couldn't update the object: " << objectID << std::endl;
     140    bool b = no->updateData(mem, mode);
     141    assert(b);
     142    b = no->create();
     143    assert(b);
     144    return no;
     145  }
     146
     147 
     148  /**
     149   * Finds and deletes the Synchronisable with the appropriate objectID
     150   * @param objectID objectID of the Synchronisable
     151   * @return true/false
     152   */
     153  bool Synchronisable::deleteObject(unsigned int objectID){
     154//     assert(getSynchronisable(objectID));
     155    if(!getSynchronisable(objectID))
    120156      return false;
    121     }
    122     if( !no->create() )
    123     {
    124       COUT(1) << "We couldn't manifest (create() ) the object: " << objectID << std::endl;
     157    assert(getSynchronisable(objectID)->objectID==objectID);
     158//     delete objectMap_[objectID];
     159    Synchronisable *s = getSynchronisable(objectID);
     160    if(s)
     161      delete s;
     162    else
    125163      return false;
    126     }
    127164    return true;
    128165  }
    129 
     166 
     167  /**
     168   * This function looks up the objectID in the objectMap_ and returns a pointer to the right Synchronisable
     169   * @param objectID objectID of the Synchronisable
     170   * @return pointer to the Synchronisable with the objectID
     171   */
     172  Synchronisable* Synchronisable::getSynchronisable(unsigned int objectID){
     173    orxonox::ObjectList<Synchronisable>::iterator it;
     174    for(it = orxonox::ObjectList<Synchronisable>::begin(); it; ++it){
     175      if( it->getObjectID()==objectID )
     176           return *it;
     177    }
     178    return NULL;
     179
     180//     std::map<unsigned int, Synchronisable *>::iterator i = objectMap_.find(objectID);
     181//     if(i==objectMap_.end())
     182//       return NULL;
     183//     assert(i->second->objectID==objectID);
     184//     return (*i).second;
     185  }
     186
     187 
    130188  /**
    131189  * This function is used to register a variable to be synchronized
     
    133191  * @param var pointer to the variable
    134192  * @param size size of the datatype the variable consists of
     193  * @param t the type of the variable (network::DATA or network::STRING
     194  * @param mode same as in getData
     195  * @param cb callback object that should get called, if the value of the variable changes
    135196  */
    136197  void Synchronisable::registerVar(void *var, int size, variableType t, int mode, NetworkCallbackBase *cb){
     
    143204    temp->callback = cb;
    144205    COUT(5) << "Syncronisable::registering var with size: " << temp->size << " and type: " << temp->type << std::endl;
    145     // increase datasize
    146     datasize+=sizeof(int)+size;
    147206    //std::cout << "push temp to syncList (at the bottom) " << datasize << std::endl;
    148207    COUT(5) << "Syncronisable::objectID: " << objectID << " this: " << this << " name: " << this->getIdentifier()->getName() << " networkID: " << this->getIdentifier()->getNetworkID() << std::endl;
    149208    syncList->push_back(temp);
    150   }
    151 
    152   /**
    153    * This function takes all SynchronisableVariables out of the Synchronisable and saves it into a syncData struct
    154    * Difference to the above function:
     209#ifndef NDEBUG
     210    std::list<synchronisableVariable *>::iterator it = syncList->begin();
     211    while(it!=syncList->end()){
     212      assert(*it!=var);
     213      it++;
     214    }
     215#endif
     216  }
     217
     218  /**
     219   * This function takes all SynchronisableVariables out of the Synchronisable and saves them together with the size, objectID and classID to the given memory
    155220   * takes a pointer to already allocated memory (must have at least getSize bytes length)
    156221   * structure of the bitstream:
    157    * (var1_size,var1,var2_size,var2,...)
    158    * varx_size: size = sizeof(int)
    159    * varx: size = varx_size
    160    * @return data containing all variables and their sizes
    161    */
    162   bool Synchronisable::getData(unsigned char*& mem, unsigned int id, int mode){
     222   * |totalsize,objectID,classID,var1,var2,string1_length,string1,var3,...|
     223   * length of varx: size saved int syncvarlist
     224   * @param mem pointer to allocated memory with enough size
     225   * @param id gamestateid of the gamestate to be saved (important for priorities)
     226   * @param mode defines the direction in which the data will be send/received
     227   *             0x1: server->client
     228   *             0x2: client->server (not recommended)
     229   *             0x3: bidirectional
     230   * @return true: if !isMyTick or if everything was successfully saved
     231   */
     232  bool Synchronisable::getData(uint8_t*& mem, unsigned int id, int mode){
     233    //if this tick is we dont synchronise, then abort now
     234    if(!isMyTick(id))
     235      return true;
    163236    //std::cout << "inside getData" << std::endl;
    164237    unsigned int tempsize = 0;
     
    167240    if(classID==0)
    168241      COUT(3) << "classid 0 " << this->getIdentifier()->getName() << std::endl;
    169     this->classID=this->getIdentifier()->getNetworkID(); // TODO: correct this
     242    assert(this->classID==this->getIdentifier()->getNetworkID());
     243//     this->classID=this->getIdentifier()->getNetworkID(); // TODO: correct this
    170244    std::list<synchronisableVariable *>::iterator i;
    171245    unsigned int size;
    172     size=getSize2(id, mode);
     246    size=getSize(id, mode);
    173247
    174248    // start copy header
    175     memcpy(mem, &size, sizeof(unsigned int));
    176     mem+=sizeof(unsigned int);
    177     memcpy(mem, &(this->objectID), sizeof(unsigned int));
    178     mem+=sizeof(unsigned int);
    179     memcpy(mem, &(this->classID), sizeof(unsigned int));
    180     mem+=sizeof(unsigned int);
    181     tempsize+=12;
     249    synchronisableHeader *header = (synchronisableHeader *)mem;
     250    header->size = size;
     251    header->objectID = this->objectID;
     252    header->classID = this->classID;
     253    header->dataAvailable = true;
     254    tempsize+=sizeof(synchronisableHeader);
     255    mem+=sizeof(synchronisableHeader);
    182256    // end copy header
    183257
    184     //if this tick is we dont synchronise, then abort now
    185     if(!isMyTick(id))
    186       return true;
    187258
    188259    COUT(5) << "Synchronisable getting data from objectID: " << objectID << " classID: " << classID << " length: " << size << std::endl;
    189260    // copy to location
    190261    for(i=syncList->begin(); i!=syncList->end(); ++i){
    191       //(std::memcpy(retVal.data+n, (const void*)(&(i->size)), sizeof(int));
    192262      if( ((*i)->mode & mode) == 0 ){
    193263        COUT(5) << "not getting data: " << std::endl;
     
    217287
    218288  /**
    219    * This function takes a syncData struct and takes it to update the variables
    220    * @param vars data of the variables
     289   * This function takes a bytestream and loads the data into the registered variables
     290   * @param mem pointer to the bytestream
     291   * @param mode same as in getData
    221292   * @return true/false
    222293   */
    223   bool Synchronisable::updateData(unsigned char*& mem, int mode){
    224     unsigned char *data = mem;
     294  bool Synchronisable::updateData(uint8_t*& mem, int mode){
    225295    if(mode==0x0)
    226296      mode=state_;
     
    231301    }
    232302
     303    uint8_t *data=mem;
    233304    // start extract header
    234     unsigned int objectID, classID, size;
    235     size = *(int *)mem;
    236     mem+=sizeof(size);
    237     objectID = *(int *)mem;
    238     mem+=sizeof(objectID);
    239     classID = *(int *)mem;
    240     mem+=sizeof(classID);
     305    synchronisableHeader *syncHeader = (synchronisableHeader *)mem;
     306    assert(syncHeader->objectID==this->objectID);
     307    if(syncHeader->dataAvailable==false){
     308      mem+=syncHeader->size;
     309      return true;
     310    }
     311
     312    mem+=sizeof(synchronisableHeader);
    241313    // stop extract header
    242     assert(this->objectID==objectID);
    243     assert(this->classID==classID);
    244     if(size==3*sizeof(unsigned int)) //if true, only the header is available
    245       return true;
    246       //assert(0);
    247 
    248     COUT(5) << "Synchronisable: objectID " << objectID << ", classID " << classID << " size: " << size << " synchronising data" << std::endl;
    249     for(i=syncList->begin(); i!=syncList->end() && mem <= data+size; i++){
     314    assert(this->objectID==syncHeader->objectID);
     315//    assert(this->classID==syncHeader->classID); //TODO: fix this!!! maybe a problem with the identifier ?
     316   
     317    COUT(5) << "Synchronisable: objectID " << syncHeader->objectID << ", classID " << syncHeader->classID << " size: " << syncHeader->size << " synchronising data" << std::endl;
     318    for(i=syncList->begin(); i!=syncList->end() && mem <= data+syncHeader->size; i++){
    250319      if( ((*i)->mode ^ mode) == 0 ){
    251320        COUT(5) << "synchronisable: not updating variable " << std::endl;
     
    263332          break;
    264333        case STRING:
    265           (*i)->size = *(int *)mem;
     334          (*i)->size = *(uint32_t *)mem;
    266335          COUT(5) << "string size: " << (*i)->size << std::endl;
    267336          mem+=sizeof(int);
     
    283352  /**
    284353  * This function returns the total amount of bytes needed by getData to save the whole content of the variables
     354  * @param id id of the gamestate
     355  * @param mode same as getData
    285356  * @return amount of bytes
    286357  */
    287   int Synchronisable::getSize(unsigned int id, int mode){
     358  uint32_t Synchronisable::getSize(unsigned int id, int mode){
    288359    if(!isMyTick(id))
    289360      return 0;
    290     int tsize=0;
     361    int tsize=sizeof(synchronisableHeader);
    291362    if(mode==0x0)
    292363      mode=state_;
     
    311382
    312383  /**
    313    * This function returns the total amount of bytes needed by getData to save the whole content of the variables
    314    * @return amount of bytes
    315    */
    316   int Synchronisable::getSize2(unsigned int id, int mode){
    317     return sizeof(synchronisableHeader) + getSize( id, mode );
    318   }
    319 
    320   /**
    321    *
    322    * @param id
    323    * @return
     384   * This function determines, wheter the object should be saved to the bytestream (according to its syncmode/direction)
     385   * @param id gamestate id
     386   * @return true/false
    324387   */
    325388  bool Synchronisable::isMyTick(unsigned int id){
    326 //     return true;
     389    return ( (objectMode_&state_)!=0 );
     390  }
     391
     392  bool Synchronisable::doSelection(unsigned int id){
    327393    return ( id==0 || id%objectFrequency_==objectID%objectFrequency_ ) && ((objectMode_&state_)!=0);
    328394  }
    329395
    330   bool Synchronisable::isMyData(unsigned char* mem)
     396  /**
     397   * This function looks at the header located in the bytestream and checks wheter objectID and classID match with the Synchronisables ones
     398   * @param mem pointer to the bytestream
     399   */
     400  bool Synchronisable::isMyData(uint8_t* mem)
    331401  {
    332     unsigned int objectID, classID, size;
    333     size = *(int *)mem;
    334     mem+=sizeof(size);
    335     objectID = *(int *)mem;
    336     mem+=sizeof(objectID);
    337     classID = *(int *)mem;
    338     mem+=sizeof(classID);
    339 
    340     assert(classID == this->classID);
    341     return (objectID == this->objectID);
    342   }
    343 
     402    synchronisableHeader *header = (synchronisableHeader *)mem;
     403    assert(header->objectID==this->objectID);
     404    return header->dataAvailable;
     405  }
     406
     407  /**
     408   * This function sets the synchronisation mode of the object
     409   * If set to 0x1 variables will only be synchronised to the client
     410   * If set to 0x2 variables will only be synchronised to the server
     411   * If set to 0x3 variables will be synchronised bidirectionally (only if set so in registerVar)
     412   * @param mode same as in registerVar
     413   */
    344414  void Synchronisable::setObjectMode(int mode){
    345415    assert(mode==0x1 || mode==0x2 || mode==0x3);
Note: See TracChangeset for help on using the changeset viewer.