Index: code/branches/network64/src/network/synchronisable/CMakeLists.txt
===================================================================
--- code/branches/network64/src/network/synchronisable/CMakeLists.txt	(revision 2211)
+++ code/branches/network64/src/network/synchronisable/CMakeLists.txt	(revision 2245)
@@ -1,4 +1,5 @@
 SET( SRC_FILES
   Synchronisable.cc
+  SynchronisableVariable.cc
 )
 
Index: code/branches/network64/src/network/synchronisable/Synchronisable.cc
===================================================================
--- code/branches/network64/src/network/synchronisable/Synchronisable.cc	(revision 2211)
+++ code/branches/network64/src/network/synchronisable/Synchronisable.cc	(revision 2245)
@@ -40,4 +40,5 @@
 
 #include "Synchronisable.h"
+#include "SynchronisableSpecialisations.cc" // this defines all specialisations for registerVariable
 
 #include <cstring>
@@ -78,5 +79,4 @@
       objectID=OBJECTID_UNKNOWN;
     classID = (unsigned int)-1;
-    syncList = new std::list<synchronisableVariable *>;
 
 
@@ -114,6 +114,6 @@
     // delete callback function objects
     if(!Identifier::isCreatingHierarchy()){
-      for(std::list<synchronisableVariable *>::iterator it = syncList->begin(); it!=syncList->end(); it++)
-        delete (*it)->callback;
+      for(std::list<SynchronisableVariableBase*>::iterator it = syncList.begin(); it!=syncList.end(); it++)
+        delete (*it);
       if (this->objectMode_ != 0x0 && (Host::running() && Host::isServer()))
         deletedObjects_.push(objectID);
@@ -127,20 +127,4 @@
     if (it != objectMap_.end())
       objectMap_.erase(it);
-  }
-
-  /**
-   * This function gets called after all neccessary data has been passed to the object
-   * Overload this function and recall the create function of the parent class
-   * @return true/false
-   */
-  bool Synchronisable::create(){
-    this->classID = this->getIdentifier()->getNetworkID();
-//     COUT(4) << "creating synchronisable: setting classid from " << this->getIdentifier()->getName() << " to: " << classID << std::endl;
-
-//     COUT(3) << "construct synchronisable +++" << objectID << " | " << classID << std::endl;
-//     objectMap_[objectID]=this;
-//     assert(objectMap_[objectID]==this);
-//     assert(objectMap_[objectID]->objectID==objectID);
-    return true;
   }
 
@@ -204,5 +188,5 @@
     if (b)
     {
-        b = no->create();
+//        b = no->create();
         assert(b);
     }
@@ -261,5 +245,6 @@
   * @param cb callback object that should get called, if the value of the variable changes
   */
