Index: trunk/src/lib/network/synchronizeable.h
===================================================================
--- trunk/src/lib/network/synchronizeable.h	(revision 7230)
+++ trunk/src/lib/network/synchronizeable.h	(revision 7954)
@@ -1,4 +1,4 @@
 /*!
- * @file connection_monitor.h
+ * @file synchronizeable.h
     \brief interface for all classes that have to be synchronized
  */
@@ -10,5 +10,14 @@
 #include "netdefs.h"
 #include "converter.h"
-
+#include "vector.h"
+#include "quaternion.h"
+#include "synchronizeable_var/synchronizeable_var.h"
+#include "synchronizeable_var/synchronizeable_vector.h"
+#include "synchronizeable_var/synchronizeable_quaternion.h"
+#include "synchronizeable_var/synchronizeable_string.h"
+#include "synchronizeable_var/synchronizeable_int.h"
+#include "synchronizeable_var/synchronizeable_float.h"
+#include "synchronizeable_var/synchronizeable_bool.h"
+#include "synchronizeable_var/synchronizeable_uint.h"
 
 
@@ -18,285 +27,20 @@
 //State constants: They have to be of the form 2^n
 #define STATE_SERVER 1
-#define STATE_OUTOFSYNC 2
-#define STATE_REQUESTEDSYNC 4
 
