Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/trunk/src/libraries/network/synchronisable/Synchronisable.h @ 8781

Last change on this file since 8781 was 8706, checked in by dafrick, 13 years ago

Merging presentation branch back into trunk.
There are many new features and also a lot of other changes and bugfixes, if you want to know, digg through the svn log.
Not everything is yet working as it should, but it should be fairly stable. If you habe any bug reports, just send me an email.

  • Property svn:eol-style set to native
File size: 9.3 KB
RevLine 
[1505]1/*
2 *   ORXONOX - the hottest 3D action shooter ever to exist
3 *                    > www.orxonox.net <
4 *
5 *
6 *   License notice:
7 *
8 *   This program is free software; you can redistribute it and/or
9 *   modify it under the terms of the GNU General Public License
10 *   as published by the Free Software Foundation; either version 2
11 *   of the License, or (at your option) any later version.
12 *
13 *   This program is distributed in the hope that it will be useful,
14 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
15 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 *   GNU General Public License for more details.
17 *
18 *   You should have received a copy of the GNU General Public License
19 *   along with this program; if not, write to the Free Software
20 *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
21 *
22 *   Author:
23 *      Oliver Scheuss, (C) 2007
24 *   Co-authors:
25 *      ...
26 *
27 */
28
29#ifndef _Synchronisable_H__
30#define _Synchronisable_H__
31
[2211]32#include "network/NetworkPrereqs.h"
[1505]33
[3214]34#include <cassert>
35#include <cstring>
[3084]36#include <vector>
[1907]37#include <map>
38#include <queue>
[7163]39#include <set>
[3214]40
[2245]41#include "util/mbool.h"
[1505]42#include "core/OrxonoxClass.h"
[3214]43#include "SynchronisableVariable.h"
[1534]44#include "NetworkCallback.h"
[1505]45
[1907]46
[2171]47namespace orxonox
[1505]48{
[2087]49
[3280]50  namespace ObjectDirection{
51    enum Value{
[8706]52      None=0x0,
[3280]53      ToClient=0x1,
54      ToServer=0x2,
55      Bidirectional=0x3
[1907]56    };
57  }
[2485]58
[3280]59  namespace Priority{
60    enum Value{
61      VeryHigh    = -100,
62      High        = -15,
63      Normal      = 0,
64      Low         = 15,
65      VeryLow     = 100
[2415]66    };
67  }
[2087]68
[7801]69    /**
70   * @brief: stores information about a Synchronisable (light version)
[6417]71   *
[7801]72   * This class stores the information about a Synchronisable (objectID_, dataSize)
[2662]73   * in an emulated bitset.
74   * Bit 1 to 31 store the size of the Data the synchronisable consumes in the stream
[7163]75   * Bit 32 is a bool and defines whether the variables are stored in diff mode
[5929]76   * Byte 5 to 8: objectID_
[2662]77   */
[7801]78  class _NetworkExport SynchronisableHeaderLight
79  {
80    protected:
[7163]81      uint8_t* data_;
[2662]82    public:
[7801]83      SynchronisableHeaderLight(uint8_t* data)
[2662]84        { data_ = data; }
85      inline static uint32_t getSize()
[7801]86        { return 6; }
[7163]87      inline uint16_t getDataSize() const
[7801]88        { return (*(uint16_t*)data_) & 0x7FFF; } //only use the first 31 bits
[7163]89      inline void setDataSize(uint16_t size)
[7801]90        { *(uint16_t*)(data_) = (size & 0x7FFFFFFF) | (*(uint16_t*)(data_) & 0x8000 ); }
[7163]91      inline bool isDiffed() const
92        { return ( (*(uint16_t*)data_) & 0x8000 ) == 0x8000; }
93      inline void setDiffed( bool b)
94        { *(uint16_t*)(data_) = (b << 15) | (*(uint16_t*)(data_) & 0x7FFF ); }
[2662]95      inline uint32_t getObjectID() const
[7163]96        { return *(uint32_t*)(data_+2); }
[5929]97      inline void setObjectID(uint32_t objectID_)
[7163]98        { *(uint32_t*)(data_+2) = objectID_; }
[7801]99      inline void operator=(SynchronisableHeaderLight& h)
100        { memcpy(data_, h.data_, SynchronisableHeaderLight::getSize()); }
[1505]101  };
[7801]102 
103  typedef uint8_t VariableID;
104 
105  /**
106   * @brief: stores information about a Synchronisable
[7163]107   *
[7801]108   * This class stores the information about a Synchronisable (objectID_, classID_, creatorID_, dataSize)
[7163]109   * in an emulated bitset.
110   * Bit 1 to 31 store the size of the Data the synchronisable consumes in the stream
111   * Bit 32 is a bool and defines whether the variables are stored in diff mode
112   * Byte 5 to 8: objectID_
[7801]113   * Byte 9 to 12: classID_
114   * Byte 13 to 16: creatorID_
[7163]115   */
[7801]116  class _NetworkExport SynchronisableHeader: public SynchronisableHeaderLight
117  {
[7163]118    public:
[7801]119      SynchronisableHeader(uint8_t* data): SynchronisableHeaderLight(data)
120        {}
[7163]121      inline static uint32_t getSize()
[7801]122        { return SynchronisableHeaderLight::getSize()+8; }
123      inline uint32_t getClassID() const
124        { return *(uint32_t*)(data_+SynchronisableHeaderLight::getSize()); }
125      inline void setClassID(uint32_t classID_)
126        { *(uint32_t*)(data_+SynchronisableHeaderLight::getSize()) = classID_; }
127      inline uint32_t getCreatorID() const
128        { return *(uint32_t*)(data_+SynchronisableHeaderLight::getSize()+4); }
129      inline void setCreatorID(uint32_t creatorID_)
130        { *(uint32_t*)(data_+SynchronisableHeaderLight::getSize()+4) = creatorID_; }
[7163]131      inline void operator=(SynchronisableHeader& h)
132        { memcpy(data_, h.data_, getSize()); }
133  };
[7801]134 
135//   inline void operator=(SynchronisableHeaderLight& h1, SynchronisableHeader& h2)
136//   {
137//     memcpy(h1.data_, h2.data_, h1.getSize());
138//   }
[1505]139
140  /**
141  * This class is the base class of all the Objects in the universe that need to be synchronised over the network
[2662]142  * Every class, that inherits from this class has to link the DATA THAT NEEDS TO BE SYNCHRONISED into the linked list.
[1505]143  * @author Oliver Scheuss
144  */
[2171]145  class _NetworkExport Synchronisable : virtual public OrxonoxClass{
[1505]146  public:
[1907]147    friend class packet::Gamestate;
[1505]148    virtual ~Synchronisable();
149
150    static void setClient(bool b);
[2087]151
[2171]152    static Synchronisable *fabricate(uint8_t*& mem, uint8_t mode=0x0);
[5929]153    static bool deleteObject(uint32_t objectID_);
154    static Synchronisable *getSynchronisable(uint32_t objectID_);
[1907]155    static unsigned int getNumberOfDeletedObject(){ return deletedObjects_.size(); }
[2309]156    static uint32_t popDeletedObject(){ uint32_t i = deletedObjects_.front(); deletedObjects_.pop(); return i; }
[2087]157
[5929]158    inline uint32_t getObjectID() const {return this->objectID_;}
159    inline unsigned int getCreatorID() const {return this->creatorID_;}
160    inline uint32_t getClassID() const {return this->classID_;}
161    inline unsigned int getPriority() const { return this->objectFrequency_;}
162    inline uint8_t getSyncMode() const { return this->objectMode_; }
[6417]163
[5929]164    void setSyncMode(uint8_t mode);
[7163]165   
166    inline uint32_t getNrOfVariables(){ return this->syncList_.size(); }
167    inline uint32_t getVarSize( VariableID ID )
168    { return this->syncList_[ID]->getSize(state_); }
[2355]169
[1505]170  protected:
[2171]171    Synchronisable(BaseObject* creator);
[2245]172    template <class T> void registerVariable(T& variable, uint8_t mode=0x1, NetworkCallbackBase *cb=0, bool bidirectional=false);
[7163]173    template <class T> void registerVariable(std::set<T>& variable, uint8_t mode=0x1, NetworkCallbackBase *cb=0, bool bidirectional=false);
174    template <class T> void unregisterVariable(T& var);
[6417]175
[2415]176    void setPriority(unsigned int freq){ objectFrequency_ = freq; }
[2087]177
178
[1505]179  private:
[7163]180    uint32_t getData(uint8_t*& mem, std::vector<uint32_t>& sizes, int32_t id, uint8_t mode);
[2309]181    uint32_t getSize(int32_t id, uint8_t mode=0x0);
[2171]182    bool updateData(uint8_t*& mem, uint8_t mode=0x0, bool forceCallback=false);
[8329]183    bool doSync(/*int32_t id,*/ uint8_t mode=0x0);
184    bool doReceive( uint8_t mode );
[6417]185
[5929]186    inline void setObjectID(uint32_t id){ this->objectID_ = id; objectMap_[this->objectID_] = this; }
187    inline void setClassID(uint32_t id){ this->classID_ = id; }
[2087]188
[5929]189    uint32_t objectID_;
190    uint32_t creatorID_;
191    uint32_t classID_;
[2087]192
[7163]193    std::vector<SynchronisableVariableBase*> syncList_;
194    std::vector<SynchronisableVariableBase*> stringList_;
[3084]195    uint32_t dataSize_; //size of all variables except strings
[2171]196    static uint8_t state_; // detemines wheter we are server (default) or client
[1505]197    bool backsync_; // if true the variables with mode > 1 will be synchronised to server (client -> server)
[1751]198    unsigned int objectFrequency_;
199    int objectMode_;
[2309]200    static std::map<uint32_t, Synchronisable *> objectMap_;
201    static std::queue<uint32_t> deletedObjects_;
[1505]202  };
[2485]203
[3084]204  template <class T> void Synchronisable::registerVariable(T& variable, uint8_t mode, NetworkCallbackBase *cb, bool bidirectional)
205  {
206    if (bidirectional)
207    {
[7163]208      syncList_.push_back(new SynchronisableVariableBidirectional<T>(variable, mode, cb));
209      this->dataSize_ += syncList_.back()->getSize(state_);
[3084]210    }
211    else
212    {
[7163]213      syncList_.push_back(new SynchronisableVariable<T>(variable, mode, cb));
[3084]214      if ( this->state_ == mode )
[7163]215        this->dataSize_ += syncList_.back()->getSize(state_);
[3084]216    }
217  }
[7163]218 
[8314]219  template <class T> void Synchronisable::unregisterVariable(T& variable)
220  {
[7163]221    std::vector<SynchronisableVariableBase*>::iterator it = syncList_.begin();
[8314]222    while(it!=syncList_.end())
223    {
224      if( ((*it)->getReference()) == &variable )
225      {
[7163]226        this->dataSize_ -= (*it)->getSize(Synchronisable::state_);
227        delete (*it);
228        syncList_.erase(it);
229        return;
230      }
231      else
232        it++;
233    }
[8314]234    COUT(1) << "Tried to unregister not registered variable" << endl;
235    assert(false); //if we reach this point something went wrong:
[7163]236    // the variable has not been registered before
237  }
[3084]238
[7163]239  template <class T> void Synchronisable::registerVariable( std::set<T>& variable, uint8_t mode, NetworkCallbackBase *cb, bool bidirectional)
240  {
241    SynchronisableVariableBase* sv;
242    if (bidirectional)
243      sv = new SynchronisableVariableBidirectional<std::set<T> >(variable, mode, cb);
244    else
245      sv = new SynchronisableVariable<std::set<T> >(variable, mode, cb);
246    syncList_.push_back(sv);
247    stringList_.push_back(sv);
248  }
249
[6417]250  template <> _NetworkExport void Synchronisable::registerVariable( std::string& variable, uint8_t mode, NetworkCallbackBase *cb, bool bidirectional);
[7163]251//   template <class T> _NetworkExport void Synchronisable::registerVariable<std::set<T> >( std::set<T>& variable, uint8_t mode, NetworkCallbackBase *cb, bool bidirectional);
252  template <> _NetworkExport void Synchronisable::unregisterVariable( std::string& variable );
[3084]253
254
[1505]255}
256
257#endif /* _Synchronisable_H__ */
Note: See TracBrowser for help on using the repository browser.