Index: code/trunk/src/network/CMakeLists.txt
===================================================================
--- code/trunk/src/network/CMakeLists.txt	(revision 2171)
+++ code/trunk/src/network/CMakeLists.txt	(revision 2662)
@@ -11,9 +11,11 @@
   PacketBuffer.cc
   Server.cc
-  Synchronisable.cc
+  TrafficControl.cc
   Host.cc
 )
 
 ADD_SOURCE_DIRECTORY(NETWORK_SRC_FILES packet)
+ADD_SOURCE_DIRECTORY(NETWORK_SRC_FILES synchronisable)
+
 
 IF(WIN32)
Index: code/trunk/src/network/Client.cc
===================================================================
--- code/trunk/src/network/Client.cc	(revision 2171)
+++ code/trunk/src/network/Client.cc	(revision 2662)
@@ -43,5 +43,5 @@
 #include "Client.h"
 #include "Host.h"
-#include "Synchronisable.h"
+#include "synchronisable/Synchronisable.h"
 #include "core/CoreIncludes.h"
 #include "packet/Packet.h"
Index: code/trunk/src/network/ClientConnection.cc
===================================================================
--- code/trunk/src/network/ClientConnection.cc	(revision 2171)
+++ code/trunk/src/network/ClientConnection.cc	(revision 2662)
@@ -172,7 +172,7 @@
         break;
       case ENET_EVENT_TYPE_RECEIVE:
-        COUT(5) << "Cl.Con: receiver-Thread while loop: got new packet" << std::endl;
+        //COUT(5) << "Cl.Con: receiver-Thread while loop: got new packet" << std::endl;
         if ( !processData(event) ) COUT(2) << "Current packet was not pushed to packetBuffer -> ev ongoing SegFault" << std::endl;
-        COUT(5) << "Cl.Con: processed Data in receiver-thread while loop" << std::endl;
+        //COUT(5) << "Cl.Con: processed Data in receiver-thread while loop" << std::endl;
         event = new ENetEvent;
         break;
