Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/netp5/src/network/synchronisable/Synchronisable.h @ 3211

Last change on this file since 3211 was 3211, checked in by rgrieder, 15 years ago

Moved PacketFlag and added includes for memcpy() and abort() (Mingw didn't seem to care).

  • Property svn:eol-style set to native
File size: 9.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/*#define REGISTERDATA(varname, ...) \
46    registerVariable((void*)&varname, sizeof(varname), DATA, __VA_ARGS__)
47#define REGISTERSTRING(stringname, ...) \
48    registerVariable(&stringname, stringname.length()+1, STRING, __VA_ARGS__)*/
49
50namespace orxonox
51{
52
53  namespace objectDirection{
54    enum objectdirection{
55      toclient=0x1,
56      toserver=0x2,
57      bidirectional=0x3
58    };
59  }
60
61  namespace priority{
62    enum prio{
63      very_high   = -100,
64      high        = -15,
65      normal      = 0,
66      low         = 15,
67      very_low    = 100
68    };
69  }
70
71  /**
72   * @brief: stores information about a Synchronisable
73   *
74   * This class stores the information about a Synchronisable (objectID, classID, creatorID, dataSize)
75   * in an emulated bitset.
76   * Bit 1 to 31 store the size of the Data the synchronisable consumes in the stream
77   * Bit 32 is a bool and defines whether the data is actually stored or is just filled up with 0
78   * Byte 5 to 8: objectID
79   * Byte 9 to 12: classID
80   * Byte 13 to 16: creatorID
81   */
82  class _NetworkExport SynchronisableHeader{
83    private:
84      uint8_t *data_;
85    public:
86      SynchronisableHeader(uint8_t* data)
87        { data_ = data; }
88      inline static uint32_t getSize()
89        { return 16; }
90      inline uint32_t getDataSize() const
91        { return (*(uint32_t*)data_) & 0x7FFFFFFF; } //only use the first 31 bits
92      inline void setDataSize(uint32_t size)
93        { *(uint32_t*)(data_) = (size & 0x7FFFFFFF) | (*(uint32_t*)(data_) & 0x80000000 ); }
94      inline bool isDataAvailable() const
95        { return ( (*(uint32_t*)data_) & 0x80000000 ) == 0x80000000; }
96      inline void setDataAvailable( bool b)
97        { *(uint32_t*)(data_) = (b << 31) | (*(uint32_t*)(data_) & 0x7FFFFFFF ); }
98      inline uint32_t getObjectID() const
99        { return *(uint32_t*)(data_+4); }
100      inline void setObjectID(uint32_t objectID)
101        { *(uint32_t*)(data_+4) = objectID; }
102      inline uint32_t getClassID() const
103        { return *(uint32_t*)(data_+8); }
104      inline void setClassID(uint32_t classID)
105        { *(uint32_t*)(data_+8) = classID; }
106      inline uint32_t getCreatorID() const
107        { return *(uint32_t*)(data_+12); }
108      inline void setCreatorID(uint32_t creatorID)
109        { *(uint32_t*)(data_+12) = creatorID; }
110      inline void operator=(SynchronisableHeader& h)
111        { memcpy(data_, h.data_, getSize()); }
112  };
113
114
115  /**
116  * This class is the base class of all the Objects in the universe that need to be synchronised over the network
117  * Every class, that inherits from this class has to link the DATA THAT NEEDS TO BE SYNCHRONISED into the linked list.
118  * @author Oliver Scheuss
119  */
120  class _NetworkExport Synchronisable : virtual public OrxonoxClass{
121  public:
122    friend class packet::Gamestate;
123    virtual ~Synchronisable();
124
125    static void setClient(bool b);
126
127    static Synchronisable *fabricate(uint8_t*& mem, uint8_t mode=0x0);
128    static bool deleteObject(uint32_t objectID);
129    static Synchronisable *getSynchronisable(uint32_t objectID);
130    static unsigned int getNumberOfDeletedObject(){ return deletedObjects_.size(); }
131    static uint32_t popDeletedObject(){ uint32_t i = deletedObjects_.front(); deletedObjects_.pop(); return i; }
132
133    inline uint32_t getObjectID() const {return objectID;}
134    inline unsigned int getCreatorID() const {return creatorID;}
135    inline uint32_t getClassID() const {return classID;}
136    inline unsigned int getPriority() const { return objectFrequency_;}
137
138  protected:
139    Synchronisable(BaseObject* creator);
140    template <class T> void registerVariable(T& variable, uint8_t mode=0x1, NetworkCallbackBase *cb=0, bool bidirectional=false);
141    //template <class T> void unregisterVariable(T& var);
142    void setObjectMode(uint8_t mode);
143    void setPriority(unsigned int freq){ objectFrequency_ = freq; }
144
145
146  private:
147    uint32_t getData(uint8_t*& men, int32_t id, uint8_t mode=0x0);
148    uint32_t getSize(int32_t id, uint8_t mode=0x0);
149    bool updateData(uint8_t*& mem, uint8_t mode=0x0, bool forceCallback=false);
150    bool isMyData(uint8_t* mem);
151    bool doSync(int32_t id, uint8_t mode=0x0);
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<const T>(variable, mode, cb));
189      this->dataSize_ += syncList.back()->getSize(state_);
190    }
191    else
192    {
193      syncList.push_back(new SynchronisableVariable<const T>(variable, mode, cb));
194      if ( this->state_ == mode )
195        this->dataSize_ += syncList.back()->getSize(state_);
196    }
197  }
198 
199
200
201//   template <class T> void Synchronisable::unregisterVariable(T& var){
202//     std::vector<SynchronisableVariableBase*>::iterator it = syncList.begin();
203//     while(it!=syncList.end()){
204//       if( ((*it)->getReference()) == &var ){
205//         delete (*it);
206//         syncList.erase(it);
207//         return;
208//       }
209//       else
210//         it++;
211//     }
212//     bool unregistered_nonexistent_variable = false;
213//     assert(unregistered_nonexistent_variable); //if we reach this point something went wrong:
214//     // the variable has not been registered before
215//   }
216
217 
218}
219
220#endif /* _Synchronisable_H__ */
Note: See TracBrowser for help on using the repository browser.