Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/network2/src/libraries/network/synchronisable/Synchronisable.h @ 6449

Last change on this file since 6449 was 6449, checked in by scheusso, 14 years ago

changed diff behaviour in order to reduce datasize before and after compress
this reduces time needed for gamestate diff and compress about 50%

  • Property svn:eol-style set to native
File size: 8.0 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
40#include "util/mbool.h"
41#include "core/OrxonoxClass.h"
42#include "SynchronisableVariable.h"
43#include "NetworkCallback.h"
44
45
46namespace orxonox
47{
48
49  namespace ObjectDirection{
50    enum Value{
51      ToClient=0x1,
52      ToServer=0x2,
53      Bidirectional=0x3
54    };
55  }
56
57  namespace Priority{
58    enum Value{
59      VeryHigh    = -100,
60      High        = -15,
61      Normal      = 0,
62      Low         = 15,
63      VeryLow     = 100
64    };
65  }
66
67  /**
68   * @brief: stores information about a Synchronisable
69   *
70   * This class stores the information about a Synchronisable (objectID_, classID_, creatorID_, dataSize)
71   * in an emulated bitset.
72   * 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 variables are stored in diff mode
74   * Byte 5 to 8: objectID_
75   * Byte 9 to 12: classID_
76   * Byte 13 to 16: creatorID_
77   */
78  class _NetworkExport SynchronisableHeader{
79    private:
80      uint8_t *data_;
81    public:
82      SynchronisableHeader(uint8_t* data)
83        { data_ = data; }
84      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 isDiffed() const
91        { return ( (*(uint32_t*)data_) & 0x80000000 ) == 0x80000000; }
92      inline void setDiffed( bool b)
93        { *(uint32_t*)(data_) = (b << 31) | (*(uint32_t*)(data_) & 0x7FFFFFFF ); }
94      inline uint32_t getObjectID() const
95        { return *(uint32_t*)(data_+4); }
96      inline void setObjectID(uint32_t objectID_)
97        { *(uint32_t*)(data_+4) = objectID_; }
98      inline uint32_t getClassID() const
99        { return *(uint32_t*)(data_+8); }
100      inline void setClassID(uint32_t classID_)
101        { *(uint32_t*)(data_+8) = classID_; }
102      inline uint32_t getCreatorID() const
103        { return *(uint32_t*)(data_+12); }
104      inline void setCreatorID(uint32_t creatorID_)
105        { *(uint32_t*)(data_+12) = creatorID_; }
106      inline void operator=(SynchronisableHeader& h)
107        { memcpy(data_, h.data_, getSize()); }
108  };
109
110    /**
111   * @brief: stores information about a Synchronisable (light version)
112   *
113   * This class stores the information about a Synchronisable (objectID_, dataSize)
114   * in an emulated bitset.
115   * Bit 1 to 31 store the size of the Data the synchronisable consumes in the stream
116   * Bit 32 is a bool and defines whether the variables are stored in diff mode
117   * Byte 5 to 8: objectID_
118   */
119  class _NetworkExport SynchronisableHeaderLight{
120    private:
121      uint8_t *data_;
122    public:
123      SynchronisableHeader(uint8_t* data)
124        { data_ = data; }
125      inline static uint32_t getSize()
126        { return 16; }
127      inline uint32_t getDataSize() const
128        { return (*(uint32_t*)data_) & 0x7FFFFFFF; } //only use the first 31 bits
129      inline void setDataSize(uint32_t size)
130        { *(uint32_t*)(data_) = (size & 0x7FFFFFFF) | (*(uint32_t*)(data_) & 0x80000000 ); }
131      inline bool isDiffed() const
132        { return ( (*(uint32_t*)data_) & 0x80000000 ) == 0x80000000; }
133      inline void setDiffed( bool b)
134        { *(uint32_t*)(data_) = (b << 31) | (*(uint32_t*)(data_) & 0x7FFFFFFF ); }
135      inline uint32_t getObjectID() const
136        { return *(uint32_t*)(data_+4); }
137      inline void setObjectID(uint32_t objectID_)
138        { *(uint32_t*)(data_+4) = objectID_; }
139      inline void operator=(SynchronisableHeader& h)
140        { memcpy(data_, h.data_, getSize()); }
141  };
142
143  /**
144  * This class is the base class of all the Objects in the universe that need to be synchronised over the network
145  * Every class, that inherits from this class has to link the DATA THAT NEEDS TO BE SYNCHRONISED into the linked list.
146  * @author Oliver Scheuss
147  */
148  class _NetworkExport Synchronisable : virtual public OrxonoxClass{
149  public:
150    friend class packet::Gamestate;
151    virtual ~Synchronisable();
152
153    static void setClient(bool b);
154
155    static Synchronisable *fabricate(uint8_t*& mem, bool diffed, uint8_t mode=0x0);
156    static bool deleteObject(uint32_t objectID_);
157    static Synchronisable *getSynchronisable(uint32_t objectID_);
158    static unsigned int getNumberOfDeletedObject(){ return deletedObjects_.size(); }
159    static uint32_t popDeletedObject(){ uint32_t i = deletedObjects_.front(); deletedObjects_.pop(); return i; }
160
161    inline uint32_t getObjectID() const {return this->objectID_;}
162    inline unsigned int getCreatorID() const {return this->creatorID_;}
163    inline uint32_t getClassID() const {return this->classID_;}
164    inline unsigned int getPriority() const { return this->objectFrequency_;}
165    inline uint8_t getSyncMode() const { return this->objectMode_; }
166
167    void setSyncMode(uint8_t mode);
168   
169    inline uint32_t getNrOfVariables(){ return this->syncList_.size(); }
170    inline uint32_t getVarSize( uint32_t ID )
171    { return this->syncList_[ID]->getSize(state_); }
172
173  protected:
174    Synchronisable(BaseObject* creator);
175    template <class T> void registerVariable(T& variable, uint8_t mode=0x1, NetworkCallbackBase *cb=0, bool bidirectional=false);
176
177    void setPriority(unsigned int freq){ objectFrequency_ = freq; }
178
179
180  private:
181    uint32_t getData(uint8_t*& mem, std::vector<uint32_t>& sizes, int32_t id, uint8_t mode);
182    uint32_t getSize(int32_t id, uint8_t mode=0x0);
183    bool updateData(uint8_t*& mem, uint8_t mode=0x0, bool forceCallback=false);
184    bool doSync(int32_t id, uint8_t mode=0x0);
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 <> _NetworkExport void Synchronisable::registerVariable( std::string& variable, uint8_t mode, NetworkCallbackBase *cb, bool bidirectional);
220
221
222}
223
224#endif /* _Synchronisable_H__ */
Note: See TracBrowser for help on using the repository browser.