Index: code/trunk/src/network/ClientInformation.cc
===================================================================
--- code/trunk/src/network/ClientInformation.cc	(revision 2171)
+++ code/trunk/src/network/ClientInformation.cc	(revision 2662)
@@ -45,4 +45,5 @@
 namespace orxonox
 {
+  
 
   ClientInformation *ClientInformation::head_=0;
Index: code/trunk/src/network/ClientInformation.h
===================================================================
--- code/trunk/src/network/ClientInformation.h	(revision 2171)
+++ code/trunk/src/network/ClientInformation.h	(revision 2662)
@@ -46,10 +46,9 @@
 #include <boost/thread/recursive_mutex.hpp>
 
+
 // WATCH OUT: THE CLIENTINFORMATION LIST IS NOT THREADSAFE ANYMORE
 
 namespace orxonox
 {
-  static const unsigned int GAMESTATEID_INITIAL = (unsigned int)-1;
-  static const unsigned int CLIENTID_UNKNOWN = (unsigned int)-2;
 
   /**
Index: code/trunk/src/network/ConnectionManager.cc
===================================================================
--- code/trunk/src/network/ConnectionManager.cc	(revision 2171)
+++ code/trunk/src/network/ConnectionManager.cc	(revision 2662)
@@ -52,5 +52,5 @@
 #include "util/Sleep.h"
 #include "ClientInformation.h"
-#include "Synchronisable.h"
+#include "synchronisable/Synchronisable.h"
 #include "packet/ClassID.h"
 
@@ -206,5 +206,5 @@
         // log handling ================
         case ENET_EVENT_TYPE_CONNECT:
-          COUT(3) << "adding event_type_connect to queue" << std::endl;
+          //COUT(3) << "adding event_type_connect to queue" << std::endl;
         case ENET_EVENT_TYPE_DISCONNECT:
           //addClient(event);
@@ -214,5 +214,5 @@
         case ENET_EVENT_TYPE_RECEIVE:
           //std::cout << "received data" << std::endl;
-          COUT(5) << "Con.Man: receive event has occured" << std::endl;
+          //COUT(5) << "Con.Man: receive event has occured" << std::endl;
           // only add, if client has connected yet and not been disconnected
           //if(head_->findClient(&event->peer->address))
Index: code/trunk/src/network/GamestateClient.cc
===================================================================
--- code/trunk/src/network/GamestateClient.cc	(revision 2171)
+++ code/trunk/src/network/GamestateClient.cc	(revision 2662)
@@ -35,5 +35,6 @@
 #include "core/BaseObject.h"
 #include "core/Iterator.h"
-#include "Synchronisable.h"
+#include "synchronisable/Synchronisable.h"
+#include "synchronisable/NetworkCallbackManager.h"
 #include "packet/Acknowledgement.h"
 
@@ -74,13 +75,21 @@
     if(tempGamestate_==NULL)
       return false;
+    bool isDiffed = tempGamestate_->isDiffed();
     int id = GAMESTATEID_INITIAL;
     packet::Gamestate *processed = processGamestate(tempGamestate_);
-//    assert(processed);
-    if (!processed)
-        return false;
+    assert(processed);
+    
+    //now call the queued callbacks
+    NetworkCallbackManager::callCallbacks();
+    
+    if (!processed){
+      sendAck(0);
+      return false;
+    }
     //successfully loaded data from gamestate. now save gamestate for diff and delete the old gs
     tempGamestate_=NULL;
     gamestateMap_[processed->getID()]=processed;
-    last_diff_ = processed->getID();
+    if(isDiffed)
+      last_diff_ = processed->getBaseID();
     id = processed->getID();
     sendAck(id);
@@ -153,4 +162,5 @@
       packet::Gamestate *base = gamestateMap_[gs->getBaseID()];
       if(!base){
+        COUT(3) << "could not find base gamestate id: " << gs->getBaseID() << endl;
         delete gs;
         return 0;
@@ -165,5 +175,8 @@
       return gs;
     else
+    {
+      COUT(3) << "could not spread gamestate" << endl;
       return NULL;
+    }
   }
 
Index: code/trunk/src/network/GamestateManager.cc
===================================================================
--- code/trunk/src/network/GamestateManager.cc	(revision 2171)
+++ code/trunk/src/network/GamestateManager.cc	(revision 2662)
@@ -49,13 +49,19 @@
 #include "core/BaseObject.h"
 #include "ClientInformation.h"
-#include "Synchronisable.h"
+#include "synchronisable/Synchronisable.h"
+#include "synchronisable/NetworkCallbackManager.h"
+#include "packet/Acknowledgement.h"
 
 namespace orxonox
 {
-  GamestateManager::GamestateManager() {
-    id_=0;
-  }
-
-  GamestateManager::~GamestateManager() {
+  GamestateManager::GamestateManager() :
+  reference(0), id_(0)
+  {
+    trafficControl_ = new TrafficControl();
+  }
+
+  GamestateManager::~GamestateManager()
+  {
+    delete trafficControl_;
   }
 
@@ -86,4 +92,6 @@
     // now clear the queue
     gamestateQueue.clear();
+    //and call all queued callbacks
+    NetworkCallbackManager::callCallbacks();
     return true;
   }
@@ -91,4 +99,6 @@
 
   bool GamestateManager::getSnapshot(){
+    if ( reference != 0 )
+      delete reference;
     reference = new packet::Gamestate();
     if(!reference->collectData(++id_)){ //we have no data to send
@@ -99,31 +109,4 @@
   }
 
-  /**
-   * this function is used to keep the memory usage low
-   * it tries to delete all the unused gamestates
-   *
-   *
-   */
-/*  void GamestateManager::cleanup(){
-    std::map<int,int>::iterator it = gamestateUsed.begin();
-    while(it!=gamestateUsed.end()){
-      if((id_-(*it).first)<KEEP_GAMESTATES)
-        break;
-      if( (*it).second <= 0 ){
-        COUT(5) << "GameStateManager: deleting gamestate with id: " << (*it).first << ", uses: " << (*it).second << std::endl;
-        std::map<int, packet::Gamestate *>::iterator tempit = gamestateMap.find((*it).first);
-        if( tempit != gamestateMap.end() ){
-          packet::Gamestate *temp = tempit->second;
-          if(temp){
-            delete gamestateMap[(*it).first];
-            gamestateMap.erase((*it).first);
-          }
-        }
-        gamestateUsed.erase(it++);
-        continue;
-      }
-      it++;
-    }
-  }*/
 
   packet::Gamestate *GamestateManager::popGameState(unsigned int clientID) {
@@ -134,17 +117,16 @@
     if(!reference)
       return 0;
-    gs = reference->doSelection(clientID);
-//     gs = new packet::Gamestate(*reference);
+    gs = reference->doSelection(clientID, 10000);
 //     gs = new packet::Gamestate(*reference);
     // save the (undiffed) gamestate in the clients gamestate map
-    gamestateMap_[clientID].insert(std::pair<int, packet::Gamestate*>(gs->getID(), gs));
+    gamestateMap_[clientID][gs->getID()]=gs;
     //chose wheather the next gamestate is the first or not
-    packet::Gamestate *client=NULL;
+    packet::Gamestate *client=0;
     if(gID != GAMESTATEID_INITIAL){
-      std::map<unsigned int, std::map<unsigned int, packet::Gamestate*> >::iterator clientMap = gamestateMap_.find(clientID);
-      if(clientMap!=gamestateMap_.end()){
-        std::map<unsigned int, packet::Gamestate*>::iterator it = clientMap->second.find(gID);
-        if(it!=clientMap->second.end())
-          client = it->second;
+      assert(gamestateMap_.find(clientID)!=gamestateMap_.end());
+      std::map<unsigned int, packet::Gamestate*>::iterator it = gamestateMap_[clientID].find(gID);
+      if(it!=gamestateMap_[clientID].end())
+      {
+        client = it->second;
       }
     }
@@ -152,4 +134,5 @@
 //       COUT(3) << "diffing" << std::endl;
       gs = gs->diff(client);
+//       gs = new packet::Gamestate(*gs);
     }
     else{
@@ -159,4 +142,9 @@
     bool b = gs->compressData();
     assert(b);
+    COUT(4) << "sending gamestate with id " << gs->getID();
+    if(gs->isDiffed())
+    COUT(4) << " and baseid " << gs->getBaseID() << endl;
+    else
+    COUT(4) << endl;
     return gs;
   }
@@ -168,6 +156,12 @@
     unsigned int curid = temp->getGamestateID();
 
-    if(gamestateID == 0){
+    if(gamestateID == ACKID_NACK){
       temp->setGamestateID(GAMESTATEID_INITIAL);
+      // now delete all saved gamestates for this client
+      std::map<unsigned int, packet::Gamestate*>::iterator it;
+      for(it = gamestateMap_[clientID].begin(); it!=gamestateMap_[clientID].end(); ){
+        delete it->second;
+        gamestateMap_[clientID].erase(it++);
+      }
       return true;
     }
@@ -175,11 +169,11 @@
     assert(curid==(unsigned int)GAMESTATEID_INITIAL || curid<gamestateID);
     COUT(4) << "acking gamestate " << gamestateID << " for clientid: " << clientID << " curid: " << curid << std::endl;
-    std::map<unsigned int, packet::Gamestate*>::iterator it, tempit;
-    for(it = gamestateMap_[clientID].begin(); it!=gamestateMap_[clientID].end() && it->first<gamestateID; it++){
-      delete it->second;
-      tempit=it++;
-      gamestateMap_[clientID].erase(tempit);
+    std::map<unsigned int, packet::Gamestate*>::iterator it;
+    for(it = gamestateMap_[clientID].begin(); it!=gamestateMap_[clientID].end() && it->first<gamestateID; ){
+      delete it->second;
+      gamestateMap_[clientID].erase(it++);
     }
     temp->setGamestateID(gamestateID);
+    TrafficControl::processAck(clientID, gamestateID);
     return true;
   }
Index: code/trunk/src/network/GamestateManager.h
===================================================================
--- code/trunk/src/network/GamestateManager.h	(revision 2171)
+++ code/trunk/src/network/GamestateManager.h	(revision 2662)
@@ -43,4 +43,5 @@
 #include "NetworkPrereqs.h"
 #include "GamestateHandler.h"
+#include "TrafficControl.h"
 #include <map>
 
@@ -81,5 +82,4 @@
     void removeClient(ClientInformation *client);
     private:
-//     void cleanup(); // "garbage handler"
     bool processGamestate(packet::Gamestate *gs);
 
@@ -89,4 +89,5 @@
     std::map<unsigned int, packet::Gamestate*> gamestateQueue;
     packet::Gamestate *reference;
+    TrafficControl *trafficControl_;
     unsigned int id_;
   };
Index: code/trunk/src/network/NetworkCallback.h
===================================================================
--- code/trunk/src/network/NetworkCallback.h	(revision 2171)
+++ 	(revision )
@@ -1,32 +1,0 @@
-#ifndef _NETWORK_CALLBACK__
-#define _NETWORK_CALLBACK__
-
-#include "NetworkPrereqs.h"
-
-namespace orxonox{
-  class _NetworkExport NetworkCallbackBase
-  {
-    public:
-      virtual void call() = 0;
-	  virtual ~NetworkCallbackBase() {}
-  };
-
-  template <class T>
-  class NetworkCallback: public NetworkCallbackBase
-  {
-    public:
-      NetworkCallback(T* object, void (T::*function) (void)) : object_(object), function_(function) {}
-	  virtual ~NetworkCallback() {}
-      virtual void call()
-        { (this->object_->*function_)(); }
-
-    private:
-      T* object_;
-      void (T::*function_) (void);
-  };
-
-
-}
-
-
-#endif
Index: code/trunk/src/network/NetworkPrereqs.h
===================================================================
--- code/trunk/src/network/NetworkPrereqs.h	(revision 2171)
+++ code/trunk/src/network/NetworkPrereqs.h	(revision 2662)
@@ -57,4 +57,19 @@
 
 //-----------------------------------------------------------------------
+// Includes
+//-----------------------------------------------------------------------
+#include "util/Integers.h"
+
+//-----------------------------------------------------------------------
+// Library global contants
+//-----------------------------------------------------------------------
+namespace orxonox
+{
+  static const unsigned int GAMESTATEID_INITIAL = (unsigned int)-1;
+  static const unsigned int CLIENTID_UNKNOWN    = (unsigned int)-2;
+  static const uint32_t     OBJECTID_UNKNOWN    = (uint32_t)(-1);
+}
+
+//-----------------------------------------------------------------------
 // Forward declarations
 //-----------------------------------------------------------------------
@@ -70,14 +85,23 @@
   class GamestateManager;
   class GamestateHandler;
+  class NetworkCallbackBase;
+  template <class T> class NetworkCallback;
+  class NetworkCallbackManager;
   class PacketBuffer;
   class Server;
   class ServerFrameListener;
   class Synchronisable;
+  class SynchronisableVariableBase;
+  template <class T> class SynchronisableVariable;
+  template <class T> class SynchronisableVariableBidirectional;
   struct ClientList;
   struct PacketEnvelope;
   struct QueueItem;
   struct syncData;
-  struct synchronisableVariable;
-  namespace packet{
+  class obj;
+  class objInfo;
+
+  namespace packet
+  {
     class Gamestate;
     class Packet;
Index: code/trunk/src/network/Server.cc
===================================================================
--- code/trunk/src/network/Server.cc	(revision 2171)
+++ code/trunk/src/network/Server.cc	(revision 2662)
@@ -63,6 +63,4 @@
 {
   const unsigned int MAX_FAILURES = 20;
-  const unsigned int NETWORK_FREQUENCY = 25;
-  const float NETWORK_PERIOD = (float)1/NETWORK_FREQUENCY;
 
   /**
@@ -218,4 +216,7 @@
   */
   void Server::updateGamestate() {
+//     if( ClientInformation::getBegin()==NULL )
+      //no client connected
+//       return;
     gamestates_->update();
     COUT(5) << "Server: one gamestate update complete, goig to sendGameState" << std::endl;
@@ -276,4 +277,7 @@
   bool Server::sendObjectDeletes(){
     ClientInformation *temp = ClientInformation::getBegin();
+    if( temp == NULL )
+      //no client connected
+      return true;
     packet::DeleteObjects *del = new packet::DeleteObjects();
     if(!del->fetchIDs())
Index: code/trunk/src/network/Server.h
===================================================================
--- code/trunk/src/network/Server.h	(revision 2171)
+++ code/trunk/src/network/Server.h	(revision 2662)
@@ -52,4 +52,6 @@
 {
   const int CLIENTID_SERVER = 0;
+  const unsigned int NETWORK_FREQUENCY = 25;
+  const float NETWORK_PERIOD = 1./NETWORK_FREQUENCY;
 
   /**
Index: code/trunk/src/network/Synchronisable.cc
===================================================================
--- code/trunk/src/network/Synchronisable.cc	(revision 2171)
+++ 	(revision )
@@ -1,627 +1,0 @@
-/*
- *   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:
- *      Dumeni Manatschal, (C) 2007
- *      Oliver Scheuss, (C) 2007
- *   Co-authors:
- *      ...
- *
- */
-
-//
-// C++ Implementation: synchronisable
-//
-// Description:
-//
-//
-// Author:  Dumeni, Oliver Scheuss, (C) 2007
-//
-// Copyright: See COPYING file that comes with this distribution
-//
-
-#include "Synchronisable.h"
-
-#include <cstring>
-#include <string>
-#include <iostream>
-#include <assert.h>
-
-#include "core/CoreIncludes.h"
-#include "core/BaseObject.h"
-// #include "core/Identifier.h"
-
-#include "Host.h"
-namespace orxonox
-{
-
-
-  std::map<unsigned int, Synchronisable *> Synchronisable::objectMap_;
-  std::queue<unsigned int> Synchronisable::deletedObjects_;
-
-  uint8_t Synchronisable::state_=0x1; // detemines wheter we are server (default) or client
-
-  /**
-  * Constructor:
-  * Initializes all Variables and sets the right objectID
-  */
-  Synchronisable::Synchronisable(BaseObject* creator){
-    RegisterRootObject(Synchronisable);
-    static uint32_t idCounter=0;
-    objectFrequency_=1;
-    objectMode_=0x1; // by default do not send data to server
-    if ( !Host::running() || ( Host::running() && Host::isServer() ) )
-    {
-      this->objectID = idCounter++; //this is only needed when running a server
-    //add synchronisable to the objectMap
-      objectMap_[this->objectID] = this;
-    }
-    else
-      objectID=OBJECTID_UNKNOWN;
-    classID = (unsigned int)-1;
-    syncList = new std::list<synchronisableVariable *>;
-
-
-#ifndef NDEBUG
-    ObjectList<Synchronisable>::iterator it;
-    for(it = ObjectList<Synchronisable>::begin(); it!=ObjectList<Synchronisable>::end(); ++it){
-      if( it->getObjectID()==this->objectID )
-        assert(*it==this || (it->objectID==OBJECTID_UNKNOWN && it->objectMode_==0x0));
-    }
-#endif
-
-    this->creatorID = OBJECTID_UNKNOWN;
-
-    searchcreatorID:
-    if (creator)
-    {
-        Synchronisable* synchronisable_creator = dynamic_cast<Synchronisable*>(creator);
-        if (synchronisable_creator && synchronisable_creator->objectMode_)
-        {
-            this->creatorID = synchronisable_creator->getObjectID();
-        }
-        else if (creator != creator->getCreator())
-        {
-            creator = creator->getCreator();
-            goto searchcreatorID;
-        }
-    }
-  }
-
-  /**
-   * Destructor:
-   * Delete all callback objects and remove objectID from the objectMap_
-   */
-  Synchronisable::~Synchronisable(){
-    // delete callback function objects
-    if(!Identifier::isCreatingHierarchy()){
-      for(std::list<synchronisableVariable *>::iterator it = syncList->begin(); it!=syncList->end(); it++)
-        delete (*it)->callback;
-      if (this->objectMode_ != 0x0 && (Host::running() && Host::isServer()))
-        deletedObjects_.push(objectID);
-//       COUT(3) << "destruct synchronisable +++" << objectID << " | " << classID << std::endl;
-//       COUT(3) << " bump ---" << objectID << " | " << &objectMap_ << std::endl;
-//       assert(objectMap_[objectID]->objectID==objectID);
-//       objectMap_.erase(objectID);
-    }
-    std::map<unsigned int, Synchronisable*>::iterator it;
-    it = objectMap_.find(objectID);
-    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;
-  }
-
-
-  /**
-   * This function sets the internal mode for synchronisation
-   * @param b true if this object is located on a client or on a server
-   */
-  void Synchronisable::setClient(bool b){
-    if(b) // client
-      state_=0x2;
-    else  // server
-      state_=0x1;
-  }
-
-  /**
-   * This function fabricated a new synchrnisable (and children of it), sets calls updateData and create
-   * After calling this function the mem pointer will be increased by the size of the needed data
-   * @param mem pointer to where the appropriate data is located
-   * @param mode defines the mode, how the data should be loaded
-   * @return pointer to the newly created synchronisable
-   */
-  Synchronisable *Synchronisable::fabricate(uint8_t*& mem, uint8_t mode)
-  {
-    synchronisableHeader *header = (synchronisableHeader *)mem;
-
-    if(!header->dataAvailable)
-    {
-      mem += header->size;
-      return 0;
-    }
-
-    COUT(4) << "fabricating object with id: " << header->objectID << std::endl;
-
-    Identifier* id = ClassByID(header->classID);
-    assert(id);
-    BaseObject* creator = 0;
-    if (header->creatorID != OBJECTID_UNKNOWN)
-    {
-      Synchronisable* synchronisable_creator = Synchronisable::getSynchronisable(header->creatorID);
-      if (!synchronisable_creator)
-      {
-        mem += header->size; //.TODO: this suckz.... remove size from header
-        return 0;
-      }
-      else
-        creator = dynamic_cast<BaseObject*>(synchronisable_creator);
-    }
-    assert(getSynchronisable(header->objectID)==0);   //make sure no object with this id exists
-    BaseObject *bo = id->fabricate(creator);
-    assert(bo);
-    Synchronisable *no = dynamic_cast<Synchronisable *>(bo);
-    assert(no);
-    no->objectID=header->objectID;
-    no->creatorID=header->creatorID; //TODO: remove this
-    no->classID=header->classID;
-    COUT(4) << "fabricate objectID: " << no->objectID << " classID: " << no->classID << std::endl;
-          // update data and create object/entity...
-    bool b = no->updateData(mem, mode, true);
-    assert(b);
-    if (b)
-    {
-        b = no->create();
-        assert(b);
-    }
-    return no;
-  }
-
-
-  /**
-   * Finds and deletes the Synchronisable with the appropriate objectID
-   * @param objectID objectID of the Synchronisable
-   * @return true/false
-   */
-  bool Synchronisable::deleteObject(unsigned int objectID){
-//     assert(getSynchronisable(objectID));
-    if(!getSynchronisable(objectID))
-      return false;
-    assert(getSynchronisable(objectID)->objectID==objectID);
-//     delete objectMap_[objectID];
-    Synchronisable *s = getSynchronisable(objectID);
-    if(s)
-      delete s;
-    else
-      return false;
-    return true;
-  }
-
-  /**
-   * This function looks up the objectID in the objectMap_ and returns a pointer to the right Synchronisable
-   * @param objectID objectID of the Synchronisable
-   * @return pointer to the Synchronisable with the objectID
-   */
-  Synchronisable* Synchronisable::getSynchronisable(unsigned int objectID){
-    std::map<unsigned int, Synchronisable*>::iterator it1;
-    it1 = objectMap_.find(objectID);
-    if (it1 != objectMap_.end())
-      return it1->second;
-
-    ObjectList<Synchronisable>::iterator it;
-    for(it = ObjectList<Synchronisable>::begin(); it; ++it){
-      if( it->getObjectID()==objectID ){
-        objectMap_[objectID] = *it;
-        return *it;
-      }
-    }
-    return NULL;
-  }
-
-
-  /**
-  * This function is used to register a variable to be synchronized
-  * also counts the total datasize needed to save the variables
-  * @param var pointer to the variable
-  * @param size size of the datatype the variable consists of
-  * @param t the type of the variable (DATA or STRING
-  * @param mode same as in getData
-  * @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){
-    assert( mode==direction::toclient || mode==direction::toserver || mode==direction::serverMaster || mode==direction::clientMaster);
-    // create temporary synch.Var struct
-    synchronisableVariable *temp = new synchronisableVariable;
-    temp->size = size;
-    temp->var = var;
-    temp->mode = mode;
-    temp->type = t;
-    temp->callback = cb;
-    if( ( mode & direction::bidirectional ) )
-    {
-      if(t!=STRING)
-      {
-        temp->varBuffer = new uint8_t[size];
-        memcpy(temp->varBuffer, temp->var, size); //now fill the buffer for the first time
-      }
-      else
-      {
-        temp->varBuffer=new std::string( *static_cast<std::string*>(var) );
-      }
-      temp->varReference = 0;
-    }
-    COUT(5) << "Syncronisable::registering var with size: " << temp->size << " and type: " << temp->type << std::endl;
-    //std::cout << "push temp to syncList (at the bottom) " << datasize << std::endl;
-    COUT(5) << "Syncronisable::objectID: " << objectID << " this: " << this << " name: " << this->getIdentifier()->getName() << " networkID: " << this->getIdentifier()->getNetworkID() << std::endl;
-    syncList->push_back(temp);
-#ifndef NDEBUG
-    std::list<synchronisableVariable *>::iterator it = syncList->begin();
-    while(it!=syncList->end()){
-      assert(*it!=var);
-      it++;
-    }
-#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
-  }
-
-
-  /**
-   * This function takes all SynchronisableVariables out of the Synchronisable and saves them together with the size, objectID and classID to the given memory
-   * takes a pointer to already allocated memory (must have at least getSize bytes length)
-   * structure of the bitstream:
-   * |totalsize,objectID,classID,var1,var2,string1_length,string1,var3,...|
-   * length of varx: size saved int syncvarlist
-   * @param mem pointer to allocated memory with enough size
-   * @param id gamestateid of the gamestate to be saved (important for priorities)
-   * @param mode defines the direction in which the data will be send/received
-   *             0x1: server->client
-   *             0x2: client->server (not recommended)
-   *             0x3: bidirectional
-   * @return true: if !doSync or if everything was successfully saved
-   */
-  bool Synchronisable::getData(uint8_t*& mem, unsigned int id, uint8_t mode){
-    if(mode==0x0)
-      mode=state_;
-    //if this tick is we dont synchronise, then abort now
-    if(!doSync(id, mode))
-      return true;
-    //std::cout << "inside getData" << std::endl;
-    unsigned int tempsize = 0;
-    if(classID==0)
-      COUT(3) << "classid 0 " << this->getIdentifier()->getName() << std::endl;
-
-    if (this->classID == (unsigned int)-1)
-        this->classID = this->getIdentifier()->getNetworkID();
-
-    assert(this->classID==this->getIdentifier()->getNetworkID());
-//     this->classID=this->getIdentifier()->getNetworkID(); // TODO: correct this
-    std::list<synchronisableVariable *>::iterator i;
-    unsigned int size;
-    size=getSize(id, mode);
-
-    // start copy header
-    synchronisableHeader *header = (synchronisableHeader *)mem;
-    header->size = size;
-    header->objectID = this->objectID;
-    header->creatorID = this->creatorID;
-    header->classID = this->classID;
-    header->dataAvailable = true;
-    tempsize += sizeof(synchronisableHeader);
-    mem += sizeof(synchronisableHeader);
-    // end copy header
-
-
-    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;
-      }
-    }
-    assert(tempsize==size);
-    return true;
-  }
-
-
-  /**
-   * This function takes a bytestream and loads the data into the registered variables
-   * @param mem pointer to the bytestream
-   * @param mode same as in getData
-   * @return true/false
-   */
-  bool Synchronisable::updateData(uint8_t*& mem, uint8_t mode, bool forceCallback){
-    if(mode==0x0)
-      mode=state_;
-    std::list<synchronisableVariable *>::iterator i;
-    //assert(objectMode_!=0x0);
-    //assert( (mode ^ objectMode_) != 0);
-    if(syncList->empty()){
-      COUT(4) << "Synchronisable::updateData syncList is empty" << std::endl;
-      return false;
-    }
-
-    uint8_t *data=mem;
-    // start extract header
-    synchronisableHeader *syncHeader = (synchronisableHeader *)mem;
-    assert(syncHeader->objectID==this->objectID);
-    assert(syncHeader->creatorID==this->creatorID);
-    assert(this->classID==syncHeader->classID); //TODO: fix this!!! maybe a problem with the identifier ?
-    if(syncHeader->dataAvailable==false){
-      mem += syncHeader->size;
-      return true;
-    }
-
-    mem += sizeof(synchronisableHeader);
-    // stop extract header
-
-    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();
-    }
-    assert(mem == data+syncHeader->size);
-    return true;
-  }
-
-  /**
-  * This function returns the total amount of bytes needed by getData to save the whole content of the variables
-  * @param id id of the gamestate
-  * @param mode same as getData
-  * @return amount of bytes
-  */
-  uint32_t Synchronisable::getSize(unsigned int id, uint8_t mode){
-    int tsize=sizeof(synchronisableHeader);
-    if(mode==0x0)
-      mode=state_;
-    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 );
-      }
-    }
-    return tsize;
-  }
-
-  /**
-   * This function determines, wheter the object should be saved to the bytestream (according to its syncmode/direction)
-   * @param id gamestate id
-   * @return true/false
-   */
-  bool Synchronisable::doSync(unsigned int id, uint8_t mode){
-    if(mode==0x0)
-      mode=state_;
-    return ( (objectMode_&mode)!=0 && (!syncList->empty() ) );
-  }
-
-  bool Synchronisable::doSelection(unsigned int id){
-    return true; //TODO: change this
-    //return ( id==0 || id%objectFrequency_==objectID%objectFrequency_ ) && ((objectMode_&state_)!=0);
-  }
-
-  /**
-   * This function looks at the header located in the bytestream and checks wheter objectID and classID match with the Synchronisables ones
-   * @param mem pointer to the bytestream
-   */
-  bool Synchronisable::isMyData(uint8_t* mem)
-  {
-    synchronisableHeader *header = (synchronisableHeader *)mem;
-    assert(header->objectID==this->objectID);
-    return header->dataAvailable;
-  }
-
-  /**
-   * This function sets the synchronisation mode of the object
-   * If set to 0x0 variables will not be synchronised at all
-   * If set to 0x1 variables will only be synchronised to the client
-   * If set to 0x2 variables will only be synchronised to the server
-   * If set to 0x3 variables will be synchronised bidirectionally (only if set so in registerVar)
-   * @param mode same as in registerVar
-   */
-  void Synchronisable::setObjectMode(uint8_t mode){
-    assert(mode==0x0 || mode==0x1 || mode==0x2 || mode==0x3);
-    objectMode_=mode;
-  }
-
-
-}
Index: code/trunk/src/network/Synchronisable.h
===================================================================
--- code/trunk/src/network/Synchronisable.h	(revision 2171)
+++ 	(revision )
@@ -1,145 +1,0 @@
-/*
- *   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) 2007
- *   Co-authors:
- *      ...
- *
- */
-
-#ifndef _Synchronisable_H__
-#define _Synchronisable_H__
-
-#include "NetworkPrereqs.h"
-
-#include <list>
-#include <map>
-#include <queue>
-#include "util/Integers.h"
-#include "core/OrxonoxClass.h"
-#include "core/XMLIncludes.h"
-#include "NetworkCallback.h"
-#include "util/Integers.h"
-
-#define REGISTERDATA(varname, ...) \
-    registerVariable((void*)&varname, sizeof(varname), DATA, __VA_ARGS__)
-#define REGISTERSTRING(stringname, ...) \
-    registerVariable(&stringname, stringname.length()+1, STRING, __VA_ARGS__)
-
-namespace orxonox
-{
-  static const unsigned int OBJECTID_UNKNOWN = (unsigned int)-1;
-
-  namespace direction{
-    enum syncdirection{
-      toclient=0x1,
-      toserver=0x2,
-      bidirectional=0x3,
-      serverMaster=0x3,
-      clientMaster=0x7
-    };
-  }
-
-  namespace syncmode{
-    enum mode{
-      once=0,
-      always=1
-    };
-  }
-
-  enum variableType{
-    DATA,
-    STRING,
-  };
-
-  struct _NetworkExport synchronisableHeader{
-    uint32_t size:31;
-    bool dataAvailable:1;
-    uint32_t objectID;
-    uint32_t creatorID;
-    uint32_t classID;
-  };
-
-  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;
-  };
-
-  /**
-  * This class is the base class of all the Objects in the universe that need to be synchronised over the network
-   * Every class, that inherits from this class has to link the DATA THAT NEEDS TO BE SYNCHRONISED into the linked list.
-  * @author Oliver Scheuss
-  */
-  class _NetworkExport Synchronisable : virtual public OrxonoxClass{
-  public:
-    friend class packet::Gamestate;
-//     friend class Server;
-    virtual ~Synchronisable();
-
-
-    virtual bool create();
-    static void setClient(bool b);
-
-    static Synchronisable *fabricate(uint8_t*& mem, uint8_t mode=0x0);
-    static bool deleteObject(unsigned int objectID);
-    static Synchronisable *getSynchronisable(unsigned int objectID);
-    static unsigned int getNumberOfDeletedObject(){ return deletedObjects_.size(); }
-    static unsigned int popDeletedObject(){ unsigned int i = deletedObjects_.front(); deletedObjects_.pop(); return i; }
-
-    inline unsigned int getObjectID(){return objectID;}
-    inline unsigned int getClassID(){return classID;}
-  protected:
-    Synchronisable(BaseObject* creator);
-    void registerVariable(void *var, int size, variableType t, uint8_t mode=0x1, NetworkCallbackBase *cb=0);
-    void unregisterVariable(void *var);
-    void setObjectMode(uint8_t mode);
-    void setObjectFrequency(unsigned int freq){ objectFrequency_ = freq; }
-
-
-  private:
-    bool getData(uint8_t*& men, unsigned int id, uint8_t mode=0x0);
-    uint32_t getSize(unsigned int id, uint8_t mode=0x0);
-    bool updateData(uint8_t*& mem, uint8_t mode=0x0, bool forceCallback=false);
-    bool isMyData(uint8_t* mem);
-    bool doSelection(unsigned int id);
-    bool doSync(unsigned int id, uint8_t mode=0x0);
-
-    unsigned int objectID;
-    unsigned int creatorID;
-    unsigned int classID;
-
-    std::list<synchronisableVariable *> *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)
-    unsigned int objectFrequency_;
-    int objectMode_;
-    static std::map<unsigned int, Synchronisable *> objectMap_;
-    static std::queue<unsigned int> deletedObjects_;
-  };
-}
-
-#endif /* _Synchronisable_H__ */
Index: code/trunk/src/network/TrafficControl.cc
===================================================================
--- code/trunk/src/network/TrafficControl.cc	(revision 2662)
+++ code/trunk/src/network/TrafficControl.cc	(revision 2662)
@@ -0,0 +1,313 @@
+/*
+ *   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 <scheusso [at] ee.ethz.ch>, (C) 2008
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "TrafficControl.h"
+
+#include "synchronisable/Synchronisable.h"
+#include "core/ConfigValueIncludes.h"
+
+#include <cassert>
+#include <boost/bind.hpp>
+
+namespace orxonox {
+
+  static const unsigned int SCHED_PRIORITY_OFFSET = (unsigned int)-1;
+
+  objInfo::objInfo(uint32_t ID, uint32_t creatorID, int32_t curGsID, int32_t diffGsID, uint32_t size, unsigned int prioperm, unsigned int priosched)
+  {
+    objID = ID; objCreatorID = creatorID; objCurGS = curGsID; objDiffGS = diffGsID; objSize = size; objValuePerm = prioperm; objValueSched = priosched;
+  }
+
+  objInfo::objInfo()
+  {
+    objID = OBJECTID_UNKNOWN; objCreatorID = OBJECTID_UNKNOWN; objCurGS = GAMESTATEID_INITIAL; objDiffGS = objCurGS; objSize = 0; objValuePerm = 0; objValueSched = 0;
+  }
+
+
+
+  obj::obj()
+  {
+    objID = OBJECTID_UNKNOWN; objCreatorID = OBJECTID_UNKNOWN; objSize = 0; objDataOffset = 0;
+  }
+  obj::obj( uint32_t ID, uint32_t creatorID, uint32_t size, uint32_t offset )
+  {
+    objID = ID; objCreatorID = creatorID; objSize = size; objDataOffset = offset;
+  }
+
+/**
+*Initializing protected members
+*/
+	TrafficControl *TrafficControl::instance_=0;
+
+	/**
+	* @brief Constructor: assures that only one reference will be created and sets the pointer
+	*/
+	TrafficControl::TrafficControl()
+	{
+    RegisterObject(TrafficControl);
+	  assert(instance_==0);
+	  instance_=this;
+    this->setConfigValues();
+	}
+
+	/**
+	* @brief Destructor: resets the instance pointer to 0
+	*/
+	TrafficControl::~TrafficControl()
+	{
+	  instance_=0;
+	}
+
+/**
+*Definition of public members
+*/
+
+  void TrafficControl::setConfigValues()
+  {
+    SetConfigValue ( bActive_, true );
+    SetConfigValue ( targetSize, 5000 );
+  }
+
+  /**
+  * sort-algorithm for sorting the objectlist after priorities
+  */
+  bool TrafficControl::prioritySort(uint32_t clientID, obj i, obj j)
+  {
+    assert(clientListPerm_.find(clientID) != clientListPerm_.end());  //make sure the client exists in our list
+    assert(clientListPerm_[clientID].find(i.objID) != clientListPerm_[clientID].end()); // make sure the object i is in the client list
+    assert(clientListPerm_[clientID].find(j.objID) != clientListPerm_[clientID].end()); // make sure the object j is in the client list
+
+    int prio1 = clientListPerm_[clientID][i.objID].objValuePerm + clientListPerm_[clientID][i.objID].objValueSched;
+    int prio2 = clientListPerm_[clientID][j.objID].objValuePerm + clientListPerm_[clientID][j.objID].objValueSched;
+    return prio1 < prio2;
+  }
+
+  /**
+  * sort-algorithm for sorting the objectList after position in original data stream
+  */
+  bool TrafficControl::dataSort(obj i, obj j)
+  {
+    int pos1 = i.objDataOffset;
+    int pos2 = j.objDataOffset;
+    return pos1 < pos2;
+  }
+
+
+
+	void TrafficControl::processObjectList(unsigned int clientID, unsigned int gamestateID, std::list<obj> *list)
+	{
+// 	  copiedVector = *list;
+	  currentClientID=clientID;
+	  currentGamestateID=gamestateID;
+	  evaluateList(clientID, list);
+	  return;
+	}
+
+  TrafficControl *TrafficControl::getInstance()
+  {
+    assert(instance_);
+    return instance_;
+  }
+
+	void TrafficControl::ack(unsigned int clientID, unsigned int gamestateID)
+	{
+	  std::list<obj>::iterator itvec;  // iterator to iterate through the acked objects
+
+    //assertions to make sure the maps already exist
+    assert(clientListTemp_.find(clientID) != clientListTemp_.end() );
+    assert(clientListPerm_.find(clientID) != clientListPerm_.end() );
+	  assert( clientListTemp_[clientID].find(gamestateID) != clientListTemp_[clientID].end() );
+
+    for(itvec = clientListTemp_[clientID][gamestateID].begin(); itvec != clientListTemp_[clientID][gamestateID].end(); itvec++)
+	  {
+      if(clientListPerm_[clientID].find((*itvec).objID) != clientListPerm_[clientID].end()) // check whether the obj already exists in our lists
+      {
+        clientListPerm_[clientID][(*itvec).objID].objCurGS = gamestateID;
+        clientListPerm_[clientID][(*itvec).objID].objValueSched = 0; //set scheduling value back
+      }
+      else
+      {
+        assert(0);
+        clientListPerm_[clientID][(*itvec).objID].objCurGS = gamestateID;
+        clientListPerm_[clientID][(*itvec).objID].objID = (*itvec).objID;
+        clientListPerm_[clientID][(*itvec).objID].objCreatorID = (*itvec).objCreatorID;
+        clientListPerm_[clientID][(*itvec).objID].objSize = (*itvec).objSize;
+      }
+	  }
+	   // remove temporary list (with acked objects) from the map
+    clientListTemp_[clientID].erase( clientListTemp_[clientID].find(gamestateID) );
+	}
+
+/**
+*Definition of private members
+*/
+
+	/**
+	*updateClientListPerm
+	*returns void
+	*/
+	void TrafficControl::insertinClientListPerm(unsigned int clientID, obj objinf)
+	{
+	  std::map<unsigned int,std::map<unsigned int, objInfo> >::iterator itperm;//iterator clientListPerm over clientIDs
+// 	  itperm = (clientListPerm_).find(clientID);
+// 	  assert(itperm != clientListPerm_.end() );
+    unsigned int gsid=GAMESTATEID_INITIAL, gsdiff=currentGamestateID, prioperm=Synchronisable::getSynchronisable(objinf.objID)->getPriority(), priomom=0;
+    clientListPerm_[clientID][objinf.objID] = objInfo(objinf.objID, objinf.objCreatorID,gsid,gsdiff, objinf.objSize,prioperm,priomom);
+// 	  itperm->second.insert(std::pair<unsigned int, objInfo>(objid,objinf));
+//     permObjPrio_.insert(objid, objinf.objValuePerm);
+	}
+
+  /**
+  * updateClientListTemp
+  * takes the shortened list which will be sent to the gsmanager and puts the *info into clientListTemp
+  */
+  void TrafficControl::updateClientListTemp(std::list<obj> *list)
+  {
+    clientListTemp_[currentClientID][currentGamestateID] = std::list<obj>(*list);
+  }
+
+  /**
+  *cut
+  *takes the current list that has to be returned to the gsmanager and shortens it in criteria of bandwidth of clientID(XY)
+  */
+  void TrafficControl::cut(std::list<obj> *list, unsigned int targetsize)
+  {
+    unsigned int size=0;
+    std::list<obj>::iterator itvec, ittemp;
+    assert(!list->empty());
+    for(itvec = list->begin(); itvec != list->end();)
+    {
+      assert( (*itvec).objSize < 1000);
+      if ( ( size + (*itvec).objSize ) < targetsize )
+      {
+        size += (*itvec).objSize;//objSize is given in bytes
+        ++itvec;
+      }
+      else
+      {
+        clientListPerm_[currentClientID][(*itvec).objID].objValueSched += SCHED_PRIORITY_OFFSET; // NOTE: SCHED_PRIORITY_OFFSET is negative
+        list->erase(itvec++);
+      }
+//       printList(list, currentClientID);
+    }
+    assert(!list->empty());
+  }
+
+
+	/**
+	*evaluateList evaluates whether new obj are there, whether there are things to be updatet and manipulates all this.
+	*/
+	void TrafficControl::evaluateList(unsigned int clientID, std::list<obj> *list)
+	{
+
+	  //now the sorting
+
+	  //compare listToProcess vs clientListPerm
+    //if listToProcess contains new Objects, add them to clientListPerm
+    std::list<obj>::iterator itvec;
+	  for( itvec=list->begin(); itvec != list->end(); itvec++)
+	  {
+	    if ( clientListPerm_[clientID].find( (*itvec).objID) != clientListPerm_[clientID].end() )
+      {
+        // we already have the object in our map
+        //obj bleibt in liste und permanente prio wird berechnet
+        clientListPerm_[clientID][(*itvec).objID].objDiffGS = currentGamestateID - clientListPerm_[clientID][(*itvec).objID].objCurGS;
+        continue;//check next objId
+      }
+      else
+      {
+        // insert the object into clientListPerm
+        insertinClientListPerm(clientID,*itvec);
+        continue;//check next objId
+      }
+    }
+	  //end compare listToProcess vs clientListPerm
+
+    if( bActive_ )
+    {
+      //sort copied list according to priorities
+      // use boost bind here because we need to pass a memberfunction to stl sort
+      list->sort(boost::bind(&TrafficControl::prioritySort, this, clientID, _1, _2) );
+
+      //now we check, that the creator of an object always exists on a client
+      std::list<obj>::iterator itcreator;
+      for(itvec = list->begin(); itvec != list->end(); itvec++)
+      {
+        fixCreatorDependencies(itvec, list, clientID);
+      }
+      //end of sorting
+      //now the cutting, work the same obj out in processobjectlist and copiedlist, compression rate muss noch festgelegt werden.
+//       printList(list, clientID);
+      cut(list, targetSize);
+
+      //now sort again after objDataOffset
+      list->sort(boost::bind(&TrafficControl::dataSort, this, _1, _2) );
+    }
+    //diese Funktion updateClientList muss noch gemacht werden
+    updateClientListTemp(list);
+    //end of sorting
+  }
+
+  void TrafficControl::printList(std::list<obj> *list, unsigned int clientID)
+  {
+    std::list<obj>::iterator it;
+    COUT(0) << "=========== Objectlist ===========" << endl;
+    for( it=list->begin(); it!=list->end(); it++)
+      COUT(0) << "ObjectID: " << (*it).objID << " creatorID: " << (*it).objCreatorID << " Priority: " << clientListPerm_[clientID][(*it).objID].objValuePerm + clientListPerm_[clientID][(*it).objID].objValueSched << " size: " << (*it).objSize << endl;
+  }
+
+  void TrafficControl::fixCreatorDependencies(std::list<obj>::iterator it1, std::list<obj> *list, unsigned int clientID)
+  {
+    if ( (*it1).objCreatorID == OBJECTID_UNKNOWN )
+      return;
+    if( clientListPerm_[clientID][(*it1).objCreatorID].objCurGS != GAMESTATEID_INITIAL )
+      return;
+    std::list<obj>::iterator it2, it3=it1;
+    for( it2 = ++it3; it2 != list->end(); it2++ )
+    {
+      if( (*it2).objID == (*it1).objCreatorID )
+      {
+        it3 = list->insert(it1, *it2); //insert creator before it1
+        list->erase(it2);
+//         printList(list, clientID);
+        fixCreatorDependencies( it3, list, clientID );
+        break;
+      }
+    }
+  }
+
+  void TrafficControl::clientDisconnected(unsigned int clientID)
+  {
+    assert(clientListTemp_.find(clientID) != clientListTemp_.end() );
+    assert(clientListPerm_.find(clientID) != clientListPerm_.end() );
+    clientListTemp_.erase(clientListTemp_.find(clientID));
+    clientListPerm_.erase(clientListPerm_.find(clientID));
+  }
+
+
+}//namespace network
Index: code/trunk/src/network/TrafficControl.h
===================================================================
--- code/trunk/src/network/TrafficControl.h	(revision 2662)
+++ code/trunk/src/network/TrafficControl.h	(revision 2662)
@@ -0,0 +1,181 @@
+/*
+ *   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 <scheusso [at] ee.ethz.ch>, (C) 2008
+ *   Co-authors:
+ *      ...
+ *
+ */
+#ifndef NETWORK_TRAFFICCONTROL_H
+#define NETWORK_TRAFFICCONTROL_H
+
+#include "NetworkPrereqs.h"
+
+#include <string>
+#include <list>
+#include <map>
+#include <utility>
+#include <algorithm>
+#include "util/Integers.h"
+#include "core/OrxonoxClass.h"
+#include "network/ClientConnectionListener.h"
+
+namespace orxonox {
+
+
+  /**
+   *a list of objects of this type will be given by the Server's Gamestate Manager
+   */
+  class objInfo
+  {
+    public:
+      uint32_t objID;
+      uint32_t objCreatorID;
+      uint32_t objCurGS;//current GameState ID
+      uint32_t objDiffGS;//difference between current and latest GameState
+      uint32_t objSize;
+      int objValuePerm;
+      int objValueSched;
+      objInfo(uint32_t ID, uint32_t creatorID, int32_t curGsID, int32_t diffGsID, uint32_t size, unsigned int prioperm, unsigned int priosched);
+      objInfo();
+  };
+
+/**
+   *a list of objects of this type will be given by the Server's Gamestate Manager
+ */
+  class obj
+  {
+    public:
+      uint32_t objID;
+      uint32_t objCreatorID;
+      uint32_t objSize;
+      uint32_t objDataOffset;
+      obj();
+      obj( uint32_t ID, uint32_t creatorID, uint32_t size, uint32_t offset );
+  };
+  
+
+
+
+/**
+*
+*/
+class TrafficControl : public ClientConnectionListener {
+  private:
+
+    /**
+    *Lists that will be used:
+    *listToProcess
+    *clientListPerm
+    *clientListTemp
+    *referenceList
+    *permObjPrio list
+    *schedObjPrio
+    */
+    //start: lists to be used
+    /**
+    *creates list (typ map) that contains objids, struct with info concerning object(objid)
+    */
+//     std::map<unsigned int, objInfo> listToProcess_;//copy of argument, when traffic control tool is being called, the original of this must be returned later on, eg the list given by GS
+    /**
+    *permanent client list: contains client ids, object ids and objectInfos (in this order)
+    */
+    std::map<unsigned int, std::map<unsigned int, objInfo > > clientListPerm_;
+    //has to be created with constructor and then needs to be updated by evaluateList().
+
+    /**
+    *temporary client list: contains client ids, gamestate ids and object ids (in this order)
+    */
+    std::map<unsigned int, std::map<unsigned int, std::list<obj> > > clientListTemp_;
+    /**
+    *static priority list: contains obj id, basic priority (in this order)
+    */
+//     std::map<unsigned int, unsigned int> permObjPrio_;
+    /**
+    *dynamic priority list: contains obj id, dynamic priority (eg scheduled) (in this order)
+    */
+//     std::map<unsigned int, unsigned int> schedObjPrio_;
+    //end: lists to be used
+
+    /**updateReferenceList
+    *currentGamestateID and currentClientID will be defined as soon as TrafficControl is being called by Server
+    */
+    unsigned int currentGamestateID;
+    unsigned int currentClientID;
+    unsigned int targetSize;
+    bool         bActive_;
+    /**
+    *copiedVector is a copy of the given Vector by the GSmanager, on this list all manipulations are performed
+    */
+//     std::list<obj> copiedVector;
+
+//     void updateReferenceList(std::map<unsigned int, objInfo> *list);//done
+    void insertinClientListPerm(unsigned int clientID, obj objinf);//done
+    /**
+    *creates listToProcess, which can be easialy compared with other lists
+    */
+//     void copyList(std::list<obj> *list);//done
+    
+    void cut(std::list<obj> *list, unsigned int targetsize);
+    void updateClientListTemp(std::list<obj> *list);//done
+    /**
+    *evaluates Data given (list) and produces result(->Data to be updated)
+    */
+    void evaluateList(unsigned int clientID, std::list<obj> *list);//done    
+    void ack(unsigned int clientID, unsigned int gamestateID);  // this function gets called when the server receives an ack from the client
+    
+    //ClientConnectionListener functions
+    virtual void clientConnected(unsigned int clientID){};
+    virtual void clientDisconnected(unsigned int clientID);
+
+ 
+  protected:
+    static TrafficControl *instance_;
+
+  public:
+    TrafficControl();
+    virtual ~TrafficControl();
+    /**
+    *is being used by GSManager from Server:
+    *list contains: ObjIds, CreatorIds, Size (in this order) from Client XY 
+    *Elements of list are accessed by *list[i]
+    *Elements of struct i are therefore: *list[i].objID
+    */
+    void setConfigValues();
+    static TrafficControl *getInstance();
+    void processObjectList(unsigned int clientID, unsigned int gamestateID, std::list<obj>* list); //gets a pointer to the list (containing objectIDs) and sorts it
+    //done
+    static void processAck(unsigned int clientID, unsigned int gamestateID)
+    { return instance_->ack(clientID, gamestateID); }
+    //done
+    void deleteObject(unsigned int objectID);				// this function gets called when an object has been deleted (in order to clean up lists and maps)
+    
+    bool prioritySort(uint32_t clientID, obj i, obj j);
+    bool dataSort(obj i, obj j);
+    void printList(std::list<obj> *list, unsigned int clientID);
+    void fixCreatorDependencies(std::list<obj>::iterator it, std::list<obj> *list, unsigned int clientID);
+};
+
+}
+
+#endif
+
Index: code/trunk/src/network/packet/Acknowledgement.cc
===================================================================
--- code/trunk/src/network/packet/Acknowledgement.cc	(revision 2171)
+++ code/trunk/src/network/packet/Acknowledgement.cc	(revision 2662)
@@ -64,4 +64,5 @@
 
 bool Acknowledgement::process(){
+COUT(0) << "processing ACK with ID: " << getAckID() << endl;
   bool b = GamestateHandler::ackGamestate(getAckID(), clientID_);
   delete this;
Index: code/trunk/src/network/packet/Acknowledgement.h
===================================================================
--- code/trunk/src/network/packet/Acknowledgement.h	(revision 2171)
+++ code/trunk/src/network/packet/Acknowledgement.h	(revision 2662)
@@ -32,4 +32,5 @@
 #include "Packet.h"
 
+const unsigned int ACKID_NACK = 0;
 
 namespace orxonox {
Index: code/trunk/src/network/packet/DeleteObjects.cc
===================================================================
--- code/trunk/src/network/packet/DeleteObjects.cc	(revision 2171)
+++ code/trunk/src/network/packet/DeleteObjects.cc	(revision 2662)
@@ -30,5 +30,5 @@
 #include "DeleteObjects.h"
 #include <enet/enet.h>
-#include "network/Synchronisable.h"
+#include "network/synchronisable/Synchronisable.h"
 #include "core/CoreIncludes.h"
 #include <assert.h>
@@ -61,9 +61,9 @@
   if(number==0)
     return false;
-  COUT(3) << "sending DeleteObjects: ";
+  COUT(4) << "sending DeleteObjects: ";
   unsigned int size = sizeof(ENUM::Type) + sizeof(uint32_t)*(number+1);
   data_ = new uint8_t[size];
   uint8_t *tdata = data_;
-  *(ENUM::Type *)(tdata) = ENUM::DeleteObjects;
+  *reinterpret_cast<ENUM::Type*>(tdata) = ENUM::DeleteObjects;
   tdata += sizeof(ENUM::Type);
   *(uint32_t *)tdata = number;
@@ -72,9 +72,9 @@
     unsigned int temp = Synchronisable::popDeletedObject();
 //     assert(temp<10000); //ugly hack
-    *(uint32_t *)(tdata) = temp;
-    COUT(3) << temp << " ";
+    *reinterpret_cast<uint32_t*>(tdata) = temp;
+    COUT(4) << temp << " ";
     tdata += sizeof(uint32_t);
   }
-  COUT(3) << std::endl;
+  COUT(4) << std::endl;
   return true;
 }
