Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/network64/src/network/synchronisable/SynchronisableVariable.h @ 2307

Last change on this file since 2307 was 2307, checked in by rgrieder, 15 years ago
  • Removed source file inclusion in Synchronisable.cc (please don't do that, it had cost me half an hour to fix the build)
  • updated msvc files
  • Added missing declarations of template specialisations in order to export them properly
  • Added missing includes caused by the fix with source file inclusion.
  • Removed double declaration (there was the same declaration just behind) of registerVariable<const ColourValue>
  • Removed _NetworkExport macro in template definitions with parameters
  • Added _NetworkExport macro in template definitions that have no parameters any more (specialisations)
  • Property svn:eol-style set to native
File size: 14.1 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) 2008
24 *   Co-authors:
25 *      ...
26 *
27 */
28
29
30#ifndef _NETWORK_SYNCHRONISABLEVARIABLE__
31#define _NETWORK_SYNCHRONISABLEVARIABLE__
32
33#include "network/NetworkPrereqs.h"
34
35#include <string>
36#include <cassert>
37#include "util/Integers.h"
38#include "core/Core.h"
39#include "core/CoreIncludes.h"
40#include "network/synchronisable/NetworkCallback.h"
41
42namespace orxonox{
43 
44  namespace variableDirection{
45    enum syncdirection{
46      toclient=0x1,
47      toserver=0x2
48    };
49    enum bidirectional{
50      serverMaster=0x1,
51      clientMaster=0x2
52    };
53  }
54 
55  class _NetworkExport SynchronisableVariableBase
56  {
57    public:
58      virtual void getData(uint8_t*& mem, uint8_t mode)=0;
59      virtual void putData(uint8_t*& mem, uint8_t mode, bool forceCallback = false)=0;
60      virtual uint32_t getSize(uint8_t mode)=0;
61      virtual void* getReference()=0;
62      virtual uint8_t getMode()=0;
63      virtual ~SynchronisableVariableBase() {}
64    protected:
65      static uint8_t state_;
66  };
67
68  template <class T>
69  class SynchronisableVariable: public SynchronisableVariableBase
70  {
71    public:
72      SynchronisableVariable(T& variable, uint8_t syncDirection=variableDirection::toclient, NetworkCallbackBase *cb=0);
73      virtual ~SynchronisableVariable();
74
75      virtual inline uint8_t getMode(){ return mode_; }
76      virtual void getData(uint8_t*& mem, uint8_t mode);
77      virtual inline void putData(uint8_t*& mem, uint8_t mode, bool forceCallback = false);
78      virtual uint32_t getSize(uint8_t mode);
79      virtual inline void* getReference(){ return (void *)&this->variable_; }
80    protected:
81      bool checkEquality(uint8_t* mem);
82      void setAndIncrease(uint8_t*& mem);
83      void getAndIncrease(uint8_t*& mem);
84      uint32_t returnSize();
85     
86      T& variable_;
87      uint8_t mode_;
88      NetworkCallbackBase *callback_;
89  };
90 
91  template <class T>
92  class SynchronisableVariableBidirectional: public SynchronisableVariable<T>
93  {
94    public:
95      SynchronisableVariableBidirectional(T& variable, uint8_t master=variableDirection::serverMaster, NetworkCallbackBase *cb=0);
96      virtual ~SynchronisableVariableBidirectional();
97     
98      virtual inline uint8_t getMode(){ return 0x3; } //this basically is a hack ^^
99      virtual void getData(uint8_t*& mem, uint8_t mode);
100      virtual void putData(uint8_t*& mem, uint8_t mode, bool forceCallback = false);
101      virtual uint32_t getSize(uint8_t mode);
102    private:
103      T varBuffer_;
104      uint8_t varReference_;
105  };
106
107  // ================= Unidirectional Part ===============
108
109  template <class T> SynchronisableVariable<T>::SynchronisableVariable(T& variable, uint8_t syncDirection, NetworkCallbackBase *cb):
110      variable_( variable ), mode_( syncDirection ), callback_( cb )
111  {
112    if ( state_ == 0x0 )
113    {
114      state_ = Core::isMaster() ? 0x1 : 0x2;  // set the appropriate mode here
115    }
116  }
117 
118  template <class T> SynchronisableVariable<T>::~SynchronisableVariable()
119  {
120    if (this->callback_ != 0)
121      delete this->callback_;
122  }
123
124  template <class T> void SynchronisableVariable<T>::getData(uint8_t*& mem, uint8_t mode)
125  {
126    if ( state_ == this->mode_ )
127      getAndIncrease( mem );
128//   mem += SynchronisableVariable<T>::getSize();
129  }
130
131  template <class T> void SynchronisableVariable<T>::putData(uint8_t*& mem, uint8_t mode, bool forceCallback)
132  {
133    assert ( mode == 0x1 || mode == 0x2 );
134    bool callback = false;
135    if ( mode == this->mode_ ) //don't do anything
136      return;
137  // check whether we need to consider a callback
138    if ( this->callback_ != 0 )
139    {
140      if( forceCallback || !checkEquality( mem ) )
141        callback = true;
142    }
143  // write the data
144    setAndIncrease( mem );
145//   mem += SynchronisableVariable<T>::getSize();
146  // now do a callback if neccessary
147    if ( callback )
148      this->callback_->call();
149  }
150
151  template <class T> uint32_t SynchronisableVariable<T>::getSize(uint8_t mode)
152  {
153    if ( mode == this->mode_ )
154      return returnSize();
155    else
156      return 0;
157  }
158
159  template <> _NetworkExport uint32_t SynchronisableVariable<const bool>::returnSize();
160  template <> _NetworkExport void     SynchronisableVariable<const bool>::setAndIncrease(uint8_t*& mem);
161  template <> _NetworkExport void     SynchronisableVariable<const bool>::getAndIncrease(uint8_t*& mem);
162  template <> _NetworkExport bool     SynchronisableVariable<const bool>::checkEquality(uint8_t* mem);
163  template <> _NetworkExport uint32_t SynchronisableVariable<const unsigned char>::returnSize();
164  template <> _NetworkExport void     SynchronisableVariable<const unsigned char>::setAndIncrease(uint8_t*& mem);
165  template <> _NetworkExport void     SynchronisableVariable<const unsigned char>::getAndIncrease(uint8_t*& mem);
166  template <> _NetworkExport bool     SynchronisableVariable<const unsigned char>::checkEquality(uint8_t* mem);
167  template <> _NetworkExport uint32_t SynchronisableVariable<const short>::returnSize();
168  template <> _NetworkExport void     SynchronisableVariable<const short>::setAndIncrease(uint8_t*& mem);
169  template <> _NetworkExport void     SynchronisableVariable<const short>::getAndIncrease(uint8_t*& mem);
170  template <> _NetworkExport bool     SynchronisableVariable<const short>::checkEquality(uint8_t* mem);
171  template <> _NetworkExport uint32_t SynchronisableVariable<const unsigned short>::returnSize();
172  template <> _NetworkExport void     SynchronisableVariable<const unsigned short>::setAndIncrease(uint8_t*& mem);
173  template <> _NetworkExport void     SynchronisableVariable<const unsigned short>::getAndIncrease(uint8_t*& mem);
174  template <> _NetworkExport bool     SynchronisableVariable<const unsigned short>::checkEquality(uint8_t* mem);
175  template <> _NetworkExport uint32_t SynchronisableVariable<const int>::returnSize();
176  template <> _NetworkExport void     SynchronisableVariable<const int>::setAndIncrease(uint8_t*& mem);
177  template <> _NetworkExport void     SynchronisableVariable<const int>::getAndIncrease(uint8_t*& mem);
178  template <> _NetworkExport bool     SynchronisableVariable<const int>::checkEquality(uint8_t* mem);
179  template <> _NetworkExport uint32_t SynchronisableVariable<const unsigned int>::returnSize();
180  template <> _NetworkExport void     SynchronisableVariable<const unsigned int>::setAndIncrease(uint8_t*& mem);
181  template <> _NetworkExport void     SynchronisableVariable<const unsigned int>::getAndIncrease(uint8_t*& mem);
182  template <> _NetworkExport bool     SynchronisableVariable<const unsigned int>::checkEquality(uint8_t* mem);
183  template <> _NetworkExport uint32_t SynchronisableVariable<const long>::returnSize();
184  template <> _NetworkExport void     SynchronisableVariable<const long>::setAndIncrease(uint8_t*& mem);
185  template <> _NetworkExport void     SynchronisableVariable<const long>::getAndIncrease(uint8_t*& mem);
186  template <> _NetworkExport bool     SynchronisableVariable<const long>::checkEquality(uint8_t* mem);
187  template <> _NetworkExport uint32_t SynchronisableVariable<const unsigned long>::returnSize();
188  template <> _NetworkExport void     SynchronisableVariable<const unsigned long>::setAndIncrease(uint8_t*& mem);
189  template <> _NetworkExport void     SynchronisableVariable<const unsigned long>::getAndIncrease(uint8_t*& mem);
190  template <> _NetworkExport bool     SynchronisableVariable<const unsigned long>::checkEquality(uint8_t* mem);
191  template <> _NetworkExport uint32_t SynchronisableVariable<const long long>::returnSize();
192  template <> _NetworkExport void     SynchronisableVariable<const long long>::setAndIncrease(uint8_t*& mem);
193  template <> _NetworkExport void     SynchronisableVariable<const long long>::getAndIncrease(uint8_t*& mem);
194  template <> _NetworkExport bool     SynchronisableVariable<const long long>::checkEquality(uint8_t* mem);
195  template <> _NetworkExport uint32_t SynchronisableVariable<const unsigned long long>::returnSize();
196  template <> _NetworkExport void     SynchronisableVariable<const unsigned long long>::setAndIncrease(uint8_t*& mem);
197  template <> _NetworkExport void     SynchronisableVariable<const unsigned long long>::getAndIncrease(uint8_t*& mem);
198  template <> _NetworkExport bool     SynchronisableVariable<const unsigned long long>::checkEquality(uint8_t* mem);
199  template <> _NetworkExport uint32_t SynchronisableVariable<const float>::returnSize();
200  template <> _NetworkExport void     SynchronisableVariable<const float>::setAndIncrease(uint8_t*& mem);
201  template <> _NetworkExport void     SynchronisableVariable<const float>::getAndIncrease(uint8_t*& mem);
202  template <> _NetworkExport bool     SynchronisableVariable<const float>::checkEquality(uint8_t* mem);
203  template <> _NetworkExport uint32_t SynchronisableVariable<const double>::returnSize();
204  template <> _NetworkExport void     SynchronisableVariable<const double>::setAndIncrease(uint8_t*& mem);
205  template <> _NetworkExport void     SynchronisableVariable<const double>::getAndIncrease(uint8_t*& mem);
206  template <> _NetworkExport bool     SynchronisableVariable<const double>::checkEquality(uint8_t* mem);
207  template <> _NetworkExport uint32_t SynchronisableVariable<const long double>::returnSize();
208  template <> _NetworkExport void     SynchronisableVariable<const long double>::setAndIncrease(uint8_t*& mem);
209  template <> _NetworkExport void     SynchronisableVariable<const long double>::getAndIncrease(uint8_t*& mem);
210  template <> _NetworkExport bool     SynchronisableVariable<const long double>::checkEquality(uint8_t* mem);
211  template <> _NetworkExport uint32_t SynchronisableVariable<const std::string>::returnSize();
212  template <> _NetworkExport void     SynchronisableVariable<const std::string>::setAndIncrease(uint8_t*& mem);
213  template <> _NetworkExport void     SynchronisableVariable<const std::string>::getAndIncrease(uint8_t*& mem);
214  template <> _NetworkExport bool     SynchronisableVariable<const std::string>::checkEquality(uint8_t* mem);
215  template <> _NetworkExport uint32_t SynchronisableVariable<const Degree>::returnSize();
216  template <> _NetworkExport void     SynchronisableVariable<const Degree>::setAndIncrease(uint8_t*& mem);
217  template <> _NetworkExport void     SynchronisableVariable<const Degree>::getAndIncrease(uint8_t*& mem);
218  template <> _NetworkExport bool     SynchronisableVariable<const Degree>::checkEquality(uint8_t* mem);
219
220
221
222// ================= Bidirectional Part ================
223
224    template <class T> SynchronisableVariableBidirectional<T>::SynchronisableVariableBidirectional(T& variable, uint8_t master, NetworkCallbackBase *cb):
225    SynchronisableVariable<T>( variable, master, cb ), varBuffer_( variable ), varReference_( 0 )
226    {
227    }
228
229    template <class T> SynchronisableVariableBidirectional<T>::~SynchronisableVariableBidirectional()
230    {
231    }
232
233    template <class T> void SynchronisableVariableBidirectional<T>::getData(uint8_t*& mem, uint8_t mode)
234    {
235      if ( this->mode_ == mode )
236      {   // we are master for this variable and have to check whether to change the varReference
237        if( this->varBuffer_ != this->variable_ )
238        {
239          this->varReference_++;
240          memcpy((void*)&this->varBuffer_, &this->variable_, sizeof(this->variable_));
241        }
242      }
243  // write the reference number to the stream
244      *static_cast<uint8_t*>(mem) = varReference_;
245      mem += sizeof(this->varReference_);
246  // now write the content
247      SynchronisableVariable<T>::getAndIncrease( mem );
248//   mem += SynchronisableVariable<T>::getSize();
249    }
250
251    template <class T> void SynchronisableVariableBidirectional<T>::putData(uint8_t*& mem, uint8_t mode, bool forceCallback)
252    {
253      bool callback = false;
254      if ( this->mode_ == mode )
255      {   //        MASTER
256        // check that the client (source of the data) has a recent version of this variable
257        if ( *static_cast<uint8_t*>(mem) != this->varReference_ )
258        { // wrong reference number, so discard the data
259          mem += getSize( mode ); // SynchronisableVariableBidirectional::getSize returns size of variable + reference
260          return;
261        }
262        else{
263          // apply data
264          mem += sizeof(varReference_);
265          if ( SynchronisableVariableBidirectional<T>::checkEquality( mem )==true )
266          {
267            mem += SynchronisableVariable<T>::getSize( mode );
268            return;
269          }
270          else
271          {
272            memcpy((void*)&this->varBuffer_, &this->variable_, sizeof(T));
273            if ( this->callback_ != 0 )
274              callback = true;
275          }
276        }
277      }
278      else
279      {   // we are slave for this variable
280        if (*static_cast<uint8_t*>(mem) == this->varReference_ && !forceCallback)
281        {
282          mem += getSize( mode ); //just skip the variable because nothing changed
283          return;
284        }
285        else
286        {
287          this->varReference_ = *static_cast<uint8_t*>(mem);
288          mem += sizeof(varReference_);
289          if ( SynchronisableVariable<T>::checkEquality( mem ) == false )
290          {
291            // value changed so remark for callback
292            if ( this->callback_ != 0 )
293              callback = true;
294          }
295        }
296      }
297  // now write the data
298      SynchronisableVariable<T>::setAndIncrease(mem);
299  // now do a callback if neccessary
300      if ( callback )
301        this->callback_->call();
302    }
303
304    template <class T> uint32_t SynchronisableVariableBidirectional<T>::getSize(uint8_t mode)
305    {
306      return SynchronisableVariable<T>::returnSize() + sizeof(varReference_);
307    }
308 
309
310}
311
312
313#endif
Note: See TracBrowser for help on using the repository browser.