-enum {
-  NWT_SS_WE_STATE = 1000000,
-  NWT_SS_B,
-  NWT_SS_FLAGS,
-  NWT_SS_MOUSEDIRX,
-  NWT_SS_MOUSEDIRY,
-  NWT_SS_MOUSEDIRZ,
-  NWT_SS_MOUSEDIRW,
-  NWT_SS_PN_SYNC,
-  NWT_SS_VELX,
-  NWT_SS_VELY,
-  NWT_SS_VELZ,
-  NWT_SS_PL_SYNC,
-  NWT_SS_CO_N,
-  NWT_SS_CO_CLID,
-
-  NWT_HS_HOST_ID,
-  NWT_HS_NGM_ID,
-
-  NWT_PL_B,
-  NWT_PL_FLAGS,
-  NWT_PL_SCORE,
-
-  NWT_PN_BO_WRITESTATE,
-  NWT_PN_PARENTMODE,
-  NWT_PN_COORX,
-  NWT_PN_COORY,
-  NWT_PN_COORZ,
-  NWT_PN_ROTX,
-  NWT_PN_ROTY,
-  NWT_PN_ROTZ,
-  NWT_PN_ROTV,
-
-  NWT_PN_FLAGS,
-  NWT_PN_SCOORX,
-  NWT_PN_SCOORY,
-  NWT_PN_SCOORZ,
-  NWT_PN_SROTX,
-  NWT_PN_SROTY,
-  NWT_PN_SROTZ,
-  NWT_PN_SROTV,
-
-  NWT_BO_NAME,
-
-  NWT_WE_PN_WRITESTATE,
-  NWT_WE_PN_MODELFILENAME,
-  NWT_WE_PN_SCALING,
-
-  NWT_GT_WE_STATE,
-
-  NWT_SB_WE_STATE,
-  NWT_SB_SIZE,
-  NWT_SB_TEXTURENAME,
-
-  NWT_TER_WE_STATE,
-
-  NWT_PU_WE_STATE,
-
-  NWT_TPU_WE_STATE,
-
-  NWT_LPU_WE_STATE,
-
-  NWT_WPU_WE_STATE,
-
-  NWT_PPU_WE_STATE,
-  NWT_PPU_TYPE,
-  NWT_PPU_VALUE,
-  NWT_PPU_MINVALUE,
-  NWT_PPU_MAXVALUE,
-
-  NWT_WAT_STATE,
-  NWT_WAT_WE_STATE,
-  NWT_WAT_SIZEX,
-  NWT_WAT_SIZEY,
-  NWT_WAT_RESX,
-  NWT_WAT_RESY,
-  NWT_WAT_HEIGHT
+struct StateHistoryEntry
+{
+  int             stateId;
+  byte *          data;
+  int             dataLength;
+  std::list<int>  sizeList;
 };
 
+typedef std::list<StateHistoryEntry*> StateHistory;
 
-//macros to help writing data in byte buffer
-/*
- * Important: these macros must be used in
- *     SYNCHELP_READ_*:  virtual void      writeBytes(const byte* data, int length, int sender);
- *     SYNCHELP_WRITE_*: virtual int       readBytes(byte* data, int maxLength, int * reciever);
- * with the same argument names!
- *
- * id is one int out of that enum on top of this comment it is used to identify
- * read/write. when you read a value you have to use exactly the same as you used
- * to write or you will see an assertion failing.
- *
- * SYNCHELP_WRITE_BEGIN()
- * SYNCHELP_WRITE_INT(i,id)
- * SYNCHELP_WRITE_FLOAT(f,id)
- * SYNCHELP_WRITE_BYTE(b,id)
- * SYNCHELP_WRITE_STRING(s,id)
- * SYNCHELP_WRITE_N
- *
- * SYNCHELP_READ_BEGIN()
- * SYNCHELP_READ_INT(i,id)
- * SYNCHELP_READ_FLOAT(f,id)
- * SYNCHELP_READ_STRING(s,l,id) l = size of buffer s
- * SYNCHELP_READ_STRINGM(s,id)  allocates memory for string! you have to delete this later
- * SYNCHELP_READ_BYTE(b,id)
- * SYNCHELP_READ_REMAINING() returns the remaining buffer size
- * SYNCHELP_READ_NEXTBYTE()  reads the next byte but it is not removed from the buffer
- * SYNCHELP_READ_N
- *
- *
- *
- * Example 1:
- *  SYNCHELP_READ_BEGIN();
- *  SYNCHELP_READ_FLOAT(size);
- *  SYNCHELP_READ_STRING( textureName, 1024 ); //1024 is the length of textureName
- *  delete[] textureName;
- *  textureName = NULL;
- *  SYNCHELP_READ_STRINGM( texturename );      //this will call new char[strlen()+1]
- *
- * Example 2:
- *  SYNCHELP_WRITE_BEGIN();
- *  SYNCHELP_WRITE_FLOAT(this->size);
- *  SYNCHELP_WRITE_STRING(this->textureName);
- *  return SYNCHELP_WRITE_N;
- *
- */
+typedef std::vector<StateHistory> UserStateHistory;
 
-#define SYNCHELP_WRITE_DEBUG(n) {\
-  __synchelp_write_n = Converter::intToByteArray( n, data+__synchelp_write_i, maxLength-__synchelp_write_i ); \
-  assert( __synchelp_write_n == INTSIZE ); \
-  __synchelp_write_i += __synchelp_write_n; \
-}
-
-#define SYNCHELP_READ_DEBUG(n) {  \
-  int nn; \
-  __synchelp_read_n = Converter::byteArrayToInt( data+__synchelp_read_i, &nn );  \
-  assert( __synchelp_read_n == INTSIZE ); \
-  if ( n != nn ) { \
-    PRINTF(1)("Check your code! read/writes not in right order! read %d instead of %d\n", nn, n); \
-    assert( false ); \
-  } \
-  __synchelp_read_i += __synchelp_read_n; \
-}
-
-#define SYNCHELP_WRITE_BEGIN()    int __synchelp_write_i = 0; \
-                                  int __synchelp_write_n
-#define SYNCHELP_WRITE_INT(i,n) { SYNCHELP_WRITE_DEBUG(n); \
-                                __synchelp_write_n = \
-                                Converter::intToByteArray( i, data+__synchelp_write_i, maxLength-__synchelp_write_i ); \
-                                assert( __synchelp_write_n == INTSIZE ); \
-                                if ( __synchelp_write_n <= 0) \
-{ \
-                                  PRINTF(1)("Buffer is too small to store a int\n"); \
-                                  return 0; \
-} \
-                                __synchelp_write_i += __synchelp_write_n; \
-}
-#define SYNCHELP_WRITE_FLOAT(f,n) { SYNCHELP_WRITE_DEBUG(n); \
-                                __synchelp_write_n = \
-                                Converter::floatToByteArray( f, data+__synchelp_write_i, maxLength-__synchelp_write_i ); \
-                                assert( __synchelp_write_n == FLOATSIZE ); \
-                                if ( __synchelp_write_n <= 0) \
-{ \
-                                  PRINTF(1)("Buffer is too small to store a float\n"); \
-                                  return 0; \
-} \
-                                __synchelp_write_i += __synchelp_write_n; \
-}
-#define SYNCHELP_WRITE_BYTE(b,n) { SYNCHELP_WRITE_DEBUG(n); \
-                                \
-                                if (maxLength - __synchelp_write_i < 1) \
-{ \
-                                  PRINTF(1)("Buffer is too small to store string\n"); \
-                                  return 0; \
-} \
-                                data[__synchelp_write_i] = b; \
-                                __synchelp_write_i++; \
-}
-#define SYNCHELP_WRITE_STRING(s,n) { SYNCHELP_WRITE_DEBUG(n); \
-                                __synchelp_write_n = \
-                                Converter::stringToByteArray( s, data+__synchelp_write_i, maxLength-__synchelp_write_i ); \
-                                assert( __synchelp_write_n == ((std::string)s).length()+INTSIZE ); \
-                                if ( __synchelp_write_n <= 0) \
-{ \
-                                  PRINTF(1)("Buffer is too small to store string\n"); \
-                                  return 0; \
-} \
-                                __synchelp_write_i += __synchelp_write_n; \
-}
-#define SYNCHELP_WRITE_N        __synchelp_write_i
-#define SYNCHELP_WRITE_FKT(f,n)   { SYNCHELP_WRITE_DEBUG(n); \
-                                  PRINTF(0)("calling %s with %d left\n", #f, maxLength - __synchelp_write_i);  \
-                                  byte * spos = data+__synchelp_write_i;  \
-                                  if (maxLength - __synchelp_write_i < INTSIZE) \
-{ \
-                                    PRINTF(1)("Buffer is too small to store more data\n"); \
-                                    return 0; \
-} \
-                                  __synchelp_write_i += INTSIZE; \
-                                  __synchelp_write_n = \
-                                  f( data+__synchelp_write_i, maxLength-__synchelp_write_i ); \
-                                  __synchelp_write_i += __synchelp_write_n;  \
-                                  Converter::intToByteArray( __synchelp_write_n, spos, INTSIZE ); \
-                                }
-
-
-#define SYNCHELP_READ_BEGIN()     int __synchelp_read_i = 0; \
-                                  int __synchelp_read_n
-
-#define SYNCHELP_READ_INT(i,n)       { SYNCHELP_READ_DEBUG(n); \
-                                    if ( length-__synchelp_read_i < INTSIZE ) \
-{ \
-                                      PRINTF(1)("There is not enough data to read an int\n");  \
-                                      return 0; \
-} \
-                                    __synchelp_read_n = Converter::byteArrayToInt( data+__synchelp_read_i, &i );  \
-                                    assert( __synchelp_read_n == INTSIZE ); \
-                                    __synchelp_read_i += __synchelp_read_n; \
-}
-#define SYNCHELP_READ_FLOAT(f,n)    { SYNCHELP_READ_DEBUG(n); \
-                                    if ( length-__synchelp_read_i < FLOATSIZE ) \
-{ \
-                                      PRINTF(1)("There is not enough data to read a flaot\n");  \
-                                      return 0; \
-} \
-                                    __synchelp_read_n = Converter::byteArrayToFloat( data+__synchelp_read_i, &f );  \
-                                    assert( __synchelp_read_n == FLOATSIZE ) ;\
-                                    __synchelp_read_i += __synchelp_read_n; \
-}
-#define SYNCHELP_READ_STRING(s,n)    {SYNCHELP_READ_DEBUG(n); \
-                                    __synchelp_read_n = Converter::byteArrayToString( data+__synchelp_read_i, s, length-__synchelp_read_i );  \
-                                    assert( __synchelp_read_n == s.length()+INTSIZE ) ;\
-                                    if ( __synchelp_read_n <0 )  \
-{ \
-                                      PRINTF(1)("There is not enough data to read string\n");  \
-                                      return 0; \
-} \
-                                    __synchelp_read_i += __synchelp_read_n; \
-}
-#if 0 //not needed any more
-#define SYNCHELP_READ_STRINGM(s,n)    { SYNCHELP_READ_DEBUG(n); \
-                                    __synchelp_read_n = Converter::byteArrayToStringM( data+__synchelp_read_i, s );  \
-                                    assert( __synchelp_read_n == strlen(s)+INTSIZE ) ;\
-                                    if ( __synchelp_read_n <0 )  \
-{ \
-                                      PRINTF(1)("There is not enough data to read string\n");  \
-                                      return 0; \
-} \
-                                    __synchelp_read_i += __synchelp_read_n; \
-}
-#endif
-#define SYNCHELP_READ_BYTE(b,n)      { SYNCHELP_READ_DEBUG(n); \
-                                    if ( length-__synchelp_read_i < 1 ) \
-{ \
-                                      PRINTF(1)("There is not enough data to read a byte\n");  \
-                                      return 0; \
-} \
-                                    b = data[__synchelp_read_i]; \
-                                    __synchelp_read_i ++;  \
-}
-#define SYNCHELP_READ_FKT(f,n)   { SYNCHELP_READ_DEBUG(n); \
-                                  int s; \
-                                  if ( length-__synchelp_read_i < INTSIZE ) \
-{ \
-                                      PRINTF(1)("There is not enough data to read an int\n");  \
-                                      return 0; \
-} \
-                                    __synchelp_read_n = Converter::byteArrayToInt( data+__synchelp_read_i, &s );  \
-                                    assert( __synchelp_read_n == INTSIZE ); \
-                                    __synchelp_read_i += __synchelp_read_n; \
-                                  __synchelp_read_i += \
-                                  f( data+__synchelp_read_i, s, sender); \
-                                  }
-#define SYNCHELP_READ_REMAINING() ( length-__synchelp_read_i )
-#define SYNCHELP_READ_NEXTBYTE() ( data[__synchelp_read_i] )
-#define SYNCHELP_READ_N           __synchelp_read_i
+typedef std::vector<SynchronizeableVar*> SyncVarList;
 
 class NetworkStream;