-  void Synchronisable::registerVariable(void *var, int size, variableType t, uint8_t mode, NetworkCallbackBase *cb){
+
+/*  void Synchronisable::registerVariable(void *var, int size, variableType t, uint8_t mode, NetworkCallbackBase *cb){
     assert( mode==direction::toclient || mode==direction::toserver || mode==direction::serverMaster || mode==direction::clientMaster);
     // create temporary synch.Var struct
@@ -294,22 +279,6 @@
     }
 #endif
-  }
-
-  void Synchronisable::unregisterVariable(void *var){
-    std::list<synchronisableVariable *>::iterator it = syncList->begin();
-    while(it!=syncList->end()){
-      if( (*it)->var == var ){
-        delete *it;
-        syncList->erase(it);
-        return;
-      }
-      else
-        it++;
-    }
-    bool unregistered_nonexistent_variable = false;
-    assert(unregistered_nonexistent_variable); //if we reach this point something went wrong:
-    // the variable has not been registered before
-  }
-
+  }*/
+  
 
   /**
@@ -343,5 +312,5 @@
     assert(this->classID==this->getIdentifier()->getNetworkID());
 //     this->classID=this->getIdentifier()->getNetworkID(); // TODO: correct this
-    std::list<synchronisableVariable *>::iterator i;
+    std::list<SynchronisableVariableBase*>::iterator i;
     unsigned int size;
     size=getSize(id, mode);
@@ -361,57 +330,7 @@
     COUT(5) << "Synchronisable getting data from objectID: " << objectID << " classID: " << classID << " length: " << size << std::endl;
     // copy to location
-    for(i=syncList->begin(); i!=syncList->end(); ++i){
-      if( ((*i)->mode & mode) == 0 ){
-        COUT(5) << "not getting data: " << std::endl;
-        continue;  // this variable should only be received
-      }
-
-      // =========== start bidirectional stuff =============
-      // if the variable gets synchronised bidirectional, then add the reference to the bytestream
-      if( ( (*i)->mode & direction::bidirectional ) == direction::bidirectional )
-      {
-        if( ( ((*i)->mode == direction::serverMaster) && (mode == 0x1) ) || \
-            ( ((*i)->mode == direction::clientMaster) && (mode == 0x2) ) )
-        {
-          // MASTER
-          if((*i)->type==DATA){
-            if( memcmp((*i)->var,(*i)->varBuffer,(*i)->size) != 0 ) //check whether the variable changed during the last tick
-            {
-              ((*i)->varReference)++;   //the variable changed so increase the refnr
-              memcpy((*i)->varBuffer, (*i)->var, (*i)->size); //set the buffer to the new value
-            }
-          }
-          else //STRING
-          {
-            if( *static_cast<std::string*>((*i)->var) != *static_cast<std::string*>((*i)->varBuffer) ) //the string changed
-            {
-              ((*i)->varReference)++;   //the variable changed
-              *static_cast<std::string*>((*i)->varBuffer) = *static_cast<std::string*>((*i)->var);  //now set the buffer to the new value
-            }
-          }
-        }
-        // copy the reference number to the stream
-        *(uint8_t*)mem = (*i)->varReference;
-        mem += sizeof( (*i)->varReference );
-        tempsize += sizeof( (*i)->varReference );
-      }
-      // ================== end bidirectional stuff
-
-      switch((*i)->type){
-        case DATA:
-          memcpy( (void *)(mem), (void*)((*i)->var), (*i)->size);
-          mem += (*i)->size;
-          tempsize += (*i)->size;
-          break;
-        case STRING:
-          memcpy( (void *)(mem), (void *)&((*i)->size), sizeof(size_t) );
-          mem += sizeof(size_t);
-          const char *data = ( ( *(std::string *) (*i)->var).c_str());
-          memcpy( mem, (void*)data, (*i)->size);
-          COUT(5) << "synchronisable: char: " << (const char *)(mem) << " data: " << data << " string: " << *(std::string *)((*i)->var) << std::endl;
-          mem += (*i)->size;
-          tempsize += (*i)->size + sizeof(size_t);
-          break;
-      }
+    for(i=syncList.begin(); i!=syncList.end(); ++i){
+      (*i)->getData( mem, mode );
+      tempsize += (*i)->getSize( mode );
     }
     assert(tempsize==size);
@@ -429,13 +348,13 @@
     if(mode==0x0)
       mode=state_;
-    std::list<synchronisableVariable *>::iterator i;
+    std::list<SynchronisableVariableBase *>::iterator i;
     //assert(objectMode_!=0x0);
     //assert( (mode ^ objectMode_) != 0);
-    if(syncList->empty()){
+    if(syncList.empty()){
       COUT(4) << "Synchronisable::updateData syncList is empty" << std::endl;
       return false;
     }
 
-    uint8_t *data=mem;
+    uint8_t* data=mem;
     // start extract header
     synchronisableHeader *syncHeader = (synchronisableHeader *)mem;
@@ -452,96 +371,7 @@
 
     COUT(5) << "Synchronisable: objectID " << syncHeader->objectID << ", classID " << syncHeader->classID << " size: " << syncHeader->size << " synchronising data" << std::endl;
-    for(i=syncList->begin(); i!=syncList->end() && mem <= data+syncHeader->size; i++){
-      if( ((*i)->mode ^ mode) == 0 ){
-        COUT(5) << "synchronisable: not updating variable " << std::endl;
-        // if we have a forcecallback then do the callback
-        continue;  // this variable should only be set
-      }
-      COUT(5) << "Synchronisable: element size: " << (*i)->size << " type: " << (*i)->type << std::endl;
-      bool callback=false;
-      bool master=false;
-
-      if( ( (*i)->mode & direction::bidirectional ) == direction::bidirectional )
-      {
-        uint8_t refNr = *(uint8_t *)mem;
-        if( ( ((*i)->mode == direction::serverMaster) && (mode == 0x1) ) || \
-            ( ((*i)->mode == direction::clientMaster) && (mode == 0x2) ) )
-        { // MASTER
-          master=true;
-          if( refNr != (*i)->varReference || ( memcmp((*i)->var, (*i)->varBuffer, (*i)->size) != 0 ) )
-          { // DISCARD data
-            if( (*i)->type == DATA )
-            {
-              mem += sizeof((*i)->varReference) + (*i)->size;
-            }
-            else //STRING
-            {
-              mem += sizeof(size_t) + *(size_t *)mem;
-            }
-            if( forceCallback && (*i)->callback)
-              (*i)->callback->call();
-            continue;
-          }//otherwise everything is ok and we update the value
-        }
-        else // SLAVE
-        {
-          if( (*i)->varReference == refNr ){
-            //discard data because it's outdated or not different to what we've got
-            if( (*i)->type == DATA )
-            {
-              mem += sizeof((*i)->varReference) + (*i)->size;
-            }
-            else //STRING
-            {
-              mem += sizeof(size_t) + *(size_t *)mem;
-            }
-            if( forceCallback && (*i)->callback)
-              (*i)->callback->call();
-            continue;
-          }
-          else
-            (*i)->varReference = refNr; //copy the reference value for this variable
-        }
-        mem += sizeof((*i)->varReference);
-      }
-
-      switch((*i)->type){
-        case DATA:
-          if((*i)->callback) // check whether this variable changed (but only if callback was set)
-          {
-            if(memcmp((*i)->var, mem, (*i)->size) != 0)
-              callback=true;
-          }
-          if( master )
-          {
-            if( callback || memcmp((*i)->var, mem, (*i)->size) != 0 )
-              //value changed, so set the buffer to the new value
-              memcpy((*i)->varBuffer, mem, (*i)->size);
-          }
-          memcpy((*i)->var, mem, (*i)->size);
-          mem += (*i)->size;
-          break;
-        case STRING:
-          (*i)->size = *(size_t *)mem;
-          mem += sizeof(size_t);
-
-          if( (*i)->callback) // check whether this string changed
-            if( *static_cast<std::string*>((*i)->var) != std::string((char *)mem) )
-              callback=true;
-          if( master )
-          {
-            if( callback || *static_cast<std::string*>((*i)->var) != std::string((char *)mem) )
-              //string changed. set the buffer to the new one
-              *static_cast<std::string*>((*i)->varBuffer)=*static_cast<std::string*>( (void*)(mem+sizeof(size_t)) );
-          }
-
-          *((std::string *)((*i)->var)) = std::string((const char*)mem);
-          COUT(5) << "synchronisable: char: " << (const char*)mem << " string: " << std::string((const char*)mem) << std::endl;
-          mem += (*i)->size;
-          break;
-      }
-      // call the callback function, if defined
-      if((callback || forceCallback) && (*i)->callback)
-        (*i)->callback->call();
+    for(i=syncList.begin(); i!=syncList.end() && mem <= data+syncHeader->size; i++)
+    {
+      (*i)->putData( mem, mode, forceCallback );
     }
     assert(mem == data+syncHeader->size);
@@ -561,23 +391,7 @@
     if(!doSync(id, mode))
       return 0;
-    std::list<synchronisableVariable *>::iterator i;
-    for(i=syncList->begin(); i!=syncList->end(); i++){
-      if( ((*i)->mode & mode) == 0 )
-        continue;  // this variable should only be received, so dont add its size to the send-size
-      switch((*i)->type){
-      case DATA:
-        tsize+=(*i)->size;
-        break;
-      case STRING:
-        tsize+=sizeof(int);
-        (*i)->size=((std::string *)(*i)->var)->length()+1;
-        COUT(5) << "String size: " << (*i)->size << std::endl;
-        tsize+=(*i)->size;
-        break;
-      }
-      if( ( (*i)->mode & direction::bidirectional ) == direction::bidirectional )
-      {
-        tsize+=sizeof( (*i)->varReference );
-      }
+    std::list<SynchronisableVariableBase*>::iterator i;
+    for(i=syncList.begin(); i!=syncList.end(); i++){
+      tsize += (*i)->getSize( mode );
     }
     return tsize;
@@ -592,5 +406,5 @@
     if(mode==0x0)
       mode=state_;
-    return ( (objectMode_&mode)!=0 && (!syncList->empty() ) );
+    return ( (objectMode_&mode)!=0 && (!syncList.empty() ) );
   }
 
@@ -623,5 +437,5 @@
     objectMode_=mode;
   }
-
+  
 
 }
Index: code/branches/network64/src/network/synchronisable/Synchronisable.h
===================================================================
--- code/branches/network64/src/network/synchronisable/Synchronisable.h	(revision 2211)
+++ code/branches/network64/src/network/synchronisable/Synchronisable.h	(revision 2245)
@@ -35,14 +35,19 @@
 #include <map>
 #include <queue>
-#include "util/Integers.h"
+#include <cassert>
+#include "util/Math.h"
+#include "util/mbool.h"
 #include "core/OrxonoxClass.h"
-#include "core/XMLIncludes.h"
+// TODO: this has to be removed
+// #include <OgreLight.h>
+// #include "OrxonoxPrereqs.h"
+// ============================
 #include "NetworkCallback.h"
-#include "util/Integers.h"
+#include "SynchronisableVariable.h"
 
-#define REGISTERDATA(varname, ...) \
+/*#define REGISTERDATA(varname, ...) \
     registerVariable((void*)&varname, sizeof(varname), DATA, __VA_ARGS__)
 #define REGISTERSTRING(stringname, ...) \
-    registerVariable(&stringname, stringname.length()+1, STRING, __VA_ARGS__)
+    registerVariable(&stringname, stringname.length()+1, STRING, __VA_ARGS__)*/
 
 namespace orxonox
@@ -50,25 +55,11 @@
   static const unsigned int OBJECTID_UNKNOWN = (unsigned int)-1;
 
-  namespace direction{
-    enum syncdirection{
+  namespace objectDirection{
+    enum objectdirection{
       toclient=0x1,
       toserver=0x2,
-      bidirectional=0x3,
-      serverMaster=0x3,
-      clientMaster=0x7
+      bidirectional=0x3
     };
   }
-
-  namespace syncmode{
-    enum mode{
-      once=0,
-      always=1
-    };
-  }
-
-  enum variableType{
-    DATA,
-    STRING,
-  };
 
   struct _NetworkExport synchronisableHeader{
@@ -80,13 +71,4 @@
   };
 
-  struct _NetworkExport synchronisableVariable{
-    size_t size;
-    uint8_t mode; // this determines in which direction the variable gets synchronised
-    void *var;
-    variableType type;
-    NetworkCallbackBase *callback;
-    void *varBuffer;
-    uint8_t varReference;
-  };
 
   /**
@@ -101,6 +83,4 @@
     virtual ~Synchronisable();
 
-
-    virtual bool create();
     static void setClient(bool b);
 
@@ -115,6 +95,7 @@
   protected:
     Synchronisable(BaseObject* creator);
-    void registerVariable(void *var, int size, variableType t, uint8_t mode=0x1, NetworkCallbackBase *cb=0);
-    void unregisterVariable(void *var);
+//     void registerVariable(void *var, int size, variableType t, uint8_t mode=0x1, NetworkCallbackBase *cb=0);
+    template <class T> void registerVariable(T& variable, uint8_t mode=0x1, NetworkCallbackBase *cb=0, bool bidirectional=false);
+    template <class T> void unregisterVariable(T& var);
     void setObjectMode(uint8_t mode);
     void setObjectFrequency(unsigned int freq){ objectFrequency_ = freq; }
@@ -133,5 +114,5 @@
     unsigned int classID;
 
-    std::list<synchronisableVariable *> *syncList;
+    std::list<SynchronisableVariableBase*> syncList;
     static uint8_t state_; // detemines wheter we are server (default) or client
     bool backsync_; // if true the variables with mode > 1 will be synchronised to server (client -> server)
@@ -141,4 +122,43 @@
     static std::queue<unsigned int> deletedObjects_;
   };
+  
+  template <class T> void Synchronisable::registerVariable(T& variable, uint8_t mode, NetworkCallbackBase *cb, bool bidirectional)
+  {
+    if (bidirectional)
+      syncList.push_back(new SynchronisableVariableBidirectional<const T>(variable, mode, cb));
+    else
+      syncList.push_back(new SynchronisableVariable<const T>(variable, mode, cb));
+  }
+
+  template <class T> void Synchronisable::unregisterVariable(T& var){
+    std::list<SynchronisableVariableBase*>::iterator it = syncList.begin();
+    while(it!=syncList.end()){
+      if( ((*it)->getReference()) == &var ){
+        delete (*it);
+        syncList.erase(it);
+        return;
+      }
+      else
+        it++;
+    }
+    bool unregistered_nonexistent_variable = false;
+    assert(unregistered_nonexistent_variable); //if we reach this point something went wrong:
+    // the variable has not been registered before
+  }
+  
+  // ================= Specialisation declarations
+  template <> void Synchronisable::registerVariable( const ColourValue& variable, uint8_t mode, NetworkCallbackBase* cb, bool bidirectional);template <> void Synchronisable::registerVariable( const ColourValue& variable, uint8_t mode, NetworkCallbackBase* cb, bool bidirectional);
+  template <> void Synchronisable::registerVariable( ColourValue& variable, uint8_t mode, NetworkCallbackBase* cb, bool bidirectional);
+  template <> void Synchronisable::registerVariable( const Vector2& variable, uint8_t mode, NetworkCallbackBase* cb, bool bidirectional);
+  template <> void Synchronisable::registerVariable( Vector2& variable, uint8_t mode, NetworkCallbackBase* cb, bool bidirectional);
+  template <> void Synchronisable::registerVariable( const Vector3& variable, uint8_t mode, NetworkCallbackBase* cb, bool bidirectional);
+  template <> void Synchronisable::registerVariable( Vector3& variable, uint8_t mode, NetworkCallbackBase* cb, bool bidirectional);
+  template <> void Synchronisable::registerVariable( const Vector4& variable, uint8_t mode, NetworkCallbackBase* cb, bool bidirectional);
+  template <> void Synchronisable::registerVariable( Vector4& variable, uint8_t mode, NetworkCallbackBase* cb, bool bidirectional);
+  template <> void Synchronisable::registerVariable( mbool& variable, uint8_t mode, NetworkCallbackBase* cb, bool bidirectional);
+  template <> void Synchronisable::registerVariable( const Quaternion& variable, uint8_t mode, NetworkCallbackBase* cb, bool bidirectional);
+  template <> void Synchronisable::registerVariable( Quaternion& variable, uint8_t mode, NetworkCallbackBase* cb, bool bidirectional);
+//   template <> void Synchronisable::registerVariable( LODParticle::LOD& variable, uint8_t mode, NetworkCallbackBase* cb, bool bidirectional);
+//   template <> void Synchronisable::registerVariable( Ogre::Light::LightTypes& variable, uint8_t mode, NetworkCallbackBase* cb, bool bidirectional);
 }
 
Index: code/branches/network64/src/network/synchronisable/SynchronisableVariable.cc
===================================================================
--- code/branches/network64/src/network/synchronisable/SynchronisableVariable.cc	(revision 2245)
+++ code/branches/network64/src/network/synchronisable/SynchronisableVariable.cc	(revision 2245)
@@ -0,0 +1,409 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   This program is free software; you can redistribute it and/or
+ *   modify it under the terms of the GNU General Public License
+ *   as published by the Free Software Foundation; either version 2
+ *   of the License, or (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *   Author:
+ *      Oliver Scheuss, (C) 2008
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "SynchronisableVariable.h"
+#include <cstring>
+#include "util/Math.h"
+
+
+namespace orxonox{
+
+uint8_t SynchronisableVariableBase::state_ = 0;
+
+
+
+// =================== Template specialisation stuff =============
+
+// =========== bool
+
+template <> uint32_t SynchronisableVariable<const bool>::returnSize()
+{
+  return sizeof(uint8_t);
+}
+
+template <> void SynchronisableVariable<const bool>::setAndIncrease( uint8_t*& mem )
+{
+  *(uint8_t*)(&this->variable_) = *static_cast<uint8_t*>(mem);
+  mem += SynchronisableVariable<const bool>::returnSize();
+}
+
+template <> void SynchronisableVariable<const bool>::getAndIncrease( uint8_t*& mem )
+{
+  *static_cast<uint8_t*>(mem) = *(uint8_t*)(&this->variable_);
+  mem += SynchronisableVariable<const bool>::returnSize();
+}
+
+template <> bool SynchronisableVariable<const bool>::checkEquality( uint8_t* mem )
+{
+  return *static_cast<uint8_t*>(mem) == *(uint8_t*)(&this->variable_);
+}
+
+// =========== unsigned char
+
+template <> uint32_t SynchronisableVariable<const unsigned char>::returnSize()
+{
+  return sizeof(uint8_t);
+}
+
+template <> void SynchronisableVariable<const unsigned char>::setAndIncrease( uint8_t*& mem )
+{
+  *(uint8_t*)(&this->variable_) = *static_cast<uint8_t*>(mem);
+  mem += SynchronisableVariable<const unsigned char>::returnSize();
+}
+
+template <> void SynchronisableVariable<const unsigned char>::getAndIncrease( uint8_t*& mem )
+{
+  *static_cast<uint8_t*>(mem) = *(uint8_t*)(&this->variable_);
+  mem += SynchronisableVariable<const unsigned char>::returnSize();
+}
+
+template <> bool SynchronisableVariable<const unsigned char>::checkEquality( uint8_t* mem )
+{
+  return *static_cast<uint8_t*>(mem) == *(uint8_t*)(&this->variable_);
+}
+
+// =========== short
+
+template <> uint32_t SynchronisableVariable<const short>::returnSize()
+{
+  return sizeof(int16_t);
+}
+
+template <> void SynchronisableVariable<const short>::setAndIncrease( uint8_t*& mem )
+{
+  *(short*)(&this->variable_) = *(int16_t*)(mem);
+  mem += SynchronisableVariable<const short>::returnSize();
+}
+
+template <> void SynchronisableVariable<const short>::getAndIncrease( uint8_t*& mem )
+{
+  *(int16_t*)(mem) = this->variable_;
+  mem += SynchronisableVariable<const short>::returnSize();
+}
+
+template <> bool SynchronisableVariable<const short>::checkEquality( uint8_t* mem )
+{
+  return *(int16_t*)(mem) == static_cast<int16_t>(this->variable_);
+}
+
+// =========== unsigned short
+
+template <> uint32_t SynchronisableVariable<const unsigned short>::returnSize()
+{
+  return sizeof(uint16_t);
+}
+
+template <> void SynchronisableVariable<const unsigned short>::setAndIncrease( uint8_t*& mem )
+{
+  *(unsigned short*)(&this->variable_) = *(uint16_t*)(mem);
+  mem += SynchronisableVariable<const unsigned short>::returnSize();
+}
+
+template <> void SynchronisableVariable<const unsigned short>::getAndIncrease( uint8_t*& mem )
+{
+  *(uint16_t*)(mem) = this->variable_;
+  mem += SynchronisableVariable<const unsigned short>::returnSize();
+}
+
+template <> bool SynchronisableVariable<const unsigned short>::checkEquality( uint8_t* mem )
+{
+  return *(uint16_t*)(mem) == this->variable_;
+}
+
+// =========== int
+
+template <> uint32_t SynchronisableVariable<const int>::returnSize()
+{
+  return sizeof(int32_t);
+}
+
+template <> void SynchronisableVariable<const int>::setAndIncrease( uint8_t*& mem )
+{
+  *(int *)(&this->variable_) = *(int32_t*)(mem);
+  mem += SynchronisableVariable<const int>::returnSize();
+}
+
+template <> void SynchronisableVariable<const int>::getAndIncrease( uint8_t*& mem )
+{
+  *(int32_t*)(mem) = this->variable_;
+  mem += SynchronisableVariable<const int>::returnSize();
+}
+
+template <> bool SynchronisableVariable<const int>::checkEquality( uint8_t* mem )
+{
+  return *(int32_t*)(mem) == this->variable_;
+}
+
+// =========== unsigned int
+
+template <> uint32_t SynchronisableVariable<const unsigned int>::returnSize()
+{
+  return sizeof(uint32_t);
+}
+    
+template <> void SynchronisableVariable<const unsigned int>::setAndIncrease( uint8_t*& mem )
+{
+  *(unsigned int*)(&this->variable_) = *(uint32_t*)(mem);
+  mem += SynchronisableVariable<const unsigned int>::returnSize();
+}
+
+template <> void SynchronisableVariable<const unsigned int>::getAndIncrease( uint8_t*& mem )
+{
+  *(uint32_t*)(mem) = this->variable_;
+  mem += SynchronisableVariable<const unsigned int>::returnSize();
+}
+
+template <> bool SynchronisableVariable<const unsigned int>::checkEquality( uint8_t* mem )
+{
+  return *(uint32_t*)(mem) == this->variable_;
+}
+
+// =========== long
+
+template <> uint32_t SynchronisableVariable<const long>::returnSize()
+{
+  return sizeof(int32_t);
+}
+
+template <> void SynchronisableVariable<const long>::setAndIncrease( uint8_t*& mem )
+{
+  *(long*)(&this->variable_) = *(int32_t*)(mem);
+  mem += SynchronisableVariable<const long>::returnSize();
+}
+
+template <> void SynchronisableVariable<const long>::getAndIncrease( uint8_t*& mem )
+{
+  *(int32_t*)(mem) = this->variable_;
+  mem += SynchronisableVariable<const long>::returnSize();
+}
+
+template <> bool SynchronisableVariable<const long>::checkEquality( uint8_t* mem )
+{
+  return *(int32_t*)(mem) == this->variable_;
+}
+
+// =========== unsigned long
+
+template <> uint32_t SynchronisableVariable<const unsigned long>::returnSize()
+{
+  return sizeof(uint32_t);
+}
+
+template <> void SynchronisableVariable<const unsigned long>::setAndIncrease( uint8_t*& mem )
+{
+  *(unsigned long*)(&this->variable_) = *(uint32_t*)(mem);
+  mem += SynchronisableVariable<const unsigned long>::returnSize();
+}
+
+template <> void SynchronisableVariable<const unsigned long>::getAndIncrease( uint8_t*& mem )
+{
+  *(uint32_t*)(mem) = this->variable_;
+  mem += SynchronisableVariable<const unsigned long>::returnSize();
+}
+
+template <> bool SynchronisableVariable<const unsigned long>::checkEquality( uint8_t* mem )
+{
+  return *(uint32_t*)(mem) == this->variable_;
+}
+
+// =========== long long
+
+template <> uint32_t SynchronisableVariable<const long long>::returnSize()
+{
+  return sizeof(int64_t);
+}
+
+template <> void SynchronisableVariable<const long long>::setAndIncrease( uint8_t*& mem )
+{
+  *(long long*)(&this->variable_) = *(int64_t*)(mem);
+  mem += SynchronisableVariable<const long long>::returnSize();
+}
+
+template <> void SynchronisableVariable<const long long>::getAndIncrease( uint8_t*& mem )
+{
+  *(int64_t*)(mem) = this->variable_;
+  mem += SynchronisableVariable<const long long>::returnSize();
+}
+
+template <> bool SynchronisableVariable<const long long>::checkEquality( uint8_t* mem )
+{
+  return *(int64_t*)(mem) == this->variable_;
+}
+
+// =========== unsigned long long
+
+template <> uint32_t SynchronisableVariable<const unsigned long long>::returnSize()
+{
+  return sizeof(uint64_t);
+}
+
+template <> void SynchronisableVariable<const unsigned long long>::setAndIncrease( uint8_t*& mem )
+{
+  *(unsigned long long*)(&this->variable_) = *(uint64_t*)(mem);
+  mem += SynchronisableVariable<const unsigned long long>::returnSize();
+}
+
+template <> void SynchronisableVariable<const unsigned long long>::getAndIncrease( uint8_t*& mem )
+{
+  *(uint64_t*)(mem) = this->variable_;
+  mem += SynchronisableVariable<const unsigned long long>::returnSize();
+}
+
+template <> bool SynchronisableVariable<const unsigned long long>::checkEquality( uint8_t* mem )
+{
+  return *(uint64_t*)(mem) == this->variable_;
+}
+
+// =========== float
+
+template <> uint32_t SynchronisableVariable<const float>::returnSize()
+{
+  return sizeof(uint32_t);
+}
+
+template <> void SynchronisableVariable<const float>::setAndIncrease( uint8_t*& mem )
+{
+  *(uint32_t*)(&this->variable_) = *(uint32_t*)(mem);
+  mem += SynchronisableVariable<const float>::returnSize();
+}
+
+template <> void SynchronisableVariable<const float>::getAndIncrease( uint8_t*& mem )
+{
+  *(uint32_t*)(mem) = *(uint32_t*)(&this->variable_);
+  mem += SynchronisableVariable<const float>::returnSize();
+}
+
+template <> bool SynchronisableVariable<const float>::checkEquality( uint8_t* mem )
+{
+  return *(uint32_t*)(mem) == *(uint32_t*)(&this->variable_);
+}
+
+// =========== double
+
+template <> uint32_t SynchronisableVariable<const double>::returnSize()
+{
+  return sizeof(uint64_t);
+}
+
+template <> void SynchronisableVariable<const double>::setAndIncrease( uint8_t*& mem )
+{
+  *(uint64_t*)(&this->variable_) = *(uint64_t*)(mem);
+  mem += SynchronisableVariable<const double>::returnSize();
+}
+
+template <> void SynchronisableVariable<const double>::getAndIncrease( uint8_t*& mem )
+{
+  *(uint64_t*)(mem) = *(uint64_t*)(&this->variable_);
+  mem += SynchronisableVariable<const double>::returnSize();
+}
+
+template <> bool SynchronisableVariable<const double>::checkEquality( uint8_t* mem )
+{
+  return *(uint64_t*)(mem) == *(uint64_t*)(&this->variable_);
+}
+
+// =========== long double
+
+template <> uint32_t SynchronisableVariable<const long double>::returnSize()
+{
+  return sizeof(uint64_t);
+}
+
+template <> void SynchronisableVariable<const long double>::setAndIncrease( uint8_t*& mem )
+{
+  double temp;
+  *(uint64_t*)(&temp) = *(uint64_t*)(mem);
+  *(long double*)(&this->variable_) = static_cast<const long double>(temp);
+  mem += SynchronisableVariable<const long double>::returnSize();
+}
+
+template <> void SynchronisableVariable<const long double>::getAndIncrease( uint8_t*& mem )
+{
+  double temp = static_cast<double>(this->variable_);
+  *(uint64_t*)(mem) = *(uint64_t*)(&temp);
+  mem += SynchronisableVariable<const long double>::returnSize();
+}
+
+template <> bool SynchronisableVariable<const long double>::checkEquality( uint8_t* mem )
+{
+  double temp = static_cast<double>(this->variable_);
+  return *(uint64_t*)(mem) == *(uint64_t*)(&temp);
+}
+
+// =========== string
+
+template <> uint32_t SynchronisableVariable<const std::string>::returnSize()
+{
+  return variable_.length()+1;
+}
+
+template <> void SynchronisableVariable<const std::string>::getAndIncrease( uint8_t*& mem )
+{
+  memcpy(mem, this->variable_.c_str(), this->variable_.length()+1);
+  mem += this->variable_.length()+1;
+}
+
+template <> void SynchronisableVariable<const std::string>::setAndIncrease( uint8_t*& mem )
+{
+  *(std::string*)(&this->variable_) = std::string((const char *)mem);
+  mem += this->variable_.length()+1;
+}
+
+template <> bool SynchronisableVariable<const std::string>::checkEquality( uint8_t* mem )
+{
+  return std::string((const char*)mem)==this->variable_;
+}
+
+// =========== Degree
+
+template <> uint32_t SynchronisableVariable<const Degree>::returnSize()
+{
+  return sizeof(Ogre::Real);
+}
+
+template <> void SynchronisableVariable<const Degree>::getAndIncrease( uint8_t*& mem )
+{
+  Ogre::Real r = this->variable_.valueDegrees();
+  memcpy(mem, &r, returnSize());
+  mem += returnSize();
+}
+
+template <> void SynchronisableVariable<const Degree>::setAndIncrease( uint8_t*& mem )
+{
+  Ogre::Real* r = (Ogre::Real*)mem;
+  static_cast<Degree>(this->variable_) = *r;
+  mem += returnSize();
+}
+
+template <> bool SynchronisableVariable<const Degree>::checkEquality( uint8_t* mem )
+{
+  Ogre::Real* r = (Ogre::Real*)mem;
+  return this->variable_==Degree(*r);
+}
+
+}
Index: code/branches/network64/src/network/synchronisable/SynchronisableVariable.h
===================================================================
--- code/branches/network64/src/network/synchronisable/SynchronisableVariable.h	(revision 2245)
+++ code/branches/network64/src/network/synchronisable/SynchronisableVariable.h	(revision 2245)
@@ -0,0 +1,250 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   This program is free software; you can redistribute it and/or
+ *   modify it under the terms of the GNU General Public License
+ *   as published by the Free Software Foundation; either version 2
+ *   of the License, or (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *   Author:
+ *      Oliver Scheuss, (C) 2008
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+
+#ifndef _NETWORK_SYNCHRONISABLEVARIABLE__
+#define _NETWORK_SYNCHRONISABLEVARIABLE__
+
+#include "core/Core.h"
+#include "core/CoreIncludes.h"
+#include <string>
+#include <cassert>
+#include "network/NetworkPrereqs.h"
+
+namespace orxonox{
+  
+  namespace variableDirection{
+    enum syncdirection{
+      toclient=0x1,
+      toserver=0x2
+    };
+    enum bidirectional{
+      serverMaster=0x1,
+      clientMaster=0x2
+    };
+  }
+  
+  class _NetworkExport SynchronisableVariableBase
+  {
+    public:
+      virtual void getData(uint8_t*& mem, uint8_t mode)=0;
+      virtual void putData(uint8_t*& mem, uint8_t mode, bool forceCallback = false)=0;
+      virtual uint32_t getSize(uint8_t mode)=0;
+      virtual void* getReference()=0;
+      virtual uint8_t getMode()=0;
+      virtual ~SynchronisableVariableBase() {}
+    protected:
+      static uint8_t state_;
+  };
+
+  template <class T>
+  class _NetworkExport SynchronisableVariable: public SynchronisableVariableBase
+  {
+    public:
+      SynchronisableVariable(T& variable, uint8_t syncDirection=variableDirection::toclient, NetworkCallbackBase *cb=0);
+      virtual ~SynchronisableVariable();
+
+      virtual inline uint8_t getMode(){ return mode_; }
+      virtual void getData(uint8_t*& mem, uint8_t mode);
+      virtual void putData(uint8_t*& mem, uint8_t mode, bool forceCallback = false);
+      virtual inline uint32_t getSize(uint8_t mode);
+      virtual void* getReference(){ return (void *)&this->variable_; }
+    protected:
+      inline bool checkEquality(uint8_t* mem);
+      inline void setAndIncrease(uint8_t*& mem);
+      inline void getAndIncrease(uint8_t*& mem);
+      inline uint32_t returnSize();
+      
+      T& variable_;
+      uint8_t mode_;
+      NetworkCallbackBase *callback_;
+  };
+  
+  template <class T>
+  class _NetworkExport SynchronisableVariableBidirectional: public SynchronisableVariable<T>
+  {
+    public:
+      SynchronisableVariableBidirectional(T& variable, uint8_t master=variableDirection::serverMaster, NetworkCallbackBase *cb=0);
+      virtual ~SynchronisableVariableBidirectional();
+      
+      virtual inline uint8_t getMode(){ return 0x3; } //this basically is a hack ^^
+      virtual void getData(uint8_t*& mem, uint8_t mode);
+      virtual void putData(uint8_t*& mem, uint8_t mode, bool forceCallback = false);
+      virtual inline uint32_t getSize(uint8_t mode);
+    private:
+      T varBuffer_;
+      uint8_t varReference_;
+  };
+
+  // ================= Unidirectional Part ===============
+
+  template <class T> SynchronisableVariable<T>::SynchronisableVariable(T& variable, uint8_t syncDirection, NetworkCallbackBase *cb):
+      variable_( variable ), mode_( syncDirection ), callback_( cb )
+  {
+    if ( state_ == 0x0 )
+    {
+      state_ = Core::isMaster() ? 0x1 : 0x2;  // set the appropriate mode here
+    }
+  }
+  
+  template <class T> SynchronisableVariable<T>::~SynchronisableVariable()
+  {
+    if (this->callback_ != 0)
+      delete this->callback_;
+  }
+
+  template <class T> void SynchronisableVariable<T>::getData(uint8_t*& mem, uint8_t mode)
+  {
+    if ( state_ == this->mode_ )
+      getAndIncrease( mem );
+//   mem += SynchronisableVariable<T>::getSize();
+  }
+
+  template <class T> void SynchronisableVariable<T>::putData(uint8_t*& mem, uint8_t mode, bool forceCallback)
+  {
+    assert ( mode == 0x1 || mode == 0x2 );
+    bool callback = false;
+    if ( mode == this->mode_ ) //don't do anything
+      return;
+  // check whether we need to consider a callback
+    if ( this->callback_ != 0 )
+    {
+      if( forceCallback || !checkEquality( mem ) )
+        callback = true;
+    }
+  // write the data
+    setAndIncrease( mem );
+//   mem += SynchronisableVariable<T>::getSize();
+  // now do a callback if neccessary
+    if ( callback )
+      this->callback_->call();
+  }
+
+  template <class T> uint32_t SynchronisableVariable<T>::getSize(uint8_t mode)
+  {
+    if ( mode == this->mode_ )
+      return returnSize();
+    else
+      return 0;
+  }
+
+
+// ================= Bidirectional Part ================
+
+    template <class T> SynchronisableVariableBidirectional<T>::SynchronisableVariableBidirectional(T& variable, uint8_t master, NetworkCallbackBase *cb):
+    SynchronisableVariable<T>( variable, master, cb ), varBuffer_( variable ), varReference_( 0 )
+    {
+    }
+
+    template <class T> SynchronisableVariableBidirectional<T>::~SynchronisableVariableBidirectional()
+    {
+    }
+
+    template <class T> void SynchronisableVariableBidirectional<T>::getData(uint8_t*& mem, uint8_t mode)
+    {
+      if ( this->mode_ == mode )
+      {   // we are master for this variable and have to check whether to change the varReference
+        if( this->varBuffer_ != this->variable_ )
+        {
+          this->varReference_++;
+          memcpy((void*)&this->varBuffer_, &this->variable_, sizeof(this->variable_));
+        }
+      }
+  // write the reference number to the stream
+      *static_cast<uint8_t*>(mem) = varReference_;
+      mem += sizeof(this->varReference_);
+  // now write the content
+      SynchronisableVariable<T>::getAndIncrease( mem );
+//   mem += SynchronisableVariable<T>::getSize();
+    }
+
+    template <class T> void SynchronisableVariableBidirectional<T>::putData(uint8_t*& mem, uint8_t mode, bool forceCallback)
+    {
+      bool callback = false;
+      if ( this->mode_ == mode )
+      {   //        MASTER
+        // check that the client (source of the data) has a recent version of this variable
+        if ( *static_cast<uint8_t*>(mem) != this->varReference_ )
+        { // wrong reference number, so discard the data
+          mem += getSize( mode ); // SynchronisableVariableBidirectional::getSize returns size of variable + reference
+          COUT(0) << "not updateing variable because of wrong reference number" << endl;
+          return;
+        }
+        else{
+          // apply data
+          mem += sizeof(varReference_);
+          if ( SynchronisableVariableBidirectional<T>::checkEquality( mem )==true )
+          {
+            mem += SynchronisableVariable<T>::getSize( mode );
+            return;
+          }
+          else
+          {
+            COUT(0) << "variable changed so copy over the buffer and do callback" << endl;
+            memcpy((void*)&this->varBuffer_, &this->variable_, sizeof(T));
+            if ( this->callback_ != 0 )
+              callback = true;
+          }
+        }
+      }
+      else
+      {   // we are slave for this variable
+        if (*static_cast<uint8_t*>(mem) == this->varReference_ && !forceCallback)
+        {
+          mem += getSize( mode ); //just skip the variable because nothing changed
+          return;
+        }
+        else
+        {
+          this->varReference_ = *static_cast<uint8_t*>(mem);
+          mem += sizeof(varReference_);
+          if ( SynchronisableVariable<T>::checkEquality( mem ) == false )
+          {
+            // value changed so remark for callback
+            if ( this->callback_ != 0 )
+              callback = true;
+          }
+        }
+      }
+  // now write the data
+      SynchronisableVariable<T>::setAndIncrease(mem);
+  // now do a callback if neccessary
+      if ( callback )
+        this->callback_->call();
+    }
+
+    template <class T> uint32_t SynchronisableVariableBidirectional<T>::getSize(uint8_t mode)
+    {
+      return SynchronisableVariable<T>::returnSize() + sizeof(varReference_);
+    }
+  
+
+}
+
+
+#endif
