Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

Changeset 7954 in orxonox.OLD for trunk/src/lib/network/synchronizeable.h


Ignore:
Timestamp:
May 29, 2006, 3:28:41 PM (19 years ago)
Author:
patrick
Message:

trunk: merged the network branche back to trunk.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/lib/network/synchronizeable.h

    r7230 r7954  
    11/*!
    2  * @file connection_monitor.h
     2 * @file synchronizeable.h
    33    \brief interface for all classes that have to be synchronized
    44 */
     
    1010#include "netdefs.h"
    1111#include "converter.h"
    12 
     12#include "vector.h"
     13#include "quaternion.h"
     14#include "synchronizeable_var/synchronizeable_var.h"
     15#include "synchronizeable_var/synchronizeable_vector.h"
     16#include "synchronizeable_var/synchronizeable_quaternion.h"
     17#include "synchronizeable_var/synchronizeable_string.h"
     18#include "synchronizeable_var/synchronizeable_int.h"
     19#include "synchronizeable_var/synchronizeable_float.h"
     20#include "synchronizeable_var/synchronizeable_bool.h"
     21#include "synchronizeable_var/synchronizeable_uint.h"
    1322
    1423
     
    1827//State constants: They have to be of the form 2^n
    1928#define STATE_SERVER 1
    20 #define STATE_OUTOFSYNC 2
    21 #define STATE_REQUESTEDSYNC 4
    2229
    23 enum {
    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_B,
    43   NWT_PL_FLAGS,
    44   NWT_PL_SCORE,
    45 
    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,
    55 
    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,
    64 
    65   NWT_BO_NAME,
    66 
    67   NWT_WE_PN_WRITESTATE,
    68   NWT_WE_PN_MODELFILENAME,
    69   NWT_WE_PN_SCALING,
    70 
    71   NWT_GT_WE_STATE,
    72 
    73   NWT_SB_WE_STATE,
    74   NWT_SB_SIZE,
    75   NWT_SB_TEXTURENAME,
    76 
    77   NWT_TER_WE_STATE,
    78 
    79   NWT_PU_WE_STATE,
    80 
    81   NWT_TPU_WE_STATE,
    82 
    83   NWT_LPU_WE_STATE,
    84 
    85   NWT_WPU_WE_STATE,
    86 
    87   NWT_PPU_WE_STATE,
    88   NWT_PPU_TYPE,
    89   NWT_PPU_VALUE,
    90   NWT_PPU_MINVALUE,
    91   NWT_PPU_MAXVALUE,
    92 
    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
     30struct StateHistoryEntry
     31{
     32  int             stateId;
     33  byte *          data;
     34  int             dataLength;
     35  std::list<int>  sizeList;
    10036};
    10137
     38typedef std::list<StateHistoryEntry*> StateHistory;
    10239
    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  *
    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  *
    114  * SYNCHELP_WRITE_BEGIN()
    115  * SYNCHELP_WRITE_INT(i,id)
    116  * SYNCHELP_WRITE_FLOAT(f,id)
    117  * SYNCHELP_WRITE_BYTE(b,id)
    118  * SYNCHELP_WRITE_STRING(s,id)
    119  * SYNCHELP_WRITE_N
    120  *
    121  * SYNCHELP_READ_BEGIN()
    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
    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
    137  *  delete[] textureName;
    138  *  textureName = NULL;
    139  *  SYNCHELP_READ_STRINGM( texturename );      //this will call new char[strlen()+1]
    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  */
     40typedef std::vector<StateHistory> UserStateHistory;
    14841
    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 
    166 #define SYNCHELP_WRITE_BEGIN()    int __synchelp_write_i = 0; \
    167                                   int __synchelp_write_n
    168 #define SYNCHELP_WRITE_INT(i,n) { SYNCHELP_WRITE_DEBUG(n); \
    169                                 __synchelp_write_n = \
    170                                 Converter::intToByteArray( i, data+__synchelp_write_i, maxLength-__synchelp_write_i ); \
    171                                 assert( __synchelp_write_n == INTSIZE ); \
    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 }
    179 #define SYNCHELP_WRITE_FLOAT(f,n) { SYNCHELP_WRITE_DEBUG(n); \
    180                                 __synchelp_write_n = \
    181                                 Converter::floatToByteArray( f, data+__synchelp_write_i, maxLength-__synchelp_write_i ); \
    182                                 assert( __synchelp_write_n == FLOATSIZE ); \
    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 }
    190 #define SYNCHELP_WRITE_BYTE(b,n) { SYNCHELP_WRITE_DEBUG(n); \
    191                                 \
    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 }
    200 #define SYNCHELP_WRITE_STRING(s,n) { SYNCHELP_WRITE_DEBUG(n); \
    201                                 __synchelp_write_n = \
    202                                 Converter::stringToByteArray( s, data+__synchelp_write_i, maxLength-__synchelp_write_i ); \
    203                                 assert( __synchelp_write_n == ((std::string)s).length()+INTSIZE ); \
    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
    212 #define SYNCHELP_WRITE_FKT(f,n)   { SYNCHELP_WRITE_DEBUG(n); \
    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 = \
    222                                   f( data+__synchelp_write_i, maxLength-__synchelp_write_i ); \
    223                                   __synchelp_write_i += __synchelp_write_n;  \
    224                                   Converter::intToByteArray( __synchelp_write_n, spos, INTSIZE ); \
    225                                 }
    226 
    227 
    228 #define SYNCHELP_READ_BEGIN()     int __synchelp_read_i = 0; \
    229                                   int __synchelp_read_n
    230 
    231 #define SYNCHELP_READ_INT(i,n)       { SYNCHELP_READ_DEBUG(n); \
    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 } \
    237                                     __synchelp_read_n = Converter::byteArrayToInt( data+__synchelp_read_i, &i );  \
    238                                     assert( __synchelp_read_n == INTSIZE ); \
    239                                     __synchelp_read_i += __synchelp_read_n; \
    240 }
    241 #define SYNCHELP_READ_FLOAT(f,n)    { SYNCHELP_READ_DEBUG(n); \
    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 } \
    247                                     __synchelp_read_n = Converter::byteArrayToFloat( data+__synchelp_read_i, &f );  \
    248                                     assert( __synchelp_read_n == FLOATSIZE ) ;\
    249                                     __synchelp_read_i += __synchelp_read_n; \
    250 }
    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 ) ;\
    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 }
    261 #if 0 //not needed any more
    262 #define SYNCHELP_READ_STRINGM(s,n)    { SYNCHELP_READ_DEBUG(n); \
    263                                     __synchelp_read_n = Converter::byteArrayToStringM( data+__synchelp_read_i, s );  \
    264                                     assert( __synchelp_read_n == strlen(s)+INTSIZE ) ;\
    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 }
    272 #endif
    273 #define SYNCHELP_READ_BYTE(b,n)      { SYNCHELP_READ_DEBUG(n); \
    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 }
    282 #define SYNCHELP_READ_FKT(f,n)   { SYNCHELP_READ_DEBUG(n); \
    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; \
    292                                   __synchelp_read_i += \
    293                                   f( data+__synchelp_read_i, s, sender); \
    294                                   }
    295 #define SYNCHELP_READ_REMAINING() ( length-__synchelp_read_i )
    296 #define SYNCHELP_READ_NEXTBYTE() ( data[__synchelp_read_i] )
    297 #define SYNCHELP_READ_N           __synchelp_read_i
     42typedef std::vector<SynchronizeableVar*> SyncVarList;
    29843
    29944class NetworkStream;
    300 
    30145
    30246class Synchronizeable : virtual public BaseObject
     
    30751    virtual ~Synchronizeable();
    30852
    309     virtual int       writeBytes(const byte* data, int length, int sender);
    310     virtual int       readBytes(byte* data, int maxLength, int * reciever);
    311     virtual void      writeDebug() const;
    312     virtual void      readDebug() const;
     53    void setIsServer( bool isServer );
     54    bool isServer();
    31355
    314     void setIsServer( bool isServer );
    315     void setIsOutOfSync( bool outOfSync );
    316     void setRequestedSync( bool requestedSync );
    317     bool isServer();
    318     bool isOutOfSync();
    319     bool requestedSync();
     56    virtual void varChangeHandler( std::list<int> & id );
     57
     58    virtual int getStateDiff( int userId, byte* data, int maxLength, int stateId, int fromStateId, int priorityTH );
     59    virtual int setStateDiff( int userId, byte* data, int length, int stateId, int fromStateId );
     60    virtual void cleanUpUser( int userId );
     61    virtual void handleSentState( int userId, int stateId, int fromStateId );
     62    virtual void handleRecvState( int userId, int stateId, int fromStateId );
     63
     64    void registerVar( SynchronizeableVar * var );
     65    int registerVarId( SynchronizeableVar * var );
    32066
    32167    inline void setUniqueID( int id ){ uniqueID = id; }
     
    32672    inline void setOwner(int owner){ this->owner = owner; }
    32773
    328     /** @returns true if this Synchronizeable has to be synchronized over network */
     74    /** @returns true if this Synchronizeable wants to be synchronized over network */
    32975    inline bool beSynchronized() { return this->bSynchronize; }
    33076    /** @param bSynchronize sets the Synchronizeable to be sunchronized or not */
    33177    inline void setSynchronized(bool bSynchronize) { this->bSynchronize = bSynchronize; }
    332 
    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; } };
    33578
    33679    inline void setNetworkStream(NetworkStream* stream) { this->networkStream = stream; }
     
    33982
    34083  protected:
    341     NetworkStream*    networkStream;
     84    NetworkStream*    networkStream;  //!< reference network stream we are connected to
    34285    int               state;
    34386
     87  private:
     88    int               uniqueID;       //!< unique id assigned to synchronizeable
     89    int               mLeafClassId;   //!< store leafClassId to send via states
     90    int               owner;          //!< hostId of owner ( 0 if none / server )
     91    int               hostID;         //!< my own host id
     92    bool              bSynchronize;   //!< do we need beeing synchronized?
    34493
    345   private:
    346     int               uniqueID;
    347     int               owner;
    348     int               hostID;
    349     bool              bSynchronize;
     94    SyncVarList       syncVarList;    //!< list containing variables to synchronize
    35095
    351     std::list<int>    synchronizeRequests;
     96    UserStateHistory  sentStates;     //!< store already sent states to create diffs from, offset corresponds to the user id
     97    UserStateHistory  recvStates;     //!< store recieved states to apply diffs, offset corresponds to the user id
    35298
    35399};
Note: See TracChangeset for help on using the changeset viewer.