Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/netp2/src/network/synchronisable/SynchronisableVariable.h @ 2937

Last change on this file since 2937 was 2861, checked in by scheusso, 16 years ago
  • moved serialise functions from SynchronisableVariableSpecialisation.cc

to util/Serialise.h

  • made MultiType serialisable (use functions importData/exportData or

operator << / >> )

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