Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

Ignore:
Timestamp:
Aug 11, 2010, 8:55:13 AM (14 years ago)
Author:
dafrick
Message:

Merged presentation3 branch into trunk.

Location:
code/trunk
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • code/trunk

  • code/trunk/src/libraries/network/synchronisable/Serialise.h

    r6417 r7163  
    3838#include "util/TypeTraits.h"
    3939#include "core/CorePrereqs.h"
     40#include "core/CoreIncludes.h"
     41#include "core/SmartPtr.h"
    4042
    4143namespace orxonox{
     
    7274            return *(uint32_t*)(mem) == variable->getObjectID();
    7375        else
     76            return variable == variable->getSynchronisable(*(uint32_t*)(mem));
     77    }
     78   
     79    // These functions implement loading / saving / etc. for SmartPtr<T>
     80   
     81    /** @brief returns the size of the objectID needed to synchronise the pointer */
     82    template <class T> inline uint32_t returnSize( const SmartPtr<T>& variable )
     83    {
     84        return sizeof(uint32_t);
     85    }
     86   
     87    /** @brief reads the objectID of a pointer out of the bytestream and increases the mem pointer */
     88    template <class T> inline void loadAndIncrease( const SmartPtr<T>& variable, uint8_t*& mem )
     89    {
     90//         *const_cast<typename Loki::TypeTraits<T*>::UnqualifiedType*>(&variable) = dynamic_cast<T*>(variable->getSynchronisable( *(uint32_t*)(mem) ));
     91        *const_cast<typename Loki::TypeTraits<SmartPtr<T> >::UnqualifiedType*>(&variable) = orxonox_cast<T*>(T::getSynchronisable(*(uint32_t*)(mem)));
     92        mem += returnSize( variable );
     93    }
     94   
     95    /** @brief saves the objectID of a pointer into the bytestream and increases the mem pointer */
     96    template <class T> inline void saveAndIncrease( const SmartPtr<T>& variable, uint8_t*& mem )
     97    {
     98        if ( variable.get() )
     99            *(uint32_t*)(mem) = static_cast<uint32_t>(variable->getObjectID());
     100        else
     101            *(uint32_t*)(mem) = OBJECTID_UNKNOWN;
     102        mem += returnSize( variable );
     103    }
     104   
     105    /** @brief checks whether the objectID of the variable is the same as in the bytestream */
     106    template <class T> inline  bool checkEquality( const SmartPtr<T>& variable, uint8_t* mem )
     107    {
     108        if ( variable.get() )
     109            return *(uint32_t*)(mem) == variable->getObjectID();
     110        else
     111            return *(uint32_t*)(mem) == OBJECTID_UNKNOWN;
     112    }
     113   
     114    // These functions implement loading / saving / etc. for WeakPtr<T>
     115   
     116    /** @brief returns the size of the objectID needed to synchronise the pointer */
     117    template <class T> inline uint32_t returnSize( const WeakPtr<T>& variable )
     118    {
     119        return sizeof(uint32_t);
     120    }
     121   
     122    /** @brief reads the objectID of a pointer out of the bytestream and increases the mem pointer */
     123    template <class T> inline void loadAndIncrease( const WeakPtr<T>& variable, uint8_t*& mem )
     124    {
     125        //         *const_cast<typename Loki::TypeTraits<T*>::UnqualifiedType*>(&variable) = dynamic_cast<T*>(variable->getSynchronisable( *(uint32_t*)(mem) ));
     126        *const_cast<typename Loki::TypeTraits<SmartPtr<T> >::UnqualifiedType*>(&variable) = orxonox_cast<T*>(T::getSynchronisable(*(uint32_t*)(mem)));
     127        mem += returnSize( variable );
     128    }
     129   
     130    /** @brief saves the objectID of a pointer into the bytestream and increases the mem pointer */
     131    template <class T> inline void saveAndIncrease( const WeakPtr<T>& variable, uint8_t*& mem )
     132    {
     133        if ( variable.get() )
     134            *(uint32_t*)(mem) = static_cast<uint32_t>(variable->getObjectID());
     135        else
     136            *(uint32_t*)(mem) = OBJECTID_UNKNOWN;
     137        mem += returnSize( variable );
     138    }
     139   
     140    /** @brief checks whether the objectID of the variable is the same as in the bytestream */
     141    template <class T> inline  bool checkEquality( const WeakPtr<T>& variable, uint8_t* mem )
     142    {
     143        if ( variable.get() )
     144            return *(uint32_t*)(mem) == variable->getObjectID();
     145        else
    74146            return *(uint32_t*)(mem) == OBJECTID_UNKNOWN;
    75147    }
  • code/trunk/src/libraries/network/synchronisable/Synchronisable.cc

    r6417 r7163  
    4949  * Initializes all Variables and sets the right objectID_
    5050  */
    51   Synchronisable::Synchronisable(BaseObject* creator ){
     51  Synchronisable::Synchronisable(BaseObject* creator )
     52  {
    5253    RegisterRootObject(Synchronisable);
    5354    static uint32_t idCounter=0;
    5455    objectMode_=0x1; // by default do not send data to server
    55     if ( GameMode::isMaster() || ( Host::running() && Host::isServer() ) )
     56    if ( GameMode::isMaster()/* || ( Host::running() && Host::isServer() )*/ )
    5657    {
    5758      this->setObjectID( idCounter++ );
     
    7374    else
    7475      this->creatorID_ = OBJECTID_UNKNOWN;
    75 
    76     /*searchcreatorID:
    77     if (creator)
    78     {
    79         Synchronisable* synchronisable_creator = orxonox_cast<Synchronisable*>(creator);
    80         if (synchronisable_creator && synchronisable_creator->objectMode_)
    81         {
    82             this->creatorID = synchronisable_creator->getScene()->getObjectID();
    83         }
    84         else if (creator != creator->getCreator())
    85         {
    86             creator = creator->getCreator();
    87             goto searchcreatorID;
    88         }
    89     }*/
    9076  }
    9177
     
    9480   * Delete all callback objects and remove objectID_ from the objectMap_
    9581   */
    96   Synchronisable::~Synchronisable(){
     82  Synchronisable::~Synchronisable()
     83  {
    9784    // delete callback function objects
    9885    if(!Identifier::isCreatingHierarchy()){
     
    10188        deletedObjects_.push(objectID_);
    10289    }
    103     // delete all Synchronisable Variables from syncList ( which are also in stringList )
    104     for(std::vector<SynchronisableVariableBase*>::iterator it = syncList.begin(); it!=syncList.end(); it++)
     90    // delete all Synchronisable Variables from syncList_ ( which are also in stringList_ )
     91    for(std::vector<SynchronisableVariableBase*>::iterator it = syncList_.begin(); it!=syncList_.end(); it++)
    10592      delete (*it);
    106     syncList.clear();
    107     stringList.clear();
     93    syncList_.clear();
     94    stringList_.clear();
    10895    std::map<uint32_t, Synchronisable*>::iterator it;
    10996    it = objectMap_.find(objectID_);
     
    118105   * @param b true if this object is located on a client or on a server
    119106   */
    120   void Synchronisable::setClient(bool b){
     107  void Synchronisable::setClient(bool b)
     108  {
    121109    if(b) // client
    122110      state_=0x2;
     
    135123  {
    136124    SynchronisableHeader header(mem);
    137 
    138     if(!header.isDataAvailable())
    139     {
    140       mem += header.getDataSize();
    141       return 0;
    142     }
     125    assert( !header.isDiffed() );
    143126
    144127    COUT(4) << "fabricating object with id: " << header.getObjectID() << std::endl;
     
    160143      if (!synchronisable_creator)
    161144      {
    162         mem += header.getDataSize(); //.TODO: this suckz.... remove size from header
     145        mem += header.getDataSize()+SynchronisableHeader::getSize(); //.TODO: this suckz.... remove size from header
    163146        assert(0); // TODO: uncomment this if we have a clean objecthierarchy (with destruction of children of objects) ^^
    164147        return 0;
     
    177160    no->setClassID(header.getClassID());
    178161    assert(no->creatorID_ == header.getCreatorID());
     162    if( creator )
     163      bo->setLevel(creator->getLevel());          // Note: this ensures that the level is known on the client for child objects of the scene (and the scene itself)
    179164    //assert(no->classID_ == header.getClassID());
    180165    COUT(4) << "fabricate objectID_: " << no->objectID_ << " classID_: " << no->classID_ << std::endl;
     
    196181   * @return true/false
    197182   */
    198   bool Synchronisable::deleteObject(uint32_t objectID_){
     183  bool Synchronisable::deleteObject(uint32_t objectID_)
     184  {
    199185    if(!getSynchronisable(objectID_))
    200186      return false;
     
    213199   * @return pointer to the Synchronisable with the objectID_
    214200   */
    215   Synchronisable* Synchronisable::getSynchronisable(uint32_t objectID_){
     201  Synchronisable* Synchronisable::getSynchronisable(uint32_t objectID_)
     202  {
    216203    std::map<uint32_t, Synchronisable*>::iterator it1;
    217204    it1 = objectMap_.find(objectID_);
    218205    if (it1 != objectMap_.end())
    219206      return it1->second;
    220 
    221 //     ObjectList<Synchronisable>::iterator it;
    222 //     for(it = ObjectList<Synchronisable>::begin(); it; ++it){
    223 //       if( it->getObjectID()==objectID_ ){
    224 //         objectMap_[objectID_] = *it;
    225 //         return *it;
    226 //       }
    227 //     }
    228207    // if the objects not in the map it should'nt exist at all anymore
    229208    return NULL;
     
    245224   * @return true: if !doSync or if everything was successfully saved
    246225   */
    247   uint32_t Synchronisable::getData(uint8_t*& mem, int32_t id, uint8_t mode){
     226  uint32_t Synchronisable::getData(uint8_t*& mem, std::vector<uint32_t>& sizes, int32_t id, uint8_t mode)
     227  {
     228    unsigned int test = 0;
    248229    if(mode==0x0)
    249230      mode=state_;
     
    253234    uint32_t tempsize = 0;
    254235#ifndef NDEBUG
     236    uint8_t* oldmem = mem;
    255237    if (this->classID_==0)
    256238      COUT(3) << "classid 0 " << this->getIdentifier()->getName() << std::endl;
     
    270252    // end copy header
    271253
    272 
    273     COUT(5) << "Synchronisable getting data from objectID_: " << objectID_ << " classID_: " << classID_ << std::endl;
     254    CCOUT(5) << "getting data from objectID_: " << objectID_ << ", classID_: " << classID_ << std::endl;
     255//     COUT(4) << "objectid: " << this->objectID_ << ":";
    274256    // copy to location
    275     for(i=syncList.begin(); i!=syncList.end(); ++i){
    276       tempsize += (*i)->getData( mem, mode );
     257    for(i=syncList_.begin(); i!=syncList_.end(); ++i)
     258    {
     259      uint32_t varsize = (*i)->getData( mem, mode );
     260//       COUT(4) << " " << varsize;
     261      tempsize += varsize;
     262      sizes.push_back(varsize);
     263      ++test;
    277264      //tempsize += (*i)->getSize( mode );
    278265    }
    279 
    280     tempsize += SynchronisableHeader::getSize();
     266//     COUT(4) << endl;
     267
    281268    header.setObjectID( this->objectID_ );
    282269    header.setCreatorID( this->creatorID_ );
    283270    header.setClassID( this->classID_ );
    284     header.setDataAvailable( true );
    285271    header.setDataSize( tempsize );
     272    assert( tempsize == mem-oldmem-SynchronisableHeader::getSize() );
     273    assert( test == this->getNrOfVariables() );
     274    header.setDiffed(false);
     275    tempsize += SynchronisableHeader::getSize();
    286276
    287277#ifndef NDEBUG
     
    300290   * @return true/false
    301291   */
    302   bool Synchronisable::updateData(uint8_t*& mem, uint8_t mode, bool forceCallback){
     292  bool Synchronisable::updateData(uint8_t*& mem, uint8_t mode, bool forceCallback)
     293  {
    303294    if(mode==0x0)
    304295      mode=state_;
    305     std::vector<SynchronisableVariableBase *>::iterator i;
    306     if(syncList.empty()){
     296    if(syncList_.empty())
     297    {
    307298      assert(0);
    308       COUT(4) << "Synchronisable::updateData syncList is empty" << std::endl;
     299      COUT(2) << "Synchronisable::updateData syncList_ is empty" << std::endl;
    309300      return false;
    310301    }
     
    312303    uint8_t* data=mem;
    313304    // start extract header
    314     SynchronisableHeader syncHeader(mem);
    315     assert(syncHeader.getObjectID()==this->objectID_);
    316     assert(syncHeader.getCreatorID()==this->creatorID_);
    317     assert(syncHeader.getClassID()==this->classID_);
    318     if(syncHeader.isDataAvailable()==false){
    319       mem += syncHeader.getDataSize();
    320       return true;
    321     }
    322 
    323     mem += SynchronisableHeader::getSize();
    324     // stop extract header
     305    SynchronisableHeaderLight syncHeaderLight(mem);
     306    assert(syncHeaderLight.getObjectID()==this->getObjectID());
    325307
    326308    //COUT(5) << "Synchronisable: objectID_ " << syncHeader.getObjectID() << ", classID_ " << syncHeader.getClassID() << " size: " << syncHeader.getDataSize() << " synchronising data" << std::endl;
    327     for(i=syncList.begin(); i!=syncList.end(); i++)
    328     {
    329       assert( mem <= data+syncHeader.getDataSize() ); // always make sure we don't exceed the datasize in our stream
    330       (*i)->putData( mem, mode, forceCallback );
    331     }
    332     assert(mem == data+syncHeader.getDataSize());
     309    if( !syncHeaderLight.isDiffed() )
     310    {
     311      SynchronisableHeader syncHeader2(mem);
     312      assert( this->getClassID() == syncHeader2.getClassID() );
     313      assert( this->getCreatorID() == syncHeader2.getCreatorID() );
     314      mem += SynchronisableHeader::getSize();
     315      std::vector<SynchronisableVariableBase *>::iterator i;
     316      for(i=syncList_.begin(); i!=syncList_.end(); i++)
     317      {
     318        assert( mem <= data+syncHeader2.getDataSize()+SynchronisableHeader::getSize() ); // always make sure we don't exceed the datasize in our stream
     319        (*i)->putData( mem, mode, forceCallback );
     320      }
     321      assert(mem == data+syncHeaderLight.getDataSize()+SynchronisableHeader::getSize() );
     322    }
     323    else
     324    {
     325      mem += SynchronisableHeaderLight::getSize();
     326//       COUT(0) << "objectID: " << this->objectID_ << endl;
     327      while( mem < data+syncHeaderLight.getDataSize()+SynchronisableHeaderLight::getSize() )
     328      {
     329        VariableID varID = *(VariableID*)mem;
     330//         COUT(0) << "varID: " << varID << endl;
     331        assert( varID < syncList_.size() );
     332        mem += sizeof(VariableID);
     333        syncList_[varID]->putData( mem, mode, forceCallback );
     334      }
     335      assert(mem == data+syncHeaderLight.getDataSize()+SynchronisableHeaderLight::getSize() );
     336    }
    333337    return true;
    334338  }
     
    340344  * @return amount of bytes
    341345  */
    342   uint32_t Synchronisable::getSize(int32_t id, uint8_t mode){
    343     int tsize=SynchronisableHeader::getSize();
     346  uint32_t Synchronisable::getSize(int32_t id, uint8_t mode)
     347  {
     348    uint32_t tsize=SynchronisableHeader::getSize();
    344349    if (mode==0x0)
    345350      mode=state_;
     
    349354    tsize += this->dataSize_;
    350355    std::vector<SynchronisableVariableBase*>::iterator i;
    351     for(i=stringList.begin(); i!=stringList.end(); ++i){
     356    for(i=stringList_.begin(); i!=stringList_.end(); ++i)
     357    {
    352358      tsize += (*i)->getSize( mode );
    353359    }
     
    360366   * @return true/false
    361367   */
    362   bool Synchronisable::doSync(int32_t id, uint8_t mode){
     368  bool Synchronisable::doSync(int32_t id, uint8_t mode)
     369  {
    363370    if(mode==0x0)
    364371      mode=state_;
    365     return ( (this->objectMode_ & mode)!=0 && (!syncList.empty() ) );
    366   }
    367 
    368   /**
    369    * This function looks at the header located in the bytestream and checks wheter objectID_ and classID_ match with the Synchronisables ones
    370    * @param mem pointer to the bytestream
    371    */
    372   bool Synchronisable::isMyData(uint8_t* mem)
    373   {
    374     SynchronisableHeader header(mem);
    375     assert(header.getObjectID()==this->objectID_);
    376     return header.isDataAvailable();
     372    return ( (this->objectMode_ & mode)!=0 && (!syncList_.empty() ) );
    377373  }
    378374
     
    385381   * @param mode same as in registerVar
    386382   */
    387   void Synchronisable::setSyncMode(uint8_t mode){
     383  void Synchronisable::setSyncMode(uint8_t mode)
     384  {
    388385    assert(mode==0x0 || mode==0x1 || mode==0x2 || mode==0x3);
    389386    this->objectMode_=mode;
     
    397394    else
    398395      sv = new SynchronisableVariable<std::string>(variable, mode, cb);
    399     syncList.push_back(sv);
    400     stringList.push_back(sv);
     396    syncList_.push_back(sv);
     397    stringList_.push_back(sv);
     398  }
     399
     400template <> void Synchronisable::unregisterVariable( std::string& variable )
     401  {
     402    bool unregistered_nonexistent_variable = true;
     403    std::vector<SynchronisableVariableBase*>::iterator it = syncList_.begin();
     404    while(it!=syncList_.end())
     405    {
     406      if( ((*it)->getReference()) == &variable )
     407      {
     408        delete (*it);
     409        syncList_.erase(it);
     410        unregistered_nonexistent_variable = false;
     411        break;
     412      }
     413      else
     414        ++it;
     415    }
     416    assert(unregistered_nonexistent_variable == false);
     417   
     418    it = stringList_.begin();
     419    while(it!=stringList_.end())
     420    {
     421      if( ((*it)->getReference()) == &variable )
     422      {
     423        delete (*it);
     424        stringList_.erase(it);
     425        return;
     426      }
     427      else
     428        ++it;
     429    }
     430    unregistered_nonexistent_variable = true;
     431    assert(unregistered_nonexistent_variable == false); //if we reach this point something went wrong:
     432    // the variable has not been registered before
    401433  }
    402434
  • code/trunk/src/libraries/network/synchronisable/Synchronisable.h

    r6417 r7163  
    3737#include <map>
    3838#include <queue>
     39#include <set>
    3940
    4041#include "util/mbool.h"
     
    6465    };
    6566  }
     67 
     68  typedef uint8_t VariableID;
    6669
    6770  /**
     
    7174   * in an emulated bitset.
    7275   * Bit 1 to 31 store the size of the Data the synchronisable consumes in the stream
    73    * Bit 32 is a bool and defines whether the data is actually stored or is just filled up with 0
     76   * Bit 32 is a bool and defines whether the variables are stored in diff mode
    7477   * Byte 5 to 8: objectID_
    7578   * Byte 9 to 12: classID_
     
    7780   */
    7881  class _NetworkExport SynchronisableHeader{
     82    friend class SynchronisableHeaderLight;
    7983    private:
    80       uint8_t *data_;
     84      uint8_t* data_;
    8185    public:
    8286      SynchronisableHeader(uint8_t* data)
    8387        { data_ = data; }
    8488      inline static uint32_t getSize()
    85         { return 16; }
    86       inline uint32_t getDataSize() const
    87         { return (*(uint32_t*)data_) & 0x7FFFFFFF; } //only use the first 31 bits
    88       inline void setDataSize(uint32_t size)
    89         { *(uint32_t*)(data_) = (size & 0x7FFFFFFF) | (*(uint32_t*)(data_) & 0x80000000 ); }
    90       inline bool isDataAvailable() const
    91         { return ( (*(uint32_t*)data_) & 0x80000000 ) == 0x80000000; }
    92       inline void setDataAvailable( bool b)
    93         { *(uint32_t*)(data_) = (b << 31) | (*(uint32_t*)(data_) & 0x7FFFFFFF ); }
     89        { return 14; }
     90      inline uint16_t getDataSize() const
     91        { return (*(uint16_t*)data_) & 0x7FFF; } //only use the first 15 bits
     92      inline void setDataSize(uint16_t size)
     93        { *(uint16_t*)(data_) = (size & 0x7FFF) | (*(uint16_t*)(data_) & 0x8000 ); }
     94      inline bool isDiffed() const
     95        { return ( (*(uint16_t*)data_) & 0x8000 ) == 0x8000; }
     96      inline void setDiffed( bool b)
     97        { *(uint16_t*)(data_) = (b << 15) | (*(uint16_t*)(data_) & 0x7FFF ); }
    9498      inline uint32_t getObjectID() const
    95         { return *(uint32_t*)(data_+4); }
     99        { return *(uint32_t*)(data_+2); }
    96100      inline void setObjectID(uint32_t objectID_)
    97         { *(uint32_t*)(data_+4) = objectID_; }
     101        { *(uint32_t*)(data_+2) = objectID_; }
    98102      inline uint32_t getClassID() const
    99         { return *(uint32_t*)(data_+8); }
     103        { return *(uint32_t*)(data_+6); }
    100104      inline void setClassID(uint32_t classID_)
    101         { *(uint32_t*)(data_+8) = classID_; }
     105        { *(uint32_t*)(data_+6) = classID_; }
    102106      inline uint32_t getCreatorID() const
    103         { return *(uint32_t*)(data_+12); }
     107        { return *(uint32_t*)(data_+10); }
    104108      inline void setCreatorID(uint32_t creatorID_)
    105         { *(uint32_t*)(data_+12) = creatorID_; }
     109        { *(uint32_t*)(data_+10) = creatorID_; }
    106110      inline void operator=(SynchronisableHeader& h)
    107111        { memcpy(data_, h.data_, getSize()); }
    108112  };
    109113
     114    /**
     115   * @brief: stores information about a Synchronisable (light version)
     116   *
     117   * This class stores the information about a Synchronisable (objectID_, dataSize)
     118   * in an emulated bitset.
     119   * Bit 1 to 31 store the size of the Data the synchronisable consumes in the stream
     120   * Bit 32 is a bool and defines whether the variables are stored in diff mode
     121   * Byte 5 to 8: objectID_
     122   */
     123  class _NetworkExport SynchronisableHeaderLight{
     124    private:
     125      uint8_t* data_;
     126    public:
     127      SynchronisableHeaderLight(uint8_t* data)
     128        { data_ = data; }
     129      inline static uint32_t getSize()
     130        { return 6; }
     131      inline uint16_t getDataSize() const
     132        { return (*(uint16_t*)data_) & 0x7FFF; } //only use the first 31 bits
     133      inline void setDataSize(uint16_t size)
     134        { *(uint16_t*)(data_) = (size & 0x7FFFFFFF) | (*(uint16_t*)(data_) & 0x8000 ); }
     135      inline bool isDiffed() const
     136        { return ( (*(uint16_t*)data_) & 0x8000 ) == 0x8000; }
     137      inline void setDiffed( bool b)
     138        { *(uint16_t*)(data_) = (b << 15) | (*(uint16_t*)(data_) & 0x7FFF ); }
     139      inline uint32_t getObjectID() const
     140        { return *(uint32_t*)(data_+2); }
     141      inline void setObjectID(uint32_t objectID_)
     142        { *(uint32_t*)(data_+2) = objectID_; }
     143      inline void operator=(SynchronisableHeader& h)
     144        { memcpy(data_, h.data_, getSize()); }
     145  };
    110146
    111147  /**
     
    134170
    135171    void setSyncMode(uint8_t mode);
     172   
     173    inline uint32_t getNrOfVariables(){ return this->syncList_.size(); }
     174    inline uint32_t getVarSize( VariableID ID )
     175    { return this->syncList_[ID]->getSize(state_); }
    136176
    137177  protected:
    138178    Synchronisable(BaseObject* creator);
    139179    template <class T> void registerVariable(T& variable, uint8_t mode=0x1, NetworkCallbackBase *cb=0, bool bidirectional=false);
     180    template <class T> void registerVariable(std::set<T>& variable, uint8_t mode=0x1, NetworkCallbackBase *cb=0, bool bidirectional=false);
     181    template <class T> void unregisterVariable(T& var);
    140182
    141183    void setPriority(unsigned int freq){ objectFrequency_ = freq; }
     
    143185
    144186  private:
    145     uint32_t getData(uint8_t*& men, int32_t id, uint8_t mode=0x0);
     187    uint32_t getData(uint8_t*& mem, std::vector<uint32_t>& sizes, int32_t id, uint8_t mode);
    146188    uint32_t getSize(int32_t id, uint8_t mode=0x0);
    147189    bool updateData(uint8_t*& mem, uint8_t mode=0x0, bool forceCallback=false);
    148     bool isMyData(uint8_t* mem);
    149190    bool doSync(int32_t id, uint8_t mode=0x0);
    150191
     
    156197    uint32_t classID_;
    157198
    158     std::vector<SynchronisableVariableBase*> syncList;
    159     std::vector<SynchronisableVariableBase*> stringList;
     199    std::vector<SynchronisableVariableBase*> syncList_;
     200    std::vector<SynchronisableVariableBase*> stringList_;
    160201    uint32_t dataSize_; //size of all variables except strings
    161202    static uint8_t state_; // detemines wheter we are server (default) or client
     
    171212    if (bidirectional)
    172213    {
    173       syncList.push_back(new SynchronisableVariableBidirectional<T>(variable, mode, cb));
    174       this->dataSize_ += syncList.back()->getSize(state_);
     214      syncList_.push_back(new SynchronisableVariableBidirectional<T>(variable, mode, cb));
     215      this->dataSize_ += syncList_.back()->getSize(state_);
    175216    }
    176217    else
    177218    {
    178       syncList.push_back(new SynchronisableVariable<T>(variable, mode, cb));
     219      syncList_.push_back(new SynchronisableVariable<T>(variable, mode, cb));
    179220      if ( this->state_ == mode )
    180         this->dataSize_ += syncList.back()->getSize(state_);
     221        this->dataSize_ += syncList_.back()->getSize(state_);
    181222    }
    182223  }
     224 
     225  template <class T> void Synchronisable::unregisterVariable(T& variable){
     226    std::vector<SynchronisableVariableBase*>::iterator it = syncList_.begin();
     227    while(it!=syncList_.end()){
     228      if( ((*it)->getReference()) == &variable ){
     229        this->dataSize_ -= (*it)->getSize(Synchronisable::state_);
     230        delete (*it);
     231        syncList_.erase(it);
     232        return;
     233      }
     234      else
     235        it++;
     236    }
     237    bool unregistered_nonexistent_variable = false;
     238    assert(unregistered_nonexistent_variable); //if we reach this point something went wrong:
     239    // the variable has not been registered before
     240  }
     241
     242  template <class T> void Synchronisable::registerVariable( std::set<T>& variable, uint8_t mode, NetworkCallbackBase *cb, bool bidirectional)
     243  {
     244    SynchronisableVariableBase* sv;
     245    if (bidirectional)
     246      sv = new SynchronisableVariableBidirectional<std::set<T> >(variable, mode, cb);
     247    else
     248      sv = new SynchronisableVariable<std::set<T> >(variable, mode, cb);
     249    syncList_.push_back(sv);
     250    stringList_.push_back(sv);
     251  }
    183252
    184253  template <> _NetworkExport void Synchronisable::registerVariable( std::string& variable, uint8_t mode, NetworkCallbackBase *cb, bool bidirectional);
     254//   template <class T> _NetworkExport void Synchronisable::registerVariable<std::set<T> >( std::set<T>& variable, uint8_t mode, NetworkCallbackBase *cb, bool bidirectional);
     255  template <> _NetworkExport void Synchronisable::unregisterVariable( std::string& variable );
    185256
    186257
Note: See TracChangeset for help on using the changeset viewer.