Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/pickups/src/network/synchronisable/SynchronisableVariable.h @ 2988

Last change on this file since 2988 was 2710, checked in by rgrieder, 16 years ago

Merged buildsystem3 containing buildsystem2 containing Adi's buildsystem branch back to the trunk.
Please update the media directory if you were not using buildsystem3 before.

  • Property svn:eol-style set to native
File size: 14.3 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 "core/Core.h"
38#include "core/CoreIncludes.h"
39#include "network/synchronisable/NetworkCallback.h"
40#include "network/synchronisable/NetworkCallbackManager.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 inline void getData(uint8_t*& mem, uint8_t mode);
77      virtual inline void putData(uint8_t*& mem, uint8_t mode, bool forceCallback = false);
78      virtual inline 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      NetworkCallbackManager::deleteCallback(this->callback_); //safe call for deletion
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      NetworkCallbackManager::triggerCallback( this->callback_ );
149      //this->callback_->call();
150  }
151
152  template <class T> uint32_t SynchronisableVariable<T>::getSize(uint8_t mode)
153  {
154    if ( mode == this->mode_ )
155      return returnSize();
156    else
157      return 0;
158  }
159
160  template <> _NetworkExport uint32_t SynchronisableVariable<const bool>::returnSize();
161  template <> _NetworkExport void     SynchronisableVariable<const bool>::setAndIncrease(uint8_t*& mem);
162  template <> _NetworkExport void     SynchronisableVariable<const bool>::getAndIncrease(uint8_t*& mem);
163  template <> _NetworkExport bool     SynchronisableVariable<const bool>::checkEquality(uint8_t* mem);
164  template <> _NetworkExport uint32_t SynchronisableVariable<const unsigned char>::returnSize();
165  template <> _NetworkExport void     SynchronisableVariable<const unsigned char>::setAndIncrease(uint8_t*& mem);
166  template <> _NetworkExport void     SynchronisableVariable<const unsigned char>::getAndIncrease(uint8_t*& mem);
167  template <> _NetworkExport bool     SynchronisableVariable<const unsigned char>::checkEquality(uint8_t* mem);
168  template <> _NetworkExport uint32_t SynchronisableVariable<const short>::returnSize();
169  template <> _NetworkExport void     SynchronisableVariable<const short>::setAndIncrease(uint8_t*& mem);
170  template <> _NetworkExport void     SynchronisableVariable<const short>::getAndIncrease(uint8_t*& mem);
171  template <> _NetworkExport bool     SynchronisableVariable<const short>::checkEquality(uint8_t* mem);
172  template <> _NetworkExport uint32_t SynchronisableVariable<const unsigned short>::returnSize();
173  template <> _NetworkExport void     SynchronisableVariable<const unsigned short>::setAndIncrease(uint8_t*& mem);
174  template <> _NetworkExport void     SynchronisableVariable<const unsigned short>::getAndIncrease(uint8_t*& mem);
175  template <> _NetworkExport bool     SynchronisableVariable<const unsigned short>::checkEquality(uint8_t* mem);
176  template <> _NetworkExport uint32_t SynchronisableVariable<const int>::returnSize();
177  template <> _NetworkExport void     SynchronisableVariable<const int>::setAndIncrease(uint8_t*& mem);
178  template <> _NetworkExport void     SynchronisableVariable<const int>::getAndIncrease(uint8_t*& mem);
179  template <> _NetworkExport bool     SynchronisableVariable<const int>::checkEquality(uint8_t* mem);
180  template <> _NetworkExport uint32_t SynchronisableVariable<const unsigned int>::returnSize();
181  template <> _NetworkExport void     SynchronisableVariable<const unsigned int>::setAndIncrease(uint8_t*& mem);
182  template <> _NetworkExport void     SynchronisableVariable<const unsigned int>::getAndIncrease(uint8_t*& mem);
183  template <> _NetworkExport bool     SynchronisableVariable<const unsigned int>::checkEquality(uint8_t* mem);
184  template <> _NetworkExport uint32_t SynchronisableVariable<const long>::returnSize();
185  template <> _NetworkExport void     SynchronisableVariable<const long>::setAndIncrease(uint8_t*& mem);
186  template <> _NetworkExport void     SynchronisableVariable<const long>::getAndIncrease(uint8_t*& mem);
187  template <> _NetworkExport bool     SynchronisableVariable<const long>::checkEquality(uint8_t* mem);
188  template <> _NetworkExport uint32_t SynchronisableVariable<const unsigned long>::returnSize();
189  template <> _NetworkExport void     SynchronisableVariable<const unsigned long>::setAndIncrease(uint8_t*& mem);
190  template <> _NetworkExport void     SynchronisableVariable<const unsigned long>::getAndIncrease(uint8_t*& mem);
191  template <> _NetworkExport bool     SynchronisableVariable<const unsigned long>::checkEquality(uint8_t* mem);
192  template <> _NetworkExport uint32_t SynchronisableVariable<const long long>::returnSize();
193  template <> _NetworkExport void     SynchronisableVariable<const long long>::setAndIncrease(uint8_t*& mem);
194  template <> _NetworkExport void     SynchronisableVariable<const long long>::getAndIncrease(uint8_t*& mem);
195  template <> _NetworkExport bool     SynchronisableVariable<const long long>::checkEquality(uint8_t* mem);
196  template <> _NetworkExport uint32_t SynchronisableVariable<const unsigned long long>::returnSize();
197  template <> _NetworkExport void     SynchronisableVariable<const unsigned long long>::setAndIncrease(uint8_t*& mem);
198  template <> _NetworkExport void     SynchronisableVariable<const unsigned long long>::getAndIncrease(uint8_t*& mem);
199  template <> _NetworkExport bool     SynchronisableVariable<const unsigned long long>::checkEquality(uint8_t* mem);
200  template <> _NetworkExport uint32_t SynchronisableVariable<const float>::returnSize();
201  template <> _NetworkExport void     SynchronisableVariable<const float>::setAndIncrease(uint8_t*& mem);
202  template <> _NetworkExport void     SynchronisableVariable<const float>::getAndIncrease(uint8_t*& mem);
203  template <> _NetworkExport bool     SynchronisableVariable<const float>::checkEquality(uint8_t* mem);
204  template <> _NetworkExport uint32_t SynchronisableVariable<const double>::returnSize();
205  template <> _NetworkExport void     SynchronisableVariable<const double>::setAndIncrease(uint8_t*& mem);
206  template <> _NetworkExport void     SynchronisableVariable<const double>::getAndIncrease(uint8_t*& mem);
207  template <> _NetworkExport bool     SynchronisableVariable<const double>::checkEquality(uint8_t* mem);
208  template <> _NetworkExport uint32_t SynchronisableVariable<const long double>::returnSize();
209  template <> _NetworkExport void     SynchronisableVariable<const long double>::setAndIncrease(uint8_t*& mem);
210  template <> _NetworkExport void     SynchronisableVariable<const long double>::getAndIncrease(uint8_t*& mem);
211  template <> _NetworkExport bool     SynchronisableVariable<const long double>::checkEquality(uint8_t* mem);
212  template <> _NetworkExport uint32_t SynchronisableVariable<const std::string>::returnSize();
213  template <> _NetworkExport void     SynchronisableVariable<const std::string>::setAndIncrease(uint8_t*& mem);
214  template <> _NetworkExport void     SynchronisableVariable<const std::string>::getAndIncrease(uint8_t*& mem);
215  template <> _NetworkExport bool     SynchronisableVariable<const std::string>::checkEquality(uint8_t* mem);
216  template <> _NetworkExport uint32_t SynchronisableVariable<const Degree>::returnSize();
217  template <> _NetworkExport void     SynchronisableVariable<const Degree>::setAndIncrease(uint8_t*& mem);
218  template <> _NetworkExport void     SynchronisableVariable<const Degree>::getAndIncrease(uint8_t*& mem);
219  template <> _NetworkExport bool     SynchronisableVariable<const Degree>::checkEquality(uint8_t* mem);
220
221
222
223// ================= Bidirectional Part ================
224
225    template <class T> SynchronisableVariableBidirectional<T>::SynchronisableVariableBidirectional(T& variable, uint8_t master, NetworkCallbackBase *cb):
226    SynchronisableVariable<T>( variable, master, cb ), varBuffer_( variable ), varReference_( 0 )
227    {
228    }
229
230    template <class T> SynchronisableVariableBidirectional<T>::~SynchronisableVariableBidirectional()
231    {
232    }
233
234    template <class T> void SynchronisableVariableBidirectional<T>::getData(uint8_t*& mem, uint8_t mode)
235    {
236      if ( this->mode_ == mode )
237      {   // we are master for this variable and have to check whether to change the varReference
238        if( this->varBuffer_ != this->variable_ )
239        {
240          this->varReference_++;
241          memcpy((void*)&this->varBuffer_, &this->variable_, sizeof(this->variable_));
242        }
243      }
244  // write the reference number to the stream
245      *static_cast<uint8_t*>(mem) = varReference_;
246      mem += sizeof(this->varReference_);
247  // now write the content
248      SynchronisableVariable<T>::getAndIncrease( mem );
249//   mem += SynchronisableVariable<T>::getSize();
250    }
251
252    template <class T> void SynchronisableVariableBidirectional<T>::putData(uint8_t*& mem, uint8_t mode, bool forceCallback)
253    {
254      bool callback = false;
255      if ( this->mode_ == mode )
256      {   //        MASTER
257        // check that the client (source of the data) has a recent version of this variable
258        if ( *static_cast<uint8_t*>(mem) != this->varReference_ )
259        { // wrong reference number, so discard the data
260          mem += getSize( mode ); // SynchronisableVariableBidirectional::getSize returns size of variable + reference
261          return;
262        }
263        else{
264          // apply data
265          mem += sizeof(varReference_);
266          if ( SynchronisableVariableBidirectional<T>::checkEquality( mem )==true )
267          {
268            mem += SynchronisableVariable<T>::getSize( mode );
269            return;
270          }
271          else
272          {
273            memcpy((void*)&this->varBuffer_, &this->variable_, sizeof(T));
274            if ( this->callback_ != 0 )
275              callback = true;
276          }
277        }
278      }
279      else
280      {   // we are slave for this variable
281        if (*static_cast<uint8_t*>(mem) == this->varReference_ && !forceCallback)
282        {
283          mem += getSize( mode ); //just skip the variable because nothing changed
284          return;
285        }
286        else
287        {
288          this->varReference_ = *static_cast<uint8_t*>(mem);
289          mem += sizeof(varReference_);
290          if ( SynchronisableVariable<T>::checkEquality( mem ) == false )
291          {
292            // value changed so remark for callback
293            if ( this->callback_ != 0 )
294              callback = true;
295          }
296        }
297      }
298  // now write the data
299      SynchronisableVariable<T>::setAndIncrease(mem);
300  // now do a callback if neccessary
301      if ( callback )
302        NetworkCallbackManager::triggerCallback( this->callback_ );
303        //this->callback_->call();
304    }
305
306    template <class T> uint32_t SynchronisableVariableBidirectional<T>::getSize(uint8_t mode)
307    {
308      return SynchronisableVariable<T>::returnSize() + sizeof(varReference_);
309    }
310 
311
312}
313
314
315#endif
Note: See TracBrowser for help on using the repository browser.