Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

Last change on this file since 7952 was 7230, checked in by bensch, 19 years ago

orxonox/trunk: merged the std::branche back

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