Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

Last change on this file since 6788 was 6788, checked in by rennerc, 18 years ago

redesigned spaceship sync
fixed bug in syncmacro

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