| 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 |  | 
|---|
| 23 |  | 
|---|
| 24 | //macros to help writing data in byte buffer | 
|---|
| 25 | /* | 
|---|
| 26 |  * Important: these macros must be used in | 
|---|
| 27 |  *     SYNCHELP_READ_*:  virtual void      writeBytes(const byte* data, int length, int sender); | 
|---|
| 28 |  *     SYNCHELP_WRITE_*: virtual int       readBytes(byte* data, int maxLength, int * reciever); | 
|---|
| 29 |  * with the same argument names! | 
|---|
| 30 |  * | 
|---|
| 31 |  * SYNCHELP_WRITE_BEGIN() | 
|---|
| 32 |  * SYNCHELP_WRITE_INT(i) | 
|---|
| 33 |  * SYNCHELP_WRITE_FLOAT(f) | 
|---|
| 34 |  * SYNCHELP_WRITE_BYTE(b) | 
|---|
| 35 |  * SYNCHELP_WRITE_STRING(s) | 
|---|
| 36 |  * SYNCHELP_WRITE_N | 
|---|
| 37 |  * | 
|---|
| 38 |  * SYNCHELP_READ_BEGIN() | 
|---|
| 39 |  * SYNCHELP_READ_INT(i) | 
|---|
| 40 |  * SYNCHELP_READ_FLOAT(f) | 
|---|
| 41 |  * SYNCHELP_READ_STRING(s,l) l = size of buffer s | 
|---|
| 42 |  * SYNCHELP_READ_STRINGM(s)  allocates memory for string! you have to free this after | 
|---|
| 43 |  * SYNCHELP_READ_BYTE(b) | 
|---|
| 44 |  * SYNCHELP_READ_N | 
|---|
| 45 |  * | 
|---|
| 46 |  * | 
|---|
| 47 |  * | 
|---|
| 48 |  * Example 1: | 
|---|
| 49 |  *  SYNCHELP_READ_BEGIN(); | 
|---|
| 50 |  *  SYNCHELP_READ_FLOAT(size); | 
|---|
| 51 |  *  SYNCHELP_READ_STRING( textureName, 1024 ); //1024 is the length of textureName | 
|---|
| 52 |  * | 
|---|
| 53 |  * Example 2: | 
|---|
| 54 |  *  SYNCHELP_WRITE_BEGIN(); | 
|---|
| 55 |  *  SYNCHELP_WRITE_FLOAT(this->size); | 
|---|
| 56 |  *  SYNCHELP_WRITE_STRING(this->textureName); | 
|---|
| 57 |  *  return SYNCHELP_WRITE_N; | 
|---|
| 58 |  * | 
|---|
| 59 |  */ | 
|---|
| 60 | #define SYNCHELP_WRITE_BEGIN()    int __synchelp_write_i = 0; \ | 
|---|
| 61 |                                   int __synchelp_write_n | 
|---|
| 62 | #define SYNCHELP_WRITE_INT(i) { __synchelp_write_n = \ | 
|---|
| 63 |                                 Converter::intToByteArray( i, data+__synchelp_write_i, maxLength-__synchelp_write_i ); \ | 
|---|
| 64 |                                 if ( __synchelp_write_n <= 0) \ | 
|---|
| 65 | { \ | 
|---|
| 66 |                                   PRINTF(1)("Buffer is too small to store a int\n"); \ | 
|---|
| 67 |                                   return 0; \ | 
|---|
| 68 | } \ | 
|---|
| 69 |                                 __synchelp_write_i += __synchelp_write_n; \ | 
|---|
| 70 | } | 
|---|
| 71 | #define SYNCHELP_WRITE_FLOAT(f) { __synchelp_write_n = \ | 
|---|
| 72 |                                 Converter::floatToByteArray( f, data+__synchelp_write_i, maxLength-__synchelp_write_i ); \ | 
|---|
| 73 |                                 if ( __synchelp_write_n <= 0) \ | 
|---|
| 74 | { \ | 
|---|
| 75 |                                   PRINTF(1)("Buffer is too small to store a float\n"); \ | 
|---|
| 76 |                                   return 0; \ | 
|---|
| 77 | } \ | 
|---|
| 78 |                                 __synchelp_write_i += __synchelp_write_n; \ | 
|---|
| 79 | } | 
|---|
| 80 | #define SYNCHELP_WRITE_BYTE(b) { \ | 
|---|
| 81 |                                 if (maxLength - __synchelp_write_i < 1) \ | 
|---|
| 82 | { \ | 
|---|
| 83 |                                   PRINTF(1)("Buffer is too small to store string\n"); \ | 
|---|
| 84 |                                   return 0; \ | 
|---|
| 85 | } \ | 
|---|
| 86 |                                 data[__synchelp_write_i] = b; \ | 
|---|
| 87 |                                 __synchelp_write_i++; \ | 
|---|
| 88 | } | 
|---|
| 89 | #define SYNCHELP_WRITE_STRING(s) { if (s!=NULL) \ | 
|---|
| 90 |                                 __synchelp_write_n = \ | 
|---|
| 91 |                                 Converter::stringToByteArray( s, data+__synchelp_write_i, strlen(s), maxLength-__synchelp_write_i ); \ | 
|---|
| 92 |                                 else \ | 
|---|
| 93 |                                 __synchelp_write_n = \ | 
|---|
| 94 |                                 Converter::stringToByteArray( "", data+__synchelp_write_i, strlen(""), maxLength-__synchelp_write_i ); \ | 
|---|
| 95 |                                 if ( __synchelp_write_n <= 0) \ | 
|---|
| 96 | { \ | 
|---|
| 97 |                                   PRINTF(1)("Buffer is too small to store string\n"); \ | 
|---|
| 98 |                                   return 0; \ | 
|---|
| 99 | } \ | 
|---|
| 100 |                                 __synchelp_write_i += __synchelp_write_n; \ | 
|---|
| 101 | } | 
|---|
| 102 | #define SYNCHELP_WRITE_N        __synchelp_write_i | 
|---|
| 103 | #define SYNCHELP_WRITE_FKT(f)   { \ | 
|---|
| 104 |                                   __synchelp_write_i += \ | 
|---|
| 105 |                                   f( data+__synchelp_write_i, maxLength-__synchelp_write_i ); \ | 
|---|
| 106 |                                 } | 
|---|
| 107 |  | 
|---|
| 108 |  | 
|---|
| 109 | #define SYNCHELP_READ_BEGIN()     int __synchelp_read_i = 0; \ | 
|---|
| 110 |                                   int __synchelp_read_n | 
|---|
| 111 |  | 
|---|
| 112 | #define SYNCHELP_READ_INT(i)       { \ | 
|---|
| 113 |                                     if ( length-__synchelp_read_i < INTSIZE ) \ | 
|---|
| 114 | { \ | 
|---|
| 115 |                                       PRINTF(1)("There is not enough data to read an int\n");  \ | 
|---|
| 116 |                                       return 0; \ | 
|---|
| 117 | } \ | 
|---|
| 118 |                                     __synchelp_read_i += Converter::byteArrayToInt( data+__synchelp_read_i, &i );  \ | 
|---|
| 119 | } | 
|---|
| 120 | #define SYNCHELP_READ_FLOAT(f)    { \ | 
|---|
| 121 |                                     if ( length-__synchelp_read_i < FLOATSIZE ) \ | 
|---|
| 122 | { \ | 
|---|
| 123 |                                       PRINTF(1)("There is not enough data to read a flaot\n");  \ | 
|---|
| 124 |                                       return 0; \ | 
|---|
| 125 | } \ | 
|---|
| 126 |                                     __synchelp_read_i += Converter::byteArrayToFloat( data+__synchelp_read_i, &f );  \ | 
|---|
| 127 | } | 
|---|
| 128 | #define SYNCHELP_READ_STRING(s,l)    { \ | 
|---|
| 129 |                                     __synchelp_read_n = Converter::byteArrayToString( data+__synchelp_read_i, s, l );  \ | 
|---|
| 130 |                                     if ( __synchelp_read_n <0 )  \ | 
|---|
| 131 | { \ | 
|---|
| 132 |                                       PRINTF(1)("There is not enough data to read string\n");  \ | 
|---|
| 133 |                                       return 0; \ | 
|---|
| 134 | } \ | 
|---|
| 135 |                                     __synchelp_read_i += __synchelp_read_n; \ | 
|---|
| 136 | } | 
|---|
| 137 | #define SYNCHELP_READ_STRINGM(s)    { \ | 
|---|
| 138 |                                     __synchelp_read_n = Converter::byteArrayToStringM( data+__synchelp_read_i, s );  \ | 
|---|
| 139 |                                     if ( __synchelp_read_n <0 )  \ | 
|---|
| 140 | { \ | 
|---|
| 141 |                                       PRINTF(1)("There is not enough data to read string\n");  \ | 
|---|
| 142 |                                       return 0; \ | 
|---|
| 143 | } \ | 
|---|
| 144 |                                     __synchelp_read_i += __synchelp_read_n; \ | 
|---|
| 145 | } | 
|---|
| 146 | #define SYNCHELP_READ_BYTE(b)      { \ | 
|---|
| 147 |                                     if ( length-__synchelp_read_i < 1 ) \ | 
|---|
| 148 | { \ | 
|---|
| 149 |                                       PRINTF(1)("There is not enough data to read a byte\n");  \ | 
|---|
| 150 |                                       return 0; \ | 
|---|
| 151 | } \ | 
|---|
| 152 |                                     b = data[__synchelp_read_i]; \ | 
|---|
| 153 |                                     __synchelp_read_i ++;  \ | 
|---|
| 154 | } | 
|---|
| 155 | #define SYNCHELP_READ_FKT(f)   { \ | 
|---|
| 156 |                                   __synchelp_read_i += \ | 
|---|
| 157 |                                   f( data+__synchelp_read_i, length-__synchelp_read_i, sender); \ | 
|---|
| 158 |                                   } | 
|---|
| 159 | #define SYNCHELP_READ_N           __synchelp_read_i | 
|---|
| 160 |  | 
|---|
| 161 | class NetworkStream; | 
|---|
| 162 |  | 
|---|
| 163 |  | 
|---|
| 164 | class Synchronizeable : virtual public BaseObject | 
|---|
| 165 |   { | 
|---|
| 166 |   public: | 
|---|
| 167 |     Synchronizeable(); | 
|---|
| 168 |     ~Synchronizeable(); | 
|---|
| 169 |  | 
|---|
| 170 |     virtual int       writeBytes(const byte* data, int length, int sender); | 
|---|
| 171 |     virtual int       readBytes(byte* data, int maxLength, int * reciever); | 
|---|
| 172 |     virtual void      writeDebug() const; | 
|---|
| 173 |     virtual void      readDebug() const; | 
|---|
| 174 |  | 
|---|
| 175 |     void setIsServer( bool isServer ); | 
|---|
| 176 |     void setIsOutOfSync( bool outOfSync ); | 
|---|
| 177 |     void setRequestedSync( bool requestedSync ); | 
|---|
| 178 |     bool isServer(); | 
|---|
| 179 |     bool isOutOfSync(); | 
|---|
| 180 |     bool requestedSync(); | 
|---|
| 181 |     inline void setUniqueID( int id ){ uniqueID = id; } | 
|---|
| 182 |     inline int  getUniqueID() const { return uniqueID; }; | 
|---|
| 183 |     inline void requestSync( int hostID ){ this->synchronizeRequests.push_back( hostID ); } | 
|---|
| 184 |     inline int getRequestSync( void ){ if ( this->synchronizeRequests.size()>0 ){ int n = *(synchronizeRequests.begin()); synchronizeRequests.pop_front(); return n; } else { return -1; } }; | 
|---|
| 185 |     inline int getHostID() { return this->hostID; } | 
|---|
| 186 |  | 
|---|
| 187 |     inline int getOwner(){ return owner; } | 
|---|
| 188 |     inline void setOwner(int owner){ this->owner = owner; } | 
|---|
| 189 |  | 
|---|
| 190 |     inline void setNetworkStream(NetworkStream* stream) { this->networkStream = stream; } | 
|---|
| 191 |  | 
|---|
| 192 |   private: | 
|---|
| 193 |  | 
|---|
| 194 |     int               uniqueID; | 
|---|
| 195 |  | 
|---|
| 196 |  | 
|---|
| 197 |  | 
|---|
| 198 |     //static std::vector<Synchronizeable*> classList; | 
|---|
| 199 |     int owner; | 
|---|
| 200 |     int hostID; | 
|---|
| 201 |  | 
|---|
| 202 |     std::list<int> synchronizeRequests; | 
|---|
| 203 |  | 
|---|
| 204 |   protected: | 
|---|
| 205 |     NetworkStream* networkStream; | 
|---|
| 206 |     int state; | 
|---|
| 207 |  | 
|---|
| 208 |   }; | 
|---|
| 209 | #endif /* _SYNCHRONIZEABLE_H */ | 
|---|