Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/output/src/libraries/network/synchronisable/Synchronisable.h @ 8805

Last change on this file since 8805 was 8706, checked in by dafrick, 14 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
Line 
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
32#include "network/NetworkPrereqs.h"
33
34#include <cassert>
35#include <cstring>
36#include <vector>
37#include <map>
38#include <queue>
39#include <set>
40
41#include "util/mbool.h"
42#include "core/OrxonoxClass.h"
43#include "SynchronisableVariable.h"
44#include "NetworkCallback.h"
45
46
47namespace orxonox
48{
49
50  namespace ObjectDirection{
51    enum Value{
52      None=0x0,
53      ToClient=0x1,
54      ToServer=0x2,
55      Bidirectional=0x3
56    };
57  }
58
59  namespace Priority{
60    enum Value{
61      VeryHigh    = -100,
62      High        = -15,
63      Normal      = 0,
64      Low         = 15,
65      VeryLow     = 100
66    };
67  }
68
69    /**
70   * @brief: stores information about a Synchronisable (light version)
71   *
72   * This class stores the information about a Synchronisable (objectID_, dataSize)
73   * in an emulated bitset.
74   * Bit 1 to 31 store the size of the Data the synchronisable consumes in the stream
75   * Bit 32 is a bool and defines whether the variables are stored in diff mode
76   * Byte 5 to 8: objectID_
77   */
78  class _NetworkExport SynchronisableHeaderLight
79  {
80    protected:
81      uint8_t* data_;
82    public:
83      SynchronisableHeaderLight(uint8_t* data)
84        { data_ = data; }
85      inline static uint32_t getSize()
86        { return 6; }
87      inline uint16_t getDataSize() const
88        { return (*(uint16_t*)data_) & 0x7FFF; } //only use the first 31 bits
89      inline void setDataSize(uint16_t size)
90        { *(uint16_t*)(data_) = (size & 0x7FFFFFFF) | (*(uint16_t*)(data_) & 0x8000 ); }
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 ); }
95      inline uint32_t getObjectID() const
96        { return *(uint32_t*)(data_+2); }
97      inline void setObjectID(uint32_t objectID_)
98        { *(uint32_t*)(data_+2) = objectID_; }
99      inline void operator=(SynchronisableHeaderLight& h)
100        { memcpy(data_, h.data_, SynchronisableHeaderLight::getSize()); }
101  };
102 
103  typedef uint8_t VariableID;
104 
105  /**
106   * @brief: stores information about a Synchronisable
107   *
108   * This class stores the information about a Synchronisable (objectID_, classID_, creatorID_, dataSize)
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_
113   * Byte 9 to 12: classID_
114   * Byte 13 to 16: creatorID_
115   */
116  class _NetworkExport SynchronisableHeader: public SynchronisableHeaderLight
117  {
118    public:
119      SynchronisableHeader(uint8_t* data): SynchronisableHeaderLight(data)
120        {}
121      inline static uint32_t getSize()
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_; }
131      inline void operator=(SynchronisableHeader& h)
132        { memcpy(data_, h.data_, getSize()); }
133  };
134 
135//   inline void operator=(SynchronisableHeaderLight& h1, SynchronisableHeader& h2)
136//   {
137//     memcpy(h1.data_, h2.data_, h1.getSize());
138//   }
139
140  /**
141  * This class is the base class of all the Objects in the universe that need to be synchronised over the network
142  * Every class, that inherits from this class has to link the DATA THAT NEEDS TO BE SYNCHRONISED into the linked list.
143  * @author Oliver Scheuss
144  */
145  class _NetworkExport Synchronisable : virtual public OrxonoxClass{
146  public:
147    friend class packet::Gamestate;
148    virtual ~Synchronisable();
149
150    static void setClient(bool b);
151
152    static Synchronisable *fabricate(uint8_t*& mem, uint8_t mode=0x0);
153    static bool deleteObject(uint32_t objectID_);
154    static Synchronisable *getSynchronisable(uint32_t objectID_);
155    static unsigned int getNumberOfDeletedObject(){ return deletedObjects_.size(); }
156    static uint32_t popDeletedObject(){ uint32_t i = deletedObjects_.front(); deletedObjects_.pop(); return i; }
157
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_; }
163
164    void setSyncMode(uint8_t mode);
165   
166    inline uint32_t getNrOfVariables(){ return this->syncList_.size(); }
167    inline uint32_t getVarSize( VariableID ID )
168    { return this->syncList_[ID]->getSize(state_); }
169
170  protected:
171    Synchronisable(BaseObject* creator);
172    template <class T> void registerVariable(T& variable, uint8_t mode=0x1, NetworkCallbackBase *cb=0, bool bidirectional=false);
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);
175
176    void setPriority(unsigned int freq){ objectFrequency_ = freq; }
177
178
179  private:
180    uint32_t getData(uint8_t*& mem, std::vector<uint32_t>& sizes, int32_t id, uint8_t mode);
181    uint32_t getSize(int32_t id, uint8_t mode=0x0);
182    bool updateData(uint8_t*& mem, uint8_t mode=0x0, bool forceCallback=false);
183    bool doSync(/*int32_t id,*/ uint8_t mode=0x0);
184    bool doReceive( uint8_t mode );
185
186    inline void setObjectID(uint32_t id){ this->objectID_ = id; objectMap_[this->objectID_] = this; }
187    inline void setClassID(uint32_t id){ this->classID_ = id; }
188
189    uint32_t objectID_;
190    uint32_t creatorID_;
191    uint32_t classID_;
192
193    std::vector<SynchronisableVariableBase*> syncList_;
194    std::vector<SynchronisableVariableBase*> stringList_;
195    uint32_t dataSize_; //size of all variables except strings
196    static uint8_t state_; // detemines wheter we are server (default) or client
197    bool backsync_; // if true the variables with mode > 1 will be synchronised to server (client -> server)
198    unsigned int objectFrequency_;
199    int objectMode_;
200    static std::map<uint32_t, Synchronisable *> objectMap_;
201    static std::queue<uint32_t> deletedObjects_;
202  };
203
204  template <class T> void Synchronisable::registerVariable(T& variable, uint8_t mode, NetworkCallbackBase *cb, bool bidirectional)
205  {
206    if (bidirectional)
207    {
208      syncList_.push_back(new SynchronisableVariableBidirectional<T>(variable, mode, cb));
209      this->dataSize_ += syncList_.back()->getSize(state_);
210    }
211    else
212    {
213      syncList_.push_back(new SynchronisableVariable<T>(variable, mode, cb));
214      if ( this->state_ == mode )
215        this->dataSize_ += syncList_.back()->getSize(state_);
216    }
217  }
218 
219  template <class T> void Synchronisable::unregisterVariable(T& variable)
220  {
221    std::vector<SynchronisableVariableBase*>::iterator it = syncList_.begin();
222    while(it!=syncList_.end())
223    {
224      if( ((*it)->getReference()) == &variable )
225      {
226        this->dataSize_ -= (*it)->getSize(Synchronisable::state_);
227        delete (*it);
228        syncList_.erase(it);
229        return;
230      }
231      else
232        it++;
233    }
234    COUT(1) << "Tried to unregister not registered variable" << endl;
235    assert(false); //if we reach this point something went wrong:
236    // the variable has not been registered before
237  }
238
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
250  template <> _NetworkExport void Synchronisable::registerVariable( std::string& variable, uint8_t mode, NetworkCallbackBase *cb, bool bidirectional);
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 );
253
254
255}
256
257#endif /* _Synchronisable_H__ */
Note: See TracBrowser for help on using the repository browser.