Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/presentation2/src/libraries/network/synchronisable/Synchronisable.h @ 6124

Last change on this file since 6124 was 6123, checked in by scheusso, 15 years ago

synchronisation of pointers to classes that inherit from Synchronisable are now possible
just use the normal registerVariable syntax

  • Property svn:eol-style set to native
File size: 8.4 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 data is actually stored or is just filled up with 0
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 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 ); }
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  /**
112  * This class is the base class of all the Objects in the universe that need to be synchronised over the network
113  * Every class, that inherits from this class has to link the DATA THAT NEEDS TO BE SYNCHRONISED into the linked list.
114  * @author Oliver Scheuss
115  */
116  class _NetworkExport Synchronisable : virtual public OrxonoxClass{
117  public:
118    friend class packet::Gamestate;
119    virtual ~Synchronisable();
120
121    static void setClient(bool b);
122
123    static Synchronisable *fabricate(uint8_t*& mem, uint8_t mode=0x0);
124    static bool deleteObject(uint32_t objectID_);
125    static Synchronisable *getSynchronisable(uint32_t objectID_);
126    static unsigned int getNumberOfDeletedObject(){ return deletedObjects_.size(); }
127    static uint32_t popDeletedObject(){ uint32_t i = deletedObjects_.front(); deletedObjects_.pop(); return i; }
128
129    inline uint32_t getObjectID() const {return this->objectID_;}
130    inline unsigned int getCreatorID() const {return this->creatorID_;}
131    inline uint32_t getClassID() const {return this->classID_;}
132    inline unsigned int getPriority() const { return this->objectFrequency_;}
133    inline uint8_t getSyncMode() const { return this->objectMode_; }
134   
135    void setSyncMode(uint8_t mode);
136
137  protected:
138    Synchronisable(BaseObject* creator);
139    template <class T> void registerVariable(T& variable, uint8_t mode=0x1, NetworkCallbackBase *cb=0, bool bidirectional=false);
140    void setPriority(unsigned int freq){ objectFrequency_ = freq; }
141
142
143  private:
144    uint32_t getData(uint8_t*& men, int32_t id, uint8_t mode=0x0);
145    uint32_t getSize(int32_t id, uint8_t mode=0x0);
146    bool updateData(uint8_t*& mem, uint8_t mode=0x0, bool forceCallback=false);
147    bool isMyData(uint8_t* mem);
148    bool doSync(int32_t id, uint8_t mode=0x0);
149   
150    inline void setObjectID(uint32_t id){ this->objectID_ = id; objectMap_[this->objectID_] = this; }
151    inline void setClassID(uint32_t id){ this->classID_ = id; }
152
153    uint32_t objectID_;
154    uint32_t creatorID_;
155    uint32_t classID_;
156
157    std::vector<SynchronisableVariableBase*> syncList;
158    std::vector<SynchronisableVariableBase*> stringList;
159    uint32_t dataSize_; //size of all variables except strings
160    static uint8_t state_; // detemines wheter we are server (default) or client
161    bool backsync_; // if true the variables with mode > 1 will be synchronised to server (client -> server)
162    unsigned int objectFrequency_;
163    int objectMode_;
164    static std::map<uint32_t, Synchronisable *> objectMap_;
165    static std::queue<uint32_t> deletedObjects_;
166  };
167
168  // ================= Specialisation declarations
169 
170//   template <> _NetworkExport void Synchronisable::registerVariable( const std::string& variable, uint8_t mode, NetworkCallbackBase *cb, bool bidirectional);
171  template <> _NetworkExport void Synchronisable::registerVariable( std::string& variable, uint8_t mode, NetworkCallbackBase *cb, bool bidirectional);
172  template <> _NetworkExport void Synchronisable::registerVariable( const ColourValue& variable, uint8_t mode, NetworkCallbackBase* cb, bool bidirectional);
173  template <> _NetworkExport void Synchronisable::registerVariable( ColourValue& variable, uint8_t mode, NetworkCallbackBase* cb, bool bidirectional);
174  template <> _NetworkExport void Synchronisable::registerVariable( const Vector2& variable, uint8_t mode, NetworkCallbackBase* cb, bool bidirectional);
175  template <> _NetworkExport void Synchronisable::registerVariable( Vector2& variable, uint8_t mode, NetworkCallbackBase* cb, bool bidirectional);
176  template <> _NetworkExport void Synchronisable::registerVariable( const Vector3& variable, uint8_t mode, NetworkCallbackBase* cb, bool bidirectional);
177  template <> _NetworkExport void Synchronisable::registerVariable( Vector3& variable, uint8_t mode, NetworkCallbackBase* cb, bool bidirectional);
178  template <> _NetworkExport void Synchronisable::registerVariable( const Vector4& variable, uint8_t mode, NetworkCallbackBase* cb, bool bidirectional);
179  template <> _NetworkExport void Synchronisable::registerVariable( Vector4& variable, uint8_t mode, NetworkCallbackBase* cb, bool bidirectional);
180  template <> _NetworkExport void Synchronisable::registerVariable( mbool& variable, uint8_t mode, NetworkCallbackBase* cb, bool bidirectional);
181  template <> _NetworkExport void Synchronisable::registerVariable( const Quaternion& variable, uint8_t mode, NetworkCallbackBase* cb, bool bidirectional);
182  template <> _NetworkExport void Synchronisable::registerVariable( Quaternion& variable, uint8_t mode, NetworkCallbackBase* cb, bool bidirectional);
183 
184  template <class T> void Synchronisable::registerVariable(T& variable, uint8_t mode, NetworkCallbackBase *cb, bool bidirectional)
185  {
186    if (bidirectional)
187    {
188      syncList.push_back(new SynchronisableVariableBidirectional<T>(variable, mode, cb));
189      this->dataSize_ += syncList.back()->getSize(state_);
190    }
191    else
192    {
193      syncList.push_back(new SynchronisableVariable<T>(variable, mode, cb));
194      if ( this->state_ == mode )
195        this->dataSize_ += syncList.back()->getSize(state_);
196    }
197  }
198
199 
200}
201
202#endif /* _Synchronisable_H__ */
Note: See TracBrowser for help on using the repository browser.