Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

Last change on this file since 6936 was 6868, checked in by bensch, 19 years ago

orxonox/trunk: merged the Network back to the trunk.
merged with command
svn merge https://svn.orxonox.net/orxonox/branches/network . -r6817:HEAD
no conflicts

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