Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

Last change on this file since 2312 was 2309, checked in by scheusso, 16 years ago

made some adjustments mostly to the networkid (classid) in order to have it platform independent

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