Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/netp3/src/network/synchronisable/SynchronisableVariable.h @ 2990

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

merged netp2 → netp3

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