Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

Ignore:
Timestamp:
Nov 1, 2008, 7:04:09 PM (16 years ago)
Author:
landauf
Message:

merged objecthierarchy branch back to trunk

Location:
code/trunk
Files:
33 edited
4 copied

Legend:

Unmodified
Added
Removed
  • code/trunk

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

    r1907 r2087  
    11SET( NETWORK_SRC_FILES
     2  ChatListener.cc
    23  Client.cc
    34  ClientConnection.cc
    45  ClientInformation.cc
     6  ClientConnectionListener.cc
    57  ConnectionManager.cc
    68  GamestateManager.cc
  • code/trunk/src/network/Client.cc

    r1907 r2087  
    3939//
    4040
     41#include <cassert>
     42
    4143#include "Client.h"
    4244#include "Host.h"
     
    4446#include "core/CoreIncludes.h"
    4547#include "packet/Packet.h"
     48
    4649// #include "packet/Acknowledgement.h"
    4750
     
    6770  * @param port port of the application on the server
    6871  */
    69   Client::Client(std::string address, int port) : client_connection(port, address){
     72  Client::Client(const std::string& address, int port) : client_connection(port, address){
    7073    isConnected=false;
    7174    isSynched_=false;
     
    114117  }
    115118
    116   bool Client::processChat(std::string message, unsigned int playerID){
    117     COUT(1) << "Player " << playerID << ": " << message << std::endl;
     119  bool Client::processChat(const std::string& message, unsigned int playerID){
     120//    COUT(1) << "Player " << playerID << ": " << message << std::endl;
    118121    return true;
    119122  }
    120  
     123
    121124  /**
    122125   * This function implements the method of sending a chat message to the server
    123    * @param message message to be sent 
     126   * @param message message to be sent
    124127   * @return result(true/false)
    125128   */
    126   bool Client::chat(std::string message){
     129  bool Client::chat(const std::string& message){
    127130    packet::Chat *m = new packet::Chat(message, Host::getPlayerID());
    128131    return m->send();
     
    132135  /**
    133136   * Processes incoming packets, sends a gamestate to the server and does the cleanup
    134    * @param time 
     137   * @param time
    135138   */
    136139  void Client::tick(float time){
     
    152155      COUT(5) << "tick packet size " << event->packet->dataLength << std::endl;
    153156      packet::Packet *packet = packet::Packet::createPacket(event->packet, event->peer);
     157      // note: packet commits suicide here except for the GameState. That is then deleted by a GamestateHandler
    154158      bool b = packet->process();
    155159      assert(b);
  • code/trunk/src/network/Client.h

    r1907 r2087  
    6666  public:
    6767    Client();
    68     Client(std::string address, int port);
     68    Client(const std::string& address, int port);
    6969    Client(const char *address, int port);
    7070    ~Client();
    71    
     71
    7272    bool establishConnection();
    7373    bool closeConnection();
    7474    bool queuePacket(ENetPacket *packet, int clientID);
    75     bool processChat(std::string message, unsigned int playerID);
    76     virtual bool chat(std::string message);
     75    bool processChat(const std::string& message, unsigned int playerID);
     76    virtual bool chat(const std::string& message);
     77    virtual bool broadcast(const std::string& message) { return false; }
    7778    //bool sendChat(packet::Chat *chat);
    78    
    79 //    static void Chat( std::string message );
    80    
    81     //static void setShipID( unsigned int shipID){ dynamic_cast<Client *>(instance_)->shipID_=shipID; }
    82     static void setClientID( unsigned int clientID){ dynamic_cast<Client *>(instance_)->clientID_=clientID; }
    83    
     79
    8480    void tick(float time);
    8581
    8682  private:
    8783    virtual bool isServer_(){return false;}
    88    
     84
    8985    ClientConnection client_connection;
    9086    GamestateClient gamestate;
    9187    bool isConnected;
    9288    bool isSynched_;
    93    
     89
    9490    bool gameStateFailure_;
    9591  };
  • code/trunk/src/network/ClientConnection.cc

    r1907 r2087  
    5454  boost::recursive_mutex ClientConnection::enet_mutex_;
    5555
    56   ClientConnection::ClientConnection(int port, std::string address) {
     56  ClientConnection::ClientConnection(int port, const std::string& address) {
    5757    quit=false;
    5858    server=NULL;
     
    7272  bool ClientConnection::waitEstablished(int milisec) {
    7373    for(int i=0; i<=milisec && !established; i++)
    74       usleep(1000);
     74      msleep(1);
    7575
    7676    return established;
     
    184184      case ENET_EVENT_TYPE_NONE:
    185185        //receiverThread_->yield();
    186         usleep(1000);
     186        msleep(1);
    187187        break;
    188188      }
  • code/trunk/src/network/ClientConnection.h

    r1907 r2087  
    6060
    6161
    62   class ClientConnection{
     62  class _NetworkExport ClientConnection{
    6363  public:
    64     ClientConnection(int port, std::string address);
     64    ClientConnection(int port, const std::string& address);
    6565    ClientConnection(int port, const char* address);
    6666    ~ClientConnection();
     
    9696    ENetPeer *server;
    9797    boost::thread *receiverThread_;
    98    
     98
    9999    static boost::recursive_mutex enet_mutex_;
    100100  };
  • code/trunk/src/network/ClientInformation.cc

    r1735 r2087  
    4545namespace network
    4646{
    47  
     47
    4848  ClientInformation *ClientInformation::head_=0;
    49  
     49
    5050  ClientInformation::ClientInformation() {
    5151    if(!head_)
     
    5959
    6060  ClientInformation::~ClientInformation() {
    61     if(this==head_)
    62       head_=next();
    6361    if(prev()!=0)
    6462      prev()->setNext(this->next());
    6563    if(next()!=0)
    6664      next()->setPrev(this->prev());
     65    if(this==head_)
     66      head_=next();
    6767  }
    6868
     
    129129    return true;
    130130  }
    131  
     131
    132132  bool ClientInformation::setPartialGamestateID(int id){
    133133    if(!this)
     
    137137  }
    138138
    139   int ClientInformation::getID() {
     139  unsigned int ClientInformation::getID() {
    140140    if(!this)
    141141      return CLIENTID_UNKNOWN;
     
    150150      return NULL;
    151151  }
    152  
     152
    153153  int ClientInformation::getFailures(){
    154154    return failures_;
     
    160160    failures_=0;
    161161  }
    162  
     162
    163163  enet_uint32 ClientInformation::getRTT(){
    164     return peer_->roundTripTime;
    165   }
    166  
    167   enet_uint32 ClientInformation::getPacketLoss(){
    168     return peer_->packetLoss;
    169   }
    170 
    171   int ClientInformation::getGamestateID() {
     164    return this->peer_->roundTripTime;
     165  }
     166
     167  double ClientInformation::getPacketLoss(){
     168    return ((double)this->peer_->packetLoss)/ENET_PEER_PACKET_LOSS_SCALE;
     169  }
     170
     171  unsigned int ClientInformation::getGamestateID() {
    172172    if(this)
    173173      return gamestateID_;
    174174    else
    175       return -1;
    176   }
    177  
    178   int ClientInformation::getPartialGamestateID() {
     175      return (unsigned int)-1;
     176  }
     177
     178  unsigned int ClientInformation::getPartialGamestateID() {
    179179    if(this)
    180180      return partialGamestateID_;
    181181    else
    182       return -1;
     182      return (unsigned int)-1;
    183183  }
    184184
    185185  ClientInformation *ClientInformation::insertBack(ClientInformation *ins) {
    186186    ClientInformation *temp = head_;
    187     if(temp==head_){
     187    if(temp==ins){
    188188      return head_;
    189189    }
     
    196196  }
    197197
    198   bool ClientInformation::removeClient(int clientID) {
    199     if(clientID==CLIENTID_UNKNOWN)
     198  bool ClientInformation::removeClient(unsigned int clientID) {
     199    if((unsigned int)clientID==CLIENTID_UNKNOWN)
    200200      return false;
    201201    ClientInformation *temp = head_;
     
    229229  * @return pointer to the last element in the list or 0 if the search was unsuccessfull
    230230  */
    231   ClientInformation *ClientInformation::findClient(int clientID, bool look_backwards) {
     231  ClientInformation *ClientInformation::findClient(unsigned int clientID, bool look_backwards) {
    232232    ClientInformation *temp = head_;
    233233    while(temp!=0 && temp->getID()!=clientID){
  • code/trunk/src/network/ClientInformation.h

    r1735 r2087  
    4646#include <boost/thread/recursive_mutex.hpp>
    4747
    48 #define GAMESTATEID_INITIAL -1
    49 #define CLIENTID_UNKNOWN -2
    50 
    5148// WATCH OUT: THE CLIENTINFORMATION LIST IS NOT THREADSAFE ANYMORE
    5249
    5350namespace network
    5451{
     52  static const unsigned int GAMESTATEID_INITIAL = (unsigned int)-1;
     53  static const unsigned int CLIENTID_UNKNOWN = (unsigned int)-2;
     54
    5555  /**
    5656  * This class implements a list for client informations
    5757  * @author Oliver Scheuss
    5858  */
    59   class ClientInformation{
     59  class _NetworkExport ClientInformation{
    6060  public:
    6161    ClientInformation();
     
    6666    ClientInformation *prev();
    6767    static ClientInformation *insertBack(ClientInformation *ins);
    68    
     68
    6969    // set functions
    7070    void setID(int clientID);
     
    7373    bool setPartialGamestateID(int id);
    7474    inline void setShipID(unsigned int id){ShipID_=id;}
    75    
     75
    7676    // get functions
    7777    inline unsigned int getShipID(){return ShipID_;}
    78     int getID();
    79     int getGamestateID();
    80     int getPartialGamestateID();
     78    unsigned int getID();
     79    unsigned int getGamestateID();
     80    unsigned int getPartialGamestateID();
    8181    ENetPeer *getPeer();
    82    
     82
    8383    int getFailures();
    8484    void addFailure();
    8585    void resetFailures();
    8686    enet_uint32 getRTT();
    87     enet_uint32 getPacketLoss();
    88    
    89     static bool removeClient(int clientID);
     87    double getPacketLoss();
     88
     89    static bool removeClient(unsigned int clientID);
    9090    static bool removeClient(ENetPeer *peer);
    91     static ClientInformation *findClient(int clientID, bool look_backwards=false);
     91    static ClientInformation *findClient(unsigned int clientID, bool look_backwards=false);
    9292    static ClientInformation *findClient(ENetAddress *address, bool look_backwards=false);
    9393    static ClientInformation *getBegin(){return head_;}
     
    9999  private:
    100100    static ClientInformation *head_;
    101    
     101
    102102    bool setNext(ClientInformation *next);
    103103    bool setPrev(ClientInformation *prev);
    104104    ClientInformation *insertAfter(ClientInformation *ins);
    105105    ClientInformation *insertBefore(ClientInformation *ins);
    106    
     106
    107107    ClientInformation *preve;
    108108    ClientInformation *nexte;
    109109    //actual information:
    110110    ENetPeer *peer_;
    111     int clientID_;
    112     int gamestateID_;
    113     int partialGamestateID_;
     111    unsigned int clientID_;
     112    unsigned int gamestateID_;
     113    unsigned int partialGamestateID_;
    114114    unsigned int ShipID_;   // this is the unique objectID
    115115    bool synched_;
    116116    unsigned short failures_;
    117    
     117
    118118  };
    119119
  • code/trunk/src/network/ConnectionManager.cc

    r1907 r2087  
    4949#include "core/BaseObject.h"
    5050#include "core/Iterator.h"
    51 #include "objects/SpaceShip.h"
    5251#include "util/Math.h"
    5352#include "util/Sleep.h"
     
    8988  }
    9089
    91   ConnectionManager::ConnectionManager(int port, std::string address) :receiverThread_(0) {
     90  ConnectionManager::ConnectionManager(int port, const std::string& address) :receiverThread_(0) {
    9291    assert(instance_==0);
    9392    instance_=this;
     
    228227        case ENET_EVENT_TYPE_NONE:
    229228          //receiverThread_->yield();
    230           usleep(1000);
     229          msleep(1);
    231230          break;
    232231      }
     
    331330
    332331
    333 
    334   bool ConnectionManager::removeShip(ClientInformation *client){
    335     unsigned int id=client->getShipID();
    336     orxonox::ObjectList<orxonox::SpaceShip>::iterator it;
    337     for(it = orxonox::ObjectList<orxonox::SpaceShip>::begin(); it; ++it){
    338       if(it->getObjectID()!=id)
    339         continue;
    340       delete *it;
    341     }
    342     return true;
    343   }
    344 
    345 
    346332  void ConnectionManager::disconnectClient(ClientInformation *client){
    347333    {
     
    350336      lock.unlock();
    351337    }
    352     removeShip(client);
    353338  }
    354339
  • code/trunk/src/network/ConnectionManager.h

    r1785 r2087  
    6666    const int NETWORK_DEFAULT_CHANNEL = 0;
    6767
    68   struct ClientList{
     68  struct _NetworkExport ClientList{
    6969    ENetEvent *event;
    7070    int ID;
     
    7272  };
    7373
    74   class ConnectionManager{
     74  class _NetworkExport ConnectionManager{
    7575    public:
    7676    static boost::recursive_mutex enet_mutex;
     
    7979    ConnectionManager(int port);
    8080    ConnectionManager(int port, const char *address);
    81     ConnectionManager(int port, std::string address);
     81    ConnectionManager(int port, const std::string& address);
    8282    ~ConnectionManager();
    8383    //ENetPacket *getPacket(ENetAddress &address); // thread1
     
    107107    int getClientID(ENetAddress address);
    108108    ENetPeer *getClientPeer(int clientID);
    109     //bool createShip(ClientInformation *client);
    110     bool removeShip(ClientInformation *client);
    111109    PacketBuffer buffer;
    112110
  • code/trunk/src/network/GamestateClient.cc

    r1907 r2087  
    2929#include "GamestateClient.h"
    3030
     31#include <cassert>
    3132#include <zlib.h>
    3233
     
    4041namespace network
    4142{
    42   struct GameStateItem{
     43  struct _NetworkExport GameStateItem{
    4344    packet::Gamestate *state;
    44     int id;
     45    unsigned int id;
    4546  };
    4647
     
    5051    last_gamestate_=GAMESTATEID_INITIAL-1;
    5152    tempGamestate_=NULL;
    52     myShip_=NULL;
    5353  }
    5454
     
    5656  }
    5757
    58   bool GamestateClient::ack(int gamestateID, int clientID){
     58  bool GamestateClient::ack(unsigned int gamestateID, unsigned int clientID){
    5959    return true;
    6060  }
    6161
    62   bool GamestateClient::add(packet::Gamestate *gs, int clientID){
     62  bool GamestateClient::add(packet::Gamestate *gs, unsigned int clientID){
    6363    if(tempGamestate_!=NULL){
    6464      //delete the obsolete gamestate
     
    7575      return false;
    7676    int id = GAMESTATEID_INITIAL;
    77     bool b = saveShipCache();
    7877    packet::Gamestate *processed = processGamestate(tempGamestate_);
    79     if(!processed){
    80       if(b)
    81         loadShipCache();
    82       return false;
    83     }
    8478//    assert(processed);
     79    if (!processed)
     80        return false;
    8581    //successfully loaded data from gamestate. now save gamestate for diff and delete the old gs
    8682    tempGamestate_=NULL;
    8783    gamestateMap_[processed->getID()]=processed;
    8884    last_diff_ = processed->getID();
    89     if(b)
    90       loadShipCache();
    9185    id = processed->getID();
    9286    sendAck(id);
     
    108102  packet::Gamestate *GamestateClient::getGamestate(){
    109103    packet::Gamestate *gs = new packet::Gamestate();
    110     gs->collectData(0);
     104    if(!gs->collectData(0)){
     105      delete gs;
     106      return 0;
     107    }
    111108    return gs;
    112109  }
    113110
    114111  void GamestateClient::cleanup(){
    115     std::map<int, packet::Gamestate*>::iterator temp, it = gamestateMap_.begin();
     112    std::map<unsigned int, packet::Gamestate*>::iterator temp, it = gamestateMap_.begin();
    116113    while(it!=gamestateMap_.end()){
    117114      if(it->first>=last_diff_)
     
    126123
    127124  void GamestateClient::printGamestateMap(){
    128     std::map<int, packet::Gamestate*>::iterator it;
     125    std::map<unsigned int, packet::Gamestate*>::iterator it;
    129126    COUT(4) << "gamestates: ";
    130127    for(it=gamestateMap_.begin(); it!=gamestateMap_.end(); it++){
     
    134131
    135132  }
    136  
     133
    137134  bool GamestateClient::sendAck(unsigned int gamestateID){
    138135    packet::Acknowledgement *ack = new packet::Acknowledgement(gamestateID, 0);
     
    142139    }
    143140    else{
    144       COUT(3) << "acked a gamestate: " << gamestateID << std::endl;
     141      COUT(5) << "acked a gamestate: " << gamestateID << std::endl;
    145142      return true;
    146143    }
    147   }
    148 
    149   bool GamestateClient::saveShipCache(){
    150     if(myShip_==NULL){
    151       myShip_ = orxonox::SpaceShip::getLocalShip();
    152 //      COUT(2) << "myShip_: " << myShip_ << " getLocalShip(): " << orxonox::SpaceShip::getLocalShip() << std::endl;
    153       if(!myShip_)
    154         return false;
    155     }
    156     if(myShip_){
    157       //      unsigned char *data = new unsigned char[myShip_->getSize()];
    158       int size=myShip_->getSize(0, 0x1);
    159       if(size==0)
    160         return false;
    161       shipCache_ = new unsigned char [size];
    162       unsigned char *temp = shipCache_;
    163       if(!myShip_->getData(temp, 0, 0x1))
    164         COUT(3) << "could not save shipCache" << std::endl;
    165       return true;
    166     }else
    167       return false;
    168   }
    169 
    170   bool GamestateClient::loadShipCache(){
    171     myShip_=orxonox::SpaceShip::getLocalShip(); //TODO: remove this (only a hack)
    172     if(myShip_ && shipCache_){
    173       assert(myShip_->getIdentifier());
    174       unsigned char *temp = shipCache_;
    175       myShip_->updateData(temp, 0x2);
    176       delete shipCache_;
    177       return true;
    178     }else
    179       return false;
    180144  }
    181145
     
    196160      delete gs;
    197161      gs=undiffed;
    198       COUT(3) << "successfully undiffed gamestate id: " << undiffed->getID() << std::endl;
     162      COUT(5) << "successfully undiffed gamestate id: " << undiffed->getID() << std::endl;
    199163    }
    200164    if(gs->spreadData())
  • code/trunk/src/network/GamestateClient.h

    r1769 r2087  
    4646#include "core/CorePrereqs.h"
    4747#include "packet/Gamestate.h"
    48 #include "objects/SpaceShip.h"
    4948#include "GamestateHandler.h"
    5049
    51 #define GAMESTATEID_INITIAL -1
     50const unsigned int GAMESTATEID_INITIAL = (unsigned int)-1;
    5251
    5352namespace network
    5453{
    55   class GamestateClient: public GamestateHandler
     54  class _NetworkExport GamestateClient: public GamestateHandler
    5655  {
    5756  public:
     
    5958    ~GamestateClient();
    6059
    61     bool add(packet::Gamestate *gs, int clientID);
    62     bool ack(int gamestateID, int clientID);
     60    bool add(packet::Gamestate *gs, unsigned int clientID);
     61    bool ack(unsigned int gamestateID, unsigned int clientID);
    6362
    6463    bool processGamestates();
     
    7069    void printGamestateMap();
    7170    bool sendAck(unsigned int gamestateID);
    72     bool saveShipCache();
    73     bool loadShipCache();
    7471
    75     int           last_diff_;
    76     int           last_gamestate_;
    77     std::map<int, packet::Gamestate *> gamestateMap_;
     72    unsigned int           last_diff_;
     73    unsigned int           last_gamestate_;
     74    std::map<unsigned int, packet::Gamestate *> gamestateMap_;
    7875    packet::Gamestate *tempGamestate_; // we save the received gamestates here during processQueue
    79     orxonox::SpaceShip *myShip_;
    8076    unsigned char *shipCache_;
    8177
  • code/trunk/src/network/GamestateHandler.h

    r1763 r2087  
    3939        @author Oliver Scheuss
    4040*/
    41 class GamestateHandler{
     41class _NetworkExport GamestateHandler{
    4242  private:
    43     virtual bool add(packet::Gamestate *gs, int clientID)=0;
    44     virtual bool ack(int gamestateID, int clientID)=0;
     43    virtual bool add(packet::Gamestate *gs, unsigned int clientID)=0;
     44    virtual bool ack(unsigned int gamestateID, unsigned int clientID)=0;
    4545
    4646    static GamestateHandler *instance_;
     
    5252
    5353  public:
    54     static bool addGamestate(packet::Gamestate *gs, int clientID){ return instance_->add(gs, clientID); }
    55     static bool ackGamestate(int gamestateID, int clientID){ return instance_->ack(gamestateID, clientID); }
     54    static bool addGamestate(packet::Gamestate *gs, unsigned int clientID){ return instance_->add(gs, clientID); }
     55    static bool ackGamestate(unsigned int gamestateID, unsigned int clientID){ return instance_->ack(gamestateID, clientID); }
    5656};
    5757
  • code/trunk/src/network/GamestateManager.cc

    r1907 r2087  
    6464    return getSnapshot();
    6565  }
    66  
    67   bool GamestateManager::add(packet::Gamestate *gs, int clientID){
     66
     67  bool GamestateManager::add(packet::Gamestate *gs, unsigned int clientID){
    6868    assert(gs);
    69     std::map<int, packet::Gamestate*>::iterator it = gamestateQueue.find(clientID);
     69    std::map<unsigned int, packet::Gamestate*>::iterator it = gamestateQueue.find(clientID);
    7070    if(it!=gamestateQueue.end()){
    7171      // delete obsolete gamestate
     
    7575    return true;
    7676  }
    77  
     77
    7878  bool GamestateManager::processGamestates(){
    79     std::map<int, packet::Gamestate*>::iterator it;
     79    std::map<unsigned int, packet::Gamestate*>::iterator it;
    8080    // now push only the most recent gamestates we received (ignore obsolete ones)
    8181    for(it = gamestateQueue.begin(); it!=gamestateQueue.end(); it++){
    82       assert(processGamestate(it->second));
     82      bool b = processGamestate(it->second);
     83      assert(b);
    8384      delete it->second;
    8485    }
     
    8788    return true;
    8889  }
    89  
    90  
     90
     91
    9192  bool GamestateManager::getSnapshot(){
    9293    reference = new packet::Gamestate();
    93     reference->collectData(++id_);
    94     //COUT(4) << "inserting gamestate: " << reference << std::endl;
    95     //gamestateMap_.insert(std::pair<int, packet::Gamestate*>(id_, reference));
    96 //     gamestateUsed[id_]=0;
    97     return true;
    98   }
    99  
     94    if(!reference->collectData(++id_)){ //we have no data to send
     95      delete reference;
     96      reference=0;
     97    }
     98    return true;
     99  }
     100
    100101  /**
    101102   * this function is used to keep the memory usage low
    102103   * it tries to delete all the unused gamestates
    103    * 
    104    * 
     104   *
     105   *
    105106   */
    106107/*  void GamestateManager::cleanup(){
     
    126127  }*/
    127128
    128   packet::Gamestate *GamestateManager::popGameState(int clientID) {
     129  packet::Gamestate *GamestateManager::popGameState(unsigned int clientID) {
    129130    //why are we searching the same client's gamestate id as we searched in
    130131    //Server::sendGameState?
    131132    packet::Gamestate *gs;
    132     int gID = ClientInformation::findClient(clientID)->getGamestateID();
     133    unsigned int gID = ClientInformation::findClient(clientID)->getGamestateID();
     134    if(!reference)
     135      return 0;
    133136    gs = reference->doSelection(clientID);
    134137//     gs = new packet::Gamestate(*reference);
     
    139142    packet::Gamestate *client=NULL;
    140143    if(gID != GAMESTATEID_INITIAL){
    141       std::map<unsigned int, std::map<int, packet::Gamestate*> >::iterator clientMap = gamestateMap_.find(clientID);
     144      std::map<unsigned int, std::map<unsigned int, packet::Gamestate*> >::iterator clientMap = gamestateMap_.find(clientID);
    142145      if(clientMap!=gamestateMap_.end()){
    143         std::map<int, packet::Gamestate*>::iterator it = clientMap->second.find(gID);
     146        std::map<unsigned int, packet::Gamestate*>::iterator it = clientMap->second.find(gID);
    144147        if(it!=clientMap->second.end())
    145148          client = it->second;
     
    158161    return gs;
    159162  }
    160  
    161  
    162   bool GamestateManager::ack(int gamestateID, int clientID) {
     163
     164
     165  bool GamestateManager::ack(unsigned int gamestateID, unsigned int clientID) {
    163166    ClientInformation *temp = ClientInformation::findClient(clientID);
    164167    assert(temp);
    165     int curid = temp->getGamestateID();
    166    
     168    unsigned int curid = temp->getGamestateID();
     169
    167170    if(gamestateID == 0){
    168171      temp->setGamestateID(GAMESTATEID_INITIAL);
    169172      return true;
    170173    }
    171    
    172     assert(curid<gamestateID);
     174
     175    assert(curid==(unsigned int)GAMESTATEID_INITIAL || curid<gamestateID);
    173176    COUT(4) << "acking gamestate " << gamestateID << " for clientid: " << clientID << " curid: " << curid << std::endl;
    174     std::map<int, packet::Gamestate*>::iterator it, tempit;
     177    std::map<unsigned int, packet::Gamestate*>::iterator it, tempit;
    175178    for(it = gamestateMap_[clientID].begin(); it!=gamestateMap_[clientID].end() && it->first<gamestateID; it++){
    176179      delete it->second;
     
    184187  void GamestateManager::removeClient(ClientInformation* client){
    185188    assert(client);
    186     std::map<unsigned int, std::map<int, packet::Gamestate*> >::iterator clientMap = gamestateMap_.find(client->getID());
     189    std::map<unsigned int, std::map<unsigned int, packet::Gamestate*> >::iterator clientMap = gamestateMap_.find(client->getID());
    187190    // first delete all remained gamestates
    188     std::map<int, packet::Gamestate*>::iterator it;
     191    std::map<unsigned int, packet::Gamestate*>::iterator it;
    189192    for(it=clientMap->second.begin(); it!=clientMap->second.end(); it++)
    190193      delete it->second;
     
    192195    gamestateMap_.erase(clientMap);
    193196  }
    194  
     197
    195198  bool GamestateManager::processGamestate(packet::Gamestate *gs){
    196199    if(gs->isCompressed())
  • code/trunk/src/network/GamestateManager.h

    r1907 r2087  
    6666  * @author Oliver Scheuss
    6767  */
    68   class GamestateManager: public GamestateHandler{
     68  class _NetworkExport GamestateManager: public GamestateHandler{
    6969  public:
    7070    GamestateManager();
    7171    ~GamestateManager();
    7272
    73     bool add(packet::Gamestate *gs, int clientID);
     73    bool add(packet::Gamestate *gs, unsigned int clientID);
    7474    bool processGamestates();
    7575    bool update();
    76     packet::Gamestate *popGameState(int clientID);
     76    packet::Gamestate *popGameState(unsigned int clientID);
    7777
    7878    bool getSnapshot();
    7979
    80     bool ack(int gamestateID, int clientID);
     80    bool ack(unsigned int gamestateID, unsigned int clientID);
    8181    void removeClient(ClientInformation *client);
    8282    private:
     
    8484    bool processGamestate(packet::Gamestate *gs);
    8585
    86     std::map<unsigned int, std::map<int, packet::Gamestate*> > gamestateMap_;
     86    std::map<unsigned int, std::map<unsigned int, packet::Gamestate*> > gamestateMap_;
    8787    //std::map<int, packet::Gamestate*> gamestateMap; //map gsID to gamestate*
    8888    //std::map<int, int> gamestateUsed; // save the number of clients, that use the specific gamestate
    89     std::map<int, packet::Gamestate*> gamestateQueue;
     89    std::map<unsigned int, packet::Gamestate*> gamestateQueue;
    9090    packet::Gamestate *reference;
    91     int id_;
     91    unsigned int id_;
    9292  };
    9393
  • code/trunk/src/network/Host.cc

    r1907 r2087  
    3232#include "core/ConsoleCommand.h"
    3333#include "packet/Packet.h"
     34#include "ChatListener.h"
    3435
    3536namespace network {
     
    3839
    3940Host *Host::instance_=0;
    40  
     41
    4142/**
    4243 * @brief Constructor: assures that only one reference will be created and sets the pointer
     
    9091 * @return playerID
    9192 */
    92 unsigned int Host::getPlayerID(){ 
     93unsigned int Host::getPlayerID(){
    9394  if(!instance_)
    9495    return 0;
     
    9697}
    9798
    98 bool Host::Chat(std::string message){
     99bool Host::Chat(const std::string& message){
    99100  if(!instance_)
    100101    return false;
     
    102103}
    103104
    104 bool Host::incomingChat(std::string message, unsigned int playerID){
     105bool Host::Broadcast(const std::string& message){
     106  if(!instance_)
     107    return false;
     108  return instance_->broadcast(message);
     109}
     110
     111bool Host::incomingChat(const std::string& message, unsigned int playerID){
     112  for (orxonox::ObjectList<ChatListener>::iterator it = orxonox::ObjectList<ChatListener>::begin(); it != orxonox::ObjectList<ChatListener>::end(); ++it)
     113    it->incomingChat(message, playerID);
     114
    105115  return instance_->processChat(message, playerID);
    106116}
  • code/trunk/src/network/Host.h

    r1907 r2087  
    4444*       @author Oliver Scheuss
    4545*/
    46 class Host{
     46class _NetworkExport Host{
    4747  private:
    4848    //TODO add theese functions or adequate
     
    5050    //virtual bool sendChat(packet::Chat *chat)=0;
    5151    virtual bool queuePacket(ENetPacket *packet, int clientID)=0;
    52     virtual bool chat(std::string message)=0;
    53     virtual bool processChat(std::string message, unsigned int playerID)=0;
     52    virtual bool chat(const std::string& message)=0;
     53    virtual bool broadcast(const std::string& message)=0;
     54    virtual bool processChat(const std::string& message, unsigned int playerID)=0;
    5455    virtual bool isServer_()=0;
    5556
     
    7273    static void setClientID(unsigned int id){ instance_->clientID_ = id; }
    7374    static void setShipID(unsigned int id){ instance_->shipID_ = id; }
    74     static bool isServer(){ return instance_->isServer_(); }           
    75     static bool Chat(std::string message);
    76     static bool incomingChat(std::string message, unsigned int playerID);
     75    static bool isServer(){ return instance_->isServer_(); }
     76    static bool Chat(const std::string& message);
     77    static bool Broadcast(const std::string& message);
     78    static bool incomingChat(const std::string& message, unsigned int playerID);
    7779  private:
    7880};
  • code/trunk/src/network/NetworkCallback.h

    r1536 r2087  
    22#define _NETWORK_CALLBACK__
    33
     4#include "NetworkPrereqs.h"
     5
    46namespace network{
    5   class NetworkCallbackBase
     7  class _NetworkExport NetworkCallbackBase
    68  {
    79    public:
     
    911          virtual ~NetworkCallbackBase() {}
    1012  };
    11  
     13
    1214  template <class T>
    1315  class NetworkCallback: public NetworkCallbackBase
     
    1820      virtual void call()
    1921        { (this->object_->*function_)(); }
    20  
     22
    2123    private:
    2224      T* object_;
    2325      void (T::*function_) (void);
    24   }; 
     26  };
    2527
    2628
  • code/trunk/src/network/NetworkPrereqs.h

    r1735 r2087  
    6363  class Client;
    6464  class ClientConnection;
     65  class ClientConnectionListener;
    6566  class ClientFrameListener;
    6667  class ClientInformation;
  • code/trunk/src/network/PacketBuffer.h

    r1505 r2087  
    4949namespace network
    5050{
    51   struct PacketEnvelope{
     51  struct _NetworkExport PacketEnvelope{
    5252    int length;
    5353    int data;
    5454  };
    5555
    56   struct QueueItem{
     56  struct _NetworkExport QueueItem{
    5757    ENetEvent *event;
    5858    //ENetAddress address;
     
    6060  };
    6161
    62   class PacketBuffer{
     62  class _NetworkExport PacketBuffer{
    6363  public:
    6464    PacketBuffer();
  • code/trunk/src/network/Server.cc

    r1907 r2087  
    4646
    4747#include "ConnectionManager.h"
     48#include "ClientConnectionListener.h"
    4849#include "GamestateManager.h"
    4950#include "ClientInformation.h"
    5051#include "util/Sleep.h"
    51 #include "objects/SpaceShip.h"
    5252#include "core/ConsoleCommand.h"
    5353#include "core/CoreIncludes.h"
     
    5858#include "packet/DeleteObjects.h"
    5959#include <util/Convert.h>
     60#include "ChatListener.h"
    6061
    6162namespace network
    6263{
    63   const int MAX_FAILURES = 20;
    64   const int NETWORK_FREQUENCY = 30;
     64  const unsigned int MAX_FAILURES = 20;
     65  const unsigned int NETWORK_FREQUENCY = 25;
     66  const float NETWORK_PERIOD = (float)1/NETWORK_FREQUENCY;
    6567
    6668  /**
     
    8587  * @param bindAddress Address to listen on
    8688  */
    87   Server::Server(int port, std::string bindAddress) {
     89  Server::Server(int port, const std::string& bindAddress) {
    8890    timeSinceLastUpdate_=0;
    8991    connection = new ConnectionManager(port, bindAddress);
     
    101103    gamestates_ = new GamestateManager();
    102104  }
    103  
     105
    104106  /**
    105107  * @brief Destructor
     
    128130  }
    129131
    130   bool Server::processChat(std::string message, unsigned int playerID){
     132  bool Server::processChat(const std::string& message, unsigned int playerID){
    131133    ClientInformation *temp = ClientInformation::getBegin();
    132134    packet::Chat *chat;
     
    138140      temp = temp->next();
    139141    }
    140     COUT(1) << "Player " << playerID << ": " << message << std::endl;
     142//    COUT(1) << "Player " << playerID << ": " << message << std::endl;
    141143    return true;
    142144  }
     
    152154    //this steers our network frequency
    153155    timeSinceLastUpdate_+=time;
    154     if(timeSinceLastUpdate_>=(1./NETWORK_FREQUENCY)){
    155       timeSinceLastUpdate_=(float)((int)(timeSinceLastUpdate_*NETWORK_FREQUENCY))/timeSinceLastUpdate_;
     156    if(timeSinceLastUpdate_>=NETWORK_PERIOD){
     157      timeSinceLastUpdate_ -= static_cast<unsigned int>( timeSinceLastUpdate_ / NETWORK_PERIOD ) * NETWORK_PERIOD;
    156158      gamestates_->processGamestates();
    157159      updateGamestate();
     
    162164    return connection->addPacket(packet, clientID);
    163165  }
    164 
     166 
     167  /**
     168   * @brief: returns ping time to client in milliseconds
     169   */
     170  unsigned int Server::getPing(unsigned int clientID){
     171    assert(ClientInformation::findClient(clientID));
     172    return ClientInformation::findClient(clientID)->getRTT();
     173  }
     174
     175  /**
     176   * @brief: return packet loss ratio to client (scales from 0 to 1)
     177   */
     178  double Server::getPacketLoss(unsigned int clientID){
     179    assert(ClientInformation::findClient(clientID));
     180    return ClientInformation::findClient(clientID)->getPacketLoss();
     181  }
     182 
    165183  /**
    166184  * processes all the packets waiting in the queue
     
    239257      if(gs==NULL){
    240258        COUT(2) << "Server: could not generate gamestate (NULL from compress)" << std::endl;
     259        temp = temp->next();
    241260        continue;
    242261      }
     
    281300
    282301  bool Server::addClient(ENetEvent *event){
     302    static unsigned int newid=1;
     303
     304    COUT(2) << "Server: adding client" << std::endl;
    283305    ClientInformation *temp = ClientInformation::insertBack(new ClientInformation);
    284306    if(!temp){
     
    286308      return false;
    287309    }
    288     if(temp==ClientInformation::getBegin()) { //not good if you use anything else than insertBack
    289       temp->setID(1);
     310    /*if(temp==ClientInformation::getBegin()) { //not good if you use anything else than insertBack
     311      newid=1;
    290312    }
    291313    else
    292       temp->setID(temp->prev()->getID()+1);
     314      newid=temp->prev()->getID()+1;*/
     315    temp->setID(newid);
    293316    temp->setPeer(event->peer);
     317
     318    // inform all the listeners
     319    orxonox::ObjectList<ClientConnectionListener>::iterator listener = orxonox::ObjectList<ClientConnectionListener>::begin();
     320    while(listener){
     321      listener->clientConnected(newid);
     322      listener++;
     323    }
     324
     325    newid++;
     326
    294327    COUT(3) << "Server: added client id: " << temp->getID() << std::endl;
    295328    return createClient(temp->getID());
    296   }
     329}
    297330
    298331  bool Server::createClient(int clientID){
     
    304337    COUT(4) << "Con.Man: creating client id: " << temp->getID() << std::endl;
    305338    connection->syncClassid(temp->getID());
    306     COUT(5) << "creating spaceship for clientid: " << temp->getID() << std::endl;
    307     // TODO: this is only a hack, untill we have a possibility to define default player-join actions
    308     if(!createShip(temp))
    309       COUT(2) << "Con.Man. could not create ship for clientid: " << clientID << std::endl;
    310     else
    311       COUT(3) << "created spaceship" << std::endl;
    312339    temp->setSynched(true);
    313340    COUT(3) << "sending welcome" << std::endl;
     
    319346    g->setClientID(temp->getID());
    320347    b = g->collectData(0);
    321     assert(b);
     348    if(!b)
     349      return false; //no data for the client
    322350    b = g->compressData();
    323351    assert(b);
     
    327355  }
    328356
    329   bool Server::createShip(ClientInformation *client){
    330     if(!client)
    331       return false;
    332     orxonox::Identifier* id = ClassByName("SpaceShip");
    333     if(!id){
    334       COUT(4) << "We could not create the SpaceShip for client: " << client->getID() << std::endl;
    335       return false;
    336     }
    337     orxonox::SpaceShip *no = dynamic_cast<orxonox::SpaceShip *>(id->fabricate());
    338     no->classID = id->getNetworkID();
    339     client->setShipID(no->getObjectID());
    340     no->setPosition(orxonox::Vector3(0,0,80));
    341     no->setScale(10);
    342     //no->setYawPitchRoll(orxonox::Degree(-90),orxonox::Degree(-90),orxonox::Degree(0));
    343     no->setMesh("assff.mesh");
    344     no->setMaxSpeed(500);
    345     no->setMaxSideAndBackSpeed(50);
    346     no->setMaxRotation(1.0);
    347     no->setTransAcc(200);
    348     no->setRotAcc(3.0);
    349     no->setTransDamp(75);
    350     no->setRotDamp(1.0);
    351     no->setCamera(std::string("cam_") + convertToString(client->getID()));
    352     no->create();
    353 
    354     return true;
    355   }
    356 
    357357  bool Server::disconnectClient(ENetEvent *event){
    358358    COUT(4) << "removing client from list" << std::endl;
     
    360360
    361361    //boost::recursive_mutex::scoped_lock lock(head_->mutex_);
    362     orxonox::ObjectList<orxonox::SpaceShip>::iterator it = orxonox::ObjectList<orxonox::SpaceShip>::begin();
    363362    ClientInformation *client = ClientInformation::findClient(&event->peer->address);
    364363    if(!client)
    365364      return false;
    366365    gamestates_->removeClient(client);
    367     while(it){
    368       if(it->getObjectID()!=client->getShipID()){
    369         ++it;
    370         continue;
    371       }
    372       orxonox::ObjectList<orxonox::SpaceShip>::iterator temp=it;
    373       ++it;
    374       delete  *temp;
    375       return ClientInformation::removeClient(event->peer);
    376     }
    377     return false;
     366
     367// inform all the listeners
     368    orxonox::ObjectList<ClientConnectionListener>::iterator listener = orxonox::ObjectList<ClientConnectionListener>::begin();
     369    while(listener){
     370      listener->clientDisconnected(client->getID());
     371      listener++;
     372    }
     373
     374    return ClientInformation::removeClient(event->peer);
    378375  }
    379376
     
    387384    gamestates_->removeClient(client);
    388385  }
    389  
    390   bool Server::chat(std::string message){
     386
     387  bool Server::chat(const std::string& message){
     388      return this->sendChat(message, Host::getPlayerID());
     389  }
     390
     391  bool Server::broadcast(const std::string& message){
     392      return this->sendChat(message, CLIENTID_UNKNOWN);
     393  }
     394
     395  bool Server::sendChat(const std::string& message, unsigned int clientID){
    391396    ClientInformation *temp = ClientInformation::getBegin();
    392397    packet::Chat *chat;
    393398    while(temp){
    394       chat = new packet::Chat(message, Host::getPlayerID());
     399      chat = new packet::Chat(message, clientID);
    395400      chat->setClientID(temp->getID());
    396401      if(!chat->send())
     
    398403      temp = temp->next();
    399404    }
    400     COUT(1) << "Player " << Host::getPlayerID() << ": " << message << std::endl;
     405//    COUT(1) << "Player " << Host::getPlayerID() << ": " << message << std::endl;
     406    for (orxonox::ObjectList<ChatListener>::iterator it = orxonox::ObjectList<ChatListener>::begin(); it != orxonox::ObjectList<ChatListener>::end(); ++it)
     407      it->incomingChat(message, clientID);
     408
    401409    return true;
    402410  }
  • code/trunk/src/network/Server.h

    r1907 r2087  
    5252{
    5353  const int CLIENTID_SERVER = 0;
    54  
     54
    5555  /**
    5656  * This class is the root class of the network module for a server.
     
    6161    Server();
    6262    Server(int port);
    63     Server(int port, std::string bindAddress);
     63    Server(int port, const std::string& bindAddress);
    6464    Server(int port, const char *bindAddress);
    6565    ~Server();
    66    
     66
    6767    void open();
    6868    void close();
    69     bool processChat(std::string message, unsigned int playerID);
     69    bool processChat(const std::string& message, unsigned int playerID);
    7070    bool queuePacket(ENetPacket *packet, int clientID);
    7171    void tick(float time);
     72    unsigned int getPing(unsigned int clientID);
     73    double getPacketLoss(unsigned int clientID);
    7274  protected:
    7375    void processQueue();
     
    7779    unsigned int shipID(){return 0;}
    7880    unsigned int playerID(){return 0;}
    79    
     81
    8082    bool addClient(ENetEvent *event);
    8183    bool createClient(int clientID);
    82     bool createShip(ClientInformation *client);
    8384    bool disconnectClient(ENetEvent *event);
    8485    void disconnectClient(int clientID);
     
    8788    bool sendGameState();
    8889    bool sendObjectDeletes();
    89     virtual bool chat(std::string message);
    90    
     90    virtual bool chat(const std::string& message);
     91    virtual bool broadcast(const std::string& message);
     92    bool sendChat(const std::string& message, unsigned int clientID);
     93
    9194    //void processChat( chat *data, int clientId);
    9295    ConnectionManager *connection;
    9396    GamestateManager *gamestates_;
    9497
    95    
     98
    9699    float timeSinceLastUpdate_;
    97100  };
  • code/trunk/src/network/Synchronisable.cc

    r1907 r2087  
    4242
    4343#include <cstring>
     44#include <string>
    4445#include <iostream>
    4546#include <assert.h>
     
    5152namespace network
    5253{
    53  
     54
    5455
    5556  std::map<unsigned int, Synchronisable *> Synchronisable::objectMap_;
     
    6263  * Initializes all Variables and sets the right objectID
    6364  */
    64   Synchronisable::Synchronisable(){
     65  Synchronisable::Synchronisable(orxonox::BaseObject* creator){
    6566    RegisterRootObject(Synchronisable);
    6667    static uint32_t idCounter=0;
     
    6869    objectMode_=0x1; // by default do not send data to server
    6970    objectID=idCounter++;
     71    classID = (unsigned int)-1;
    7072    syncList = new std::list<synchronisableVariable *>;
    71   }
    72 
    73   /**
    74    * Destructor:
     73
     74    this->creatorID = OBJECTID_UNKNOWN;
     75
     76    searchcreatorID:
     77    if (creator)
     78    {
     79        Synchronisable* synchronisable_creator = dynamic_cast<Synchronisable*>(creator);
     80        if (synchronisable_creator && synchronisable_creator->objectMode_)
     81        {
     82            this->creatorID = synchronisable_creator->getObjectID();
     83        }
     84        else if (creator != creator->getCreator())
     85        {
     86            creator = creator->getCreator();
     87            goto searchcreatorID;
     88        }
     89    }
     90  }
     91
     92  /**
     93   * Destructor:
    7594   * Delete all callback objects and remove objectID from the objectMap_
    7695   */
     
    8099      for(std::list<synchronisableVariable *>::iterator it = syncList->begin(); it!=syncList->end(); it++)
    81100        delete (*it)->callback;
    82       deletedObjects_.push(objectID);
     101      if (this->objectMode_ != 0x0)
     102        deletedObjects_.push(objectID);
    83103//       COUT(3) << "destruct synchronisable +++" << objectID << " | " << classID << std::endl;
    84104//       COUT(3) << " bump ---" << objectID << " | " << &objectMap_ << std::endl;
     
    96116    this->classID = this->getIdentifier()->getNetworkID();
    97117//     COUT(4) << "creating synchronisable: setting classid from " << this->getIdentifier()->getName() << " to: " << classID << std::endl;
    98    
     118
    99119//     COUT(3) << "construct synchronisable +++" << objectID << " | " << classID << std::endl;
    100120//     objectMap_[objectID]=this;
     
    127147    synchronisableHeader *header = (synchronisableHeader *)mem;
    128148
    129     COUT(3) << "fabricating object with id: " << header->objectID << std::endl;
     149    if(!header->dataAvailable)
     150    {
     151      mem += header->size;
     152      return 0;
     153    }
     154   
     155    COUT(4) << "fabricating object with id: " << header->objectID << std::endl;
    130156
    131157    orxonox::Identifier* id = ClassByID(header->classID);
    132158    assert(id);
    133     orxonox::BaseObject *bo = id->fabricate();
     159    orxonox::BaseObject* creator = 0;
     160    if (header->creatorID != OBJECTID_UNKNOWN)
     161    {
     162      Synchronisable* synchronisable_creator = Synchronisable::getSynchronisable(header->creatorID);
     163      if (!synchronisable_creator)
     164      {
     165        mem += header->size; //.TODO: this suckz.... remove size from header
     166        return 0;
     167      }
     168      else
     169        creator = dynamic_cast<orxonox::BaseObject*>(synchronisable_creator);
     170    }
     171    orxonox::BaseObject *bo = id->fabricate(creator);
     172    assert(bo);
    134173    Synchronisable *no = dynamic_cast<Synchronisable *>(bo);
    135174    assert(no);
    136175    no->objectID=header->objectID;
     176    no->creatorID=header->creatorID; //TODO: remove this
    137177    no->classID=header->classID;
    138     COUT(3) << "fabricate objectID: " << no->objectID << " classID: " << no->classID << std::endl;
     178    COUT(4) << "fabricate objectID: " << no->objectID << " classID: " << no->classID << std::endl;
    139179          // update data and create object/entity...
    140     bool b = no->updateData(mem, mode);
     180    bool b = no->updateData(mem, mode, true);
    141181    assert(b);
    142     b = no->create();
    143     assert(b);
     182    if (b)
     183    {
     184        b = no->create();
     185        assert(b);
     186    }
    144187    return no;
    145188  }
    146189
    147  
     190
    148191  /**
    149192   * Finds and deletes the Synchronisable with the appropriate objectID
     
    164207    return true;
    165208  }
    166  
     209
    167210  /**
    168211   * This function looks up the objectID in the objectMap_ and returns a pointer to the right Synchronisable
     
    185228  }
    186229
    187  
     230
    188231  /**
    189232  * This function is used to register a variable to be synchronized
     
    196239  */
    197240  void Synchronisable::registerVar(void *var, int size, variableType t, int mode, NetworkCallbackBase *cb){
     241    assert( mode==direction::toclient || mode==direction::toserver || mode==direction::serverMaster || mode==direction::clientMaster);
    198242    // create temporary synch.Var struct
    199243    synchronisableVariable *temp = new synchronisableVariable;
     
    203247    temp->type = t;
    204248    temp->callback = cb;
     249    if( ( mode & direction::bidirectional ) )
     250    {
     251      temp->varBuffer = new uint8_t[size];
     252      memcpy(temp->varBuffer, temp->var, size); //now fill the buffer for the first time
     253      temp->varReference = 0;
     254    }
    205255    COUT(5) << "Syncronisable::registering var with size: " << temp->size << " and type: " << temp->type << std::endl;
    206256    //std::cout << "push temp to syncList (at the bottom) " << datasize << std::endl;
     
    228278   *             0x2: client->server (not recommended)
    229279   *             0x3: bidirectional
    230    * @return true: if !isMyTick or if everything was successfully saved
     280   * @return true: if !doSync or if everything was successfully saved
    231281   */
    232282  bool Synchronisable::getData(uint8_t*& mem, unsigned int id, int mode){
    233283    //if this tick is we dont synchronise, then abort now
    234     if(!isMyTick(id))
     284    if(!doSync(id))
    235285      return true;
    236286    //std::cout << "inside getData" << std::endl;
     
    240290    if(classID==0)
    241291      COUT(3) << "classid 0 " << this->getIdentifier()->getName() << std::endl;
     292
     293    if (this->classID == (unsigned int)-1)
     294        this->classID = this->getIdentifier()->getNetworkID();
     295
    242296    assert(this->classID==this->getIdentifier()->getNetworkID());
    243297//     this->classID=this->getIdentifier()->getNetworkID(); // TODO: correct this
     
    250304    header->size = size;
    251305    header->objectID = this->objectID;
     306    header->creatorID = this->creatorID;
    252307    header->classID = this->classID;
    253308    header->dataAvailable = true;
     
    263318        COUT(5) << "not getting data: " << std::endl;
    264319        continue;  // this variable should only be received
     320      }
     321      // if the variable gets synchronised bidirectional, then add the reference to the bytestream
     322      if( ( (*i)->mode & direction::bidirectional ) == direction::bidirectional )
     323      {
     324        *(uint8_t*)mem = (*i)->varReference;
     325        mem += sizeof( (*i)->varReference );
     326        tempsize += sizeof( (*i)->varReference );
    265327      }
    266328      switch((*i)->type){
     
    271333          break;
    272334        case STRING:
    273           memcpy( (void *)(mem), (void *)&((*i)->size), sizeof(int) );
    274           mem+=sizeof(int);
     335          memcpy( (void *)(mem), (void *)&((*i)->size), sizeof(size_t) );
     336          mem+=sizeof(size_t);
    275337          const char *data = ( ( *(std::string *) (*i)->var).c_str());
    276338          memcpy( mem, (void*)data, (*i)->size);
    277339          COUT(5) << "synchronisable: char: " << (const char *)(mem) << " data: " << data << " string: " << *(std::string *)((*i)->var) << std::endl;
    278340          mem+=(*i)->size;
    279           tempsize+=(*i)->size + 4;
     341          tempsize+=(*i)->size + sizeof(size_t);
    280342          break;
    281343      }
     
    292354   * @return true/false
    293355   */
    294   bool Synchronisable::updateData(uint8_t*& mem, int mode){
     356  bool Synchronisable::updateData(uint8_t*& mem, int mode, bool forceCallback){
    295357    if(mode==0x0)
    296358      mode=state_;
     
    305367    synchronisableHeader *syncHeader = (synchronisableHeader *)mem;
    306368    assert(syncHeader->objectID==this->objectID);
     369//    assert(syncHeader->creatorID==this->creatorID);
    307370    if(syncHeader->dataAvailable==false){
    308371      mem+=syncHeader->size;
     
    314377    assert(this->objectID==syncHeader->objectID);
    315378//    assert(this->classID==syncHeader->classID); //TODO: fix this!!! maybe a problem with the identifier ?
    316    
     379
    317380    COUT(5) << "Synchronisable: objectID " << syncHeader->objectID << ", classID " << syncHeader->classID << " size: " << syncHeader->size << " synchronising data" << std::endl;
    318381    for(i=syncList->begin(); i!=syncList->end() && mem <= data+syncHeader->size; i++){
     
    325388      switch((*i)->type){
    326389        case DATA:
     390          if( ( (*i)->mode & direction::bidirectional ) == direction::bidirectional )
     391          {
     392            if( ( mode == 0x1 && (*i)->mode == direction::serverMaster ) || \
     393                  ( mode == 0x2 && (*i)->mode == direction::clientMaster ) )    // if true we are master on this variable
     394            {
     395              uint8_t refNr = *(uint8_t *)mem;
     396              if( refNr != (*i)->varReference )
     397              {
     398                mem += sizeof((*i)->varReference) + (*i)->size; // the reference for this variable is not recent, discard data
     399                break;
     400              }
     401            }
     402            else //we are slave for this variable
     403            {
     404              (*i)->varReference = *(uint8_t *)mem; //copy the reference value for this variable
     405            }
     406            mem += sizeof((*i)->varReference);
     407          }
    327408          if((*i)->callback) // check whether this variable changed (but only if callback was set)
    328409            if(strncmp((char *)(*i)->var, (char *)mem, (*i)->size)!=0)
     
    332413          break;
    333414        case STRING:
    334           (*i)->size = *(uint32_t *)mem;
     415          if( ( (*i)->mode & direction::bidirectional ) == direction::bidirectional )
     416          {
     417            if( ( mode == 0x1 && (*i)->mode == direction::serverMaster ) || \
     418                  ( mode == 0x2 && (*i)->mode == direction::clientMaster ) )    // if true we are master for this variable
     419            {
     420              uint8_t refNr = *(uint8_t *)mem;
     421              mem += sizeof( (*i)->varReference );
     422              if( refNr != (*i)->varReference ){
     423                mem += sizeof(size_t) + *(size_t *)mem; // the reference for this variable is not recent, discard data
     424                break;
     425              }
     426            }
     427            else //we are slave for this variable
     428            {
     429              (*i)->varReference = *(uint8_t *)mem; //copy the reference value for this variable
     430            }
     431            mem += sizeof( (*i)->varReference );
     432          }
     433          (*i)->size = *(size_t *)mem;
    335434          COUT(5) << "string size: " << (*i)->size << std::endl;
    336           mem+=sizeof(int);
     435          mem += sizeof(size_t);
    337436          if((*i)->callback) // check whether this string changed
    338437            if( *(std::string *)((*i)->var) != std::string((char *)mem) )
     
    344443      }
    345444      // call the callback function, if defined
    346       if(callback && (*i)->callback)
     445      if((callback || forceCallback) && (*i)->callback)
    347446        (*i)->callback->call();
    348447    }
     
    357456  */
    358457  uint32_t Synchronisable::getSize(unsigned int id, int mode){
    359     if(!isMyTick(id))
     458    if(!doSync(id))
    360459      return 0;
    361460    int tsize=sizeof(synchronisableHeader);
     
    377476        break;
    378477      }
     478      if( ( (*i)->mode & direction::bidirectional ) == direction::bidirectional )
     479      {
     480        tsize+=sizeof( (*i)->varReference );
     481      }
    379482    }
    380483    return tsize;
     
    386489   * @return true/false
    387490   */
    388   bool Synchronisable::isMyTick(unsigned int id){
    389     return ( (objectMode_&state_)!=0 );
     491  bool Synchronisable::doSync(unsigned int id){
     492    return ( (objectMode_&state_)!=0 && (!syncList->empty() ) );
    390493  }
    391494
     
    413516   */
    414517  void Synchronisable::setObjectMode(int mode){
    415     assert(mode==0x1 || mode==0x2 || mode==0x3);
     518    assert(mode==0x0 || mode==0x1 || mode==0x2 || mode==0x3);
    416519    objectMode_=mode;
    417520  }
  • code/trunk/src/network/Synchronisable.h

    r1910 r2087  
    4141#include "util/Integers.h"
    4242
    43 #define REGISTERDATA(varname) registerVar(&varname, sizeof(varname), network::DATA)
    44 #define REGISTERDATA_WITHDIR(varname, mode) registerVar(&varname, sizeof(varname), network::DATA, mode)
    45 #define REGISTERSTRING(stringname) registerVar(&stringname, stringname.length()+1, network::STRING)
    46 #define REGISTERSTRING_WITHDIR(stringname, mode) registerVar(&stringname, stringname.length()+1, network::STRING, mode)
    47 
    48 //TODO: this is only a very ugly hack ...
    49 namespace orxonox{
    50 class SpaceShip;
    51 }
     43#define REGISTERDATA(varname, ...) \
     44    registerVar((void*)&varname, sizeof(varname), network::DATA, __VA_ARGS__)
     45#define REGISTERSTRING(stringname, ...) \
     46    registerVar(&stringname, stringname.length()+1, network::STRING, __VA_ARGS__)
    5247
    5348namespace network
    5449{
     50  static const unsigned int OBJECTID_UNKNOWN = (unsigned int)-1;
     51
    5552  namespace direction{
    5653    enum syncdirection{
    5754      toclient=0x1,
    5855      toserver=0x2,
    59       bidirectional=0x3
     56      bidirectional=0x3,
     57      serverMaster=0x3,
     58      clientMaster=0x7
    6059    };
    6160  }
    62  
     61
    6362  namespace syncmode{
    6463    enum mode{
     
    6766    };
    6867  }
    69  
     68
    7069  enum variableType{
    7170    DATA,
     
    7372  };
    7473
    75   struct synchronisableHeader{
     74  struct _NetworkExport synchronisableHeader{
    7675    uint32_t size:31;
    7776    bool dataAvailable:1;
    7877    uint32_t objectID;
     78    uint32_t creatorID;
    7979    uint32_t classID;
    8080  };
    8181
    82   typedef struct synchronisableVariable{
     82  struct _NetworkExport synchronisableVariable{
    8383    unsigned int size;
    8484    int mode; // this determines in which direction the variable gets synchronised
     
    8686    variableType type;
    8787    NetworkCallbackBase *callback;
    88   }SYNCVAR;
     88    void *varBuffer;
     89    uint8_t varReference;
     90  };
    8991
    9092  /**
     
    98100    friend class GamestateClient;
    99101    friend class Server;
    100     friend class orxonox::SpaceShip;
    101102    virtual ~Synchronisable();
    102103
    103    
     104
    104105    virtual bool create();
    105106    static void setClient(bool b);
    106    
     107
    107108    static Synchronisable *fabricate(uint8_t*& mem, int mode=0x0);
    108109    static bool deleteObject(unsigned int objectID);
     
    110111    static unsigned int getNumberOfDeletedObject(){ return deletedObjects_.size(); }
    111112    static unsigned int popDeletedObject(){ unsigned int i = deletedObjects_.front(); deletedObjects_.pop(); return i; }
    112    
     113
    113114    inline unsigned int getObjectID(){return objectID;}
    114115    inline unsigned int getClassID(){return classID;}
    115116  protected:
    116     Synchronisable();
     117    Synchronisable(orxonox::BaseObject* creator);
    117118    void registerVar(void *var, int size, variableType t, int mode=1, NetworkCallbackBase *cb=0);
    118119    void setObjectMode(int mode);
    119120    void setObjectFrequency(unsigned int freq){ objectFrequency_ = freq; }
    120     virtual void registerAllVariables()=0;
    121    
    122    
     121
     122
    123123  private:
    124124    bool getData(uint8_t*& men, unsigned int id, int mode=0x0);
    125125    uint32_t getSize(unsigned int id, int mode=0x0);
    126     bool updateData(uint8_t*& mem, int mode=0x0);
     126    bool updateData(uint8_t*& mem, int mode=0x0, bool forceCallback=false);
    127127    bool isMyData(uint8_t* mem);
    128128    bool doSelection(unsigned int id);
    129     bool isMyTick(unsigned int id);
    130    
     129    bool doSync(unsigned int id);
     130
    131131    unsigned int objectID;
     132    unsigned int creatorID;
    132133    unsigned int classID;
    133    
     134
    134135    std::list<synchronisableVariable *> *syncList;
    135136    static int state_; // detemines wheter we are server (default) or client
  • code/trunk/src/network/packet/Acknowledgement.h

    r1907 r2087  
    2929#define NETWORKACKNOLEDGEMENT_H
    3030
     31#include "../NetworkPrereqs.h"
    3132#include "Packet.h"
    3233
     
    3536namespace packet {
    3637/**
    37         @author 
     38        @author
    3839*/
    39 class Acknowledgement : public Packet
     40class _NetworkExport Acknowledgement : public Packet
    4041{
    4142public:
     
    4344  Acknowledgement( uint8_t* data, unsigned int clientID );
    4445  ~Acknowledgement();
    45  
     46
    4647  inline unsigned int getSize() const;
    4748  bool process();
    48  
     49
    4950  unsigned int getAckID();
    5051private:
  • code/trunk/src/network/packet/Chat.h

    r1907 r2087  
    22#ifndef NETWORKCHAT_H
    33#define NETWORKCHAT_H
     4
     5#include "../NetworkPrereqs.h"
    46
    57#include <string>
     
    1113namespace packet {
    1214/**
    13         @author 
     15        @author
    1416*/
    15 class Chat : public Packet
     17class _NetworkExport Chat : public Packet
    1618{
    1719public:
     
    1921  Chat( uint8_t* data, unsigned int clientID );
    2022  ~Chat();
    21  
     23
    2224  inline unsigned int getSize() const;
    2325  bool process();
    24  
     26
    2527  unsigned int getMessageLength(){ return messageLength_; };
    2628  unsigned char *getMessage();
  • code/trunk/src/network/packet/ClassID.h

    r1907 r2087  
    2929#define NETWORKCLASSID_H
    3030
     31#include "../NetworkPrereqs.h"
     32
    3133#include <string>
    3234
     
    3739
    3840/**
    39         @author 
     41        @author
    4042*/
    41 class ClassID : public Packet
     43class _NetworkExport ClassID : public Packet
    4244{
    4345public:
     
    4547  ClassID( uint8_t* data, unsigned int clientID );
    4648  ~ClassID();
    47  
     49
    4850  inline unsigned int getSize() const;
    4951  bool process();
    50  
     52
    5153  unsigned int getClassID();
    5254  unsigned int getClassNameLength(){ return classNameLength_; }
  • code/trunk/src/network/packet/DeleteObjects.h

    r1907 r2087  
    2929#define NETWORKPACKETDELETEOBJECTS_H
    3030
     31#include "../NetworkPrereqs.h"
     32
    3133#include "Packet.h"
    3234
     
    3537namespace packet {
    3638/**
    37         @author 
     39        @author
    3840*/
    39 class DeleteObjects : public Packet
     41class _NetworkExport DeleteObjects : public Packet
    4042{
    4143public:
     
    4345  DeleteObjects( uint8_t* data, unsigned int clientID );
    4446  ~DeleteObjects();
    45  
     47
    4648  bool fetchIDs();
    47  
     49
    4850  inline unsigned int getSize() const;
    4951  bool process();
    50  
     52
    5153private:
    5254};
  • code/trunk/src/network/packet/Gamestate.cc

    r1907 r2087  
    4646#define HEADER GAMESTATE_HEADER(data_)
    4747
    48  
     48
    4949#define PACKET_FLAG_GAMESTATE  ENET_PACKET_FLAG_RELIABLE
    50  
     50
    5151Gamestate::Gamestate()
    5252{
     
    8585    return false;
    8686  }
    87  
     87
    8888#ifndef NDEBUG
    8989  std::list<Synchronisable*> slist;
     
    115115    slist.push_back(*it);
    116116#endif
    117    
     117
    118118    //if(it->doSelection(id))
    119119    dataMap_[mem-data_]=(*it);  // save the mem location of the synchronisable data
     
    157157    if(!s)
    158158    {
    159       s = Synchronisable::fabricate(mem, mode);
    160       assert(s);
    161 //       if(!s)
    162 //         return false;
     159      Synchronisable::fabricate(mem, mode);
    163160    }
    164161    else
     
    257254  HEADER->compressed = true;
    258255  assert(HEADER->compressed);
    259   COUT(3) << "gamestate compress datasize: " << HEADER->datasize << " compsize: " << HEADER->compsize << std::endl;
     256  COUT(4) << "gamestate compress datasize: " << HEADER->datasize << " compsize: " << HEADER->compsize << std::endl;
    260257  return true;
    261258}
     
    264261  assert(HEADER);
    265262  assert(HEADER->compressed);
    266   COUT(3) << "GameStateClient: uncompressing gamestate. id: " << HEADER->id << ", baseid: " << HEADER->base_id << ", datasize: " << HEADER->datasize << ", compsize: " << HEADER->compsize << std::endl;
     263  COUT(4) << "GameStateClient: uncompressing gamestate. id: " << HEADER->id << ", baseid: " << HEADER->base_id << ", datasize: " << HEADER->datasize << ", compsize: " << HEADER->compsize << std::endl;
    267264  unsigned int datasize = HEADER->datasize;
    268265  unsigned int compsize = HEADER->compsize;
    269266  unsigned int bufsize;
    270   assert(compsize<=datasize);
     267//  assert(compsize<=datasize);
    271268  bufsize = datasize;
    272269  assert(bufsize!=0);
     
    289286  //copy over the header
    290287  *GAMESTATE_HEADER(ndata) = *HEADER;
    291   //delete old (compressed data)
    292   delete[] data_;
     288
     289  if (this->bDataENetAllocated_){
     290    // Memory was allocated by ENet. --> We let it be since enet_packet_destroy will
     291    // deallocated it anyway. So data and packet stay together.
     292    this->bDataENetAllocated_ = false;
     293  }
     294  else{
     295    // We allocated the memory in the first place (unlikely). So we destroy the old data
     296    // and overwrite it with the new decompressed data.
     297    delete[] this->data_;
     298  }
     299
    293300  //set new pointers
    294301  data_ = ndata;
     
    339346  assert(data_);
    340347  std::map<unsigned int, Synchronisable *>::iterator it;
    341  
     348
    342349  // allocate memory for new data
    343350  uint8_t *gdata = new uint8_t[HEADER->datasize+sizeof(GamestateHeader)];
     
    346353  uint8_t *newdata = gdata + sizeof(GamestateHeader);
    347354  uint8_t *origdata = GAMESTATE_START(data_);
    348  
     355
    349356  //copy the GamestateHeader
    350357  *(GamestateHeader*)gdata = *HEADER;
    351  
     358
    352359  synchronisableHeader *oldobjectheader, *newobjectheader;
    353360  unsigned int objectOffset;
    354  
     361
    355362  //copy in the zeros
    356363  for(it=dataMap_.begin(); it!=dataMap_.end(); it++){
     
    360367    assert(it->second->objectID==oldobjectheader->objectID);
    361368    *newobjectheader = *oldobjectheader;
    362     objectOffset=sizeof(uint8_t)+sizeof(bool); //skip the size and the availableDate variables in the objectheader
     369    objectOffset=sizeof(uint8_t)+sizeof(bool); //skip the size and the availableData variables in the objectheader
    363370    if(it->second->doSelection(HEADER->id)){
    364371      newobjectheader->dataAvailable=true; //TODO: probably not neccessary
     
    390397  assert(!HEADER->compressed);
    391398  assert(!HEADER->diffed);
    392  
     399
    393400  //preparations
    394401  std::map<unsigned int, Synchronisable *>::iterator it;
    395402  uint8_t *origdata, *basedata, *destdata, *ndata;
    396403  unsigned int objectOffset, streamOffset=0;    //data offset
    397   unsigned int minsize = (HEADER->datasize < GAMESTATE_HEADER(base->data_)->datasize) ? HEADER->datasize : GAMESTATE_HEADER(base->data_)->datasize; 
     404  unsigned int minsize = (HEADER->datasize < GAMESTATE_HEADER(base->data_)->datasize) ? HEADER->datasize : GAMESTATE_HEADER(base->data_)->datasize;
    398405  synchronisableHeader *origheader;
    399406  synchronisableHeader *destheader;
    400  
     407
    401408  origdata = GAMESTATE_START(this->data_);
    402409  basedata = GAMESTATE_START(base->data_);
    403410  ndata = new uint8_t[HEADER->datasize + sizeof(GamestateHeader)];
    404411  destdata = ndata + sizeof(GamestateHeader);
    405  
     412
    406413  // do the diff
    407414  for(it=dataMap_.begin(); it!=dataMap_.end(); it++){
     
    410417    origheader = (synchronisableHeader *)(origdata+streamOffset);
    411418    destheader = (synchronisableHeader *)(destdata+streamOffset);
    412    
     419
    413420    //copy and partially diff the object header
    414421    assert(sizeof(synchronisableHeader)==3*sizeof(unsigned int)+sizeof(bool));
     
    420427    }else{
    421428      *(uint32_t*)(destdata+sizeof(uint32_t)+sizeof(bool)) = 0;
    422       *(uint32_t*)(destdata+2*sizeof(uint32_t)+sizeof(bool)) = 0; 
     429      *(uint32_t*)(destdata+2*sizeof(uint32_t)+sizeof(bool)) = 0;
    423430    }
    424431    objectOffset=sizeof(synchronisableHeader);
    425432    streamOffset+=sizeof(synchronisableHeader);
    426    
     433
    427434    //now handle the object data or fill with zeros
    428435    while(objectOffset<origheader->size ){
    429      
     436
    430437      if(sendData && streamOffset<minsize)
    431438        *(destdata+objectOffset)=*(basedata+objectOffset)^*(origdata+objectOffset); // do the xor
     
    434441      else
    435442        *(destdata+objectOffset)=0; // set to 0 because this object should not be transfered
    436      
     443
    437444      objectOffset++;
    438445      streamOffset++;
     
    442449    basedata+=objectOffset;
    443450  }
    444  
     451
    445452  //copy over the gamestate header and set the diffed flag
    446453  *(GamestateHeader *)ndata = *HEADER; //copy over the header
     
    458465  assert(!HEADER->compressed);
    459466  assert(HEADER->diffed);
    460  
     467
    461468  //preparations
    462469  std::map<unsigned int, Synchronisable *>::iterator it;
    463470  uint8_t *origdata, *basedata, *destdata, *ndata;
    464471  unsigned int objectOffset, streamOffset=0;    //data offset
    465   unsigned int minsize = (HEADER->datasize < GAMESTATE_HEADER(base->data_)->datasize) ? HEADER->datasize : GAMESTATE_HEADER(base->data_)->datasize; 
     472  unsigned int minsize = (HEADER->datasize < GAMESTATE_HEADER(base->data_)->datasize) ? HEADER->datasize : GAMESTATE_HEADER(base->data_)->datasize;
    466473  synchronisableHeader *origheader;
    467474  synchronisableHeader *destheader;
    468  
     475
    469476  origdata = GAMESTATE_START(this->data_);
    470477  basedata = GAMESTATE_START(base->data_);
    471478  ndata = new uint8_t[HEADER->datasize + sizeof(GamestateHeader)];
    472479  destdata = ndata + sizeof(GamestateHeader);
    473  
     480
    474481  // do the undiff
    475482  for(it=dataMap_.begin(); it!=dataMap_.end(); it++){
     
    478485    destheader = (synchronisableHeader *)(destdata+streamOffset);
    479486    bool sendData;
    480    
     487
    481488    //copy and partially diff the object header
    482489    assert(sizeof(synchronisableHeader)==3*sizeof(unsigned int)+sizeof(bool));
     
    489496    }else{
    490497      *(unsigned int*)(destdata+sizeof(unsigned int)+sizeof(bool)) = 0;
    491       *(unsigned int*)(destdata+2*sizeof(unsigned int)+sizeof(bool)) = 0; 
     498      *(unsigned int*)(destdata+2*sizeof(unsigned int)+sizeof(bool)) = 0;
    492499    }
    493500    objectOffset=sizeof(synchronisableHeader);
    494501    streamOffset+=sizeof(synchronisableHeader);
    495    
     502
    496503    //now handle the object data or fill with zeros
    497504    while(objectOffset<origheader->size ){
    498      
     505
    499506      if(sendData && streamOffset<minsize)
    500507        *(destdata+objectOffset)=*(basedata+objectOffset)^*(origdata+objectOffset); // do the xor
     
    503510      else
    504511        *(destdata+objectOffset)=0; // set to 0 because this object should not be transfered
    505      
     512
    506513      objectOffset++;
    507514      streamOffset++;
     
    511518    basedata+=objectOffset;
    512519  }
    513  
     520
    514521  //copy over the gamestate header and set the diffed flag
    515522  *(GamestateHeader *)ndata = *HEADER; //copy over the header
  • code/trunk/src/network/packet/Gamestate.h

    r1907 r2087  
    2727 */
    2828
     29
     30#ifndef NETWORK_PACKETGAMESTATE_H
     31#define NETWORK_PACKETGAMESTATE_H
     32
     33#include "../NetworkPrereqs.h"
     34
    2935#include "Packet.h"
    3036#include "network/Synchronisable.h"
     
    3440#endif
    3541
    36 
    37 #ifndef NETWORK_PACKETGAMESTATE_H
    38 #define NETWORK_PACKETGAMESTATE_H
    39 
    4042namespace network {
    4143
    4244namespace packet {
    4345
    44 struct GamestateHeader{
     46struct _NetworkExport GamestateHeader{
    4547  ENUM::Type packetType;
    4648  int32_t id; // id of the gamestate
     
    5961        @author Oliver Scheuss
    6062*/
    61 class Gamestate: public Packet{
     63class _NetworkExport Gamestate: public Packet{
    6264  public:
    6365    Gamestate();
  • code/trunk/src/network/packet/Packet.cc

    r1907 r2087  
    4949
    5050namespace packet{
    51  
     51
    5252#define PACKET_FLAG_DEFAULT ENET_PACKET_FLAG_NO_ALLOCATE
    5353#define _PACKETID           0
    54  
     54
    5555std::map<ENetPacket *, Packet *> Packet::packetMap_;
    56  
     56
    5757Packet::Packet(){
    5858  flags_ = PACKET_FLAG_DEFAULT;
     
    6161  data_=0;
    6262  enetPacket_=0;
     63  bDataENetAllocated_ = false;
    6364}
    6465
     
    7374  data_=data;
    7475  enetPacket_=0;
     76  bDataENetAllocated_ = false;
    7577}
    7678
     
    8688  }else
    8789    data_=0;
    88 }
    89 
     90  bDataENetAllocated_ = p.bDataENetAllocated_;
     91}
     92
     93/**
     94@brief
     95    Destroys a packet completely.
     96   
     97    That also means destroying the ENetPacket if one exists. There
     98*/
    9099Packet::~Packet(){
    91   if(enetPacket_){
    92     assert(enetPacket_->freeCallback==0);
     100  // Deallocate data_ memory if necessary.
     101  if (this->bDataENetAllocated_){
     102    // In this case ENet allocated data_ and will destroy it.
     103  }
     104  else if (this->data_) {
     105    // This destructor was probably called as a consequence to ENet executing our callback.
     106    // It simply serves us to be able to deallocate the packet content (data_) ourselves since
     107    // we have created it in the first place.
     108    delete[] this->data_;
     109  }
     110
     111  // Destroy the ENetPacket if necessary.
     112  // Note: For the case ENet used the callback to destroy the packet, we have already set
     113  // enetPacket_ to NULL to avoid destroying it again.
     114  if (this->enetPacket_){
     115    // enetPacket_->data gets destroyed too by ENet if it was allocated by it.
    93116    enet_packet_destroy(enetPacket_);
    94117  }
    95   if(data_)
    96     delete[] data_;
    97118}
    98119
     
    107128      return false;
    108129    }
     130    // We deliver ENet the data address so that it doesn't memcpy everything again.
     131    // --> We have to delete data_ ourselves!
    109132    enetPacket_ = enet_packet_create(getData(), getSize(), getFlags());
    110133    enetPacket_->freeCallback = &Packet::deletePacket;
    111 //     enetPacket_->freeCallback = &blub;
     134    // Add the packet to a global list so we can access it again once enet calls our
     135    // deletePacket method. We can of course only give a one argument function to the ENet C library.
    112136    packetMap_[enetPacket_] = this;
    113137  }
    114 #ifndef NDEBUG 
     138#ifndef NDEBUG
    115139  switch( *(ENUM::Type *)(data_ + _PACKETID) )
    116140  {
     
    127151  }
    128152#endif
    129   ENetPacket *temp = enetPacket_;
    130   enetPacket_ = 0; // otherwise we have a double free because enet already handles the deallocation of the packet
    131   network::Host::addPacket( temp, clientID_);
     153//  ENetPacket *temp = enetPacket_;
     154//  enetPacket_ = 0; // otherwise we have a double free because enet already handles the deallocation of the packet
     155  network::Host::addPacket( enetPacket_, clientID_);
    132156  return true;
    133157}
     
    135159Packet *Packet::createPacket(ENetPacket *packet, ENetPeer *peer){
    136160  uint8_t *data = packet->data;
     161  assert(ClientInformation::findClient(&peer->address)->getID() != (unsigned int)-2 || !Host::isServer());
    137162  unsigned int clientID = ClientInformation::findClient(&peer->address)->getID();
    138163  Packet *p;
     
    169194      break;
    170195  }
     196
     197  // Data was created by ENet
     198  p->bDataENetAllocated_ = true;
     199
    171200  return p;
    172201}
    173202
    174 void Packet::deletePacket(ENetPacket *packet){
    175   assert(packetMap_[packet]);
    176   assert(packetMap_[packet]->enetPacket_==0);
    177   delete packetMap_[packet];
     203/**
     204@brief
     205    ENet calls this method whenever it wants to destroy a packet that contains
     206    data we allocated ourselves.
     207*/
     208void Packet::deletePacket(ENetPacket *enetPacket){
     209  // Get our Packet from a gloabal map with all Packets created in the send() method of Packet.
     210  std::map<ENetPacket*, Packet*>::iterator it = packetMap_.find(enetPacket);
     211  assert(it != packetMap_.end());
     212  // Make sure we don't delete it again in the destructor
     213  it->second->enetPacket_ = 0;
     214  delete it->second;
     215  //packetMap_.erase(it);
     216  COUT(4) << "PacketMap size: " << packetMap_.size() << std::endl;
    178217}
    179218
  • code/trunk/src/network/packet/Packet.h

    r1907 r2087  
    2929#define NETWORKPACKET_H
    3030
     31#include "../NetworkPrereqs.h"
     32
    3133#include <map>
    3234#include <enet/enet.h>
     
    3739
    3840namespace packet{
    39  
     41
    4042namespace ENUM{
    4143  enum Direction{
     
    5355  };
    5456}
    55  
     57
    5658/**
    5759        @author Oliver Scheuss <scheusso [at] ee.ethz.ch>
    5860*/
    59 class Packet{
     61class _NetworkExport Packet{
    6062  public:
    6163    Packet(const Packet &p);
     
    6365    static Packet *createPacket(ENetPacket *packet, ENetPeer *peer);
    6466    static void deletePacket(ENetPacket *packet);
    65    
     67
    6668    virtual unsigned char *getData(){ return data_; };
    6769    virtual unsigned int getSize() const =0;
     
    7375    void setClientID( int id )
    7476      { clientID_ = id; }
    75    
     77
    7678    bool send();
    7779  protected:
     
    8284    unsigned int clientID_;
    8385    ENUM::Direction packetDirection_;
     86    /** Pointer to the data. Be careful when deleting it because it might
     87        point to a location that was allocated by ENet.
     88        See bDataENetAllocated_ */
    8489    uint8_t *data_;
     90    /** Tells whether data_ was allocated by ENet or ourselves.
     91        data_ might no correlate with enetPacket_->data. */
     92    bool bDataENetAllocated_;
    8593  private:
    8694    static std::map<ENetPacket *, Packet *> packetMap_;
  • code/trunk/src/network/packet/Welcome.h

    r1907 r2087  
    2929#define NETWORKWELCOME_H
    3030
     31#include "../NetworkPrereqs.h"
     32
    3133#include "Packet.h"
    3234
     
    3537
    3638/**
    37         @author 
     39        @author
    3840*/
    39 class Welcome : public Packet
     41class _NetworkExport Welcome : public Packet
    4042{
    4143public:
     
    4345  Welcome( uint8_t* data, unsigned int clientID );
    4446  virtual ~Welcome();
    45  
     47
    4648  uint8_t *getData();
    4749  inline unsigned int getSize() const;
    4850  bool process();
    49  
     51
    5052private:
    5153};
Note: See TracChangeset for help on using the changeset viewer.