Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/trunk/src/lib/network/synchronizeable.h @ 6818

Last change on this file since 6818 was 6815, checked in by bensch, 19 years ago

orxonox/trunk: merged branches/network back to the trunk.
merged with command:
svn merge https://svn.orxonox.net/orxonox/branches/network . -r6774:HEAD

no conflicts…
thats what i call orthogonal work

File size: 11.1 KB
Line 
1/*!
2 * @file connection_monitor.h
3    \brief interface for all classes that have to be synchronized
4 */
5
6#ifndef _SYNCHRONIZEABLE_H
7#define _SYNCHRONIZEABLE_H
8
9#include "base_object.h"
10#include "netdefs.h"
11#include "converter.h"
12
13
14
15#include <vector>
16#include <list>
17
18//State constants: They have to be of the form 2^n
19#define STATE_SERVER 1
20#define STATE_OUTOFSYNC 2
21#define STATE_REQUESTEDSYNC 4
22
23enum {
24  NWT_SS_WE_STATE = 1000000,
25  NWT_SS_B,
26  NWT_SS_FLAGS,
27  NWT_SS_MOUSEDIRX,
28  NWT_SS_MOUSEDIRY,
29  NWT_SS_MOUSEDIRZ,
30  NWT_SS_MOUSEDIRW,
31  NWT_SS_PN_SYNC,
32  NWT_SS_VELX,
33  NWT_SS_VELY,
34  NWT_SS_VELZ,
35 
36  NWT_HS_HOST_ID,
37  NWT_HS_NGM_ID,
38 
39  NWT_PN_BO_WRITESTATE,
40  NWT_PN_PARENTMODE,
41  NWT_PN_COORX,
42  NWT_PN_COORY,
43  NWT_PN_COORZ,
44  NWT_PN_ROTX,
45  NWT_PN_ROTY,
46  NWT_PN_ROTZ,
47  NWT_PN_ROTV,
48 
49  NWT_PN_FLAGS,
50  NWT_PN_SCOORX,
51  NWT_PN_SCOORY,
52  NWT_PN_SCOORZ,
53  NWT_PN_SROTX,
54  NWT_PN_SROTY,
55  NWT_PN_SROTZ,
56  NWT_PN_SROTV,
57 
58  NWT_BO_NAME,
59 
60  NWT_WE_PN_WRITESTATE,
61  NWT_WE_PN_MODELFILENAME,
62  NWT_WE_PN_SCALING,
63 
64  NWT_GT_WE_STATE,
65 
66  NWT_SB_WE_STATE,
67  NWT_SB_SIZE,
68  NWT_SB_TEXTURENAME,
69 
70  NWT_TER_WE_STATE,
71 
72  NWT_PU_WE_STATE,
73 
74  NWT_TPU_WE_STATE,
75 
76  NWT_LPU_WE_STATE,
77 
78  NWT_WPU_WE_STATE,
79 
80  NWT_PPU_WE_STATE,
81  NWT_PPU_TYPE,
82  NWT_PPU_VALUE,
83  NWT_PPU_MINVALUE,
84  NWT_PPU_MAXVALUE,
85
86  NWT_WAT_STATE,
87  NWT_WAT_WE_STATE,
88  NWT_WAT_SIZEX,
89  NWT_WAT_SIZEY,
90  NWT_WAT_RESX,
91  NWT_WAT_RESY,
92  NWT_WAT_HEIGHT
93};
94
95
96//macros to help writing data in byte buffer
97/*
98 * Important: these macros must be used in
99 *     SYNCHELP_READ_*:  virtual void      writeBytes(const byte* data, int length, int sender);
100 *     SYNCHELP_WRITE_*: virtual int       readBytes(byte* data, int maxLength, int * reciever);
101 * with the same argument names!
102 *
103 * SYNCHELP_WRITE_BEGIN()
104 * SYNCHELP_WRITE_INT(i)
105 * SYNCHELP_WRITE_FLOAT(f)
106 * SYNCHELP_WRITE_BYTE(b)
107 * SYNCHELP_WRITE_STRING(s)
108 * SYNCHELP_WRITE_N
109 *
110 * SYNCHELP_READ_BEGIN()
111 * SYNCHELP_READ_INT(i)
112 * SYNCHELP_READ_FLOAT(f)
113 * SYNCHELP_READ_STRING(s,l) l = size of buffer s
114 * SYNCHELP_READ_STRINGM(s)  allocates memory for string! you have to free this after
115 * SYNCHELP_READ_BYTE(b)
116 * SYNCHELP_READ_N
117 *
118 *
119 *
120 * Example 1:
121 *  SYNCHELP_READ_BEGIN();
122 *  SYNCHELP_READ_FLOAT(size);
123 *  SYNCHELP_READ_STRING( textureName, 1024 ); //1024 is the length of textureName
124 *
125 * Example 2:
126 *  SYNCHELP_WRITE_BEGIN();
127 *  SYNCHELP_WRITE_FLOAT(this->size);
128 *  SYNCHELP_WRITE_STRING(this->textureName);
129 *  return SYNCHELP_WRITE_N;
130 *
131 */
132#define SYNCHELP_WRITE_DEBUG(n) {\
133  __synchelp_write_n = Converter::intToByteArray( n, data+__synchelp_write_i, maxLength-__synchelp_write_i ); \
134  assert( __synchelp_write_n == INTSIZE ); \
135  __synchelp_write_i += __synchelp_write_n; \
136}
137
138#define SYNCHELP_READ_DEBUG(n) {  \
139  int nn; \
140  __synchelp_read_n = Converter::byteArrayToInt( data+__synchelp_read_i, &nn );  \
141  assert( __synchelp_read_n == INTSIZE ); \
142  if ( n != nn ) { \
143    PRINTF(1)("Check your code! read/writes not in right order! read %d instead of %d\n", nn, n); \
144    assert( false ); \
145  } \
146  __synchelp_read_i += __synchelp_read_n; \
147}
148
149#define SYNCHELP_WRITE_BEGIN()    int __synchelp_write_i = 0; \
150                                  int __synchelp_write_n
151#define SYNCHELP_WRITE_INT(i,n) { SYNCHELP_WRITE_DEBUG(n); \
152                                __synchelp_write_n = \
153                                Converter::intToByteArray( i, data+__synchelp_write_i, maxLength-__synchelp_write_i ); \
154                                assert( __synchelp_write_n == INTSIZE ); \
155                                if ( __synchelp_write_n <= 0) \
156{ \
157                                  PRINTF(1)("Buffer is too small to store a int\n"); \
158                                  return 0; \
159} \
160                                __synchelp_write_i += __synchelp_write_n; \
161}
162#define SYNCHELP_WRITE_FLOAT(f,n) { SYNCHELP_WRITE_DEBUG(n); \
163                                __synchelp_write_n = \
164                                Converter::floatToByteArray( f, data+__synchelp_write_i, maxLength-__synchelp_write_i ); \
165                                assert( __synchelp_write_n == FLOATSIZE ); \
166                                if ( __synchelp_write_n <= 0) \
167{ \
168                                  PRINTF(1)("Buffer is too small to store a float\n"); \
169                                  return 0; \
170} \
171                                __synchelp_write_i += __synchelp_write_n; \
172}
173#define SYNCHELP_WRITE_BYTE(b,n) { SYNCHELP_WRITE_DEBUG(n); \
174                                \
175                                if (maxLength - __synchelp_write_i < 1) \
176{ \
177                                  PRINTF(1)("Buffer is too small to store string\n"); \
178                                  return 0; \
179} \
180                                data[__synchelp_write_i] = b; \
181                                __synchelp_write_i++; \
182}
183#define SYNCHELP_WRITE_STRING(s,n) { SYNCHELP_WRITE_DEBUG(n); \
184                                if (s!=NULL) {\
185                                __synchelp_write_n = \
186                                Converter::stringToByteArray( s, data+__synchelp_write_i, strlen(s), maxLength-__synchelp_write_i ); \
187                                assert( __synchelp_write_n == strlen(s)+INTSIZE ); \
188                                } else {\
189                                __synchelp_write_n = \
190                                Converter::stringToByteArray( "", data+__synchelp_write_i, strlen(""), maxLength-__synchelp_write_i ); \
191                                assert( __synchelp_write_n == strlen("")+INTSIZE ); } \
192                                if ( __synchelp_write_n <= 0) \
193{ \
194                                  PRINTF(1)("Buffer is too small to store string\n"); \
195                                  return 0; \
196} \
197                                __synchelp_write_i += __synchelp_write_n; \
198}
199#define SYNCHELP_WRITE_N        __synchelp_write_i
200#define SYNCHELP_WRITE_FKT(f,n)   { SYNCHELP_WRITE_DEBUG(n); \
201                                  __synchelp_write_i += \
202                                  f( data+__synchelp_write_i, maxLength-__synchelp_write_i ); \
203                                }
204
205
206#define SYNCHELP_READ_BEGIN()     int __synchelp_read_i = 0; \
207                                  int __synchelp_read_n
208
209#define SYNCHELP_READ_INT(i,n)       { SYNCHELP_READ_DEBUG(n); \
210                                    if ( length-__synchelp_read_i < INTSIZE ) \
211{ \
212                                      PRINTF(1)("There is not enough data to read an int\n");  \
213                                      return 0; \
214} \
215                                    __synchelp_read_n = Converter::byteArrayToInt( data+__synchelp_read_i, &i );  \
216                                    assert( __synchelp_read_n == INTSIZE ); \
217                                    __synchelp_read_i += __synchelp_read_n; \
218}
219#define SYNCHELP_READ_FLOAT(f,n)    { SYNCHELP_READ_DEBUG(n); \
220                                    if ( length-__synchelp_read_i < FLOATSIZE ) \
221{ \
222                                      PRINTF(1)("There is not enough data to read a flaot\n");  \
223                                      return 0; \
224} \
225                                    __synchelp_read_n = Converter::byteArrayToFloat( data+__synchelp_read_i, &f );  \
226                                    assert( __synchelp_read_n == FLOATSIZE ) ;\
227                                    __synchelp_read_i += __synchelp_read_n; \
228}
229#define SYNCHELP_READ_STRING(s,l,n)    {SYNCHELP_READ_DEBUG(n); \
230                                    __synchelp_read_n = Converter::byteArrayToString( data+__synchelp_read_i, s, l );  \
231                                    assert( __synchelp_read_n == strlen(s)+INTSIZE ) ;\
232                                    if ( __synchelp_read_n <0 )  \
233{ \
234                                      PRINTF(1)("There is not enough data to read string\n");  \
235                                      return 0; \
236} \
237                                    __synchelp_read_i += __synchelp_read_n; \
238}
239#define SYNCHELP_READ_STRINGM(s,n)    { SYNCHELP_READ_DEBUG(n); \
240                                    __synchelp_read_n = Converter::byteArrayToStringM( data+__synchelp_read_i, s );  \
241                                    assert( __synchelp_read_n == strlen(s)+INTSIZE ) ;\
242                                    if ( __synchelp_read_n <0 )  \
243{ \
244                                      PRINTF(1)("There is not enough data to read string\n");  \
245                                      return 0; \
246} \
247                                    __synchelp_read_i += __synchelp_read_n; \
248}
249#define SYNCHELP_READ_BYTE(b,n)      { SYNCHELP_READ_DEBUG(n); \
250                                    if ( length-__synchelp_read_i < 1 ) \
251{ \
252                                      PRINTF(1)("There is not enough data to read a byte\n");  \
253                                      return 0; \
254} \
255                                    b = data[__synchelp_read_i]; \
256                                    __synchelp_read_i ++;  \
257}
258#define SYNCHELP_READ_FKT(f,n)   { SYNCHELP_READ_DEBUG(n); \
259                                  __synchelp_read_i += \
260                                  f( data+__synchelp_read_i, length-__synchelp_read_i, sender); \
261                                  }
262#define SYNCHELP_READ_REMAINING() ( length-__synchelp_read_i )
263#define SYNCHELP_READ_NEXTBYTE() ( data[__synchelp_read_i] )
264#define SYNCHELP_READ_N           __synchelp_read_i
265
266class NetworkStream;
267
268
269class Synchronizeable : virtual public BaseObject
270{
271
272  public:
273    Synchronizeable();
274    virtual ~Synchronizeable();
275
276    virtual int       writeBytes(const byte* data, int length, int sender);
277    virtual int       readBytes(byte* data, int maxLength, int * reciever);
278    virtual void      writeDebug() const;
279    virtual void      readDebug() const;
280
281    void setIsServer( bool isServer );
282    void setIsOutOfSync( bool outOfSync );
283    void setRequestedSync( bool requestedSync );
284    bool isServer();
285    bool isOutOfSync();
286    bool requestedSync();
287
288    inline void setUniqueID( int id ){ uniqueID = id; }
289    inline int  getUniqueID() const { return uniqueID; }
290    inline int getHostID() { return this->hostID; }
291
292    inline int getOwner(){ return owner; }
293    inline void setOwner(int owner){ this->owner = owner; }
294
295    /** @returns true if this Synchronizeable has to be synchronized over network */
296    inline bool beSynchronized() { return this->bSynchronize; }
297    /** @param bSynchronize sets the Synchronizeable to be sunchronized or not */
298    inline void setSynchronized(bool bSynchronize) { this->bSynchronize = bSynchronize; }
299
300    inline void requestSync( int hostID ){ this->synchronizeRequests.push_back( hostID ); }
301    inline int getRequestSync( void ){ if ( this->synchronizeRequests.size()>0 ){ int n = *(synchronizeRequests.begin()); synchronizeRequests.pop_front(); return n; } else { return -1; } };
302
303    inline void setNetworkStream(NetworkStream* stream) { this->networkStream = stream; }
304    inline NetworkStream* getNetworkStream() { return this->networkStream; }
305
306
307  protected:
308    NetworkStream*    networkStream;
309    int               state;
310
311
312  private:
313    int               uniqueID;
314    int               owner;
315    int               hostID;
316    bool              bSynchronize;
317
318    std::list<int>    synchronizeRequests;
319
320};
321#endif /* _SYNCHRONIZEABLE_H */
Note: See TracBrowser for help on using the repository browser.