-
 
 class Synchronizeable : virtual public BaseObject
@@ -307,15 +51,17 @@
     virtual ~Synchronizeable();
 
-    virtual int       writeBytes(const byte* data, int length, int sender);
-    virtual int       readBytes(byte* data, int maxLength, int * reciever);
-    virtual void      writeDebug() const;
-    virtual void      readDebug() const;
+    void setIsServer( bool isServer );
+    bool isServer();
 
-    void setIsServer( bool isServer );
-    void setIsOutOfSync( bool outOfSync );
-    void setRequestedSync( bool requestedSync );
-    bool isServer();
-    bool isOutOfSync();
-    bool requestedSync();
+    virtual void varChangeHandler( std::list<int> & id );
+
+    virtual int getStateDiff( int userId, byte* data, int maxLength, int stateId, int fromStateId, int priorityTH );
+    virtual int setStateDiff( int userId, byte* data, int length, int stateId, int fromStateId );
+    virtual void cleanUpUser( int userId );
+    virtual void handleSentState( int userId, int stateId, int fromStateId );
+    virtual void handleRecvState( int userId, int stateId, int fromStateId );
+
+    void registerVar( SynchronizeableVar * var );
+    int registerVarId( SynchronizeableVar * var );
 
     inline void setUniqueID( int id ){ uniqueID = id; }