@@ -87,5 +87,5 @@
 bool DeleteObjects::process(){
   for(unsigned int i=0; i<*(unsigned int *)(data_+_QUANTITY); i++){
-    COUT(3) << "deleting object with id: " << *(uint32_t*)(data_+_OBJECTIDS+i*sizeof(uint32_t)) << std::endl;
+    COUT(4) << "deleting object with id: " << *(uint32_t*)(data_+_OBJECTIDS+i*sizeof(uint32_t)) << std::endl;
     Synchronisable::deleteObject( *(uint32_t*)(data_+_OBJECTIDS+i*sizeof(uint32_t)) );
   }
Index: code/trunk/src/network/packet/Gamestate.cc
===================================================================
--- code/trunk/src/network/packet/Gamestate.cc	(revision 2171)
+++ code/trunk/src/network/packet/Gamestate.cc	(revision 2662)
@@ -28,11 +28,13 @@
 
 #include "Gamestate.h"
-#include "network/ClientInformation.h"
-#include "network/GamestateHandler.h"
+#include "../GamestateHandler.h"
+#include "../synchronisable/Synchronisable.h"
+#include "../TrafficControl.h"
+#include "core/Core.h"
 #include "core/CoreIncludes.h"
 #include "core/Iterator.h"
 
 #include <zlib.h>
-#include <assert.h>
+#include <cassert>
 
 
@@ -42,14 +44,17 @@
 namespace packet {
 
-#define GAMESTATE_START(data) (data + sizeof(GamestateHeader))
-#define GAMESTATE_HEADER(data) ((GamestateHeader *)data)
-#define HEADER GAMESTATE_HEADER(data_)
-
+#define GAMESTATE_START(data) (data + GamestateHeader::getSize())
 
 #define PACKET_FLAG_GAMESTATE  ENET_PACKET_FLAG_RELIABLE
 
+// Gamestate::Gamestate()
+// {
+//   flags_ = flags_ | PACKET_FLAG_GAMESTATE;
+// }
+
 Gamestate::Gamestate()
 {
   flags_ = flags_ | PACKET_FLAG_GAMESTATE;
+  header_ = 0;
 }
 
@@ -58,4 +63,5 @@
 {
   flags_ = flags_ | PACKET_FLAG_GAMESTATE;
+  header_ = new GamestateHeader(data_);
 }
 
@@ -64,4 +70,12 @@
   flags_ = flags_ | PACKET_FLAG_GAMESTATE;
   data_=data;
+  header_ = new GamestateHeader(data_);
+}
+
+Gamestate::Gamestate(const Gamestate& g) :
+    Packet( *(Packet*)&g )
+{
+  flags_ = flags_ | PACKET_FLAG_GAMESTATE;
+  header_ = new GamestateHeader(data_);
 }
 
@@ -73,24 +87,29 @@
 bool Gamestate::collectData(int id, uint8_t mode)
 {
-  unsigned int tempsize=0, currentsize=0;
+  assert(this->header_==0); // make sure the header didn't exist before
+  uint32_t tempsize=0, currentsize=0;
   assert(data_==0);
-  unsigned int size = calcGamestateSize(id, mode);
+  uint32_t size = calcGamestateSize(id, mode);
 
   COUT(4) << "G.ST.Man: producing gamestate with id: " << id << std::endl;
   if(size==0)
     return false;
-  data_ = new unsigned char[size + sizeof(GamestateHeader)];
+  data_ = new uint8_t[size + GamestateHeader::getSize()];
   if(!data_){
     COUT(2) << "GameStateManager: could not allocate memory" << std::endl;
     return false;
   }
+  
+  // create the header object
+  header_ = new GamestateHeader(data_);
 
   //start collect data synchronisable by synchronisable
   uint8_t *mem=data_;
-  mem+=sizeof(GamestateHeader);
+  mem += GamestateHeader::getSize();
   ObjectList<Synchronisable>::iterator it;
   for(it = ObjectList<Synchronisable>::begin(); it; ++it){
+    
+#ifndef NDEBUG
     tempsize=it->getSize(id, mode);
-
     if(currentsize+tempsize > size){
       assert(0); // if we don't use multithreading this part shouldn't be neccessary
@@ -98,16 +117,18 @@
       COUT(3) << "G.St.Man: need additional memory" << std::endl;
       ObjectList<Synchronisable>::iterator temp = it;
-      int addsize=tempsize;
+      uint32_t addsize=tempsize;
       while(++temp)
         addsize+=temp->getSize(id, mode);
-      data_ = (uint8_t *)realloc(data_, sizeof(GamestateHeader) + currentsize + addsize);
+      data_ = (uint8_t *)realloc(data_, GamestateHeader::getSize() + currentsize + addsize);
       if(!data_)
         return false;
       size = currentsize+addsize;
     }// stop allocate additional memory
-
+#endif
 
     //if(it->doSelection(id))
-    dataMap_[mem-data_]=(*it);  // save the mem location of the synchronisable data
+    if ( it->doSync( id, mode ) )
+      dataMap_.push_back( obj(it->getObjectID(), it->getCreatorID(), tempsize, mem-data_) );
+//     dataMap_[mem-data_]=(*it);  // save the mem location of the synchronisable data
     if(!it->getData(mem, id, mode))
       return false; // mem pointer gets automatically increased because of call by reference
@@ -118,10 +139,9 @@
 
   //start write gamestate header
-  HEADER->packetType = ENUM::Gamestate;
-  HEADER->datasize = currentsize;
-  HEADER->id = id;
-  HEADER->diffed = false;
-  HEADER->complete = true;
-  HEADER->compressed = false;
+  header_->setDataSize( currentsize );
+  header_->setID( id );
+  header_->setDiffed( false );
+  header_->setComplete( true );
+  header_->setCompressed( false );
   //stop write gamestate header
 
@@ -133,8 +153,9 @@
 bool Gamestate::spreadData(uint8_t mode)
 {
-  assert(data_);
-  assert(!HEADER->compressed);
-  assert(!HEADER->diffed);
-  uint8_t *mem=data_+sizeof(GamestateHeader);
+  COUT(4) << "processing gamestate with id " << header_->getID() << endl;
+  assert(data_);
+  assert(!header_->isCompressed());
+  assert(!header_->isDiffed());
+  uint8_t *mem=data_+GamestateHeader::getSize();
     // get the start of the Synchronisable list
   //ObjectList<Synchronisable>::iterator it=ObjectList<Synchronisable>::begin();
@@ -142,11 +163,21 @@
 
   // update the data of the objects we received
-  while(mem < data_+sizeof(GamestateHeader)+HEADER->datasize){
-    synchronisableHeader *objectheader = (synchronisableHeader*)mem;
-
-    s = Synchronisable::getSynchronisable( objectheader->objectID );
+  while(mem < data_+GamestateHeader::getSize()+header_->getDataSize()){
+    SynchronisableHeader objectheader(mem);
+
+    s = Synchronisable::getSynchronisable( objectheader.getObjectID() );
     if(!s)
     {
-      Synchronisable::fabricate(mem, mode);
+      if (!Core::isMaster())
+      {
+        Synchronisable::fabricate(mem, mode);
+      }
+      else
+      {
+        mem += objectheader.getDataSize();
+      }
+//         COUT(0) << "could not fabricate synchronisable: " << objectheader->objectID << " classid: " << objectheader->classID << " creator: " << objectheader->creatorID << endl;
+//       else
+//         COUT(0) << "fabricated: " << objectheader->objectID << " classid: " << objectheader->classID << " creator: "  << objectheader->creatorID << endl;
     }
     else
@@ -157,30 +188,50 @@
   }
 
+   // In debug mode, check first, whether there are no duplicate objectIDs
+#ifndef NDEBUG
+  ObjectList<Synchronisable>::iterator it;
+  for (it = ObjectList<Synchronisable>::begin(); it != ObjectList<Synchronisable>::end(); ++it) {
+    if (it->getObjectID() == OBJECTID_UNKNOWN) {
+      if (it->objectMode_ != 0x0) {
+        COUT(0) << "Found object with OBJECTID_UNKNOWN on the client with objectMode != 0x0!" << std::endl;
+        COUT(0) << "Possible reason for this error: Client created a synchronized object without the Server's approval." << std::endl;
+        COUT(0) << "Objects class: " << it->getIdentifier()->getName() << std::endl;
+        assert(false);
+      }
+    }
+    else {
+      ObjectList<Synchronisable>::iterator it2;
+      for (it2 = ObjectList<Synchronisable>::begin(); it2 != ObjectList<Synchronisable>::end(); ++it2) {
+        if (it->getObjectID() == it2->getObjectID() && *it != *it2) {
+           COUT(0) << "Found duplicate objectIDs on the client!" << std::endl
+                   << "Are you sure you don't create a Sychnronisable objcect with 'new' \
+                       that doesn't have objectMode = 0x0?" << std::endl;
+           assert(false);
+        }
+      }
+    }
+  }
+#endif
+
   return true;
 }
 
-
-
-int Gamestate::getID(){
-  return HEADER->id;
-}
-
-unsigned int Gamestate::getSize() const
-{
-  assert(data_);
-  if(HEADER->compressed)
-    return HEADER->compsize+sizeof(GamestateHeader);
+uint32_t Gamestate::getSize() const
+{
+  assert(data_);
+  if(header_->isCompressed())
+    return header_->getCompSize()+GamestateHeader::getSize();
   else
   {
-    return HEADER->datasize+sizeof(GamestateHeader);
+    return header_->getDataSize()+GamestateHeader::getSize();
   }
 }
 
 bool Gamestate::operator==(packet::Gamestate gs){
-  uint8_t *d1 = data_+sizeof(GamestateHeader);
-  uint8_t *d2 = gs.data_+sizeof(GamestateHeader);
+  uint8_t *d1 = data_+GamestateHeader::getSize();
+  uint8_t *d2 = gs.data_+GamestateHeader::getSize();
   assert(!isCompressed());
   assert(!gs.isCompressed());
-  while(d1<data_+HEADER->datasize)
+  while(d1<data_+header_->getDataSize())
   {
     if(*d1!=*d2)
@@ -201,16 +252,16 @@
 bool Gamestate::compressData()
 {
-  assert(HEADER);
-  assert(!HEADER->compressed);
-  uLongf buffer = (uLongf)(((HEADER->datasize + 12)*1.01)+1);
+  assert(data_);
+  assert(!header_->isCompressed());
+  uLongf buffer = (uLongf)(((header_->getDataSize() + 12)*1.01)+1);
   if(buffer==0)
     return false;
 
-  uint8_t *ndata = new uint8_t[buffer+sizeof(GamestateHeader)];
-  uint8_t *dest = GAMESTATE_START(ndata);
+  uint8_t *ndata = new uint8_t[buffer+GamestateHeader::getSize()];
+  uint8_t *dest = ndata + GamestateHeader::getSize();
   //unsigned char *dest = new unsigned char[buffer];
-  uint8_t *source = GAMESTATE_START(data_);
+  uint8_t *source = data_ + GamestateHeader::getSize();
   int retval;
-  retval = compress( dest, &buffer, source, (uLong)(HEADER->datasize) );
+  retval = compress( dest, &buffer, source, (uLong)(header_->getDataSize()) );
   switch ( retval ) {
     case Z_OK: COUT(5) << "G.St.Man: compress: successfully compressed" << std::endl; break;
@@ -219,45 +270,32 @@
     case Z_DATA_ERROR: COUT(2) << "G.St.Man: compress: data corrupted in gamestate.compress" << std::endl; return false;
   }
-#ifndef NDEBUG
-  //decompress and compare the start and the decompressed data
-  uint8_t *rdata = new uint8_t[HEADER->datasize+sizeof(GamestateHeader)];
-  uint8_t *d2 = GAMESTATE_START(rdata);
-  uLongf length2 = HEADER->datasize;
-  uncompress(d2, &length2, dest, buffer);
-  for(unsigned int i=0; i<HEADER->datasize; i++){
-    assert(*(source+i)==*(d2+i));
-  }
-  delete[] rdata;
-#endif
 
   //copy and modify header
-#ifndef NDEBUG
-  HEADER->crc32 = calcCRC(data_+sizeof(GamestateHeader), HEADER->datasize);
-#endif
-  *GAMESTATE_HEADER(ndata) = *HEADER;
+  GamestateHeader *temp = header_;
+  header_ = new GamestateHeader(ndata, temp);
+  delete temp;
   //delete old data
   delete[] data_;
   //save new data
   data_ = ndata;
-  HEADER->compsize = buffer;
-  HEADER->compressed = true;
-  assert(HEADER->compressed);
-  COUT(4) << "gamestate compress datasize: " << HEADER->datasize << " compsize: " << HEADER->compsize << std::endl;
+  header_->setCompSize( buffer );
+  header_->setCompressed( true );
+  COUT(5) << "gamestate compress datasize: " << header_->getDataSize() << " compsize: " << header_->getCompSize() << std::endl;
   return true;
 }
 bool Gamestate::decompressData()
 {
-  assert(HEADER);
-  assert(HEADER->compressed);
-  COUT(4) << "GameStateClient: uncompressing gamestate. id: " << HEADER->id << ", baseid: " << HEADER->base_id << ", datasize: " << HEADER->datasize << ", compsize: " << HEADER->compsize << std::endl;
-  unsigned int datasize = HEADER->datasize;
-  unsigned int compsize = HEADER->compsize;
-  unsigned int bufsize;
+  assert(data_);
+  assert(header_->isCompressed());
+  COUT(4) << "GameStateClient: uncompressing gamestate. id: " << header_->getID() << ", baseid: " << header_->getBaseID() << ", datasize: " << header_->getDataSize() << ", compsize: " << header_->getCompSize() << std::endl;
+  uint32_t datasize = header_->getDataSize();
+  uint32_t compsize = header_->getCompSize();
+  uint32_t bufsize;
 //  assert(compsize<=datasize);
   bufsize = datasize;
   assert(bufsize!=0);
-  uint8_t *ndata = new uint8_t[bufsize + sizeof(GamestateHeader)];
-  uint8_t *dest = ndata + sizeof(GamestateHeader);
-  uint8_t *source = data_ + sizeof(GamestateHeader);
+  uint8_t *ndata = new uint8_t[bufsize + GamestateHeader::getSize()];
+  uint8_t *dest = ndata + GamestateHeader::getSize();
+  uint8_t *source = data_ + GamestateHeader::getSize();
   int retval;
   uLongf length=bufsize;
@@ -269,10 +307,9 @@
     case Z_DATA_ERROR: COUT(2) << "data corrupted (zlib)" << std::endl; return false;
   }
-#ifndef NDEBUG
-  assert(HEADER->crc32==calcCRC(ndata+sizeof(GamestateHeader), HEADER->datasize));
-#endif
 
   //copy over the header
-  *GAMESTATE_HEADER(ndata) = *HEADER;
+  GamestateHeader *temp = header_;
+  header_ = new GamestateHeader( data_, header_ );
+  delete temp;
 
   if (this->bDataENetAllocated_){
@@ -289,7 +326,7 @@
   //set new pointers
   data_ = ndata;
-  HEADER->compressed = false;
-  assert(HEADER->datasize==datasize);
-  assert(HEADER->compsize==compsize);
+  header_->setCompressed( false );
+  assert(header_->getDataSize()==datasize);
+  assert(header_->getCompSize()==compsize);
   return true;
 }
@@ -297,23 +334,24 @@
 Gamestate *Gamestate::diff(Gamestate *base)
 {
-  assert(HEADER);
-  assert(!HEADER->compressed);
-  assert(!HEADER->diffed);
+  assert(data_);
+  assert(!header_->isCompressed());
+  assert(!header_->isDiffed());
+  GamestateHeader diffHeader(base->data_);
   //unsigned char *basep = base->getGs()/*, *gs = getGs()*/;
   uint8_t *basep = GAMESTATE_START(base->data_), *gs = GAMESTATE_START(this->data_);
-  unsigned int of=0; // pointers offset
-  unsigned int dest_length=0;
-  dest_length=HEADER->datasize;
+  uint32_t of=0; // pointers offset
+  uint32_t dest_length=0;
+  dest_length=header_->getDataSize();
   if(dest_length==0)
     return NULL;
-  uint8_t *ndata = new uint8_t[dest_length*sizeof(uint8_t)+sizeof(GamestateHeader)];
-  uint8_t *dest = ndata + sizeof(GamestateHeader);
-  while(of < GAMESTATE_HEADER(base->data_)->datasize && of < HEADER->datasize){
+  uint8_t *ndata = new uint8_t[dest_length*sizeof(uint8_t)+GamestateHeader::getSize()];
+  uint8_t *dest = ndata + GamestateHeader::getSize();
+  while(of < diffHeader.getDataSize() && of < header_->getDataSize()){
     *(dest+of)=*(basep+of)^*(gs+of); // do the xor
     ++of;
   }
-  if(GAMESTATE_HEADER(base->data_)->datasize!=HEADER->datasize){
+  if(diffHeader.getDataSize()!=header_->getDataSize()){
     uint8_t n=0;
-    if(GAMESTATE_HEADER(base->data_)->datasize < HEADER->datasize){
+    if(diffHeader.getDataSize() < header_->getDataSize()){
       while(of<dest_length){
         *(dest+of)=n^*(gs+of);
@@ -323,8 +361,8 @@
   }
 
-  *GAMESTATE_HEADER(ndata) = *HEADER;
-  GAMESTATE_HEADER(ndata)->diffed = true;
-  GAMESTATE_HEADER(ndata)->base_id = base->getID();
   Gamestate *g = new Gamestate(ndata, getClientID());
+  *(g->header_) = *header_;
+  g->header_->setDiffed( true );
+  g->header_->setBaseID( base->getID() );
   g->flags_=flags_;
   g->packetDirection_ = packetDirection_;
@@ -332,203 +370,96 @@
 }
 
-Gamestate* Gamestate::doSelection(unsigned int clientID){
-  assert(data_);
-  std::map<unsigned int, Synchronisable *>::iterator it;
+Gamestate* Gamestate::doSelection(unsigned int clientID, unsigned int targetSize){
+  assert(data_);
+  std::list<obj>::iterator it;
 
   // allocate memory for new data
-  uint8_t *gdata = new uint8_t[HEADER->datasize+sizeof(GamestateHeader)];
+  uint8_t *gdata = new uint8_t[header_->getDataSize()+GamestateHeader::getSize()];
   // create a gamestate out of it
   Gamestate *gs = new Gamestate(gdata);
-  uint8_t *newdata = gdata + sizeof(GamestateHeader);
+  uint8_t *newdata = gdata + GamestateHeader::getSize();
   uint8_t *origdata = GAMESTATE_START(data_);
 
   //copy the GamestateHeader
-  *(GamestateHeader*)gdata = *HEADER;
-
-  synchronisableHeader *oldobjectheader, *newobjectheader;
-  unsigned int objectOffset;
+  assert(gs->header_);
+  *(gs->header_) = *header_;
+
+  uint32_t objectOffset;
+  unsigned int objectsize, destsize=0;
+  // TODO: Why is this variable not used?
+  //Synchronisable *object;
+
+  //call TrafficControl
+  TrafficControl::getInstance()->processObjectList( clientID, header_->getID(), &dataMap_ );
 
   //copy in the zeros
-  for(it=dataMap_.begin(); it!=dataMap_.end(); it++){
-    oldobjectheader = (synchronisableHeader*)origdata;
-    newobjectheader = (synchronisableHeader*)newdata;
-    unsigned int objectsize = oldobjectheader->size;
-    assert(it->second->objectID==oldobjectheader->objectID);
-    *newobjectheader = *oldobjectheader;
-    objectOffset=sizeof(synchronisableHeader); //skip the size and the availableData variables in the objectheader
-    if(it->second->doSelection(HEADER->id)){
-      assert(newobjectheader->dataAvailable==true);
-      memcpy(newdata+objectOffset, origdata+objectOffset, objectsize-objectOffset);
+  for(it=dataMap_.begin(); it!=dataMap_.end();){
+//    if((*it).objSize==0)
+//      continue;
+//    if(it->second->getSize(HEADER->id)==0) // merged from objecthierarchy2, doesn't work anymore; TODO: change this
+//      continue;                            // merged from objecthierarchy2, doesn't work anymore; TODO: change this
+    SynchronisableHeader oldobjectheader(origdata);
+    SynchronisableHeader newobjectheader(newdata);
+    if ( (*it).objSize == 0 )
+    {
+      ++it;
+      continue;
+    }
+//     object = Synchronisable::getSynchronisable( (*it).objID );
+//     assert(object->objectID == oldobjectheader->objectID);
+    objectsize = oldobjectheader.getDataSize();
+    objectOffset=SynchronisableHeader::getSize(); //skip the size and the availableData variables in the objectheader
+    if ( (*it).objID == oldobjectheader.getObjectID() ){
+      memcpy(newdata, origdata, objectsize);
+      assert(newobjectheader.isDataAvailable()==true);
+      ++it;
     }else{
-      newobjectheader->dataAvailable=false;
+      newobjectheader = oldobjectheader;
+      newobjectheader.setDataAvailable(false);
       memset(newdata+objectOffset, 0, objectsize-objectOffset);
-      assert(objectOffset==objectsize);
     }
     newdata += objectsize;
     origdata += objectsize;
-  }
+    destsize += objectsize;
+  }
+#ifndef NDEBUG
+  uint32_t origsize = destsize;
+  while ( origsize < header_->getDataSize() )
+  {
+    SynchronisableHeader oldobjectheader(origdata);
+    objectsize = oldobjectheader.getDataSize();
+    origdata += objectsize;
+    origsize += objectsize;
+  }
+  assert(origsize==header_->getDataSize());
+  assert(destsize!=0);
+#endif
+  gs->header_->setDataSize( destsize );
   return gs;
 }
 
 
-Gamestate* Gamestate::intelligentDiff(Gamestate *base, unsigned int clientID){
-  // asserts
-  assert(data_);
-  assert(base->data_);
-  assert(!GAMESTATE_HEADER(base->data_)->diffed);
-  assert(!GAMESTATE_HEADER(base->data_)->compressed);
-  assert(!HEADER->compressed);
-  assert(!HEADER->diffed);
-
-  //preparations
-  std::map<unsigned int, Synchronisable *>::iterator it;
-  uint8_t *origdata, *basedata, *destdata, *ndata;
-  unsigned int objectOffset, streamOffset=0;    //data offset
-  unsigned int minsize = (HEADER->datasize < GAMESTATE_HEADER(base->data_)->datasize) ? HEADER->datasize : GAMESTATE_HEADER(base->data_)->datasize;
-  synchronisableHeader *origheader;
-  synchronisableHeader *destheader;
-
-  origdata = GAMESTATE_START(this->data_);
-  basedata = GAMESTATE_START(base->data_);
-  ndata = new uint8_t[HEADER->datasize + sizeof(GamestateHeader)];
-  destdata = ndata + sizeof(GamestateHeader);
-
-  // do the diff
-  for(it=dataMap_.begin(); it!=dataMap_.end(); it++){
-    assert(streamOffset<HEADER->datasize);
-    bool sendData = it->second->doSelection(HEADER->id);
-    origheader = (synchronisableHeader *)(origdata+streamOffset);
-    destheader = (synchronisableHeader *)(destdata+streamOffset);
-
-    //copy and partially diff the object header
-    assert(sizeof(synchronisableHeader)==3*sizeof(unsigned int)+sizeof(bool));
-    *(uint32_t*)destdata = *(uint32_t*)origdata; //size (do not diff)
-    *(bool*)(destdata+sizeof(uint32_t)) = sendData;
-    if(sendData){
-      *(uint32_t*)(destdata+sizeof(uint32_t)+sizeof(bool)) = *(uint32_t*)(basedata+sizeof(uint32_t)+sizeof(bool)) ^ *(uint32_t*)(origdata+sizeof(uint32_t)+sizeof(bool)); //objectid (diff it)
-      *(uint32_t*)(destdata+2*sizeof(uint32_t)+sizeof(bool)) = *(uint32_t*)(basedata+2*sizeof(uint32_t)+sizeof(bool)) ^ *(uint32_t*)(origdata+2*sizeof(uint32_t)+sizeof(bool)); //classid (diff it)
-    }else{
-      *(uint32_t*)(destdata+sizeof(uint32_t)+sizeof(bool)) = 0;
-      *(uint32_t*)(destdata+2*sizeof(uint32_t)+sizeof(bool)) = 0;
-    }
-    objectOffset=sizeof(synchronisableHeader);
-    streamOffset+=sizeof(synchronisableHeader);
-
-    //now handle the object data or fill with zeros
-    while(objectOffset<origheader->size ){
-
-      if(sendData && streamOffset<minsize)
-        *(destdata+objectOffset)=*(basedata+objectOffset)^*(origdata+objectOffset); // do the xor
-      else if(sendData)
-        *(destdata+objectOffset)=((uint8_t)0)^*(origdata+objectOffset); // xor with 0 (basestream is too short)
-      else
-        *(destdata+objectOffset)=0; // set to 0 because this object should not be transfered
-
-      objectOffset++;
-      streamOffset++;
-    }
-    destdata+=objectOffset;
-    origdata+=objectOffset;
-    basedata+=objectOffset;
-  }
-
-  //copy over the gamestate header and set the diffed flag
-  *(GamestateHeader *)ndata = *HEADER; //copy over the header
-  Gamestate *gs = new Gamestate(ndata);
-  GAMESTATE_HEADER(ndata)->diffed=true;
-  return gs;
-}
-
-Gamestate* Gamestate::intelligentUnDiff(Gamestate *base){
-  // asserts
-  assert(data_);
-  assert(base->data_);
-  assert(!GAMESTATE_HEADER(base->data_)->diffed);
-  assert(!GAMESTATE_HEADER(base->data_)->compressed);
-  assert(!HEADER->compressed);
-  assert(HEADER->diffed);
-
-  //preparations
-  std::map<unsigned int, Synchronisable *>::iterator it;
-  uint8_t *origdata, *basedata, *destdata, *ndata;
-  unsigned int objectOffset, streamOffset=0;    //data offset
-  unsigned int minsize = (HEADER->datasize < GAMESTATE_HEADER(base->data_)->datasize) ? HEADER->datasize : GAMESTATE_HEADER(base->data_)->datasize;
-  synchronisableHeader *origheader;
-  synchronisableHeader *destheader;
-
-  origdata = GAMESTATE_START(this->data_);
-  basedata = GAMESTATE_START(base->data_);
-  ndata = new uint8_t[HEADER->datasize + sizeof(GamestateHeader)];
-  destdata = ndata + sizeof(GamestateHeader);
-
-  // do the undiff
-  for(it=dataMap_.begin(); it!=dataMap_.end(); it++){
-    assert(streamOffset<HEADER->datasize);
-    origheader = (synchronisableHeader *)(origdata+streamOffset);
-    destheader = (synchronisableHeader *)(destdata+streamOffset);
-    bool sendData;
-
-    //copy and partially diff the object header
-    assert(sizeof(synchronisableHeader)==3*sizeof(unsigned int)+sizeof(bool));
-    *(unsigned int*)destdata = *(unsigned int*)origdata; //size (do not diff)
-    *(bool*)(destdata+sizeof(unsigned int)) = *(bool*)(origdata+sizeof(unsigned int));
-    sendData = *(bool*)(origdata+sizeof(unsigned int));
-    if(sendData){
-      *(unsigned int*)(destdata+sizeof(unsigned int)+sizeof(bool)) = *(unsigned int*)(basedata+sizeof(unsigned int)+sizeof(bool)) ^ *(unsigned int*)(origdata+sizeof(unsigned int)+sizeof(bool)); //objectid (diff it)
-      *(unsigned int*)(destdata+2*sizeof(unsigned int)+sizeof(bool)) = *(unsigned int*)(basedata+2*sizeof(unsigned int)+sizeof(bool)) ^ *(unsigned int*)(origdata+2*sizeof(unsigned int)+sizeof(bool)); //classid (diff it)
-    }else{
-      *(unsigned int*)(destdata+sizeof(unsigned int)+sizeof(bool)) = 0;
-      *(unsigned int*)(destdata+2*sizeof(unsigned int)+sizeof(bool)) = 0;
-    }
-    objectOffset=sizeof(synchronisableHeader);
-    streamOffset+=sizeof(synchronisableHeader);
-
-    //now handle the object data or fill with zeros
-    while(objectOffset<origheader->size ){
-
-      if(sendData && streamOffset<minsize)
-        *(destdata+objectOffset)=*(basedata+objectOffset)^*(origdata+objectOffset); // do the xor
-      else if(sendData)
-        *(destdata+objectOffset)=((unsigned char)0)^*(origdata+objectOffset); // xor with 0 (basestream is too short)
-      else
-        *(destdata+objectOffset)=0; // set to 0 because this object should not be transfered
-
-      objectOffset++;
-      streamOffset++;
-    }
-    destdata+=objectOffset;
-    origdata+=objectOffset;
-    basedata+=objectOffset;
-  }
-
-  //copy over the gamestate header and set the diffed flag
-  *(GamestateHeader *)ndata = *HEADER; //copy over the header
-  Gamestate *gs = new Gamestate(ndata);
-  GAMESTATE_HEADER(ndata)->diffed=false;
-  return gs;
-}
-
 Gamestate *Gamestate::undiff(Gamestate *base)
 {
-  assert(this && base);assert(HEADER);
-  assert(HEADER->diffed);
-  assert(!HEADER->compressed && !GAMESTATE_HEADER(base->data_)->compressed);
+  assert(this && base);assert(data_);
+  assert(header_->isDiffed());
+  assert(!header_->isCompressed() && !base->header_->isCompressed());
   //unsigned char *basep = base->getGs()/*, *gs = getGs()*/;
   uint8_t *basep = GAMESTATE_START(base->data_);
   uint8_t *gs = GAMESTATE_START(this->data_);
-  unsigned int of=0; // pointers offset
-  unsigned int dest_length=0;
-  dest_length=HEADER->datasize;
+  uint32_t of=0; // pointers offset
+  uint32_t dest_length=0;
+  dest_length=header_->getDataSize();
   if(dest_length==0)
     return NULL;
-  uint8_t *ndata = new uint8_t[dest_length*sizeof(uint8_t)+sizeof(GamestateHeader)];
-  uint8_t *dest = ndata + sizeof(GamestateHeader);
-  while(of < GAMESTATE_HEADER(base->data_)->datasize && of < HEADER->datasize){
+  uint8_t *ndata = new uint8_t[dest_length*sizeof(uint8_t)+GamestateHeader::getSize()];
+  uint8_t *dest = ndata + GamestateHeader::getSize();
+  while(of < base->header_->getDataSize() && of < header_->getDataSize()){
     *(dest+of)=*(basep+of)^*(gs+of); // do the xor
     ++of;
   }
-  if(GAMESTATE_HEADER(base->data_)->datasize!=HEADER->datasize){
+  if(base->header_->getDataSize()!=header_->getDataSize()){
     uint8_t n=0;
-    if(GAMESTATE_HEADER(base->data_)->datasize < HEADER->datasize){
+    if(base->header_->getDataSize() < header_->getDataSize()){
       while(of < dest_length){
         *(dest+of)=n^*(gs+of);
@@ -537,7 +468,8 @@
     }
   }
-  *GAMESTATE_HEADER(ndata) = *HEADER;
-  GAMESTATE_HEADER(ndata)->diffed = false;
   Gamestate *g = new Gamestate(ndata, getClientID());
+  assert(g->header_);
+  *(g->header_) = *header_;
+  g->header_->setDiffed( false );
   g->flags_=flags_;
   g->packetDirection_ = packetDirection_;
@@ -548,7 +480,7 @@
 
 
-unsigned int Gamestate::calcGamestateSize(unsigned int id, uint8_t mode)
-{
-  unsigned int size=0;
+uint32_t Gamestate::calcGamestateSize(int32_t id, uint8_t mode)
+{
+  uint32_t size=0;
     // get the start of the Synchronisable list
   ObjectList<Synchronisable>::iterator it;
@@ -556,31 +488,7 @@
   for(it = ObjectList<Synchronisable>::begin(); it; ++it)
     size+=it->getSize(id, mode); // size of the actual data of the synchronisable
-//  size+=sizeof(GamestateHeader);
   return size;
 }
 
-/**
- * This function removes a Synchronisable out of the universe
- * @param it iterator of the list pointing to the object
- * @return iterator pointing to the next object in the list
- */
-  void Gamestate::removeObject(ObjectList<Synchronisable>::iterator &it) {
-    ObjectList<Synchronisable>::iterator temp=it;
-    ++it;
-    delete  *temp;
-  }
-
-  bool Gamestate::isDiffed(){
-    return HEADER->diffed;
-  }
-
-  bool Gamestate::isCompressed(){
-    return HEADER->compressed;
-  }
-
-  int Gamestate::getBaseID(){
-    return HEADER->base_id;
-  }
-}
-
-}
+} //namespace packet
+} //namespace orxonox
Index: code/trunk/src/network/packet/Gamestate.h
===================================================================
--- code/trunk/src/network/packet/Gamestate.h	(revision 2171)
+++ code/trunk/src/network/packet/Gamestate.h	(revision 2662)
@@ -31,9 +31,11 @@
 #define NETWORK_PACKETGAMESTATE_H
 
-#include "../NetworkPrereqs.h"
+#include "network/NetworkPrereqs.h"
 
 #include "Packet.h"
-#include "network/Synchronisable.h"
+#include "network/TrafficControl.h"
+#include "core/CoreIncludes.h"
 #include <map>
+#include <list>
 #ifndef NDEBUG
 #include "util/CRC32.h"
@@ -44,16 +46,55 @@
 namespace packet {
 
-struct _NetworkExport GamestateHeader{
-  ENUM::Type packetType;
-  int32_t id; // id of the gamestate
-  uint32_t compsize;
-  uint32_t datasize;
-  int32_t base_id; // id of the base-gamestate diffed from
-  bool diffed:1; // wheter diffed or not
-  bool complete:1; // wheter it is a complete gamestate or only partial
-  bool compressed:1;
-#ifndef NDEBUG
-  uint32_t crc32;
-#endif
+class _NetworkExport GamestateHeader{
+  public:
+    GamestateHeader(uint8_t *data){ assert(data); data_ = data; *(uint32_t*)data_ = ENUM::Gamestate; }
+    GamestateHeader(uint8_t *data, GamestateHeader* h)
+    { assert(data); data_=data; memcpy(data_, h->data_, getSize()); }
+    static inline uint32_t getSize()
+    { return 21; }
+
+    inline int32_t getID() const
+    { assert(data_); return *(int32_t*)(data_+4); }
+    inline void setID(int32_t id)
+    { assert(data_); *(int32_t*)(data_+4) = id; }
+
+    inline int32_t getBaseID() const
+    { assert(data_); return *(int32_t*)(data_+8); }
+    inline void setBaseID(int32_t id)
+    { assert(data_); *(int32_t*)(data_+8) = id; }
+
+    inline uint32_t getDataSize() const
+    { assert(data_); return *(uint32_t*)(data_+12); }
+    inline void setDataSize(uint32_t size)
+    { assert(data_); *(uint32_t*)(data_+12) = size; }
+
+    inline uint32_t getCompSize() const
+    { assert(data_); return *(uint32_t*)(data_+16); }
+    inline void setCompSize(uint32_t size)
+    { assert(data_); *(uint32_t*)(data_+16) = size; }
+
+    inline bool isDiffed() const
+    { assert(data_); return *(int8_t*)(data_+20) & 0x1; }
+    inline void setDiffed(bool b)
+    { assert(data_); *(int8_t*)(data_+20) = (b<<0) | (*(int8_t*)(data_+20) & 0x6 ); }
+
+    inline bool isComplete() const
+    { assert(data_); return *(int8_t*)(data_+20) & 0x2; }
+    inline void setComplete(bool b)
+    { assert(data_); *(int8_t*)(data_+20) = (b<<1) | (*(int8_t*)(data_+20) & 0x5 ); }
+
+    inline bool isCompressed() const
+    { assert(data_); return *(int8_t*)(data_+20) & 0x4; }
+    inline void setCompressed(bool b)
+    { assert(data_); *(int8_t*)(data_+20) = (b<<2) | (*(int8_t*)(data_+20) & 0x3 ); }
+
+    inline void operator=(GamestateHeader& h)
+    { assert(data_); assert(h.data_); memcpy( data_, h.data_, getSize()); }
+  private:
+    uint8_t *data_;
+//#define GAMESTATE_START(data) (data + sizeof(GamestateHeader))
+//#define GAMESTATE_HEADER(data) ((GamestateHeader *)data)
+//#define HEADER GAMESTATE_HEADER(data_)
+
 };
 
@@ -66,4 +107,5 @@
     Gamestate(uint8_t *data, unsigned int clientID);
     Gamestate(uint8_t *data);
+    Gamestate(const Gamestate& g);
 
     ~Gamestate();
@@ -71,13 +113,11 @@
     bool collectData(int id, uint8_t mode=0x0);
     bool spreadData( uint8_t mode=0x0);
-    int getID();
-    bool isDiffed();
-    bool isCompressed();
-    int getBaseID();
+    inline int32_t getID() const { return header_->getID(); }
+    inline bool isDiffed() const { return header_->isDiffed(); }
+    inline bool isCompressed() const { return header_->isCompressed(); }
+    inline int32_t getBaseID() const { return header_->getBaseID(); }
     Gamestate *diff(Gamestate *base);
-    Gamestate* intelligentDiff(Gamestate *base, unsigned int clientID);
     Gamestate *undiff(Gamestate *base);
-    Gamestate* intelligentUnDiff(Gamestate *base);
-    Gamestate* doSelection(unsigned int clientID);
+    Gamestate* doSelection(unsigned int clientID, unsigned int targetSize);
     bool compressData();
     bool decompressData();
@@ -85,12 +125,12 @@
     // Packet functions
   private:
-    virtual unsigned int getSize() const;
-    virtual bool process();
+    virtual uint32_t getSize() const;
+    virtual inline bool process();
 
     bool operator ==(packet::Gamestate gs);
   private:
-    unsigned int calcGamestateSize(unsigned int id, uint8_t mode=0x0);
-    void removeObject(ObjectListIterator<Synchronisable> &it);
-    std::map<unsigned int, Synchronisable*> dataMap_;
+    uint32_t calcGamestateSize(int32_t id, uint8_t mode=0x0);
+    std::list<obj> dataMap_;
+    GamestateHeader* header_;
 };
 
Index: code/trunk/src/network/packet/Packet.cc
===================================================================
--- code/trunk/src/network/packet/Packet.cc	(revision 2171)
+++ code/trunk/src/network/packet/Packet.cc	(revision 2662)
@@ -129,7 +129,4 @@
       return false;
     }
-    // Assures we don't create a packet and destroy it right after in another thread
-    // without having a reference in the packetMap_
-    boost::recursive_mutex::scoped_lock lock(Packet::packetMap_mutex);
     // We deliver ENet the data address so that it doesn't memcpy everything again.
     // --> We have to delete data_ ourselves!
@@ -138,5 +135,10 @@
     // Add the packet to a global list so we can access it again once enet calls our
     // deletePacket method. We can of course only give a one argument function to the ENet C library.
-    packetMap_[(size_t)(void*)enetPacket_] = this;
+    {
+      // Assures we don't create a packet and destroy it right after in another thread
+      // without having a reference in the packetMap_
+      boost::recursive_mutex::scoped_lock lock(Packet::packetMap_mutex);
+      packetMap_[(size_t)(void*)enetPacket_] = this;
+    }
   }
 #ifndef NDEBUG
Index: code/trunk/src/network/packet/Welcome.cc
===================================================================
--- code/trunk/src/network/packet/Welcome.cc	(revision 2171)
+++ code/trunk/src/network/packet/Welcome.cc	(revision 2662)
@@ -32,5 +32,5 @@
 #include "Welcome.h"
 #include "network/Host.h"
-#include "network/Synchronisable.h"
+#include "network/synchronisable/Synchronisable.h"
 #include "core/CoreIncludes.h"
 #include <assert.h>
@@ -42,7 +42,7 @@
 #define _PACKETID             0
 #define _CLIENTID             _PACKETID + sizeof(ENUM::Type)
-#define _SHIPID               _CLIENTID + sizeof(uint32_t)
-  
-  Welcome::Welcome( unsigned int clientID, unsigned int shipID )
+#define _ENDIANTEST           _CLIENTID + sizeof(uint32_t)
+
+  Welcome::Welcome( uint32_t clientID, uint32_t shipID )
  : Packet()
 {
@@ -52,9 +52,9 @@
   assert(data_);
   *(packet::ENUM::Type *)(data_ + _PACKETID ) = packet::ENUM::Welcome;
-  *(uint32_t *)&data_[ _CLIENTID ] = clientID;
-  *(uint32_t *)&data_[ _SHIPID ] = shipID;
+  *(uint32_t *)(data_ + _CLIENTID ) = static_cast<uint32_t>(clientID);
+  *(uint32_t *)(data_ + _ENDIANTEST ) = 0xFEDC4321;
 }
 
-Welcome::Welcome( uint8_t* data, unsigned int clientID )
+Welcome::Welcome( uint8_t* data, uint32_t clientID )
   : Packet(data, clientID)
 {
@@ -74,10 +74,9 @@
 
 bool Welcome::process(){
-  unsigned int shipID, clientID;
-  clientID = *(uint32_t *)&data_[ _CLIENTID ];
-  shipID = *(uint32_t *)&data_[ _SHIPID ];
+  uint32_t clientID;
+  clientID = *(uint32_t *)(data_ + _CLIENTID );
+  assert(*(uint32_t *)(data_ + _ENDIANTEST ) == 0xFEDC4321);
   Host::setClientID(clientID);
-  Host::setShipID(shipID);
-  COUT(3) << "Welcome set clientId: " << clientID << " shipID: " << shipID << std::endl;
+  COUT(3) << "Welcome set clientId: " << clientID << endl;
   Synchronisable::setClient(true);
   delete this;
Index: code/trunk/src/network/packet/Welcome.h
===================================================================
--- code/trunk/src/network/packet/Welcome.h	(revision 2171)
+++ code/trunk/src/network/packet/Welcome.h	(revision 2662)
@@ -42,6 +42,6 @@
 {
 public:
-  Welcome( unsigned int clientID, unsigned int shipID );
-  Welcome( uint8_t* data, unsigned int clientID );
+  Welcome( uint32_t clientID, uint32_t shipID );
+  Welcome( uint8_t* data, uint32_t clientID );
   virtual ~Welcome();
 
Index: code/trunk/src/network/synchronisable/CMakeLists.txt
===================================================================
--- code/trunk/src/network/synchronisable/CMakeLists.txt	(revision 2662)
+++ code/trunk/src/network/synchronisable/CMakeLists.txt	(revision 2662)
@@ -0,0 +1,8 @@
+SET( SRC_FILES
+  NetworkCallbackManager.cc
+  Synchronisable.cc
+  SynchronisableSpecialisations.cc
+  SynchronisableVariable.cc
+)
+
+ADD_SOURCE_FILES(SRC_FILES)
Index: code/trunk/src/network/synchronisable/NetworkCallback.h
===================================================================
--- code/trunk/src/network/synchronisable/NetworkCallback.h	(revision 2662)
+++ code/trunk/src/network/synchronisable/NetworkCallback.h	(revision 2662)
@@ -0,0 +1,63 @@
+/*
+ *   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_CALLBACK__
+#define _NETWORK_CALLBACK__
+
+#include "network/NetworkPrereqs.h"
+#include "NetworkCallbackManager.h"
+
+namespace orxonox{
+  
+  class _NetworkExport NetworkCallbackBase
+  {
+    public:
+      virtual void call() = 0;
+      NetworkCallbackBase(){ NetworkCallbackManager::registerCallback( this ); }
+      virtual ~NetworkCallbackBase() {}
+  };
+
+  template <class T>
+  class NetworkCallback: public NetworkCallbackBase
+  {
+    public:
+      NetworkCallback(T* object, void (T::*function) (void)) : object_(object), function_(function) {}
+	  virtual ~NetworkCallback() {}
+      virtual void call()
+        { (this->object_->*function_)(); }
+
+    private:
+      T* object_;
+      void (T::*function_) (void);
+  };
+
+}
+
+
+#endif
Index: code/trunk/src/network/synchronisable/NetworkCallbackManager.cc
===================================================================
--- code/trunk/src/network/synchronisable/NetworkCallbackManager.cc	(revision 2662)
+++ code/trunk/src/network/synchronisable/NetworkCallbackManager.cc	(revision 2662)
@@ -0,0 +1,66 @@
+/*
+ *   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 "NetworkCallbackManager.h"
+#include "NetworkCallback.h"
+
+namespace orxonox{
+
+  std::set<NetworkCallbackBase*> NetworkCallbackManager::callbackSet_;
+  std::queue<NetworkCallbackBase*> NetworkCallbackManager::triggeredCallbacks_;
+  
+  void NetworkCallbackManager::registerCallback(NetworkCallbackBase *cb)
+  { 
+    callbackSet_.insert(cb); 
+  }
+  void NetworkCallbackManager::deleteCallback(NetworkCallbackBase *cb)
+  {
+    std::set<NetworkCallbackBase*>::iterator it = callbackSet_.find(cb);
+    if (it != callbackSet_.end())
+    {
+      delete (*it);
+      callbackSet_.erase(it);
+    }
+  }
+  
+  void NetworkCallbackManager::triggerCallback(NetworkCallbackBase *cb)
+  {
+    if (triggeredCallbacks_.empty() || triggeredCallbacks_.front() != cb)
+      triggeredCallbacks_.push(cb);
+  }
+
+  void NetworkCallbackManager::callCallbacks()
+  {
+    while( triggeredCallbacks_.empty()==false )
+    {
+      triggeredCallbacks_.front()->call();
+      triggeredCallbacks_.pop();
+    }
+  }
+}
Index: code/trunk/src/network/synchronisable/NetworkCallbackManager.h
===================================================================
--- code/trunk/src/network/synchronisable/NetworkCallbackManager.h	(revision 2662)
+++ code/trunk/src/network/synchronisable/NetworkCallbackManager.h	(revision 2662)
@@ -0,0 +1,54 @@
+/*
+ *   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_CALLBACKMANAGER__
+#define _NETWORK_CALLBACKMANAGER__
+
+#include "network/NetworkPrereqs.h"
+#include <set>
+#include <queue>
+
+namespace orxonox{
+  
+  class _NetworkExport NetworkCallbackManager{
+    public:
+      static void registerCallback(NetworkCallbackBase *cb);
+      static void deleteCallback(NetworkCallbackBase *cb);
+      static void triggerCallback(NetworkCallbackBase *cb);
+      static void callCallbacks();
+    private:
+      static std::set<NetworkCallbackBase*> callbackSet_;
+      static std::queue<NetworkCallbackBase*> triggeredCallbacks_;
+  };
+  
+
+}
+
+
+#endif
Index: code/trunk/src/network/synchronisable/Synchronisable.cc
===================================================================
--- code/trunk/src/network/synchronisable/Synchronisable.cc	(revision 2662)
+++ code/trunk/src/network/synchronisable/Synchronisable.cc	(revision 2662)
@@ -0,0 +1,440 @@
+/*
+ *   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:
+ *      Dumeni Manatschal, (C) 2007
+ *      Oliver Scheuss, (C) 2007
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+
+#include "Synchronisable.h"
+
+#include <cstring>
+#include <string>
+#include <iostream>
+#include <assert.h>
+
+#include "core/CoreIncludes.h"
+#include "core/BaseObject.h"
+// #include "core/Identifier.h"
+
+#include "network/Host.h"
+namespace orxonox
+{
+
+  std::map<uint32_t, Synchronisable *> Synchronisable::objectMap_;
+  std::queue<uint32_t> Synchronisable::deletedObjects_;
+
+  uint8_t Synchronisable::state_=0x1; // detemines wheter we are server (default) or client
+
+  /**
+  * Constructor:
+  * Initializes all Variables and sets the right objectID
+  */
+  Synchronisable::Synchronisable(BaseObject* creator){
+    RegisterRootObject(Synchronisable);
+    static uint32_t idCounter=0;
+    objectMode_=0x1; // by default do not send data to server
+    if ( !Host::running() || ( Host::running() && Host::isServer() ) )
+    {
+      this->objectID = idCounter++; //this is only needed when running a server
+    //add synchronisable to the objectMap
+      objectMap_[this->objectID] = this;
+    }
+    else
+      objectID=OBJECTID_UNKNOWN;
+    classID = static_cast<uint32_t>(-1);
+
+    // set standard priority
+    this->setPriority( priority::normal );
+
+    // get creator id
+    this->creatorID = OBJECTID_UNKNOWN;
+
+    searchcreatorID:
+    if (creator)
+    {
+        Synchronisable* synchronisable_creator = dynamic_cast<Synchronisable*>(creator);
+        if (synchronisable_creator && synchronisable_creator->objectMode_)
+        {
+            this->creatorID = synchronisable_creator->getObjectID();
+        }
+        else if (creator != creator->getCreator())
+        {
+            creator = creator->getCreator();
+            goto searchcreatorID;
+        }
+    }
+  }
+
+  /**
+   * Destructor:
+   * Delete all callback objects and remove objectID from the objectMap_
+   */
+  Synchronisable::~Synchronisable(){
+    // delete callback function objects
+    if(!Identifier::isCreatingHierarchy()){
+      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);
+//       COUT(3) << "destruct synchronisable +++" << objectID << " | " << classID << std::endl;
+//       COUT(3) << " bump ---" << objectID << " | " << &objectMap_ << std::endl;
+//       assert(objectMap_[objectID]->objectID==objectID);
+//       objectMap_.erase(objectID);
+    }
+    std::map<uint32_t, Synchronisable*>::iterator it;
+    it = objectMap_.find(objectID);
+    if (it != objectMap_.end())
+      objectMap_.erase(it);
+
+    //HACK HACK HACK HACK HACK HACK
+    // this hack ensures that children of this object also get destroyed
+//     ObjectList<Synchronisable>::iterator it2, it3;
+//     // get total size of gamestate
+//     for(it2 = ObjectList<Synchronisable>::begin(); it2; ++it2)
+//     {
+//       if ( it2->getCreatorID() == this->objectID && it2->getCreatorID() != OBJECTID_UNKNOWN )
+//       {
+//         Synchronisable::deleteObject( it2->getObjectID() );
+//       }
+//     }
+    //HACK HACK HACK HACK HACK HACK
+  }
+
+
+  /**
+   * This function sets the internal mode for synchronisation
+   * @param b true if this object is located on a client or on a server
+   */
+  void Synchronisable::setClient(bool b){
+    if(b) // client
+      state_=0x2;
+    else  // server
+      state_=0x1;
+  }
+
+  /**
+   * This function fabricated a new synchrnisable (and children of it), sets calls updateData and create
+   * After calling this function the mem pointer will be increased by the size of the needed data
+   * @param mem pointer to where the appropriate data is located
+   * @param mode defines the mode, how the data should be loaded
+   * @return pointer to the newly created synchronisable
+   */
+  Synchronisable *Synchronisable::fabricate(uint8_t*& mem, uint8_t mode)
+  {
+    SynchronisableHeader header(mem);
+
+    if(!header.isDataAvailable())
+    {
+      mem += header.getDataSize();
+      return 0;
+    }
+
+    COUT(4) << "fabricating object with id: " << header.getObjectID() << std::endl;
+
+    Identifier* id = ClassByID(header.getClassID());
+    if (!id)
+    {
+        COUT(0) << "Assertion failed: id" << std::endl;
+        COUT(0) << "Possible reason for this error: Client received a synchronizable object whose class has no factory." << std::endl;
+        abort();
+    }
+    assert(id);
+    BaseObject* creator = 0;
+    if (header.getCreatorID() != OBJECTID_UNKNOWN)
+    {
+      Synchronisable* synchronisable_creator = Synchronisable::getSynchronisable(header.getCreatorID());
+      if (!synchronisable_creator)
+      {
+        mem += header.getDataSize(); //.TODO: this suckz.... remove size from header
+        assert(0); // TODO: uncomment this if we have a clean objecthierarchy (with destruction of children of objects) ^^
+        return 0;
+      }
+      else
+        creator = dynamic_cast<BaseObject*>(synchronisable_creator);
+    }
+    assert(getSynchronisable(header.getObjectID())==0);   //make sure no object with this id exists
+    BaseObject *bo = id->fabricate(creator);
+    assert(bo);
+    Synchronisable *no = dynamic_cast<Synchronisable *>(bo);
+    assert(no);
+    no->objectID=header.getObjectID();
+    no->creatorID=header.getCreatorID(); //TODO: remove this
+    no->classID=header.getClassID();
+    COUT(4) << "fabricate objectID: " << no->objectID << " classID: " << no->classID << std::endl;
+          // update data and create object/entity...
+    bool b = no->updateData(mem, mode, true);
+    assert(b);
+    if (b)
+    {
+//        b = no->create();
+        assert(b);
+    }
+    return no;
+  }
+
+
+  /**
+   * Finds and deletes the Synchronisable with the appropriate objectID
+   * @param objectID objectID of the Synchronisable
+   * @return true/false
+   */
+  bool Synchronisable::deleteObject(uint32_t objectID){
+//     assert(getSynchronisable(objectID));
+    if(!getSynchronisable(objectID))
+      return false;
+    assert(getSynchronisable(objectID)->objectID==objectID);
+//     delete objectMap_[objectID];
+    Synchronisable *s = getSynchronisable(objectID);
+    if(s)
+      delete s;
+    else
+      return false;
+    return true;
+  }
+
+  /**
+   * This function looks up the objectID in the objectMap_ and returns a pointer to the right Synchronisable
+   * @param objectID objectID of the Synchronisable
+   * @return pointer to the Synchronisable with the objectID
+   */
+  Synchronisable* Synchronisable::getSynchronisable(uint32_t objectID){
+    std::map<uint32_t, Synchronisable*>::iterator it1;
+    it1 = objectMap_.find(objectID);
+    if (it1 != objectMap_.end())
+      return it1->second;
+
+    ObjectList<Synchronisable>::iterator it;
+    for(it = ObjectList<Synchronisable>::begin(); it; ++it){
+      if( it->getObjectID()==objectID ){
+        objectMap_[objectID] = *it;
+        return *it;
+      }
+    }
+    return NULL;
+  }
+
+
+  /**
+  * This function is used to register a variable to be synchronized
+  * also counts the total datasize needed to save the variables
+  * @param var pointer to the variable
+  * @param size size of the datatype the variable consists of
+  * @param t the type of the variable (DATA or STRING
+  * @param mode same as in getData
+  * @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){
+    assert( mode==variableDirection::toclient || mode==variableDirection::toserver || mode==variableDirection::serverMaster || mode==variableDirection::clientMaster);
+    // create temporary synch.Var struct
+    synchronisableVariable *temp = new synchronisableVariable;
+    temp->size = size;
+    temp->var = var;
+    temp->mode = mode;
+    temp->type = t;
+    temp->callback = cb;
+    if( ( mode & variableDirection::bidirectional ) )
+    {
+      if(t!=STRING)
+      {
+        temp->varBuffer = new uint8_t[size];
+        memcpy(temp->varBuffer, temp->var, size); //now fill the buffer for the first time
+      }
+      else
+      {
+        temp->varBuffer=new std::string( *static_cast<std::string*>(var) );
+      }
+      temp->varReference = 0;
+    }
+    COUT(5) << "Syncronisable::registering var with size: " << temp->size << " and type: " << temp->type << std::endl;
+    //std::cout << "push temp to syncList (at the bottom) " << datasize << std::endl;
+    COUT(5) << "Syncronisable::objectID: " << objectID << " this: " << this << " name: " << this->getIdentifier()->getName() << " networkID: " << this->getIdentifier()->getNetworkID() << std::endl;
+    syncList->push_back(temp);
+#ifndef NDEBUG
+    std::list<synchronisableVariable *>::iterator it = syncList->begin();
+    while(it!=syncList->end()){
+      assert(*it!=var);
+      it++;
+    }
+#endif
+  }*/
+
+
+  /**
+   * This function takes all SynchronisableVariables out of the Synchronisable and saves them together with the size, objectID and classID to the given memory
+   * takes a pointer to already allocated memory (must have at least getSize bytes length)
+   * structure of the bitstream:
+   * |totalsize,objectID,classID,var1,var2,string1_length,string1,var3,...|
+   * length of varx: size saved int syncvarlist
+   * @param mem pointer to allocated memory with enough size
+   * @param id gamestateid of the gamestate to be saved (important for priorities)
+   * @param mode defines the direction in which the data will be send/received
+   *             0x1: server->client
+   *             0x2: client->server (not recommended)
+   *             0x3: bidirectional
+   * @return true: if !doSync or if everything was successfully saved
+   */
+  bool Synchronisable::getData(uint8_t*& mem, int32_t id, uint8_t mode){
+    if(mode==0x0)
+      mode=state_;
+    //if this tick is we dont synchronise, then abort now
+    if(!doSync(id, mode))
+      return true;
+    //std::cout << "inside getData" << std::endl;
+    uint32_t tempsize = 0;
+    if (this->classID==0)
+      COUT(3) << "classid 0 " << this->getIdentifier()->getName() << std::endl;
+
+    if (this->classID == static_cast<uint32_t>(-1))
+        this->classID = this->getIdentifier()->getNetworkID();
+
+    assert(this->classID==this->getIdentifier()->getNetworkID());
+//     this->classID=this->getIdentifier()->getNetworkID(); // TODO: correct this
+    std::list<SynchronisableVariableBase*>::iterator i;
+    uint32_t size;
+    size=getSize(id, mode);
+
+    // start copy header
+    SynchronisableHeader header(mem);
+    header.setDataSize( size );
+    header.setObjectID( this->objectID );
+    header.setCreatorID( this->creatorID );
+    header.setClassID( this->classID );
+    header.setDataAvailable( true );
+    tempsize += SynchronisableHeader::getSize();
+    mem += SynchronisableHeader::getSize();
+    // end copy header
+
+
+    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){
+      (*i)->getData( mem, mode );
+      tempsize += (*i)->getSize( mode );
+    }
+    assert(tempsize==size);
+    return true;
+  }
+
+
+  /**
+   * This function takes a bytestream and loads the data into the registered variables
+   * @param mem pointer to the bytestream
+   * @param mode same as in getData
+   * @return true/false
+   */
+  bool Synchronisable::updateData(uint8_t*& mem, uint8_t mode, bool forceCallback){
+    if(mode==0x0)
+      mode=state_;
+    std::list<SynchronisableVariableBase *>::iterator i;
+    //assert(objectMode_!=0x0);
+    //assert( (mode ^ objectMode_) != 0);
+    if(syncList.empty()){
+      assert(0);
+      COUT(4) << "Synchronisable::updateData syncList is empty" << std::endl;
+      return false;
+    }
+
+    uint8_t* data=mem;
+    // start extract header
+    SynchronisableHeader syncHeader(mem);
+    assert(syncHeader.getObjectID()==this->objectID);
+    assert(syncHeader.getCreatorID()==this->creatorID);
+    assert(syncHeader.getClassID()==this->classID);
+    if(syncHeader.isDataAvailable()==false){
+      mem += syncHeader.getDataSize();
+      return true;
+    }
+
+    mem += SynchronisableHeader::getSize();
+    // stop extract header
+
+    //COUT(5) << "Synchronisable: objectID " << syncHeader.getObjectID() << ", classID " << syncHeader.getClassID() << " size: " << syncHeader.getDataSize() << " synchronising data" << std::endl;
+    for(i=syncList.begin(); i!=syncList.end(); i++)
+    {
+      assert( mem <= data+syncHeader.getDataSize() ); // always make sure we don't exceed the datasize in our stream
+      (*i)->putData( mem, mode, forceCallback );
+    }
+    assert(mem == data+syncHeader.getDataSize());
+    return true;
+  }
+
+  /**
+  * This function returns the total amount of bytes needed by getData to save the whole content of the variables
+  * @param id id of the gamestate
+  * @param mode same as getData
+  * @return amount of bytes
+  */
+  uint32_t Synchronisable::getSize(int32_t id, uint8_t mode){
+    int tsize=SynchronisableHeader::getSize();
+    if(mode==0x0)
+      mode=state_;
+    if(!doSync(id, mode))
+      return 0;
+    std::list<SynchronisableVariableBase*>::iterator i;
+    for(i=syncList.begin(); i!=syncList.end(); i++){
+      tsize += (*i)->getSize( mode );
+    }
+    return tsize;
+  }
+
+  /**
+   * This function determines, wheter the object should be saved to the bytestream (according to its syncmode/direction)
+   * @param id gamestate id
+   * @return true/false
+   */
+  bool Synchronisable::doSync(int32_t id, uint8_t mode){
+    if(mode==0x0)
+      mode=state_;
+    return ( (objectMode_&mode)!=0 && (!syncList.empty() ) );
+  }
+
+  /**
+   * This function looks at the header located in the bytestream and checks wheter objectID and classID match with the Synchronisables ones
+   * @param mem pointer to the bytestream
+   */
+  bool Synchronisable::isMyData(uint8_t* mem)
+  {
+    SynchronisableHeader header(mem);
+    assert(header.getObjectID()==this->objectID);
+    return header.isDataAvailable();
+  }
+
+  /**
+   * This function sets the synchronisation mode of the object
+   * If set to 0x0 variables will not be synchronised at all
+   * If set to 0x1 variables will only be synchronised to the client
+   * If set to 0x2 variables will only be synchronised to the server
+   * If set to 0x3 variables will be synchronised bidirectionally (only if set so in registerVar)
+   * @param mode same as in registerVar
+   */
+  void Synchronisable::setObjectMode(uint8_t mode){
+    assert(mode==0x0 || mode==0x1 || mode==0x2 || mode==0x3);
+    objectMode_=mode;
+  }
+
+
+}
Index: code/trunk/src/network/synchronisable/Synchronisable.h
===================================================================
--- code/trunk/src/network/synchronisable/Synchronisable.h	(revision 2662)
+++ code/trunk/src/network/synchronisable/Synchronisable.h	(revision 2662)
@@ -0,0 +1,211 @@
+/*
+ *   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) 2007
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _Synchronisable_H__
+#define _Synchronisable_H__
+
+#include "network/NetworkPrereqs.h"
+
+#include <list>
+#include <map>
+#include <queue>
+#include <cassert>
+#include "util/Math.h"
+#include "util/mbool.h"
+#include "core/OrxonoxClass.h"
+// TODO: this has to be removed
+// #include <OgreLight.h>
+// #include "OrxonoxPrereqs.h"
+// ============================
+#include "NetworkCallback.h"
+#include "SynchronisableVariable.h"
+
+/*#define REGISTERDATA(varname, ...) \
+    registerVariable((void*)&varname, sizeof(varname), DATA, __VA_ARGS__)
+#define REGISTERSTRING(stringname, ...) \
+    registerVariable(&stringname, stringname.length()+1, STRING, __VA_ARGS__)*/
+
+namespace orxonox
+{
+
+  namespace objectDirection{
+    enum objectdirection{
+      toclient=0x1,
+      toserver=0x2,
+      bidirectional=0x3
+    };
+  }
+
+  namespace priority{
+    enum prio{
+      very_high   = -100,
+      high        = -15,
+      normal      = 0,
+      low         = 15,
+      very_low    = 100
+    };
+  }
+
+  /**
+   * @brief: stores information about a Synchronisable 
+   * 
+   * This class stores the information about a Synchronisable (objectID, classID, creatorID, dataSize)
+   * in an emulated bitset.
+   * Bit 1 to 31 store the size of the Data the synchronisable consumes in the stream
+   * Bit 32 is a bool and defines whether the data is actually stored or is just filled up with 0
+   * Byte 5 to 8: objectID
+   * Byte 9 to 12: classID
+   * Byte 13 to 16: creatorID
+   */
+  class _NetworkExport SynchronisableHeader{
+    private:
+      uint8_t *data_;
+    public:
+      SynchronisableHeader(uint8_t* data)
+        { data_ = data; }
+      inline static uint32_t getSize()
+        { return 16; }
+      inline uint32_t getDataSize() const
+        { return (*(uint32_t*)data_) & 0x7FFFFFFF; } //only use the first 31 bits
+      inline void setDataSize(uint32_t size)
+        { *(uint32_t*)(data_) = (size & 0x7FFFFFFF) | (*(uint32_t*)(data_) & 0x80000000 ); }
+      inline bool isDataAvailable() const
+        { return ( (*(uint32_t*)data_) & 0x80000000 ) == 0x80000000; }
+      inline void setDataAvailable( bool b)
+        { *(uint32_t*)(data_) = (b << 31) | (*(uint32_t*)(data_) & 0x7FFFFFFF ); }
+      inline uint32_t getObjectID() const
+        { return *(uint32_t*)(data_+4); }
+      inline void setObjectID(uint32_t objectID)
+        { *(uint32_t*)(data_+4) = objectID; }
+      inline uint32_t getClassID() const
+        { return *(uint32_t*)(data_+8); }
+      inline void setClassID(uint32_t classID)
+        { *(uint32_t*)(data_+8) = classID; }
+      inline uint32_t getCreatorID() const
+        { return *(uint32_t*)(data_+12); }
+      inline void setCreatorID(uint32_t creatorID)
+        { *(uint32_t*)(data_+12) = creatorID; }
+      inline void operator=(SynchronisableHeader& h)
+        { memcpy(data_, h.data_, getSize()); }
+  };
+
+
+  /**
+  * This class is the base class of all the Objects in the universe that need to be synchronised over the network
+  * Every class, that inherits from this class has to link the DATA THAT NEEDS TO BE SYNCHRONISED into the linked list.
+  * @author Oliver Scheuss
+  */
+  class _NetworkExport Synchronisable : virtual public OrxonoxClass{
+  public:
+    friend class packet::Gamestate;
+//     friend class Server;
+    virtual ~Synchronisable();
+
+    static void setClient(bool b);
+
+    static Synchronisable *fabricate(uint8_t*& mem, uint8_t mode=0x0);
+    static bool deleteObject(uint32_t objectID);
+    static Synchronisable *getSynchronisable(uint32_t objectID);
+    static unsigned int getNumberOfDeletedObject(){ return deletedObjects_.size(); }
+    static uint32_t popDeletedObject(){ uint32_t i = deletedObjects_.front(); deletedObjects_.pop(); return i; }
+
+    inline uint32_t getObjectID() const {return objectID;}
+    inline unsigned int getCreatorID() const {return creatorID;}
+    inline uint32_t getClassID() const {return classID;}
+    inline unsigned int getPriority() const { return objectFrequency_;}
+
+  protected:
+    Synchronisable(BaseObject* creator);
+//     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 setPriority(unsigned int freq){ objectFrequency_ = freq; }
+
+
+  private:
+    bool getData(uint8_t*& men, int32_t id, uint8_t mode=0x0);
+    uint32_t getSize(int32_t id, uint8_t mode=0x0);
+    bool updateData(uint8_t*& mem, uint8_t mode=0x0, bool forceCallback=false);
+    inline bool isMyData(uint8_t* mem);
+    inline bool doSync(int32_t id, uint8_t mode=0x0);
+
+    uint32_t objectID;
+    uint32_t creatorID;
+    uint32_t classID;
+
+    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)
+    unsigned int objectFrequency_;
+    int objectMode_;
+    static std::map<uint32_t, Synchronisable *> objectMap_;
+    static std::queue<uint32_t> 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 <> _NetworkExport void Synchronisable::registerVariable( const ColourValue& variable, uint8_t mode, NetworkCallbackBase* cb, bool bidirectional);
+  template <> _NetworkExport void Synchronisable::registerVariable( ColourValue& variable, uint8_t mode, NetworkCallbackBase* cb, bool bidirectional);
+  template <> _NetworkExport void Synchronisable::registerVariable( const Vector2& variable, uint8_t mode, NetworkCallbackBase* cb, bool bidirectional);
+  template <> _NetworkExport void Synchronisable::registerVariable( Vector2& variable, uint8_t mode, NetworkCallbackBase* cb, bool bidirectional);
+  template <> _NetworkExport void Synchronisable::registerVariable( const Vector3& variable, uint8_t mode, NetworkCallbackBase* cb, bool bidirectional);
+  template <> _NetworkExport void Synchronisable::registerVariable( Vector3& variable, uint8_t mode, NetworkCallbackBase* cb, bool bidirectional);
+  template <> _NetworkExport void Synchronisable::registerVariable( const Vector4& variable, uint8_t mode, NetworkCallbackBase* cb, bool bidirectional);
+  template <> _NetworkExport void Synchronisable::registerVariable( Vector4& variable, uint8_t mode, NetworkCallbackBase* cb, bool bidirectional);
+  template <> _NetworkExport void Synchronisable::registerVariable( mbool& variable, uint8_t mode, NetworkCallbackBase* cb, bool bidirectional);
+  template <> _NetworkExport void Synchronisable::registerVariable( const Quaternion& variable, uint8_t mode, NetworkCallbackBase* cb, bool bidirectional);
+  template <> _NetworkExport void Synchronisable::registerVariable( Quaternion& variable, uint8_t mode, NetworkCallbackBase* cb, bool bidirectional);
+//   template <> _NetworkExport void Synchronisable::registerVariable( LODParticle::LOD& variable, uint8_t mode, NetworkCallbackBase* cb, bool bidirectional);
+//   template <> _NetworkExport void Synchronisable::registerVariable( Ogre::Light::LightTypes& variable, uint8_t mode, NetworkCallbackBase* cb, bool bidirectional);
+}
+
+#endif /* _Synchronisable_H__ */
Index: code/trunk/src/network/synchronisable/SynchronisableSpecialisations.cc
===================================================================
--- code/trunk/src/network/synchronisable/SynchronisableSpecialisations.cc	(revision 2662)
+++ code/trunk/src/network/synchronisable/SynchronisableSpecialisations.cc	(revision 2662)
@@ -0,0 +1,101 @@
+/*
+ *   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:
+ *      Dumeni Manatschal, (C) 2007
+ *      Oliver Scheuss, (C) 2007
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "network/synchronisable/Synchronisable.h"
+
+// ================ template spezialisation
+  
+  
+namespace orxonox{
+  
+  template <> void Synchronisable::registerVariable( const ColourValue& variable, uint8_t mode, NetworkCallbackBase* cb, bool bidirectional)
+  {
+    registerVariable(variable.r, mode, cb, bidirectional);
+    registerVariable(variable.g, mode, cb, bidirectional);
+    registerVariable(variable.b, mode, cb, bidirectional);
+    registerVariable(variable.a, mode, cb, bidirectional);
+  }
+  template <> void Synchronisable::registerVariable( ColourValue& variable, uint8_t mode, NetworkCallbackBase* cb, bool bidirectional)
+  {
+    return Synchronisable::registerVariable( (const ColourValue&)variable, mode, cb, bidirectional);
+  }
+
+  template <> void Synchronisable::registerVariable( const Vector2& variable, uint8_t mode, NetworkCallbackBase* cb, bool bidirectional)
+  {
+    registerVariable(variable.x, mode, cb, bidirectional);
+    registerVariable(variable.y, mode, cb, bidirectional);
+  }
+  template <> void Synchronisable::registerVariable( Vector2& variable, uint8_t mode, NetworkCallbackBase* cb, bool bidirectional)
+  {
+    registerVariable( (const ColourValue&)variable, mode, cb, bidirectional);
+  }
+  
+  template <> void Synchronisable::registerVariable( const Vector3& variable, uint8_t mode, NetworkCallbackBase* cb, bool bidirectional)
+  {
+    registerVariable(variable.x, mode, cb, bidirectional);
+    registerVariable(variable.y, mode, cb, bidirectional);
+    registerVariable(variable.z, mode, cb, bidirectional);
+  }
+  template <> void Synchronisable::registerVariable( Vector3& variable, uint8_t mode, NetworkCallbackBase* cb, bool bidirectional)
+  {
+    registerVariable( (const Vector3&)variable, mode, cb, bidirectional);
+  }
+
+  template <> void Synchronisable::registerVariable( const Vector4& variable, uint8_t mode, NetworkCallbackBase* cb, bool bidirectional)
+  {
+    registerVariable(variable.x, mode, cb, bidirectional);
+    registerVariable(variable.y, mode, cb, bidirectional);
+    registerVariable(variable.z, mode, cb, bidirectional);
+    registerVariable(variable.w, mode, cb, bidirectional);
+  }
+  template <> void Synchronisable::registerVariable( Vector4& variable, uint8_t mode, NetworkCallbackBase* cb, bool bidirectional)
+  {
+    registerVariable( (const Vector4&)variable, mode, cb, bidirectional);
+  }
+  
+  template <> void Synchronisable::registerVariable( mbool& variable, uint8_t mode, NetworkCallbackBase* cb, bool bidirectional)
+  {
+    registerVariable(variable.getMemory(), mode, cb, bidirectional);
+  }
+  
+  template <> void Synchronisable::registerVariable( const Quaternion& variable, uint8_t mode, NetworkCallbackBase* cb, bool bidirectional)
+  {
+    registerVariable(variable.x, mode, cb, bidirectional);
+    registerVariable(variable.y, mode, cb, bidirectional);
+    registerVariable(variable.z, mode, cb, bidirectional);
+    registerVariable(variable.w, mode, cb, bidirectional);
+  }
+  template <> void Synchronisable::registerVariable( Quaternion& variable, uint8_t mode, NetworkCallbackBase* cb, bool bidirectional)
+  {
+    registerVariable( (const Quaternion&)variable, mode, cb, bidirectional);
+  }
+
+  
+
+} //namespace
Index: code/trunk/src/network/synchronisable/SynchronisableVariable.cc
===================================================================
--- code/trunk/src/network/synchronisable/SynchronisableVariable.cc	(revision 2662)
+++ code/trunk/src/network/synchronisable/SynchronisableVariable.cc	(revision 2662)
@@ -0,0 +1,433 @@
+/*
+ *   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_);
+}
+
+// =========== char
+
+template <> uint32_t SynchronisableVariable<const char>::returnSize()
+{
+  return sizeof(uint8_t);
+}
+
+template <> void SynchronisableVariable<const char>::setAndIncrease( uint8_t*& mem )
+{
+  *(uint8_t*)(&this->variable_) = *static_cast<uint8_t*>(mem);
+  mem += SynchronisableVariable<const char>::returnSize();
+}
+
+template <> void SynchronisableVariable<const char>::getAndIncrease( uint8_t*& mem )
+{
+  *static_cast<uint8_t*>(mem) = *(uint8_t*)(&this->variable_);
+  mem += SynchronisableVariable<const char>::returnSize();
+}
+
+template <> bool SynchronisableVariable<const char>::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;
+  (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/trunk/src/network/synchronisable/SynchronisableVariable.h
===================================================================
--- code/trunk/src/network/synchronisable/SynchronisableVariable.h	(revision 2662)
+++ code/trunk/src/network/synchronisable/SynchronisableVariable.h	(revision 2662)
@@ -0,0 +1,316 @@
+/*
+ *   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 "network/NetworkPrereqs.h"
+
+#include <string>
+#include <cassert>
+#include "util/Integers.h"
+#include "core/Core.h"
+#include "core/CoreIncludes.h"
+#include "network/synchronisable/NetworkCallback.h"
+#include "network/synchronisable/NetworkCallbackManager.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 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 inline void getData(uint8_t*& mem, uint8_t mode);
+      virtual inline void putData(uint8_t*& mem, uint8_t mode, bool forceCallback = false);
+      virtual inline uint32_t getSize(uint8_t mode);
+      virtual inline void* getReference(){ return (void *)&this->variable_; }
+    protected:
+      bool checkEquality(uint8_t* mem);
+      void setAndIncrease(uint8_t*& mem);
+      void getAndIncrease(uint8_t*& mem);
+      uint32_t returnSize();
+      
+      T& variable_;
+      uint8_t mode_;
+      NetworkCallbackBase *callback_;
+  };
+  
+  template <class T>
+  class 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 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)
+      NetworkCallbackManager::deleteCallback(this->callback_); //safe call for deletion
+  }
+
+  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 )
+      NetworkCallbackManager::triggerCallback( this->callback_ );
+      //this->callback_->call();
+  }
+
+  template <class T> uint32_t SynchronisableVariable<T>::getSize(uint8_t mode)
+  {
+    if ( mode == this->mode_ )
+      return returnSize();
+    else
+      return 0;
+  }
+
+  template <> _NetworkExport uint32_t SynchronisableVariable<const bool>::returnSize();
+  template <> _NetworkExport void     SynchronisableVariable<const bool>::setAndIncrease(uint8_t*& mem);
+  template <> _NetworkExport void     SynchronisableVariable<const bool>::getAndIncrease(uint8_t*& mem);
+  template <> _NetworkExport bool     SynchronisableVariable<const bool>::checkEquality(uint8_t* mem);
+  template <> _NetworkExport uint32_t SynchronisableVariable<const unsigned char>::returnSize();
+  template <> _NetworkExport void     SynchronisableVariable<const unsigned char>::setAndIncrease(uint8_t*& mem);
+  template <> _NetworkExport void     SynchronisableVariable<const unsigned char>::getAndIncrease(uint8_t*& mem);
+  template <> _NetworkExport bool     SynchronisableVariable<const unsigned char>::checkEquality(uint8_t* mem);
+  template <> _NetworkExport uint32_t SynchronisableVariable<const short>::returnSize();
+  template <> _NetworkExport void     SynchronisableVariable<const short>::setAndIncrease(uint8_t*& mem);
+  template <> _NetworkExport void     SynchronisableVariable<const short>::getAndIncrease(uint8_t*& mem);
+  template <> _NetworkExport bool     SynchronisableVariable<const short>::checkEquality(uint8_t* mem);
+  template <> _NetworkExport uint32_t SynchronisableVariable<const unsigned short>::returnSize();
+  template <> _NetworkExport void     SynchronisableVariable<const unsigned short>::setAndIncrease(uint8_t*& mem);
+  template <> _NetworkExport void     SynchronisableVariable<const unsigned short>::getAndIncrease(uint8_t*& mem);
+  template <> _NetworkExport bool     SynchronisableVariable<const unsigned short>::checkEquality(uint8_t* mem);
+  template <> _NetworkExport uint32_t SynchronisableVariable<const int>::returnSize();
+  template <> _NetworkExport void     SynchronisableVariable<const int>::setAndIncrease(uint8_t*& mem);
+  template <> _NetworkExport void     SynchronisableVariable<const int>::getAndIncrease(uint8_t*& mem);
+  template <> _NetworkExport bool     SynchronisableVariable<const int>::checkEquality(uint8_t* mem);
+  template <> _NetworkExport uint32_t SynchronisableVariable<const unsigned int>::returnSize();
+  template <> _NetworkExport void     SynchronisableVariable<const unsigned int>::setAndIncrease(uint8_t*& mem);
+  template <> _NetworkExport void     SynchronisableVariable<const unsigned int>::getAndIncrease(uint8_t*& mem);
+  template <> _NetworkExport bool     SynchronisableVariable<const unsigned int>::checkEquality(uint8_t* mem);
+  template <> _NetworkExport uint32_t SynchronisableVariable<const long>::returnSize();
+  template <> _NetworkExport void     SynchronisableVariable<const long>::setAndIncrease(uint8_t*& mem);
+  template <> _NetworkExport void     SynchronisableVariable<const long>::getAndIncrease(uint8_t*& mem);
+  template <> _NetworkExport bool     SynchronisableVariable<const long>::checkEquality(uint8_t* mem);
+  template <> _NetworkExport uint32_t SynchronisableVariable<const unsigned long>::returnSize();
+  template <> _NetworkExport void     SynchronisableVariable<const unsigned long>::setAndIncrease(uint8_t*& mem);
+  template <> _NetworkExport void     SynchronisableVariable<const unsigned long>::getAndIncrease(uint8_t*& mem);
+  template <> _NetworkExport bool     SynchronisableVariable<const unsigned long>::checkEquality(uint8_t* mem);
+  template <> _NetworkExport uint32_t SynchronisableVariable<const long long>::returnSize();
+  template <> _NetworkExport void     SynchronisableVariable<const long long>::setAndIncrease(uint8_t*& mem);
+  template <> _NetworkExport void     SynchronisableVariable<const long long>::getAndIncrease(uint8_t*& mem);
+  template <> _NetworkExport bool     SynchronisableVariable<const long long>::checkEquality(uint8_t* mem);
+  template <> _NetworkExport uint32_t SynchronisableVariable<const unsigned long long>::returnSize();
+  template <> _NetworkExport void     SynchronisableVariable<const unsigned long long>::setAndIncrease(uint8_t*& mem);
+  template <> _NetworkExport void     SynchronisableVariable<const unsigned long long>::getAndIncrease(uint8_t*& mem);
+  template <> _NetworkExport bool     SynchronisableVariable<const unsigned long long>::checkEquality(uint8_t* mem);
+  template <> _NetworkExport uint32_t SynchronisableVariable<const float>::returnSize();
+  template <> _NetworkExport void     SynchronisableVariable<const float>::setAndIncrease(uint8_t*& mem);
+  template <> _NetworkExport void     SynchronisableVariable<const float>::getAndIncrease(uint8_t*& mem);
+  template <> _NetworkExport bool     SynchronisableVariable<const float>::checkEquality(uint8_t* mem);
+  template <> _NetworkExport uint32_t SynchronisableVariable<const double>::returnSize();
+  template <> _NetworkExport void     SynchronisableVariable<const double>::setAndIncrease(uint8_t*& mem);
+  template <> _NetworkExport void     SynchronisableVariable<const double>::getAndIncrease(uint8_t*& mem);
+  template <> _NetworkExport bool     SynchronisableVariable<const double>::checkEquality(uint8_t* mem);
+  template <> _NetworkExport uint32_t SynchronisableVariable<const long double>::returnSize();
+  template <> _NetworkExport void     SynchronisableVariable<const long double>::setAndIncrease(uint8_t*& mem);
+  template <> _NetworkExport void     SynchronisableVariable<const long double>::getAndIncrease(uint8_t*& mem);
+  template <> _NetworkExport bool     SynchronisableVariable<const long double>::checkEquality(uint8_t* mem);
+  template <> _NetworkExport uint32_t SynchronisableVariable<const std::string>::returnSize();
+  template <> _NetworkExport void     SynchronisableVariable<const std::string>::setAndIncrease(uint8_t*& mem);
+  template <> _NetworkExport void     SynchronisableVariable<const std::string>::getAndIncrease(uint8_t*& mem);
+  template <> _NetworkExport bool     SynchronisableVariable<const std::string>::checkEquality(uint8_t* mem);
+  template <> _NetworkExport uint32_t SynchronisableVariable<const Degree>::returnSize();
+  template <> _NetworkExport void     SynchronisableVariable<const Degree>::setAndIncrease(uint8_t*& mem);
+  template <> _NetworkExport void     SynchronisableVariable<const Degree>::getAndIncrease(uint8_t*& mem);
+  template <> _NetworkExport bool     SynchronisableVariable<const Degree>::checkEquality(uint8_t* mem);
+
+
+
+// ================= 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
+          return;
+        }
+        else{
+          // apply data
+          mem += sizeof(varReference_);
+          if ( SynchronisableVariableBidirectional<T>::checkEquality( mem )==true )
+          {
+            mem += SynchronisableVariable<T>::getSize( mode );
+            return;
+          }
+          else
+          {
+            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 )
+        NetworkCallbackManager::triggerCallback( this->callback_ );
+        //this->callback_->call();
+    }
+
+    template <class T> uint32_t SynchronisableVariableBidirectional<T>::getSize(uint8_t mode)
+    {
+      return SynchronisableVariable<T>::returnSize() + sizeof(varReference_);
+    }
+  
+
+}
+
+
+#endif
