Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

Ignore:
Timestamp:
Nov 22, 2008, 11:54:48 AM (16 years ago)
Author:
scheusso
Message:

most coding is done, still testing now
types should get transfered in platform independent formats now

Location:
code/branches/network64/src/network/synchronisable
Files:
2 added
3 edited

Legend:

Unmodified
Added
Removed
  • code/branches/network64/src/network/synchronisable/CMakeLists.txt

    r2211 r2245  
    11SET( SRC_FILES
    22  Synchronisable.cc
     3  SynchronisableVariable.cc
    34)
    45
  • code/branches/network64/src/network/synchronisable/Synchronisable.cc

    r2211 r2245  
    4040
    4141#include "Synchronisable.h"
     42#include "SynchronisableSpecialisations.cc" // this defines all specialisations for registerVariable
    4243
    4344#include <cstring>
     
    7879      objectID=OBJECTID_UNKNOWN;
    7980    classID = (unsigned int)-1;
    80     syncList = new std::list<synchronisableVariable *>;
    8181
    8282
     
    114114    // delete callback function objects
    115115    if(!Identifier::isCreatingHierarchy()){
    116       for(std::list<synchronisableVariable *>::iterator it = syncList->begin(); it!=syncList->end(); it++)
    117         delete (*it)->callback;
     116      for(std::list<SynchronisableVariableBase*>::iterator it = syncList.begin(); it!=syncList.end(); it++)
     117        delete (*it);
    118118      if (this->objectMode_ != 0x0 && (Host::running() && Host::isServer()))
    119119        deletedObjects_.push(objectID);
     
    127127    if (it != objectMap_.end())
    128128      objectMap_.erase(it);
    129   }
    130 
    131   /**
    132    * This function gets called after all neccessary data has been passed to the object
    133    * Overload this function and recall the create function of the parent class
    134    * @return true/false
    135    */
    136   bool Synchronisable::create(){
    137     this->classID = this->getIdentifier()->getNetworkID();
    138 //     COUT(4) << "creating synchronisable: setting classid from " << this->getIdentifier()->getName() << " to: " << classID << std::endl;
    139 
    140 //     COUT(3) << "construct synchronisable +++" << objectID << " | " << classID << std::endl;
    141 //     objectMap_[objectID]=this;
    142 //     assert(objectMap_[objectID]==this);
    143 //     assert(objectMap_[objectID]->objectID==objectID);
    144     return true;
    145129  }
    146130
     
    204188    if (b)
    205189    {
    206         b = no->create();
     190//        b = no->create();
    207191        assert(b);
    208192    }
     
    261245  * @param cb callback object that should get called, if the value of the variable changes
    262246  */
    263   void Synchronisable::registerVariable(void *var, int size, variableType t, uint8_t mode, NetworkCallbackBase *cb){
     247
     248/*  void Synchronisable::registerVariable(void *var, int size, variableType t, uint8_t mode, NetworkCallbackBase *cb){
    264249    assert( mode==direction::toclient || mode==direction::toserver || mode==direction::serverMaster || mode==direction::clientMaster);
    265250    // create temporary synch.Var struct
     
    294279    }
    295280#endif
    296   }
    297 
    298   void Synchronisable::unregisterVariable(void *var){
    299     std::list<synchronisableVariable *>::iterator it = syncList->begin();
    300     while(it!=syncList->end()){
    301       if( (*it)->var == var ){
    302         delete *it;
    303         syncList->erase(it);
    304         return;
    305       }
    306       else
    307         it++;
    308     }
    309     bool unregistered_nonexistent_variable = false;
    310     assert(unregistered_nonexistent_variable); //if we reach this point something went wrong:
    311     // the variable has not been registered before
    312   }
    313 
     281  }*/
     282 
    314283
    315284  /**
     
    343312    assert(this->classID==this->getIdentifier()->getNetworkID());
    344313//     this->classID=this->getIdentifier()->getNetworkID(); // TODO: correct this
    345     std::list<synchronisableVariable *>::iterator i;
     314    std::list<SynchronisableVariableBase*>::iterator i;
    346315    unsigned int size;
    347316    size=getSize(id, mode);
     
    361330    COUT(5) << "Synchronisable getting data from objectID: " << objectID << " classID: " << classID << " length: " << size << std::endl;
    362331    // copy to location
    363     for(i=syncList->begin(); i!=syncList->end(); ++i){
    364       if( ((*i)->mode & mode) == 0 ){
    365         COUT(5) << "not getting data: " << std::endl;
    366         continue;  // this variable should only be received
    367       }
    368 
    369       // =========== start bidirectional stuff =============
    370       // if the variable gets synchronised bidirectional, then add the reference to the bytestream
    371       if( ( (*i)->mode & direction::bidirectional ) == direction::bidirectional )
    372       {
    373         if( ( ((*i)->mode == direction::serverMaster) && (mode == 0x1) ) || \
    374             ( ((*i)->mode == direction::clientMaster) && (mode == 0x2) ) )
    375         {
    376           // MASTER
    377           if((*i)->type==DATA){
    378             if( memcmp((*i)->var,(*i)->varBuffer,(*i)->size) != 0 ) //check whether the variable changed during the last tick
    379             {
    380               ((*i)->varReference)++;   //the variable changed so increase the refnr
    381               memcpy((*i)->varBuffer, (*i)->var, (*i)->size); //set the buffer to the new value
    382             }
    383           }
    384           else //STRING
    385           {
    386             if( *static_cast<std::string*>((*i)->var) != *static_cast<std::string*>((*i)->varBuffer) ) //the string changed
    387             {
    388               ((*i)->varReference)++;   //the variable changed
    389               *static_cast<std::string*>((*i)->varBuffer) = *static_cast<std::string*>((*i)->var);  //now set the buffer to the new value
    390             }
    391           }
    392         }
    393         // copy the reference number to the stream
    394         *(uint8_t*)mem = (*i)->varReference;
    395         mem += sizeof( (*i)->varReference );
    396         tempsize += sizeof( (*i)->varReference );
    397       }
    398       // ================== end bidirectional stuff
    399 
    400       switch((*i)->type){
    401         case DATA:
    402           memcpy( (void *)(mem), (void*)((*i)->var), (*i)->size);
    403           mem += (*i)->size;
    404           tempsize += (*i)->size;
    405           break;
    406         case STRING:
    407           memcpy( (void *)(mem), (void *)&((*i)->size), sizeof(size_t) );
    408           mem += sizeof(size_t);
    409           const char *data = ( ( *(std::string *) (*i)->var).c_str());
    410           memcpy( mem, (void*)data, (*i)->size);
    411           COUT(5) << "synchronisable: char: " << (const char *)(mem) << " data: " << data << " string: " << *(std::string *)((*i)->var) << std::endl;
    412           mem += (*i)->size;
    413           tempsize += (*i)->size + sizeof(size_t);
    414           break;
    415       }
     332    for(i=syncList.begin(); i!=syncList.end(); ++i){
     333      (*i)->getData( mem, mode );
     334      tempsize += (*i)->getSize( mode );
    416335    }
    417336    assert(tempsize==size);
     
    429348    if(mode==0x0)
    430349      mode=state_;
    431     std::list<synchronisableVariable *>::iterator i;
     350    std::list<SynchronisableVariableBase *>::iterator i;
    432351    //assert(objectMode_!=0x0);
    433352    //assert( (mode ^ objectMode_) != 0);
    434     if(syncList->empty()){
     353    if(syncList.empty()){
    435354      COUT(4) << "Synchronisable::updateData syncList is empty" << std::endl;
    436355      return false;
    437356    }
    438357
    439     uint8_t *data=mem;
     358    uint8_t* data=mem;
    440359    // start extract header
    441360    synchronisableHeader *syncHeader = (synchronisableHeader *)mem;
     
    452371
    453372    COUT(5) << "Synchronisable: objectID " << syncHeader->objectID << ", classID " << syncHeader->classID << " size: " << syncHeader->size << " synchronising data" << std::endl;
    454     for(i=syncList->begin(); i!=syncList->end() && mem <= data+syncHeader->size; i++){
    455       if( ((*i)->mode ^ mode) == 0 ){
    456         COUT(5) << "synchronisable: not updating variable " << std::endl;
    457         // if we have a forcecallback then do the callback
    458         continue;  // this variable should only be set
    459       }
    460       COUT(5) << "Synchronisable: element size: " << (*i)->size << " type: " << (*i)->type << std::endl;
    461       bool callback=false;
    462       bool master=false;
    463 
    464       if( ( (*i)->mode & direction::bidirectional ) == direction::bidirectional )
    465       {
    466         uint8_t refNr = *(uint8_t *)mem;
    467         if( ( ((*i)->mode == direction::serverMaster) && (mode == 0x1) ) || \
    468             ( ((*i)->mode == direction::clientMaster) && (mode == 0x2) ) )
    469         { // MASTER
    470           master=true;
    471           if( refNr != (*i)->varReference || ( memcmp((*i)->var, (*i)->varBuffer, (*i)->size) != 0 ) )
    472           { // DISCARD data
    473             if( (*i)->type == DATA )
    474             {
    475               mem += sizeof((*i)->varReference) + (*i)->size;
    476             }
    477             else //STRING
    478             {
    479               mem += sizeof(size_t) + *(size_t *)mem;
    480             }
    481             if( forceCallback && (*i)->callback)
    482               (*i)->callback->call();
    483             continue;
    484           }//otherwise everything is ok and we update the value
    485         }
    486         else // SLAVE
    487         {
    488           if( (*i)->varReference == refNr ){
    489             //discard data because it's outdated or not different to what we've got
    490             if( (*i)->type == DATA )
    491             {
    492               mem += sizeof((*i)->varReference) + (*i)->size;
    493             }
    494             else //STRING
    495             {
    496               mem += sizeof(size_t) + *(size_t *)mem;
    497             }
    498             if( forceCallback && (*i)->callback)
    499               (*i)->callback->call();
    500             continue;
    501           }
    502           else
    503             (*i)->varReference = refNr; //copy the reference value for this variable
    504         }
    505         mem += sizeof((*i)->varReference);
    506       }
    507 
    508       switch((*i)->type){
    509         case DATA:
    510           if((*i)->callback) // check whether this variable changed (but only if callback was set)
    511           {
    512             if(memcmp((*i)->var, mem, (*i)->size) != 0)
    513               callback=true;
    514           }
    515           if( master )
    516           {
    517             if( callback || memcmp((*i)->var, mem, (*i)->size) != 0 )
    518               //value changed, so set the buffer to the new value
    519               memcpy((*i)->varBuffer, mem, (*i)->size);
    520           }
    521           memcpy((*i)->var, mem, (*i)->size);
    522           mem += (*i)->size;
    523           break;
    524         case STRING:
    525           (*i)->size = *(size_t *)mem;
    526           mem += sizeof(size_t);
    527 
    528           if( (*i)->callback) // check whether this string changed
    529             if( *static_cast<std::string*>((*i)->var) != std::string((char *)mem) )
    530               callback=true;
    531           if( master )
    532           {
    533             if( callback || *static_cast<std::string*>((*i)->var) != std::string((char *)mem) )
    534               //string changed. set the buffer to the new one
    535               *static_cast<std::string*>((*i)->varBuffer)=*static_cast<std::string*>( (void*)(mem+sizeof(size_t)) );
    536           }
    537 
    538           *((std::string *)((*i)->var)) = std::string((const char*)mem);
    539           COUT(5) << "synchronisable: char: " << (const char*)mem << " string: " << std::string((const char*)mem) << std::endl;
    540           mem += (*i)->size;
    541           break;
    542       }
    543       // call the callback function, if defined
    544       if((callback || forceCallback) && (*i)->callback)
    545         (*i)->callback->call();
     373    for(i=syncList.begin(); i!=syncList.end() && mem <= data+syncHeader->size; i++)
     374    {
     375      (*i)->putData( mem, mode, forceCallback );
    546376    }
    547377    assert(mem == data+syncHeader->size);
     
    561391    if(!doSync(id, mode))
    562392      return 0;
    563     std::list<synchronisableVariable *>::iterator i;
    564     for(i=syncList->begin(); i!=syncList->end(); i++){
    565       if( ((*i)->mode & mode) == 0 )
    566         continue;  // this variable should only be received, so dont add its size to the send-size
    567       switch((*i)->type){
    568       case DATA:
    569         tsize+=(*i)->size;
    570         break;
    571       case STRING:
    572         tsize+=sizeof(int);
    573         (*i)->size=((std::string *)(*i)->var)->length()+1;
    574         COUT(5) << "String size: " << (*i)->size << std::endl;
    575         tsize+=(*i)->size;
    576         break;
    577       }
    578       if( ( (*i)->mode & direction::bidirectional ) == direction::bidirectional )
    579       {
    580         tsize+=sizeof( (*i)->varReference );
    581       }
     393    std::list<SynchronisableVariableBase*>::iterator i;
     394    for(i=syncList.begin(); i!=syncList.end(); i++){
     395      tsize += (*i)->getSize( mode );
    582396    }
    583397    return tsize;
     
    592406    if(mode==0x0)
    593407      mode=state_;
    594     return ( (objectMode_&mode)!=0 && (!syncList->empty() ) );
     408    return ( (objectMode_&mode)!=0 && (!syncList.empty() ) );
    595409  }
    596410
     
    623437    objectMode_=mode;
    624438  }
    625 
     439 
    626440
    627441}
  • code/branches/network64/src/network/synchronisable/Synchronisable.h

    r2211 r2245  
    3535#include <map>
    3636#include <queue>
    37 #include "util/Integers.h"
     37#include <cassert>
     38#include "util/Math.h"
     39#include "util/mbool.h"
    3840#include "core/OrxonoxClass.h"
    39 #include "core/XMLIncludes.h"
     41// TODO: this has to be removed
     42// #include <OgreLight.h>
     43// #include "OrxonoxPrereqs.h"
     44// ============================
    4045#include "NetworkCallback.h"
    41 #include "util/Integers.h"
     46#include "SynchronisableVariable.h"
    4247
    43 #define REGISTERDATA(varname, ...) \
     48/*#define REGISTERDATA(varname, ...) \
    4449    registerVariable((void*)&varname, sizeof(varname), DATA, __VA_ARGS__)
    4550#define REGISTERSTRING(stringname, ...) \
    46     registerVariable(&stringname, stringname.length()+1, STRING, __VA_ARGS__)
     51    registerVariable(&stringname, stringname.length()+1, STRING, __VA_ARGS__)*/
    4752
    4853namespace orxonox
     
    5055  static const unsigned int OBJECTID_UNKNOWN = (unsigned int)-1;
    5156
    52   namespace direction{
    53     enum syncdirection{
     57  namespace objectDirection{
     58    enum objectdirection{
    5459      toclient=0x1,
    5560      toserver=0x2,
    56       bidirectional=0x3,
    57       serverMaster=0x3,
    58       clientMaster=0x7
     61      bidirectional=0x3
    5962    };
    6063  }
    61 
    62   namespace syncmode{
    63     enum mode{
    64       once=0,
    65       always=1
    66     };
    67   }
    68 
    69   enum variableType{
    70     DATA,
    71     STRING,
    72   };
    7364
    7465  struct _NetworkExport synchronisableHeader{
     
    8071  };
    8172
    82   struct _NetworkExport synchronisableVariable{
    83     size_t size;
    84     uint8_t mode; // this determines in which direction the variable gets synchronised
    85     void *var;
    86     variableType type;
    87     NetworkCallbackBase *callback;
    88     void *varBuffer;
    89     uint8_t varReference;
    90   };
    9173
    9274  /**
     
    10183    virtual ~Synchronisable();
    10284
    103 
    104     virtual bool create();
    10585    static void setClient(bool b);
    10686
     
    11595  protected:
    11696    Synchronisable(BaseObject* creator);
    117     void registerVariable(void *var, int size, variableType t, uint8_t mode=0x1, NetworkCallbackBase *cb=0);
    118     void unregisterVariable(void *var);
     97//     void registerVariable(void *var, int size, variableType t, uint8_t mode=0x1, NetworkCallbackBase *cb=0);
     98    template <class T> void registerVariable(T& variable, uint8_t mode=0x1, NetworkCallbackBase *cb=0, bool bidirectional=false);
     99    template <class T> void unregisterVariable(T& var);
    119100    void setObjectMode(uint8_t mode);
    120101    void setObjectFrequency(unsigned int freq){ objectFrequency_ = freq; }
     
    133114    unsigned int classID;
    134115
    135     std::list<synchronisableVariable *> *syncList;
     116    std::list<SynchronisableVariableBase*> syncList;
    136117    static uint8_t state_; // detemines wheter we are server (default) or client
    137118    bool backsync_; // if true the variables with mode > 1 will be synchronised to server (client -> server)
     
    141122    static std::queue<unsigned int> deletedObjects_;
    142123  };
     124 
     125  template <class T> void Synchronisable::registerVariable(T& variable, uint8_t mode, NetworkCallbackBase *cb, bool bidirectional)
     126  {
     127    if (bidirectional)
     128      syncList.push_back(new SynchronisableVariableBidirectional<const T>(variable, mode, cb));
     129    else
     130      syncList.push_back(new SynchronisableVariable<const T>(variable, mode, cb));
     131  }
     132
     133  template <class T> void Synchronisable::unregisterVariable(T& var){
     134    std::list<SynchronisableVariableBase*>::iterator it = syncList.begin();
     135    while(it!=syncList.end()){
     136      if( ((*it)->getReference()) == &var ){
     137        delete (*it);
     138        syncList.erase(it);
     139        return;
     140      }
     141      else
     142        it++;
     143    }
     144    bool unregistered_nonexistent_variable = false;
     145    assert(unregistered_nonexistent_variable); //if we reach this point something went wrong:
     146    // the variable has not been registered before
     147  }
     148 
     149  // ================= Specialisation declarations
     150  template <> void Synchronisable::registerVariable( const ColourValue& variable, uint8_t mode, NetworkCallbackBase* cb, bool bidirectional);template <> void Synchronisable::registerVariable( const ColourValue& variable, uint8_t mode, NetworkCallbackBase* cb, bool bidirectional);
     151  template <> void Synchronisable::registerVariable( ColourValue& variable, uint8_t mode, NetworkCallbackBase* cb, bool bidirectional);
     152  template <> void Synchronisable::registerVariable( const Vector2& variable, uint8_t mode, NetworkCallbackBase* cb, bool bidirectional);
     153  template <> void Synchronisable::registerVariable( Vector2& variable, uint8_t mode, NetworkCallbackBase* cb, bool bidirectional);
     154  template <> void Synchronisable::registerVariable( const Vector3& variable, uint8_t mode, NetworkCallbackBase* cb, bool bidirectional);
     155  template <> void Synchronisable::registerVariable( Vector3& variable, uint8_t mode, NetworkCallbackBase* cb, bool bidirectional);
     156  template <> void Synchronisable::registerVariable( const Vector4& variable, uint8_t mode, NetworkCallbackBase* cb, bool bidirectional);
     157  template <> void Synchronisable::registerVariable( Vector4& variable, uint8_t mode, NetworkCallbackBase* cb, bool bidirectional);
     158  template <> void Synchronisable::registerVariable( mbool& variable, uint8_t mode, NetworkCallbackBase* cb, bool bidirectional);
     159  template <> void Synchronisable::registerVariable( const Quaternion& variable, uint8_t mode, NetworkCallbackBase* cb, bool bidirectional);
     160  template <> void Synchronisable::registerVariable( Quaternion& variable, uint8_t mode, NetworkCallbackBase* cb, bool bidirectional);
     161//   template <> void Synchronisable::registerVariable( LODParticle::LOD& variable, uint8_t mode, NetworkCallbackBase* cb, bool bidirectional);
     162//   template <> void Synchronisable::registerVariable( Ogre::Light::LightTypes& variable, uint8_t mode, NetworkCallbackBase* cb, bool bidirectional);
    143163}
    144164
Note: See TracChangeset for help on using the changeset viewer.