@@ -326,11 +72,8 @@
     inline void setOwner(int owner){ this->owner = owner; }
 
-    /** @returns true if this Synchronizeable has to be synchronized over network */
+    /** @returns true if this Synchronizeable wants to be synchronized over network */
     inline bool beSynchronized() { return this->bSynchronize; }
     /** @param bSynchronize sets the Synchronizeable to be sunchronized or not */
     inline void setSynchronized(bool bSynchronize) { this->bSynchronize = bSynchronize; }
-
-    inline void requestSync( int hostID ){ this->synchronizeRequests.push_back( hostID ); }
-    inline int getRequestSync( void ){ if ( this->synchronizeRequests.size()>0 ){ int n = *(synchronizeRequests.begin()); synchronizeRequests.pop_front(); return n; } else { return -1; } };
 
     inline void setNetworkStream(NetworkStream* stream) { this->networkStream = stream; }
@@ -339,15 +82,18 @@
 
   protected:
-    NetworkStream*    networkStream;
+    NetworkStream*    networkStream;  //!< reference network stream we are connected to
     int               state;
 
+  private:
+    int               uniqueID;       //!< unique id assigned to synchronizeable
+    int               mLeafClassId;   //!< store leafClassId to send via states
+    int               owner;          //!< hostId of owner ( 0 if none / server )
+    int               hostID;         //!< my own host id
+    bool              bSynchronize;   //!< do we need beeing synchronized?
 
-  private:
-    int               uniqueID;
-    int               owner;
-    int               hostID;
-    bool              bSynchronize;
+    SyncVarList       syncVarList;    //!< list containing variables to synchronize
 
-    std::list<int>    synchronizeRequests;
+    UserStateHistory  sentStates;     //!< store already sent states to create diffs from, offset corresponds to the user id
+    UserStateHistory  recvStates;     //!< store recieved states to apply diffs, offset corresponds to the user id
 
 };
