Orxonox  0.0.5 Codename: Arcturus
Synchronisable.h
Go to the documentation of this file.
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 #include <type_traits>
41 
42 #include "util/mbool.h"
43 #include "util/Output.h"
45 #include "SynchronisableVariable.h"
46 #include "NetworkCallback.h"
47 
48 
49 namespace orxonox
50 {
51 
52  namespace ObjectDirection{
53  enum Value{
54  None=0x0,
55  ToClient=0x1,
56  ToServer=0x2,
58  };
59  }
60 
61  namespace Priority{
62  enum Value{
63  VeryHigh = -100,
64  High = -15,
65  Normal = 0,
66  Low = 15,
67  VeryLow = 100
68  };
69  }
70 
81  {
82  protected:
83  uint8_t* data_;
84  public:
86  { data_ = data; }
87  inline static uint32_t getSize()
88  { return 6; }
89  inline uint16_t getDataSize() const
90  { return (*(uint16_t*)data_) & 0x7FFF; } //only use the first 31 bits
91  inline void setDataSize(uint16_t size)
92  { *(uint16_t*)(data_) = (size & 0x7FFFFFFF) | (*(uint16_t*)(data_) & 0x8000 ); }
93  inline bool isDiffed() const
94  { return ( (*(uint16_t*)data_) & 0x8000 ) == 0x8000; }
95  inline void setDiffed( bool b)
96  { *(uint16_t*)(data_) = (b << 15) | (*(uint16_t*)(data_) & 0x7FFF ); }
97  inline uint32_t getObjectID() const
98  { return *(uint32_t*)(data_+2); }
99  inline void setObjectID(uint32_t objectID_)
100  { *(uint32_t*)(data_+2) = objectID_; }
102  { memcpy(data_, h.data_, SynchronisableHeaderLight::getSize()); }
103  };
104 
105  typedef uint8_t VariableID;
106 
119  {
120  public:
122  {}
123  inline static uint32_t getSize()
124  { return SynchronisableHeaderLight::getSize()+8; }
125  inline uint32_t getClassID() const
126  { return *(uint32_t*)(data_+SynchronisableHeaderLight::getSize()); }
127  inline void setClassID(uint32_t classID_)
128  { *(uint32_t*)(data_+SynchronisableHeaderLight::getSize()) = classID_; }
129  inline uint32_t getContextID() const
130  { return *(uint32_t*)(data_+SynchronisableHeaderLight::getSize()+4); }
131  inline void setContextID(uint32_t contextID_)
132  { *(uint32_t*)(data_+SynchronisableHeaderLight::getSize()+4) = contextID_; }
134  { memcpy(data_, h.data_, getSize()); }
135  };
136 
143  public:
144  friend class packet::Gamestate;
145  virtual ~Synchronisable();
146 
147  static void setClient(bool b);
148 
149  static Synchronisable *fabricate(uint8_t*& mem, uint8_t mode=0x0);
150  static bool deleteObject(uint32_t objectID_);
151  static Synchronisable *getSynchronisable(uint32_t objectID_);
152  static unsigned int getNumberOfDeletedObject(){ return deletedObjects_.size(); }
153  static uint32_t popDeletedObject(){ uint32_t i = deletedObjects_.front(); deletedObjects_.pop(); return i; }
154 
155  inline uint32_t getObjectID() const {return this->objectID_;}
156  inline unsigned int getContextID() const {return this->contextID_;}
157  inline uint32_t getClassID() const {return this->classID_;}
158  inline unsigned int getPriority() const { return this->objectFrequency_;}
159  inline uint8_t getSyncMode() const { return this->objectMode_; }
160 
161  void setSyncMode(uint8_t mode);
162 
163  inline uint32_t getNrOfVariables(){ return this->syncList_.size(); }
164  inline uint32_t getVarSize( VariableID ID )
165  { return this->syncList_[ID]->getSize(state_); }
166 
167  protected:
168  Synchronisable(Context* context);
169  template <class T> void registerVariable(T& variable, uint8_t mode=0x1, NetworkCallbackBase *cb=nullptr, bool bidirectional=false);
170  template <class T> void registerVariable(std::set<T>& variable, uint8_t mode=0x1, NetworkCallbackBase *cb=nullptr, bool bidirectional=false);
171  template <class T> void unregisterVariable(T& var);
172 
173  void setPriority(unsigned int freq){ objectFrequency_ = freq; }
174  uint32_t findContextID(Context* context);
175 
176  private:
177  uint32_t getData(uint8_t*& mem, std::vector<uint32_t>& sizes, int32_t id, uint8_t mode);
178  uint32_t getSize(int32_t id, uint8_t mode=0x0);
179  bool updateData(uint8_t*& mem, uint8_t mode=0x0, bool forceCallback=false);
180  bool doSync(/*int32_t id,*/ uint8_t mode=0x0);
181  bool doReceive( uint8_t mode );
182 
183  inline void setObjectID(uint32_t id){ this->objectID_ = id; objectMap_[this->objectID_] = this; }
184  inline void setClassID(uint32_t id){ this->classID_ = id; }
185 
186  uint32_t objectID_;
187  uint32_t contextID_;
188  uint32_t classID_;
189 
190  std::vector<SynchronisableVariableBase*> syncList_;
191  std::vector<SynchronisableVariableBase*> stringList_;
192  uint32_t dataSize_; //size of all variables except strings
193  static uint8_t state_; // detemines wheter we are server (default) or client
194  bool backsync_; // if true the variables with mode > 1 will be synchronised to server (client -> server)
195  unsigned int objectFrequency_;
197  static std::map<uint32_t, Synchronisable *> objectMap_;
198  static std::queue<uint32_t> deletedObjects_;
199  };
200 
201  namespace detail
202  {
203  template <class T, bool = std::is_enum<T>::value>
204  struct UnderlyingType;
205  template <class T>
206  struct UnderlyingType<T, true> { typedef typename std::underlying_type<T>::type type; };
207  template <class T>
208  struct UnderlyingType<T, false> { typedef T type; };
209  }
210 
211  template <class T>
212  void Synchronisable::registerVariable(T& variable, uint8_t mode, NetworkCallbackBase *cb, bool bidirectional)
213  {
214  typedef typename detail::UnderlyingType<T>::type UnderlyingType;
215  if (bidirectional)
216  {
217  syncList_.push_back(new SynchronisableVariableBidirectional<UnderlyingType>(reinterpret_cast<UnderlyingType&>(variable), mode, cb));
218  this->dataSize_ += syncList_.back()->getSize(state_);
219  }
220  else
221  {
222  syncList_.push_back(new SynchronisableVariable<UnderlyingType>(reinterpret_cast<UnderlyingType&>(variable), mode, cb));
223  if ( this->state_ == mode )
224  this->dataSize_ += syncList_.back()->getSize(state_);
225  }
226  }
227 
228  template <class T>
230  {
231  std::vector<SynchronisableVariableBase*>::iterator it = syncList_.begin();
232  while(it!=syncList_.end())
233  {
234  if( ((*it)->getReference()) == &variable )
235  {
236  this->dataSize_ -= (*it)->getSize(Synchronisable::state_);
237  delete (*it);
238  syncList_.erase(it);
239  return;
240  }
241  else
242  it++;
243  }
244  orxout(internal_error, context::network) << "Tried to unregister not registered variable" << endl;
245  assert(false); //if we reach this point something went wrong:
246  // the variable has not been registered before
247  }
248 
249  template <class T>
250  void Synchronisable::registerVariable( std::set<T>& variable, uint8_t mode, NetworkCallbackBase *cb, bool bidirectional)
251  {
252  typedef typename detail::UnderlyingType<T>::type UnderlyingType;
254  if (bidirectional)
255  sv = new SynchronisableVariableBidirectional<std::set<UnderlyingType>>(reinterpret_cast<std::set<UnderlyingType>&>(variable), mode, cb);
256  else
257  sv = new SynchronisableVariable<std::set<UnderlyingType>>(reinterpret_cast<std::set<UnderlyingType>&>(variable), mode, cb);
258  syncList_.push_back(sv);
259  stringList_.push_back(sv);
260  }
261 
262  template <> _NetworkExport void Synchronisable::registerVariable( std::string& variable, uint8_t mode, NetworkCallbackBase *cb, bool bidirectional);
263 // template <class T> _NetworkExport void Synchronisable::registerVariable<std::set<T>>( std::set<T>& variable, uint8_t mode, NetworkCallbackBase *cb, bool bidirectional);
264  template <> _NetworkExport void Synchronisable::unregisterVariable( std::string& variable );
265 
266 
267 }
268 
269 #endif /* _Synchronisable_H__ */
: stores information about a Synchronisable
Definition: Synchronisable.h:118
Definition: SynchronisableVariable.h:58
void registerVariable(T &variable, uint8_t mode=0x1, NetworkCallbackBase *cb=nullptr, bool bidirectional=false)
Definition: Synchronisable.h:212
static uint32_t getSize()
Definition: Synchronisable.h:87
Definition: Synchronisable.h:65
void operator=(SynchronisableHeader &h)
Definition: Synchronisable.h:133
Shared library macros, enums, constants and forward declarations for the network library ...
SynchronisableHeaderLight(uint8_t *data)
Definition: Synchronisable.h:85
void setObjectID(uint32_t objectID_)
Definition: Synchronisable.h:99
Definition: Synchronisable.h:56
This class is the base class of all the Objects in the universe that need to be synchronised over the...
Definition: Synchronisable.h:142
static uint8_t state_
Definition: Synchronisable.h:193
void setClassID(uint32_t classID_)
Definition: Synchronisable.h:127
uint8_t VariableID
Definition: Synchronisable.h:105
void unregisterVariable(T &var)
Definition: Synchronisable.h:229
::std::string string
Definition: gtest-port.h:756
static uint32_t popDeletedObject()
Definition: Synchronisable.h:153
uint32_t getClassID() const
Definition: Synchronisable.h:157
Definition: Synchronisable.h:54
SynchronisableHeader(uint8_t *data)
Definition: Synchronisable.h:121
void operator=(SynchronisableHeaderLight &h)
Definition: Synchronisable.h:101
Definition: Synchronisable.h:57
bool isDiffed() const
Definition: Synchronisable.h:93
Definition: Synchronisable.h:64
Definition: NetworkPrereqs.h:177
Definition: Synchronisable.h:66
uint32_t contextID_
Definition: Synchronisable.h:187
uint16_t getDataSize() const
Definition: Synchronisable.h:89
std::vector< SynchronisableVariableBase * > syncList_
Definition: Synchronisable.h:190
This is the class from which all interfaces of the game-logic (not the engine) are derived from...
Definition: OrxonoxInterface.h:50
uint32_t getNrOfVariables()
Definition: Synchronisable.h:163
uint32_t getContextID() const
Definition: Synchronisable.h:129
static std::map< uint32_t, Synchronisable * > objectMap_
Definition: Synchronisable.h:197
Output level, used for error messages which are important for developers.
Definition: OutputDefinitions.h:95
uint8_t getSyncMode() const
Definition: Synchronisable.h:159
static uint32_t getSize()
Definition: Synchronisable.h:123
uint32_t classID_
Definition: Synchronisable.h:188
Definition: Synchronisable.h:67
uint32_t getObjectID() const
Definition: Synchronisable.h:155
uint32_t getClassID() const
Definition: Synchronisable.h:125
Definition: Gamestate.h:109
unsigned int getPriority() const
Definition: Synchronisable.h:158
OutputStream & orxout(OutputLevel level=level::debug_output, const OutputContextContainer &context=context::undefined())
This helper function returns a reference to a commonly used instance of OutputStream.
Definition: Output.h:81
Die Wagnis Klasse hat die folgenden Aufgaben:
Definition: ApplicationPaths.cc:66
Definition: Synchronisable.h:55
static std::queue< uint32_t > deletedObjects_
Definition: Synchronisable.h:198
#define _NetworkExport
Definition: NetworkPrereqs.h:59
Declaration of OrxonoxInterface, the base class of all interfaces in Orxonox.
uint32_t getObjectID() const
Definition: Synchronisable.h:97
Value
Definition: Synchronisable.h:53
void setClassID(uint32_t id)
Definition: Synchronisable.h:184
void setDataSize(uint16_t size)
Definition: Synchronisable.h:91
Defines the helper function orxout() and includes all necessary headers to use the output system...
Declaration and implementation of the orxonox::mbool class.
Definition: InputPrereqs.h:78
Definition: Context.h:45
Definition: Synchronisable.h:63
: stores information about a Synchronisable (light version)
Definition: Synchronisable.h:80
Definition: NetworkPrereqs.h:174
unsigned int getContextID() const
Definition: Synchronisable.h:156
std::vector< SynchronisableVariableBase * > stringList_
Definition: Synchronisable.h:191
uint32_t dataSize_
Definition: Synchronisable.h:192
int objectMode_
Definition: Synchronisable.h:196
void setPriority(unsigned int freq)
Definition: Synchronisable.h:173
uint8_t * data_
Definition: Synchronisable.h:83
uint32_t objectID_
Definition: Synchronisable.h:186
void setContextID(uint32_t contextID_)
Definition: Synchronisable.h:131
void setDiffed(bool b)
Definition: Synchronisable.h:95
uint32_t getVarSize(VariableID ID)
Definition: Synchronisable.h:164
Value
Definition: Synchronisable.h:62
void setObjectID(uint32_t id)
Definition: Synchronisable.h:183
bool backsync_
Definition: Synchronisable.h:194
static unsigned int getNumberOfDeletedObject()
Definition: Synchronisable.h:152
Definition: NetworkCallback.h:41
unsigned int objectFrequency_
Definition: Synchronisable.h:195