Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/branches/network/src/lib/network/synchronizeable.h @ 6937

Last change on this file since 6937 was 6937, checked in by patrick, 18 years ago

network: implemented network cd system

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