Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

this is another commit for testing purpose
still trying to get network function calls to work (first success)

  • 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          if ( checkEquality( this->variable_, mem+sizeof(varReference_) )==true )
271          {
272            mem += getSize( mode );
273            return;
274          }
275          else
276          {
277            mem += sizeof(varReference_);
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.