Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

Ignore:
Timestamp:
Feb 14, 2009, 10:17:35 PM (15 years ago)
Author:
rgrieder
Message:

Merged presentation branch back to trunk.

Location:
code/trunk
Files:
3 deleted
21 edited
12 copied

Legend:

Unmodified
Added
Removed
  • code/trunk

  • code/trunk/src/network/CMakeLists.txt

    r2131 r2662  
    1111  PacketBuffer.cc
    1212  Server.cc
    13   Synchronisable.cc
     13  TrafficControl.cc
    1414  Host.cc
    1515)
    1616
    1717ADD_SOURCE_DIRECTORY(NETWORK_SRC_FILES packet)
     18ADD_SOURCE_DIRECTORY(NETWORK_SRC_FILES synchronisable)
     19
    1820
    1921IF(WIN32)
  • code/trunk/src/network/Client.cc

    r2171 r2662  
    4343#include "Client.h"
    4444#include "Host.h"
    45 #include "Synchronisable.h"
     45#include "synchronisable/Synchronisable.h"
    4646#include "core/CoreIncludes.h"
    4747#include "packet/Packet.h"
  • code/trunk/src/network/ClientConnection.cc

    r2171 r2662  
    172172        break;
    173173      case ENET_EVENT_TYPE_RECEIVE:
    174         COUT(5) << "Cl.Con: receiver-Thread while loop: got new packet" << std::endl;
     174        //COUT(5) << "Cl.Con: receiver-Thread while loop: got new packet" << std::endl;
    175175        if ( !processData(event) ) COUT(2) << "Current packet was not pushed to packetBuffer -> ev ongoing SegFault" << std::endl;
    176         COUT(5) << "Cl.Con: processed Data in receiver-thread while loop" << std::endl;
     176        //COUT(5) << "Cl.Con: processed Data in receiver-thread while loop" << std::endl;
    177177        event = new ENetEvent;
    178178        break;
  • code/trunk/src/network/ClientInformation.cc

    r2171 r2662  
    4545namespace orxonox
    4646{
     47 
    4748
    4849  ClientInformation *ClientInformation::head_=0;
  • code/trunk/src/network/ClientInformation.h

    r2171 r2662  
    4646#include <boost/thread/recursive_mutex.hpp>
    4747
     48
    4849// WATCH OUT: THE CLIENTINFORMATION LIST IS NOT THREADSAFE ANYMORE
    4950
    5051namespace orxonox
    5152{
    52   static const unsigned int GAMESTATEID_INITIAL = (unsigned int)-1;
    53   static const unsigned int CLIENTID_UNKNOWN = (unsigned int)-2;
    5453
    5554  /**
  • code/trunk/src/network/ConnectionManager.cc

    r2171 r2662  
    5252#include "util/Sleep.h"
    5353#include "ClientInformation.h"
    54 #include "Synchronisable.h"
     54#include "synchronisable/Synchronisable.h"
    5555#include "packet/ClassID.h"
    5656
     
    206206        // log handling ================
    207207        case ENET_EVENT_TYPE_CONNECT:
    208           COUT(3) << "adding event_type_connect to queue" << std::endl;
     208          //COUT(3) << "adding event_type_connect to queue" << std::endl;
    209209        case ENET_EVENT_TYPE_DISCONNECT:
    210210          //addClient(event);
     
    214214        case ENET_EVENT_TYPE_RECEIVE:
    215215          //std::cout << "received data" << std::endl;
    216           COUT(5) << "Con.Man: receive event has occured" << std::endl;
     216          //COUT(5) << "Con.Man: receive event has occured" << std::endl;
    217217          // only add, if client has connected yet and not been disconnected
    218218          //if(head_->findClient(&event->peer->address))
  • code/trunk/src/network/GamestateClient.cc

    r2171 r2662  
    3535#include "core/BaseObject.h"
    3636#include "core/Iterator.h"
    37 #include "Synchronisable.h"
     37#include "synchronisable/Synchronisable.h"
     38#include "synchronisable/NetworkCallbackManager.h"
    3839#include "packet/Acknowledgement.h"
    3940
     
    7475    if(tempGamestate_==NULL)
    7576      return false;
     77    bool isDiffed = tempGamestate_->isDiffed();
    7678    int id = GAMESTATEID_INITIAL;
    7779    packet::Gamestate *processed = processGamestate(tempGamestate_);
    78 //    assert(processed);
    79     if (!processed)
    80         return false;
     80    assert(processed);
     81   
     82    //now call the queued callbacks
     83    NetworkCallbackManager::callCallbacks();
     84   
     85    if (!processed){
     86      sendAck(0);
     87      return false;
     88    }
    8189    //successfully loaded data from gamestate. now save gamestate for diff and delete the old gs
    8290    tempGamestate_=NULL;
    8391    gamestateMap_[processed->getID()]=processed;
    84     last_diff_ = processed->getID();
     92    if(isDiffed)
     93      last_diff_ = processed->getBaseID();
    8594    id = processed->getID();
    8695    sendAck(id);
     
    153162      packet::Gamestate *base = gamestateMap_[gs->getBaseID()];
    154163      if(!base){
     164        COUT(3) << "could not find base gamestate id: " << gs->getBaseID() << endl;
    155165        delete gs;
    156166        return 0;
     
    165175      return gs;
    166176    else
     177    {
     178      COUT(3) << "could not spread gamestate" << endl;
    167179      return NULL;
     180    }
    168181  }
    169182
  • code/trunk/src/network/GamestateManager.cc

    r2171 r2662  
    4949#include "core/BaseObject.h"
    5050#include "ClientInformation.h"
    51 #include "Synchronisable.h"
     51#include "synchronisable/Synchronisable.h"
     52#include "synchronisable/NetworkCallbackManager.h"
     53#include "packet/Acknowledgement.h"
    5254
    5355namespace orxonox
    5456{
    55   GamestateManager::GamestateManager() {
    56     id_=0;
    57   }
    58 
    59   GamestateManager::~GamestateManager() {
     57  GamestateManager::GamestateManager() :
     58  reference(0), id_(0)
     59  {
     60    trafficControl_ = new TrafficControl();
     61  }
     62
     63  GamestateManager::~GamestateManager()
     64  {
     65    delete trafficControl_;
    6066  }
    6167
     
    8692    // now clear the queue
    8793    gamestateQueue.clear();
     94    //and call all queued callbacks
     95    NetworkCallbackManager::callCallbacks();
    8896    return true;
    8997  }
     
    9199
    92100  bool GamestateManager::getSnapshot(){
     101    if ( reference != 0 )
     102      delete reference;
    93103    reference = new packet::Gamestate();
    94104    if(!reference->collectData(++id_)){ //we have no data to send
     
    99109  }
    100110
    101   /**
    102    * this function is used to keep the memory usage low
    103    * it tries to delete all the unused gamestates
    104    *
    105    *
    106    */
    107 /*  void GamestateManager::cleanup(){
    108     std::map<int,int>::iterator it = gamestateUsed.begin();
    109     while(it!=gamestateUsed.end()){
    110       if((id_-(*it).first)<KEEP_GAMESTATES)
    111         break;
    112       if( (*it).second <= 0 ){
    113         COUT(5) << "GameStateManager: deleting gamestate with id: " << (*it).first << ", uses: " << (*it).second << std::endl;
    114         std::map<int, packet::Gamestate *>::iterator tempit = gamestateMap.find((*it).first);
    115         if( tempit != gamestateMap.end() ){
    116           packet::Gamestate *temp = tempit->second;
    117           if(temp){
    118             delete gamestateMap[(*it).first];
    119             gamestateMap.erase((*it).first);
    120           }
    121         }
    122         gamestateUsed.erase(it++);
    123         continue;
    124       }
    125       it++;
    126     }
    127   }*/
    128111
    129112  packet::Gamestate *GamestateManager::popGameState(unsigned int clientID) {
     
    134117    if(!reference)
    135118      return 0;
    136     gs = reference->doSelection(clientID);
    137 //     gs = new packet::Gamestate(*reference);
     119    gs = reference->doSelection(clientID, 10000);
    138120//     gs = new packet::Gamestate(*reference);
    139121    // save the (undiffed) gamestate in the clients gamestate map
    140     gamestateMap_[clientID].insert(std::pair<int, packet::Gamestate*>(gs->getID(), gs));
     122    gamestateMap_[clientID][gs->getID()]=gs;
    141123    //chose wheather the next gamestate is the first or not
    142     packet::Gamestate *client=NULL;
     124    packet::Gamestate *client=0;
    143125    if(gID != GAMESTATEID_INITIAL){
    144       std::map<unsigned int, std::map<unsigned int, packet::Gamestate*> >::iterator clientMap = gamestateMap_.find(clientID);
    145       if(clientMap!=gamestateMap_.end()){
    146         std::map<unsigned int, packet::Gamestate*>::iterator it = clientMap->second.find(gID);
    147         if(it!=clientMap->second.end())
    148           client = it->second;
     126      assert(gamestateMap_.find(clientID)!=gamestateMap_.end());
     127      std::map<unsigned int, packet::Gamestate*>::iterator it = gamestateMap_[clientID].find(gID);
     128      if(it!=gamestateMap_[clientID].end())
     129      {
     130        client = it->second;
    149131      }
    150132    }
     
    152134//       COUT(3) << "diffing" << std::endl;
    153135      gs = gs->diff(client);
     136//       gs = new packet::Gamestate(*gs);
    154137    }
    155138    else{
     
    159142    bool b = gs->compressData();
    160143    assert(b);
     144    COUT(4) << "sending gamestate with id " << gs->getID();
     145    if(gs->isDiffed())
     146    COUT(4) << " and baseid " << gs->getBaseID() << endl;
     147    else
     148    COUT(4) << endl;
    161149    return gs;
    162150  }
     
    168156    unsigned int curid = temp->getGamestateID();
    169157
    170     if(gamestateID == 0){
     158    if(gamestateID == ACKID_NACK){
    171159      temp->setGamestateID(GAMESTATEID_INITIAL);
     160      // now delete all saved gamestates for this client
     161      std::map<unsigned int, packet::Gamestate*>::iterator it;
     162      for(it = gamestateMap_[clientID].begin(); it!=gamestateMap_[clientID].end(); ){
     163        delete it->second;
     164        gamestateMap_[clientID].erase(it++);
     165      }
    172166      return true;
    173167    }
     
    175169    assert(curid==(unsigned int)GAMESTATEID_INITIAL || curid<gamestateID);
    176170    COUT(4) << "acking gamestate " << gamestateID << " for clientid: " << clientID << " curid: " << curid << std::endl;
    177     std::map<unsigned int, packet::Gamestate*>::iterator it, tempit;
    178     for(it = gamestateMap_[clientID].begin(); it!=gamestateMap_[clientID].end() && it->first<gamestateID; it++){
    179       delete it->second;
    180       tempit=it++;
    181       gamestateMap_[clientID].erase(tempit);
     171    std::map<unsigned int, packet::Gamestate*>::iterator it;
     172    for(it = gamestateMap_[clientID].begin(); it!=gamestateMap_[clientID].end() && it->first<gamestateID; ){
     173      delete it->second;
     174      gamestateMap_[clientID].erase(it++);
    182175    }
    183176    temp->setGamestateID(gamestateID);
     177    TrafficControl::processAck(clientID, gamestateID);
    184178    return true;
    185179  }
  • code/trunk/src/network/GamestateManager.h

    r2171 r2662  
    4343#include "NetworkPrereqs.h"
    4444#include "GamestateHandler.h"
     45#include "TrafficControl.h"
    4546#include <map>
    4647
     
    8182    void removeClient(ClientInformation *client);
    8283    private:
    83 //     void cleanup(); // "garbage handler"
    8484    bool processGamestate(packet::Gamestate *gs);
    8585
     
    8989    std::map<unsigned int, packet::Gamestate*> gamestateQueue;
    9090    packet::Gamestate *reference;
     91    TrafficControl *trafficControl_;
    9192    unsigned int id_;
    9293  };
  • code/trunk/src/network/NetworkPrereqs.h

    r2171 r2662  
    5757
    5858//-----------------------------------------------------------------------
     59// Includes
     60//-----------------------------------------------------------------------
     61#include "util/Integers.h"
     62
     63//-----------------------------------------------------------------------
     64// Library global contants
     65//-----------------------------------------------------------------------
     66namespace orxonox
     67{
     68  static const unsigned int GAMESTATEID_INITIAL = (unsigned int)-1;
     69  static const unsigned int CLIENTID_UNKNOWN    = (unsigned int)-2;
     70  static const uint32_t     OBJECTID_UNKNOWN    = (uint32_t)(-1);
     71}
     72
     73//-----------------------------------------------------------------------
    5974// Forward declarations
    6075//-----------------------------------------------------------------------
     
    7085  class GamestateManager;
    7186  class GamestateHandler;
     87  class NetworkCallbackBase;
     88  template <class T> class NetworkCallback;
     89  class NetworkCallbackManager;
    7290  class PacketBuffer;
    7391  class Server;
    7492  class ServerFrameListener;
    7593  class Synchronisable;
     94  class SynchronisableVariableBase;
     95  template <class T> class SynchronisableVariable;
     96  template <class T> class SynchronisableVariableBidirectional;
    7697  struct ClientList;
    7798  struct PacketEnvelope;
    7899  struct QueueItem;
    79100  struct syncData;
    80   struct synchronisableVariable;
    81   namespace packet{
     101  class obj;
     102  class objInfo;
     103
     104  namespace packet
     105  {
    82106    class Gamestate;
    83107    class Packet;
  • code/trunk/src/network/Server.cc

    r2171 r2662  
    6363{
    6464  const unsigned int MAX_FAILURES = 20;
    65   const unsigned int NETWORK_FREQUENCY = 25;
    66   const float NETWORK_PERIOD = (float)1/NETWORK_FREQUENCY;
    6765
    6866  /**
     
    218216  */
    219217  void Server::updateGamestate() {
     218//     if( ClientInformation::getBegin()==NULL )
     219      //no client connected
     220//       return;
    220221    gamestates_->update();
    221222    COUT(5) << "Server: one gamestate update complete, goig to sendGameState" << std::endl;
     
    276277  bool Server::sendObjectDeletes(){
    277278    ClientInformation *temp = ClientInformation::getBegin();
     279    if( temp == NULL )
     280      //no client connected
     281      return true;
    278282    packet::DeleteObjects *del = new packet::DeleteObjects();
    279283    if(!del->fetchIDs())
  • code/trunk/src/network/Server.h

    r2171 r2662  
    5252{
    5353  const int CLIENTID_SERVER = 0;
     54  const unsigned int NETWORK_FREQUENCY = 25;
     55  const float NETWORK_PERIOD = 1./NETWORK_FREQUENCY;
    5456
    5557  /**
  • code/trunk/src/network/packet/Acknowledgement.cc

    r2171 r2662  
    6464
    6565bool Acknowledgement::process(){
     66COUT(0) << "processing ACK with ID: " << getAckID() << endl;
    6667  bool b = GamestateHandler::ackGamestate(getAckID(), clientID_);
    6768  delete this;
  • code/trunk/src/network/packet/Acknowledgement.h

    r2171 r2662  
    3232#include "Packet.h"
    3333
     34const unsigned int ACKID_NACK = 0;
    3435
    3536namespace orxonox {
  • code/trunk/src/network/packet/DeleteObjects.cc

    r2171 r2662  
    3030#include "DeleteObjects.h"
    3131#include <enet/enet.h>
    32 #include "network/Synchronisable.h"
     32#include "network/synchronisable/Synchronisable.h"
    3333#include "core/CoreIncludes.h"
    3434#include <assert.h>
     
    6161  if(number==0)
    6262    return false;
    63   COUT(3) << "sending DeleteObjects: ";
     63  COUT(4) << "sending DeleteObjects: ";
    6464  unsigned int size = sizeof(ENUM::Type) + sizeof(uint32_t)*(number+1);
    6565  data_ = new uint8_t[size];
    6666  uint8_t *tdata = data_;
    67   *(ENUM::Type *)(tdata) = ENUM::DeleteObjects;
     67  *reinterpret_cast<ENUM::Type*>(tdata) = ENUM::DeleteObjects;
    6868  tdata += sizeof(ENUM::Type);
    6969  *(uint32_t *)tdata = number;
     
    7272    unsigned int temp = Synchronisable::popDeletedObject();
    7373//     assert(temp<10000); //ugly hack
    74     *(uint32_t *)(tdata) = temp;
    75     COUT(3) << temp << " ";
     74    *reinterpret_cast<uint32_t*>(tdata) = temp;
     75    COUT(4) << temp << " ";
    7676    tdata += sizeof(uint32_t);
    7777  }
    78   COUT(3) << std::endl;
     78  COUT(4) << std::endl;
    7979  return true;
    8080}
     
    8787bool DeleteObjects::process(){
    8888  for(unsigned int i=0; i<*(unsigned int *)(data_+_QUANTITY); i++){
    89     COUT(3) << "deleting object with id: " << *(uint32_t*)(data_+_OBJECTIDS+i*sizeof(uint32_t)) << std::endl;
     89    COUT(4) << "deleting object with id: " << *(uint32_t*)(data_+_OBJECTIDS+i*sizeof(uint32_t)) << std::endl;
    9090    Synchronisable::deleteObject( *(uint32_t*)(data_+_OBJECTIDS+i*sizeof(uint32_t)) );
    9191  }
  • code/trunk/src/network/packet/Gamestate.cc

    r2171 r2662  
    2828
    2929#include "Gamestate.h"
    30 #include "network/ClientInformation.h"
    31 #include "network/GamestateHandler.h"
     30#include "../GamestateHandler.h"
     31#include "../synchronisable/Synchronisable.h"
     32#include "../TrafficControl.h"
     33#include "core/Core.h"
    3234#include "core/CoreIncludes.h"
    3335#include "core/Iterator.h"
    3436
    3537#include <zlib.h>
    36 #include <assert.h>
     38#include <cassert>
    3739
    3840
     
    4244namespace packet {
    4345
    44 #define GAMESTATE_START(data) (data + sizeof(GamestateHeader))
    45 #define GAMESTATE_HEADER(data) ((GamestateHeader *)data)
    46 #define HEADER GAMESTATE_HEADER(data_)
    47 
     46#define GAMESTATE_START(data) (data + GamestateHeader::getSize())
    4847
    4948#define PACKET_FLAG_GAMESTATE  ENET_PACKET_FLAG_RELIABLE
    5049
     50// Gamestate::Gamestate()
     51// {
     52//   flags_ = flags_ | PACKET_FLAG_GAMESTATE;
     53// }
     54
    5155Gamestate::Gamestate()
    5256{
    5357  flags_ = flags_ | PACKET_FLAG_GAMESTATE;
     58  header_ = 0;
    5459}
    5560
     
    5863{
    5964  flags_ = flags_ | PACKET_FLAG_GAMESTATE;
     65  header_ = new GamestateHeader(data_);
    6066}
    6167
     
    6470  flags_ = flags_ | PACKET_FLAG_GAMESTATE;
    6571  data_=data;
     72  header_ = new GamestateHeader(data_);
     73}
     74
     75Gamestate::Gamestate(const Gamestate& g) :
     76    Packet( *(Packet*)&g )
     77{
     78  flags_ = flags_ | PACKET_FLAG_GAMESTATE;
     79  header_ = new GamestateHeader(data_);
    6680}
    6781
     
    7387bool Gamestate::collectData(int id, uint8_t mode)
    7488{
    75   unsigned int tempsize=0, currentsize=0;
     89  assert(this->header_==0); // make sure the header didn't exist before
     90  uint32_t tempsize=0, currentsize=0;
    7691  assert(data_==0);
    77   unsigned int size = calcGamestateSize(id, mode);
     92  uint32_t size = calcGamestateSize(id, mode);
    7893
    7994  COUT(4) << "G.ST.Man: producing gamestate with id: " << id << std::endl;
    8095  if(size==0)
    8196    return false;
    82   data_ = new unsigned char[size + sizeof(GamestateHeader)];
     97  data_ = new uint8_t[size + GamestateHeader::getSize()];
    8398  if(!data_){
    8499    COUT(2) << "GameStateManager: could not allocate memory" << std::endl;
    85100    return false;
    86101  }
     102 
     103  // create the header object
     104  header_ = new GamestateHeader(data_);
    87105
    88106  //start collect data synchronisable by synchronisable
    89107  uint8_t *mem=data_;
    90   mem+=sizeof(GamestateHeader);
     108  mem += GamestateHeader::getSize();
    91109  ObjectList<Synchronisable>::iterator it;
    92110  for(it = ObjectList<Synchronisable>::begin(); it; ++it){
     111   
     112#ifndef NDEBUG
    93113    tempsize=it->getSize(id, mode);
    94 
    95114    if(currentsize+tempsize > size){
    96115      assert(0); // if we don't use multithreading this part shouldn't be neccessary
     
    98117      COUT(3) << "G.St.Man: need additional memory" << std::endl;
    99118      ObjectList<Synchronisable>::iterator temp = it;
    100       int addsize=tempsize;
     119      uint32_t addsize=tempsize;
    101120      while(++temp)
    102121        addsize+=temp->getSize(id, mode);
    103       data_ = (uint8_t *)realloc(data_, sizeof(GamestateHeader) + currentsize + addsize);
     122      data_ = (uint8_t *)realloc(data_, GamestateHeader::getSize() + currentsize + addsize);
    104123      if(!data_)
    105124        return false;
    106125      size = currentsize+addsize;
    107126    }// stop allocate additional memory
    108 
     127#endif
    109128
    110129    //if(it->doSelection(id))
    111     dataMap_[mem-data_]=(*it);  // save the mem location of the synchronisable data
     130    if ( it->doSync( id, mode ) )
     131      dataMap_.push_back( obj(it->getObjectID(), it->getCreatorID(), tempsize, mem-data_) );
     132//     dataMap_[mem-data_]=(*it);  // save the mem location of the synchronisable data
    112133    if(!it->getData(mem, id, mode))
    113134      return false; // mem pointer gets automatically increased because of call by reference
     
    118139
    119140  //start write gamestate header
    120   HEADER->packetType = ENUM::Gamestate;
    121   HEADER->datasize = currentsize;
    122   HEADER->id = id;
    123   HEADER->diffed = false;
    124   HEADER->complete = true;
    125   HEADER->compressed = false;
     141  header_->setDataSize( currentsize );
     142  header_->setID( id );
     143  header_->setDiffed( false );
     144  header_->setComplete( true );
     145  header_->setCompressed( false );
    126146  //stop write gamestate header
    127147
     
    133153bool Gamestate::spreadData(uint8_t mode)
    134154{
    135   assert(data_);
    136   assert(!HEADER->compressed);
    137   assert(!HEADER->diffed);
    138   uint8_t *mem=data_+sizeof(GamestateHeader);
     155  COUT(4) << "processing gamestate with id " << header_->getID() << endl;
     156  assert(data_);
     157  assert(!header_->isCompressed());
     158  assert(!header_->isDiffed());
     159  uint8_t *mem=data_+GamestateHeader::getSize();
    139160    // get the start of the Synchronisable list
    140161  //ObjectList<Synchronisable>::iterator it=ObjectList<Synchronisable>::begin();
     
    142163
    143164  // update the data of the objects we received
    144   while(mem < data_+sizeof(GamestateHeader)+HEADER->datasize){
    145     synchronisableHeader *objectheader = (synchronisableHeader*)mem;
    146 
    147     s = Synchronisable::getSynchronisable( objectheader->objectID );
     165  while(mem < data_+GamestateHeader::getSize()+header_->getDataSize()){
     166    SynchronisableHeader objectheader(mem);
     167
     168    s = Synchronisable::getSynchronisable( objectheader.getObjectID() );
    148169    if(!s)
    149170    {
    150       Synchronisable::fabricate(mem, mode);
     171      if (!Core::isMaster())
     172      {
     173        Synchronisable::fabricate(mem, mode);
     174      }
     175      else
     176      {
     177        mem += objectheader.getDataSize();
     178      }
     179//         COUT(0) << "could not fabricate synchronisable: " << objectheader->objectID << " classid: " << objectheader->classID << " creator: " << objectheader->creatorID << endl;
     180//       else
     181//         COUT(0) << "fabricated: " << objectheader->objectID << " classid: " << objectheader->classID << " creator: "  << objectheader->creatorID << endl;
    151182    }
    152183    else
     
    157188  }
    158189
     190   // In debug mode, check first, whether there are no duplicate objectIDs
     191#ifndef NDEBUG
     192  ObjectList<Synchronisable>::iterator it;
     193  for (it = ObjectList<Synchronisable>::begin(); it != ObjectList<Synchronisable>::end(); ++it) {
     194    if (it->getObjectID() == OBJECTID_UNKNOWN) {
     195      if (it->objectMode_ != 0x0) {
     196        COUT(0) << "Found object with OBJECTID_UNKNOWN on the client with objectMode != 0x0!" << std::endl;
     197        COUT(0) << "Possible reason for this error: Client created a synchronized object without the Server's approval." << std::endl;
     198        COUT(0) << "Objects class: " << it->getIdentifier()->getName() << std::endl;
     199        assert(false);
     200      }
     201    }
     202    else {
     203      ObjectList<Synchronisable>::iterator it2;
     204      for (it2 = ObjectList<Synchronisable>::begin(); it2 != ObjectList<Synchronisable>::end(); ++it2) {
     205        if (it->getObjectID() == it2->getObjectID() && *it != *it2) {
     206           COUT(0) << "Found duplicate objectIDs on the client!" << std::endl
     207                   << "Are you sure you don't create a Sychnronisable objcect with 'new' \
     208                       that doesn't have objectMode = 0x0?" << std::endl;
     209           assert(false);
     210        }
     211      }
     212    }
     213  }
     214#endif
     215
    159216  return true;
    160217}
    161218
    162 
    163 
    164 int Gamestate::getID(){
    165   return HEADER->id;
    166 }
    167 
    168 unsigned int Gamestate::getSize() const
    169 {
    170   assert(data_);
    171   if(HEADER->compressed)
    172     return HEADER->compsize+sizeof(GamestateHeader);
     219uint32_t Gamestate::getSize() const
     220{
     221  assert(data_);
     222  if(header_->isCompressed())
     223    return header_->getCompSize()+GamestateHeader::getSize();
    173224  else
    174225  {
    175     return HEADER->datasize+sizeof(GamestateHeader);
     226    return header_->getDataSize()+GamestateHeader::getSize();
    176227  }
    177228}
    178229
    179230bool Gamestate::operator==(packet::Gamestate gs){
    180   uint8_t *d1 = data_+sizeof(GamestateHeader);
    181   uint8_t *d2 = gs.data_+sizeof(GamestateHeader);
     231  uint8_t *d1 = data_+GamestateHeader::getSize();
     232  uint8_t *d2 = gs.data_+GamestateHeader::getSize();
    182233  assert(!isCompressed());
    183234  assert(!gs.isCompressed());
    184   while(d1<data_+HEADER->datasize)
     235  while(d1<data_+header_->getDataSize())
    185236  {
    186237    if(*d1!=*d2)
     
    201252bool Gamestate::compressData()
    202253{
    203   assert(HEADER);
    204   assert(!HEADER->compressed);
    205   uLongf buffer = (uLongf)(((HEADER->datasize + 12)*1.01)+1);
     254  assert(data_);
     255  assert(!header_->isCompressed());
     256  uLongf buffer = (uLongf)(((header_->getDataSize() + 12)*1.01)+1);
    206257  if(buffer==0)
    207258    return false;
    208259
    209   uint8_t *ndata = new uint8_t[buffer+sizeof(GamestateHeader)];
    210   uint8_t *dest = GAMESTATE_START(ndata);
     260  uint8_t *ndata = new uint8_t[buffer+GamestateHeader::getSize()];
     261  uint8_t *dest = ndata + GamestateHeader::getSize();
    211262  //unsigned char *dest = new unsigned char[buffer];
    212   uint8_t *source = GAMESTATE_START(data_);
     263  uint8_t *source = data_ + GamestateHeader::getSize();
    213264  int retval;
    214   retval = compress( dest, &buffer, source, (uLong)(HEADER->datasize) );
     265  retval = compress( dest, &buffer, source, (uLong)(header_->getDataSize()) );
    215266  switch ( retval ) {
    216267    case Z_OK: COUT(5) << "G.St.Man: compress: successfully compressed" << std::endl; break;
     
    219270    case Z_DATA_ERROR: COUT(2) << "G.St.Man: compress: data corrupted in gamestate.compress" << std::endl; return false;
    220271  }
    221 #ifndef NDEBUG
    222   //decompress and compare the start and the decompressed data
    223   uint8_t *rdata = new uint8_t[HEADER->datasize+sizeof(GamestateHeader)];
    224   uint8_t *d2 = GAMESTATE_START(rdata);
    225   uLongf length2 = HEADER->datasize;
    226   uncompress(d2, &length2, dest, buffer);
    227   for(unsigned int i=0; i<HEADER->datasize; i++){
    228     assert(*(source+i)==*(d2+i));
    229   }
    230   delete[] rdata;
    231 #endif
    232272
    233273  //copy and modify header
    234 #ifndef NDEBUG
    235   HEADER->crc32 = calcCRC(data_+sizeof(GamestateHeader), HEADER->datasize);
    236 #endif
    237   *GAMESTATE_HEADER(ndata) = *HEADER;
     274  GamestateHeader *temp = header_;
     275  header_ = new GamestateHeader(ndata, temp);
     276  delete temp;
    238277  //delete old data
    239278  delete[] data_;
    240279  //save new data
    241280  data_ = ndata;
    242   HEADER->compsize = buffer;
    243   HEADER->compressed = true;
    244   assert(HEADER->compressed);
    245   COUT(4) << "gamestate compress datasize: " << HEADER->datasize << " compsize: " << HEADER->compsize << std::endl;
     281  header_->setCompSize( buffer );
     282  header_->setCompressed( true );
     283  COUT(5) << "gamestate compress datasize: " << header_->getDataSize() << " compsize: " << header_->getCompSize() << std::endl;
    246284  return true;
    247285}
    248286bool Gamestate::decompressData()
    249287{
    250   assert(HEADER);
    251   assert(HEADER->compressed);
    252   COUT(4) << "GameStateClient: uncompressing gamestate. id: " << HEADER->id << ", baseid: " << HEADER->base_id << ", datasize: " << HEADER->datasize << ", compsize: " << HEADER->compsize << std::endl;
    253   unsigned int datasize = HEADER->datasize;
    254   unsigned int compsize = HEADER->compsize;
    255   unsigned int bufsize;
     288  assert(data_);
     289  assert(header_->isCompressed());
     290  COUT(4) << "GameStateClient: uncompressing gamestate. id: " << header_->getID() << ", baseid: " << header_->getBaseID() << ", datasize: " << header_->getDataSize() << ", compsize: " << header_->getCompSize() << std::endl;
     291  uint32_t datasize = header_->getDataSize();
     292  uint32_t compsize = header_->getCompSize();
     293  uint32_t bufsize;
    256294//  assert(compsize<=datasize);
    257295  bufsize = datasize;
    258296  assert(bufsize!=0);
    259   uint8_t *ndata = new uint8_t[bufsize + sizeof(GamestateHeader)];
    260   uint8_t *dest = ndata + sizeof(GamestateHeader);
    261   uint8_t *source = data_ + sizeof(GamestateHeader);
     297  uint8_t *ndata = new uint8_t[bufsize + GamestateHeader::getSize()];
     298  uint8_t *dest = ndata + GamestateHeader::getSize();
     299  uint8_t *source = data_ + GamestateHeader::getSize();
    262300  int retval;
    263301  uLongf length=bufsize;
     
    269307    case Z_DATA_ERROR: COUT(2) << "data corrupted (zlib)" << std::endl; return false;
    270308  }
    271 #ifndef NDEBUG
    272   assert(HEADER->crc32==calcCRC(ndata+sizeof(GamestateHeader), HEADER->datasize));
    273 #endif
    274309
    275310  //copy over the header
    276   *GAMESTATE_HEADER(ndata) = *HEADER;
     311  GamestateHeader *temp = header_;
     312  header_ = new GamestateHeader( data_, header_ );
     313  delete temp;
    277314
    278315  if (this->bDataENetAllocated_){
     
    289326  //set new pointers
    290327  data_ = ndata;
    291   HEADER->compressed = false;
    292   assert(HEADER->datasize==datasize);
    293   assert(HEADER->compsize==compsize);
     328  header_->setCompressed( false );
     329  assert(header_->getDataSize()==datasize);
     330  assert(header_->getCompSize()==compsize);
    294331  return true;
    295332}
     
    297334Gamestate *Gamestate::diff(Gamestate *base)
    298335{
    299   assert(HEADER);
    300   assert(!HEADER->compressed);
    301   assert(!HEADER->diffed);
     336  assert(data_);
     337  assert(!header_->isCompressed());
     338  assert(!header_->isDiffed());
     339  GamestateHeader diffHeader(base->data_);
    302340  //unsigned char *basep = base->getGs()/*, *gs = getGs()*/;
    303341  uint8_t *basep = GAMESTATE_START(base->data_), *gs = GAMESTATE_START(this->data_);
    304   unsigned int of=0; // pointers offset
    305   unsigned int dest_length=0;
    306   dest_length=HEADER->datasize;
     342  uint32_t of=0; // pointers offset
     343  uint32_t dest_length=0;
     344  dest_length=header_->getDataSize();
    307345  if(dest_length==0)
    308346    return NULL;
    309   uint8_t *ndata = new uint8_t[dest_length*sizeof(uint8_t)+sizeof(GamestateHeader)];
    310   uint8_t *dest = ndata + sizeof(GamestateHeader);
    311   while(of < GAMESTATE_HEADER(base->data_)->datasize && of < HEADER->datasize){
     347  uint8_t *ndata = new uint8_t[dest_length*sizeof(uint8_t)+GamestateHeader::getSize()];
     348  uint8_t *dest = ndata + GamestateHeader::getSize();
     349  while(of < diffHeader.getDataSize() && of < header_->getDataSize()){
    312350    *(dest+of)=*(basep+of)^*(gs+of); // do the xor
    313351    ++of;
    314352  }
    315   if(GAMESTATE_HEADER(base->data_)->datasize!=HEADER->datasize){
     353  if(diffHeader.getDataSize()!=header_->getDataSize()){
    316354    uint8_t n=0;
    317     if(GAMESTATE_HEADER(base->data_)->datasize < HEADER->datasize){
     355    if(diffHeader.getDataSize() < header_->getDataSize()){
    318356      while(of<dest_length){
    319357        *(dest+of)=n^*(gs+of);
     
    323361  }
    324362
    325   *GAMESTATE_HEADER(ndata) = *HEADER;
    326   GAMESTATE_HEADER(ndata)->diffed = true;
    327   GAMESTATE_HEADER(ndata)->base_id = base->getID();
    328363  Gamestate *g = new Gamestate(ndata, getClientID());
     364  *(g->header_) = *header_;
     365  g->header_->setDiffed( true );
     366  g->header_->setBaseID( base->getID() );
    329367  g->flags_=flags_;
    330368  g->packetDirection_ = packetDirection_;
     
    332370}
    333371
    334 Gamestate* Gamestate::doSelection(unsigned int clientID){
    335   assert(data_);
    336   std::map<unsigned int, Synchronisable *>::iterator it;
     372Gamestate* Gamestate::doSelection(unsigned int clientID, unsigned int targetSize){
     373  assert(data_);
     374  std::list<obj>::iterator it;
    337375
    338376  // allocate memory for new data
    339   uint8_t *gdata = new uint8_t[HEADER->datasize+sizeof(GamestateHeader)];
     377  uint8_t *gdata = new uint8_t[header_->getDataSize()+GamestateHeader::getSize()];
    340378  // create a gamestate out of it
    341379  Gamestate *gs = new Gamestate(gdata);
    342   uint8_t *newdata = gdata + sizeof(GamestateHeader);
     380  uint8_t *newdata = gdata + GamestateHeader::getSize();
    343381  uint8_t *origdata = GAMESTATE_START(data_);
    344382
    345383  //copy the GamestateHeader
    346   *(GamestateHeader*)gdata = *HEADER;
    347 
    348   synchronisableHeader *oldobjectheader, *newobjectheader;
    349   unsigned int objectOffset;
     384  assert(gs->header_);
     385  *(gs->header_) = *header_;
     386
     387  uint32_t objectOffset;
     388  unsigned int objectsize, destsize=0;
     389  // TODO: Why is this variable not used?
     390  //Synchronisable *object;
     391
     392  //call TrafficControl
     393  TrafficControl::getInstance()->processObjectList( clientID, header_->getID(), &dataMap_ );
    350394
    351395  //copy in the zeros
    352   for(it=dataMap_.begin(); it!=dataMap_.end(); it++){
    353     oldobjectheader = (synchronisableHeader*)origdata;
    354     newobjectheader = (synchronisableHeader*)newdata;
    355     unsigned int objectsize = oldobjectheader->size;
    356     assert(it->second->objectID==oldobjectheader->objectID);
    357     *newobjectheader = *oldobjectheader;
    358     objectOffset=sizeof(synchronisableHeader); //skip the size and the availableData variables in the objectheader
    359     if(it->second->doSelection(HEADER->id)){
    360       assert(newobjectheader->dataAvailable==true);
    361       memcpy(newdata+objectOffset, origdata+objectOffset, objectsize-objectOffset);
     396  for(it=dataMap_.begin(); it!=dataMap_.end();){
     397//    if((*it).objSize==0)
     398//      continue;
     399//    if(it->second->getSize(HEADER->id)==0) // merged from objecthierarchy2, doesn't work anymore; TODO: change this
     400//      continue;                            // merged from objecthierarchy2, doesn't work anymore; TODO: change this
     401    SynchronisableHeader oldobjectheader(origdata);
     402    SynchronisableHeader newobjectheader(newdata);
     403    if ( (*it).objSize == 0 )
     404    {
     405      ++it;
     406      continue;
     407    }
     408//     object = Synchronisable::getSynchronisable( (*it).objID );
     409//     assert(object->objectID == oldobjectheader->objectID);
     410    objectsize = oldobjectheader.getDataSize();
     411    objectOffset=SynchronisableHeader::getSize(); //skip the size and the availableData variables in the objectheader
     412    if ( (*it).objID == oldobjectheader.getObjectID() ){
     413      memcpy(newdata, origdata, objectsize);
     414      assert(newobjectheader.isDataAvailable()==true);
     415      ++it;
    362416    }else{
    363       newobjectheader->dataAvailable=false;
     417      newobjectheader = oldobjectheader;
     418      newobjectheader.setDataAvailable(false);
    364419      memset(newdata+objectOffset, 0, objectsize-objectOffset);
    365       assert(objectOffset==objectsize);
    366420    }
    367421    newdata += objectsize;
    368422    origdata += objectsize;
    369   }
     423    destsize += objectsize;
     424  }
     425#ifndef NDEBUG
     426  uint32_t origsize = destsize;
     427  while ( origsize < header_->getDataSize() )
     428  {
     429    SynchronisableHeader oldobjectheader(origdata);
     430    objectsize = oldobjectheader.getDataSize();
     431    origdata += objectsize;
     432    origsize += objectsize;
     433  }
     434  assert(origsize==header_->getDataSize());
     435  assert(destsize!=0);
     436#endif
     437  gs->header_->setDataSize( destsize );
    370438  return gs;
    371439}
    372440
    373441
    374 Gamestate* Gamestate::intelligentDiff(Gamestate *base, unsigned int clientID){
    375   // asserts
    376   assert(data_);
    377   assert(base->data_);
    378   assert(!GAMESTATE_HEADER(base->data_)->diffed);
    379   assert(!GAMESTATE_HEADER(base->data_)->compressed);
    380   assert(!HEADER->compressed);
    381   assert(!HEADER->diffed);
    382 
    383   //preparations
    384   std::map<unsigned int, Synchronisable *>::iterator it;
    385   uint8_t *origdata, *basedata, *destdata, *ndata;
    386   unsigned int objectOffset, streamOffset=0;    //data offset
    387   unsigned int minsize = (HEADER->datasize < GAMESTATE_HEADER(base->data_)->datasize) ? HEADER->datasize : GAMESTATE_HEADER(base->data_)->datasize;
    388   synchronisableHeader *origheader;
    389   synchronisableHeader *destheader;
    390 
    391   origdata = GAMESTATE_START(this->data_);
    392   basedata = GAMESTATE_START(base->data_);
    393   ndata = new uint8_t[HEADER->datasize + sizeof(GamestateHeader)];
    394   destdata = ndata + sizeof(GamestateHeader);
    395 
    396   // do the diff
    397   for(it=dataMap_.begin(); it!=dataMap_.end(); it++){
    398     assert(streamOffset<HEADER->datasize);
    399     bool sendData = it->second->doSelection(HEADER->id);
    400     origheader = (synchronisableHeader *)(origdata+streamOffset);
    401     destheader = (synchronisableHeader *)(destdata+streamOffset);
    402 
    403     //copy and partially diff the object header
    404     assert(sizeof(synchronisableHeader)==3*sizeof(unsigned int)+sizeof(bool));
    405     *(uint32_t*)destdata = *(uint32_t*)origdata; //size (do not diff)
    406     *(bool*)(destdata+sizeof(uint32_t)) = sendData;
    407     if(sendData){
    408       *(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)
    409       *(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)
    410     }else{
    411       *(uint32_t*)(destdata+sizeof(uint32_t)+sizeof(bool)) = 0;
    412       *(uint32_t*)(destdata+2*sizeof(uint32_t)+sizeof(bool)) = 0;
    413     }
    414     objectOffset=sizeof(synchronisableHeader);
    415     streamOffset+=sizeof(synchronisableHeader);
    416 
    417     //now handle the object data or fill with zeros
    418     while(objectOffset<origheader->size ){
    419 
    420       if(sendData && streamOffset<minsize)
    421         *(destdata+objectOffset)=*(basedata+objectOffset)^*(origdata+objectOffset); // do the xor
    422       else if(sendData)
    423         *(destdata+objectOffset)=((uint8_t)0)^*(origdata+objectOffset); // xor with 0 (basestream is too short)
    424       else
    425         *(destdata+objectOffset)=0; // set to 0 because this object should not be transfered
    426 
    427       objectOffset++;
    428       streamOffset++;
    429     }
    430     destdata+=objectOffset;
    431     origdata+=objectOffset;
    432     basedata+=objectOffset;
    433   }
    434 
    435   //copy over the gamestate header and set the diffed flag
    436   *(GamestateHeader *)ndata = *HEADER; //copy over the header
    437   Gamestate *gs = new Gamestate(ndata);
    438   GAMESTATE_HEADER(ndata)->diffed=true;
    439   return gs;
    440 }
    441 
    442 Gamestate* Gamestate::intelligentUnDiff(Gamestate *base){
    443   // asserts
    444   assert(data_);
    445   assert(base->data_);
    446   assert(!GAMESTATE_HEADER(base->data_)->diffed);
    447   assert(!GAMESTATE_HEADER(base->data_)->compressed);
    448   assert(!HEADER->compressed);
    449   assert(HEADER->diffed);
    450 
    451   //preparations
    452   std::map<unsigned int, Synchronisable *>::iterator it;
    453   uint8_t *origdata, *basedata, *destdata, *ndata;
    454   unsigned int objectOffset, streamOffset=0;    //data offset
    455   unsigned int minsize = (HEADER->datasize < GAMESTATE_HEADER(base->data_)->datasize) ? HEADER->datasize : GAMESTATE_HEADER(base->data_)->datasize;
    456   synchronisableHeader *origheader;
    457   synchronisableHeader *destheader;
    458 
    459   origdata = GAMESTATE_START(this->data_);
    460   basedata = GAMESTATE_START(base->data_);
    461   ndata = new uint8_t[HEADER->datasize + sizeof(GamestateHeader)];
    462   destdata = ndata + sizeof(GamestateHeader);
    463 
    464   // do the undiff
    465   for(it=dataMap_.begin(); it!=dataMap_.end(); it++){
    466     assert(streamOffset<HEADER->datasize);
    467     origheader = (synchronisableHeader *)(origdata+streamOffset);
    468     destheader = (synchronisableHeader *)(destdata+streamOffset);
    469     bool sendData;
    470 
    471     //copy and partially diff the object header
    472     assert(sizeof(synchronisableHeader)==3*sizeof(unsigned int)+sizeof(bool));
    473     *(unsigned int*)destdata = *(unsigned int*)origdata; //size (do not diff)
    474     *(bool*)(destdata+sizeof(unsigned int)) = *(bool*)(origdata+sizeof(unsigned int));
    475     sendData = *(bool*)(origdata+sizeof(unsigned int));
    476     if(sendData){
    477       *(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)
    478       *(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)
    479     }else{
    480       *(unsigned int*)(destdata+sizeof(unsigned int)+sizeof(bool)) = 0;
    481       *(unsigned int*)(destdata+2*sizeof(unsigned int)+sizeof(bool)) = 0;
    482     }
    483     objectOffset=sizeof(synchronisableHeader);
    484     streamOffset+=sizeof(synchronisableHeader);
    485 
    486     //now handle the object data or fill with zeros
    487     while(objectOffset<origheader->size ){
    488 
    489       if(sendData && streamOffset<minsize)
    490         *(destdata+objectOffset)=*(basedata+objectOffset)^*(origdata+objectOffset); // do the xor
    491       else if(sendData)
    492         *(destdata+objectOffset)=((unsigned char)0)^*(origdata+objectOffset); // xor with 0 (basestream is too short)
    493       else
    494         *(destdata+objectOffset)=0; // set to 0 because this object should not be transfered
    495 
    496       objectOffset++;
    497       streamOffset++;
    498     }
    499     destdata+=objectOffset;
    500     origdata+=objectOffset;
    501     basedata+=objectOffset;
    502   }
    503 
    504   //copy over the gamestate header and set the diffed flag
    505   *(GamestateHeader *)ndata = *HEADER; //copy over the header
    506   Gamestate *gs = new Gamestate(ndata);
    507   GAMESTATE_HEADER(ndata)->diffed=false;
    508   return gs;
    509 }
    510 
    511442Gamestate *Gamestate::undiff(Gamestate *base)
    512443{
    513   assert(this && base);assert(HEADER);
    514   assert(HEADER->diffed);
    515   assert(!HEADER->compressed && !GAMESTATE_HEADER(base->data_)->compressed);
     444  assert(this && base);assert(data_);
     445  assert(header_->isDiffed());
     446  assert(!header_->isCompressed() && !base->header_->isCompressed());
    516447  //unsigned char *basep = base->getGs()/*, *gs = getGs()*/;
    517448  uint8_t *basep = GAMESTATE_START(base->data_);
    518449  uint8_t *gs = GAMESTATE_START(this->data_);
    519   unsigned int of=0; // pointers offset
    520   unsigned int dest_length=0;
    521   dest_length=HEADER->datasize;
     450  uint32_t of=0; // pointers offset
     451  uint32_t dest_length=0;
     452  dest_length=header_->getDataSize();
    522453  if(dest_length==0)
    523454    return NULL;
    524   uint8_t *ndata = new uint8_t[dest_length*sizeof(uint8_t)+sizeof(GamestateHeader)];
    525   uint8_t *dest = ndata + sizeof(GamestateHeader);
    526   while(of < GAMESTATE_HEADER(base->data_)->datasize && of < HEADER->datasize){
     455  uint8_t *ndata = new uint8_t[dest_length*sizeof(uint8_t)+GamestateHeader::getSize()];
     456  uint8_t *dest = ndata + GamestateHeader::getSize();
     457  while(of < base->header_->getDataSize() && of < header_->getDataSize()){
    527458    *(dest+of)=*(basep+of)^*(gs+of); // do the xor
    528459    ++of;
    529460  }
    530   if(GAMESTATE_HEADER(base->data_)->datasize!=HEADER->datasize){
     461  if(base->header_->getDataSize()!=header_->getDataSize()){
    531462    uint8_t n=0;
    532     if(GAMESTATE_HEADER(base->data_)->datasize < HEADER->datasize){
     463    if(base->header_->getDataSize() < header_->getDataSize()){
    533464      while(of < dest_length){
    534465        *(dest+of)=n^*(gs+of);
     
    537468    }
    538469  }
    539   *GAMESTATE_HEADER(ndata) = *HEADER;
    540   GAMESTATE_HEADER(ndata)->diffed = false;
    541470  Gamestate *g = new Gamestate(ndata, getClientID());
     471  assert(g->header_);
     472  *(g->header_) = *header_;
     473  g->header_->setDiffed( false );
    542474  g->flags_=flags_;
    543475  g->packetDirection_ = packetDirection_;
     
    548480
    549481
    550 unsigned int Gamestate::calcGamestateSize(unsigned int id, uint8_t mode)
    551 {
    552   unsigned int size=0;
     482uint32_t Gamestate::calcGamestateSize(int32_t id, uint8_t mode)
     483{
     484  uint32_t size=0;
    553485    // get the start of the Synchronisable list
    554486  ObjectList<Synchronisable>::iterator it;
     
    556488  for(it = ObjectList<Synchronisable>::begin(); it; ++it)
    557489    size+=it->getSize(id, mode); // size of the actual data of the synchronisable
    558 //  size+=sizeof(GamestateHeader);
    559490  return size;
    560491}
    561492
    562 /**
    563  * This function removes a Synchronisable out of the universe
    564  * @param it iterator of the list pointing to the object
    565  * @return iterator pointing to the next object in the list
    566  */
    567   void Gamestate::removeObject(ObjectList<Synchronisable>::iterator &it) {
    568     ObjectList<Synchronisable>::iterator temp=it;
    569     ++it;
    570     delete  *temp;
    571   }
    572 
    573   bool Gamestate::isDiffed(){
    574     return HEADER->diffed;
    575   }
    576 
    577   bool Gamestate::isCompressed(){
    578     return HEADER->compressed;
    579   }
    580 
    581   int Gamestate::getBaseID(){
    582     return HEADER->base_id;
    583   }
    584 }
    585 
    586 }
     493} //namespace packet
     494} //namespace orxonox
  • code/trunk/src/network/packet/Gamestate.h

    r2171 r2662  
    3131#define NETWORK_PACKETGAMESTATE_H
    3232
    33 #include "../NetworkPrereqs.h"
     33#include "network/NetworkPrereqs.h"
    3434
    3535#include "Packet.h"
    36 #include "network/Synchronisable.h"
     36#include "network/TrafficControl.h"
     37#include "core/CoreIncludes.h"
    3738#include <map>
     39#include <list>
    3840#ifndef NDEBUG
    3941#include "util/CRC32.h"
     
    4446namespace packet {
    4547
    46 struct _NetworkExport GamestateHeader{
    47   ENUM::Type packetType;
    48   int32_t id; // id of the gamestate
    49   uint32_t compsize;
    50   uint32_t datasize;
    51   int32_t base_id; // id of the base-gamestate diffed from
    52   bool diffed:1; // wheter diffed or not
    53   bool complete:1; // wheter it is a complete gamestate or only partial
    54   bool compressed:1;
    55 #ifndef NDEBUG
    56   uint32_t crc32;
    57 #endif
     48class _NetworkExport GamestateHeader{
     49  public:
     50    GamestateHeader(uint8_t *data){ assert(data); data_ = data; *(uint32_t*)data_ = ENUM::Gamestate; }
     51    GamestateHeader(uint8_t *data, GamestateHeader* h)
     52    { assert(data); data_=data; memcpy(data_, h->data_, getSize()); }
     53    static inline uint32_t getSize()
     54    { return 21; }
     55
     56    inline int32_t getID() const
     57    { assert(data_); return *(int32_t*)(data_+4); }
     58    inline void setID(int32_t id)
     59    { assert(data_); *(int32_t*)(data_+4) = id; }
     60
     61    inline int32_t getBaseID() const
     62    { assert(data_); return *(int32_t*)(data_+8); }
     63    inline void setBaseID(int32_t id)
     64    { assert(data_); *(int32_t*)(data_+8) = id; }
     65
     66    inline uint32_t getDataSize() const
     67    { assert(data_); return *(uint32_t*)(data_+12); }
     68    inline void setDataSize(uint32_t size)
     69    { assert(data_); *(uint32_t*)(data_+12) = size; }
     70
     71    inline uint32_t getCompSize() const
     72    { assert(data_); return *(uint32_t*)(data_+16); }
     73    inline void setCompSize(uint32_t size)
     74    { assert(data_); *(uint32_t*)(data_+16) = size; }
     75
     76    inline bool isDiffed() const
     77    { assert(data_); return *(int8_t*)(data_+20) & 0x1; }
     78    inline void setDiffed(bool b)
     79    { assert(data_); *(int8_t*)(data_+20) = (b<<0) | (*(int8_t*)(data_+20) & 0x6 ); }
     80
     81    inline bool isComplete() const
     82    { assert(data_); return *(int8_t*)(data_+20) & 0x2; }
     83    inline void setComplete(bool b)
     84    { assert(data_); *(int8_t*)(data_+20) = (b<<1) | (*(int8_t*)(data_+20) & 0x5 ); }
     85
     86    inline bool isCompressed() const
     87    { assert(data_); return *(int8_t*)(data_+20) & 0x4; }
     88    inline void setCompressed(bool b)
     89    { assert(data_); *(int8_t*)(data_+20) = (b<<2) | (*(int8_t*)(data_+20) & 0x3 ); }
     90
     91    inline void operator=(GamestateHeader& h)
     92    { assert(data_); assert(h.data_); memcpy( data_, h.data_, getSize()); }
     93  private:
     94    uint8_t *data_;
     95//#define GAMESTATE_START(data) (data + sizeof(GamestateHeader))
     96//#define GAMESTATE_HEADER(data) ((GamestateHeader *)data)
     97//#define HEADER GAMESTATE_HEADER(data_)
     98
    5899};
    59100
     
    66107    Gamestate(uint8_t *data, unsigned int clientID);
    67108    Gamestate(uint8_t *data);
     109    Gamestate(const Gamestate& g);
    68110
    69111    ~Gamestate();
     
    71113    bool collectData(int id, uint8_t mode=0x0);
    72114    bool spreadData( uint8_t mode=0x0);
    73     int getID();
    74     bool isDiffed();
    75     bool isCompressed();
    76     int getBaseID();
     115    inline int32_t getID() const { return header_->getID(); }
     116    inline bool isDiffed() const { return header_->isDiffed(); }
     117    inline bool isCompressed() const { return header_->isCompressed(); }
     118    inline int32_t getBaseID() const { return header_->getBaseID(); }
    77119    Gamestate *diff(Gamestate *base);
    78     Gamestate* intelligentDiff(Gamestate *base, unsigned int clientID);
    79120    Gamestate *undiff(Gamestate *base);
    80     Gamestate* intelligentUnDiff(Gamestate *base);
    81     Gamestate* doSelection(unsigned int clientID);
     121    Gamestate* doSelection(unsigned int clientID, unsigned int targetSize);
    82122    bool compressData();
    83123    bool decompressData();
     
    85125    // Packet functions
    86126  private:
    87     virtual unsigned int getSize() const;
    88     virtual bool process();
     127    virtual uint32_t getSize() const;
     128    virtual inline bool process();
    89129
    90130    bool operator ==(packet::Gamestate gs);
    91131  private:
    92     unsigned int calcGamestateSize(unsigned int id, uint8_t mode=0x0);
    93     void removeObject(ObjectListIterator<Synchronisable> &it);
    94     std::map<unsigned int, Synchronisable*> dataMap_;
     132    uint32_t calcGamestateSize(int32_t id, uint8_t mode=0x0);
     133    std::list<obj> dataMap_;
     134    GamestateHeader* header_;
    95135};
    96136
  • code/trunk/src/network/packet/Packet.cc

    r2171 r2662  
    129129      return false;
    130130    }
    131     // Assures we don't create a packet and destroy it right after in another thread
    132     // without having a reference in the packetMap_
    133     boost::recursive_mutex::scoped_lock lock(Packet::packetMap_mutex);
    134131    // We deliver ENet the data address so that it doesn't memcpy everything again.
    135132    // --> We have to delete data_ ourselves!
     
    138135    // Add the packet to a global list so we can access it again once enet calls our
    139136    // deletePacket method. We can of course only give a one argument function to the ENet C library.
    140     packetMap_[(size_t)(void*)enetPacket_] = this;
     137    {
     138      // Assures we don't create a packet and destroy it right after in another thread
     139      // without having a reference in the packetMap_
     140      boost::recursive_mutex::scoped_lock lock(Packet::packetMap_mutex);
     141      packetMap_[(size_t)(void*)enetPacket_] = this;
     142    }
    141143  }
    142144#ifndef NDEBUG
  • code/trunk/src/network/packet/Welcome.cc

    r2171 r2662  
    3232#include "Welcome.h"
    3333#include "network/Host.h"
    34 #include "network/Synchronisable.h"
     34#include "network/synchronisable/Synchronisable.h"
    3535#include "core/CoreIncludes.h"
    3636#include <assert.h>
     
    4242#define _PACKETID             0
    4343#define _CLIENTID             _PACKETID + sizeof(ENUM::Type)
    44 #define _SHIPID               _CLIENTID + sizeof(uint32_t)
    45  
    46   Welcome::Welcome( unsigned int clientID, unsigned int shipID )
     44#define _ENDIANTEST           _CLIENTID + sizeof(uint32_t)
     45
     46  Welcome::Welcome( uint32_t clientID, uint32_t shipID )
    4747 : Packet()
    4848{
     
    5252  assert(data_);
    5353  *(packet::ENUM::Type *)(data_ + _PACKETID ) = packet::ENUM::Welcome;
    54   *(uint32_t *)&data_[ _CLIENTID ] = clientID;
    55   *(uint32_t *)&data_[ _SHIPID ] = shipID;
     54  *(uint32_t *)(data_ + _CLIENTID ) = static_cast<uint32_t>(clientID);
     55  *(uint32_t *)(data_ + _ENDIANTEST ) = 0xFEDC4321;
    5656}
    5757
    58 Welcome::Welcome( uint8_t* data, unsigned int clientID )
     58Welcome::Welcome( uint8_t* data, uint32_t clientID )
    5959  : Packet(data, clientID)
    6060{
     
    7474
    7575bool Welcome::process(){
    76   unsigned int shipID, clientID;
    77   clientID = *(uint32_t *)&data_[ _CLIENTID ];
    78   shipID = *(uint32_t *)&data_[ _SHIPID ];
     76  uint32_t clientID;
     77  clientID = *(uint32_t *)(data_ + _CLIENTID );
     78  assert(*(uint32_t *)(data_ + _ENDIANTEST ) == 0xFEDC4321);
    7979  Host::setClientID(clientID);
    80   Host::setShipID(shipID);
    81   COUT(3) << "Welcome set clientId: " << clientID << " shipID: " << shipID << std::endl;
     80  COUT(3) << "Welcome set clientId: " << clientID << endl;
    8281  Synchronisable::setClient(true);
    8382  delete this;
  • code/trunk/src/network/packet/Welcome.h

    r2171 r2662  
    4242{
    4343public:
    44   Welcome( unsigned int clientID, unsigned int shipID );
    45   Welcome( uint8_t* data, unsigned int clientID );
     44  Welcome( uint32_t clientID, uint32_t shipID );
     45  Welcome( uint8_t* data, uint32_t clientID );
    4646  virtual ~Welcome();
    4747
  • code/trunk/src/network/synchronisable/NetworkCallback.h

    • Property svn:mergeinfo changed (with no actual effect on merging)
  • code/trunk/src/network/synchronisable/Synchronisable.cc

    r2653 r2662  
    2828 */
    2929
    30 //
    31 // C++ Implementation: synchronisable
    32 //
    33 // Description:
    34 //
    35 //
    36 // Author:  Dumeni, Oliver Scheuss, (C) 2007
    37 //
    38 // Copyright: See COPYING file that comes with this distribution
    39 //
    4030
    4131#include "Synchronisable.h"
     
    155145  Synchronisable *Synchronisable::fabricate(uint8_t*& mem, uint8_t mode)
    156146  {
    157     synchronisableHeader *header = (synchronisableHeader *)mem;
    158 
    159     if(!header->dataAvailable)
    160     {
    161       mem += header->size;
     147    SynchronisableHeader header(mem);
     148
     149    if(!header.isDataAvailable())
     150    {
     151      mem += header.getDataSize();
    162152      return 0;
    163153    }
    164154
    165     COUT(4) << "fabricating object with id: " << header->objectID << std::endl;
    166 
    167     Identifier* id = ClassByID(header->classID);
     155    COUT(4) << "fabricating object with id: " << header.getObjectID() << std::endl;
     156
     157    Identifier* id = ClassByID(header.getClassID());
    168158    if (!id)
    169159    {
     
    174164    assert(id);
    175165    BaseObject* creator = 0;
    176     if (header->creatorID != OBJECTID_UNKNOWN)
    177     {
    178       Synchronisable* synchronisable_creator = Synchronisable::getSynchronisable(header->creatorID);
     166    if (header.getCreatorID() != OBJECTID_UNKNOWN)
     167    {
     168      Synchronisable* synchronisable_creator = Synchronisable::getSynchronisable(header.getCreatorID());
    179169      if (!synchronisable_creator)
    180170      {
    181         mem += header->size; //.TODO: this suckz.... remove size from header
    182 //         assert(0); // TODO: uncomment this if we have a clean objecthierarchy (with destruction of children of objects) ^^
     171        mem += header.getDataSize(); //.TODO: this suckz.... remove size from header
     172        assert(0); // TODO: uncomment this if we have a clean objecthierarchy (with destruction of children of objects) ^^
    183173        return 0;
    184174      }
     
    186176        creator = dynamic_cast<BaseObject*>(synchronisable_creator);
    187177    }
    188     assert(getSynchronisable(header->objectID)==0);   //make sure no object with this id exists
     178    assert(getSynchronisable(header.getObjectID())==0);   //make sure no object with this id exists
    189179    BaseObject *bo = id->fabricate(creator);
    190180    assert(bo);
    191181    Synchronisable *no = dynamic_cast<Synchronisable *>(bo);
    192182    assert(no);
    193     no->objectID=header->objectID;
    194     no->creatorID=header->creatorID; //TODO: remove this
    195     no->classID=header->classID;
     183    no->objectID=header.getObjectID();
     184    no->creatorID=header.getCreatorID(); //TODO: remove this
     185    no->classID=header.getClassID();
    196186    COUT(4) << "fabricate objectID: " << no->objectID << " classID: " << no->classID << std::endl;
    197187          // update data and create object/entity...
     
    329319
    330320    // start copy header
    331     synchronisableHeader *header = (synchronisableHeader *)mem;
    332     header->size = size;
    333     header->objectID = this->objectID;
    334     header->creatorID = this->creatorID;
    335     header->classID = this->classID;
    336     header->dataAvailable = true;
    337     tempsize += sizeof(synchronisableHeader);
    338     mem += sizeof(synchronisableHeader);
     321    SynchronisableHeader header(mem);
     322    header.setDataSize( size );
     323    header.setObjectID( this->objectID );
     324    header.setCreatorID( this->creatorID );
     325    header.setClassID( this->classID );
     326    header.setDataAvailable( true );
     327    tempsize += SynchronisableHeader::getSize();
     328    mem += SynchronisableHeader::getSize();
    339329    // end copy header
    340330
     
    371361    uint8_t* data=mem;
    372362    // start extract header
    373     synchronisableHeader *syncHeader = (synchronisableHeader *)mem;
    374     assert(syncHeader->objectID==this->objectID);
    375     assert(syncHeader->creatorID==this->creatorID);
    376     assert(this->classID==syncHeader->classID); //TODO: fix this!!! maybe a problem with the identifier ?
    377     if(syncHeader->dataAvailable==false){
    378       mem += syncHeader->size;
     363    SynchronisableHeader syncHeader(mem);
     364    assert(syncHeader.getObjectID()==this->objectID);
     365    assert(syncHeader.getCreatorID()==this->creatorID);
     366    assert(syncHeader.getClassID()==this->classID);
     367    if(syncHeader.isDataAvailable()==false){
     368      mem += syncHeader.getDataSize();
    379369      return true;
    380370    }
    381371
    382     mem += sizeof(synchronisableHeader);
     372    mem += SynchronisableHeader::getSize();
    383373    // stop extract header
    384374
    385     COUT(5) << "Synchronisable: objectID " << syncHeader->objectID << ", classID " << syncHeader->classID << " size: " << syncHeader->size << " synchronising data" << std::endl;
    386     for(i=syncList.begin(); i!=syncList.end() && mem <= data+syncHeader->size; i++)
    387     {
     375    //COUT(5) << "Synchronisable: objectID " << syncHeader.getObjectID() << ", classID " << syncHeader.getClassID() << " size: " << syncHeader.getDataSize() << " synchronising data" << std::endl;
     376    for(i=syncList.begin(); i!=syncList.end(); i++)
     377    {
     378      assert( mem <= data+syncHeader.getDataSize() ); // always make sure we don't exceed the datasize in our stream
    388379      (*i)->putData( mem, mode, forceCallback );
    389380    }
    390     assert(mem == data+syncHeader->size);
     381    assert(mem == data+syncHeader.getDataSize());
    391382    return true;
    392383  }
     
    399390  */
    400391  uint32_t Synchronisable::getSize(int32_t id, uint8_t mode){
    401     int tsize=sizeof(synchronisableHeader);
     392    int tsize=SynchronisableHeader::getSize();
    402393    if(mode==0x0)
    403394      mode=state_;
     
    428419  bool Synchronisable::isMyData(uint8_t* mem)
    429420  {
    430     synchronisableHeader *header = (synchronisableHeader *)mem;
    431     assert(header->objectID==this->objectID);
    432     return header->dataAvailable;
     421    SynchronisableHeader header(mem);
     422    assert(header.getObjectID()==this->objectID);
     423    return header.isDataAvailable();
    433424  }
    434425
  • code/trunk/src/network/synchronisable/Synchronisable.h

    r2653 r2662  
    7272  }
    7373
    74   struct _NetworkExport synchronisableHeader{
    75     uint32_t size:31;
    76     bool dataAvailable:1;
    77     uint32_t objectID;
    78     uint32_t creatorID;
    79     uint32_t classID;
     74  /**
     75   * @brief: stores information about a Synchronisable
     76   *
     77   * This class stores the information about a Synchronisable (objectID, classID, creatorID, dataSize)
     78   * in an emulated bitset.
     79   * Bit 1 to 31 store the size of the Data the synchronisable consumes in the stream
     80   * Bit 32 is a bool and defines whether the data is actually stored or is just filled up with 0
     81   * Byte 5 to 8: objectID
     82   * Byte 9 to 12: classID
     83   * Byte 13 to 16: creatorID
     84   */
     85  class _NetworkExport SynchronisableHeader{
     86    private:
     87      uint8_t *data_;
     88    public:
     89      SynchronisableHeader(uint8_t* data)
     90        { data_ = data; }
     91      inline static uint32_t getSize()
     92        { return 16; }
     93      inline uint32_t getDataSize() const
     94        { return (*(uint32_t*)data_) & 0x7FFFFFFF; } //only use the first 31 bits
     95      inline void setDataSize(uint32_t size)
     96        { *(uint32_t*)(data_) = (size & 0x7FFFFFFF) | (*(uint32_t*)(data_) & 0x80000000 ); }
     97      inline bool isDataAvailable() const
     98        { return ( (*(uint32_t*)data_) & 0x80000000 ) == 0x80000000; }
     99      inline void setDataAvailable( bool b)
     100        { *(uint32_t*)(data_) = (b << 31) | (*(uint32_t*)(data_) & 0x7FFFFFFF ); }
     101      inline uint32_t getObjectID() const
     102        { return *(uint32_t*)(data_+4); }
     103      inline void setObjectID(uint32_t objectID)
     104        { *(uint32_t*)(data_+4) = objectID; }
     105      inline uint32_t getClassID() const
     106        { return *(uint32_t*)(data_+8); }
     107      inline void setClassID(uint32_t classID)
     108        { *(uint32_t*)(data_+8) = classID; }
     109      inline uint32_t getCreatorID() const
     110        { return *(uint32_t*)(data_+12); }
     111      inline void setCreatorID(uint32_t creatorID)
     112        { *(uint32_t*)(data_+12) = creatorID; }
     113      inline void operator=(SynchronisableHeader& h)
     114        { memcpy(data_, h.data_, getSize()); }
    80115  };
    81116
     
    83118  /**
    84119  * This class is the base class of all the Objects in the universe that need to be synchronised over the network
    85    * Every class, that inherits from this class has to link the DATA THAT NEEDS TO BE SYNCHRONISED into the linked list.
     120  * Every class, that inherits from this class has to link the DATA THAT NEEDS TO BE SYNCHRONISED into the linked list.
    86121  * @author Oliver Scheuss
    87122  */
Note: See TracChangeset for help on using the changeset viewer.