[Orxonox-commit 666] r3198 - in trunk/src: core network network/packet network/synchronisable orxonox/gamestates util

scheusso at orxonox.net scheusso at orxonox.net
Sat Jun 20 16:27:39 CEST 2009


Author: scheusso
Date: 2009-06-20 16:27:38 +0200 (Sat, 20 Jun 2009)
New Revision: 3198

Modified:
   trunk/src/core/ConfigFileManager.cc
   trunk/src/core/ConsoleCommandCompilation.cc
   trunk/src/core/Language.cc
   trunk/src/core/LuaBind.cc
   trunk/src/network/Client.cc
   trunk/src/network/ClientConnection.cc
   trunk/src/network/ClientInformation.h
   trunk/src/network/ConnectionManager.cc
   trunk/src/network/ConnectionManager.h
   trunk/src/network/GamestateManager.cc
   trunk/src/network/Server.cc
   trunk/src/network/TrafficControl.cc
   trunk/src/network/packet/Acknowledgement.cc
   trunk/src/network/packet/Gamestate.cc
   trunk/src/network/packet/Gamestate.h
   trunk/src/network/synchronisable/Synchronisable.cc
   trunk/src/orxonox/gamestates/GSDedicated.cc
   trunk/src/orxonox/gamestates/GSDedicated.h
   trunk/src/util/OutputBuffer.cc
   trunk/src/util/SignalHandler.cc
Log:
merged netp4 back to trunk


Modified: trunk/src/core/ConfigFileManager.cc
===================================================================
--- trunk/src/core/ConfigFileManager.cc	2009-06-20 13:26:42 UTC (rev 3197)
+++ trunk/src/core/ConfigFileManager.cc	2009-06-20 14:27:38 UTC (rev 3198)
@@ -39,7 +39,6 @@
 
 namespace orxonox
 {
-    const int CONFIG_FILE_MAX_LINELENGHT  = 1024;
     const char* const DEFAULT_CONFIG_FILE = "default.ini";
 
     ConfigFileManager* ConfigFileManager::singletonRef_s = 0;
@@ -243,17 +242,13 @@
         file.open(filepath.string().c_str(), std::fstream::in);
         if (file.is_open())
         {
-
-            char linearray[CONFIG_FILE_MAX_LINELENGHT];
-
             ConfigFileSection* newsection = 0;
 
             while (file.good() && !file.eof())
             {
-                file.getline(linearray, CONFIG_FILE_MAX_LINELENGHT);
+                std::string line;
+                std::getline(file, line);
 
-                std::string line = std::string(linearray);
-
                 std::string temp = getStripped(line);
                 if (!isEmpty(temp) && !isComment(temp))
                 {

Modified: trunk/src/core/ConsoleCommandCompilation.cc
===================================================================
--- trunk/src/core/ConsoleCommandCompilation.cc	2009-06-20 13:26:42 UTC (rev 3197)
+++ trunk/src/core/ConsoleCommandCompilation.cc	2009-06-20 14:27:38 UTC (rev 3198)
@@ -72,10 +72,10 @@
         executingFiles.insert(filename);
 
         // Iterate through the file and put the lines into the CommandExecutor
-        char line[1024];
         while (file.good() && !file.eof())
         {
-            file.getline(line, 1024);
+            std::string line;
+            std::getline(file, line);
             CommandExecutor::execute(line);
         }
 
@@ -143,10 +143,10 @@
         }
 
         std::string output = "";
-        char line[1024];
         while (file.good() && !file.eof())
         {
-            file.getline(line, 1024);
+            std::string line;
+            std::getline(file, line);
             output += line;
             output += "\n";
         }

Modified: trunk/src/core/Language.cc
===================================================================
--- trunk/src/core/Language.cc	2009-06-20 13:26:42 UTC (rev 3197)
+++ trunk/src/core/Language.cc	2009-06-20 14:27:38 UTC (rev 3198)
@@ -223,13 +223,11 @@
             return;
         }
 
-        char line[1024];
-
         // Iterate through the file and create the LanguageEntries
         while (file.good() && !file.eof())
         {
-            file.getline(line, 1024);
-            std::string lineString = std::string(line);
+            std::string lineString;
+            std::getline(file, lineString);
 
             // Check if the line is empty
             if ((lineString != "") && (lineString.size() > 0))
@@ -271,13 +269,11 @@
             return;
         }
 
-        char line[1024];
-
         // Iterate through the file and create the LanguageEntries
         while (file.good() && !file.eof())
         {
-            file.getline(line, 1024);
-            std::string lineString = std::string(line);
+            std::string lineString;
+            std::getline(file, lineString);
 
             // Check if the line is empty
             if ((lineString != "") && (lineString.size() > 0))

Modified: trunk/src/core/LuaBind.cc
===================================================================
--- trunk/src/core/LuaBind.cc	2009-06-20 13:26:42 UTC (rev 3197)
+++ trunk/src/core/LuaBind.cc	2009-06-20 14:27:38 UTC (rev 3198)
@@ -94,12 +94,12 @@
       // some error msg
     }
 
-    char line[1024*32];
     std::string levelString = "";
 
     while (file.good() && !file.eof())
     {
-      file.getline(line, 1024*32);
+      std::string line;
+      std::getline(file, line);
       levelString += line;
       levelString += "\n";
     }

Modified: trunk/src/network/Client.cc
===================================================================
--- trunk/src/network/Client.cc	2009-06-20 13:26:42 UTC (rev 3197)
+++ trunk/src/network/Client.cc	2009-06-20 14:27:38 UTC (rev 3198)
@@ -168,6 +168,7 @@
       // note: packet commits suicide here except for the GameState. That is then deleted by a GamestateHandler
       bool b = packet->process();
       assert(b);
+      delete event;
     }
     if(gamestate.processGamestates())
     {

Modified: trunk/src/network/ClientConnection.cc
===================================================================
--- trunk/src/network/ClientConnection.cc	2009-06-20 13:26:42 UTC (rev 3197)
+++ trunk/src/network/ClientConnection.cc	2009-06-20 14:27:38 UTC (rev 3198)
@@ -168,8 +168,8 @@
           // we should never reach this point
 // 	        assert(0);
           printf("ClientConnection: ENet returned with an error!\n");
-          quit_=true;
-          break;
+//           quit_=true;
+          continue;
           // add some error handling here ========================
         }
         lock.unlock();
@@ -196,12 +196,18 @@
         break;
       }
     }
+    delete event;
     // now disconnect
 
     if(!disconnectConnection())
+    {
+      printf("could not disconnect properly\n");
       // if disconnecting failed destroy conn.
       boost::recursive_mutex::scoped_lock lock(enet_mutex_g);
       enet_peer_reset(server);
+    }
+    else
+      printf("properly disconnected\n");
     return;
   }
 
@@ -220,6 +226,7 @@
         enet_packet_destroy(event.packet);
         break;
       case ENET_EVENT_TYPE_DISCONNECT:
+        printf("received disconnect confirmation from server");
         return true;
       }
     }

Modified: trunk/src/network/ClientInformation.h
===================================================================
--- trunk/src/network/ClientInformation.h	2009-06-20 13:26:42 UTC (rev 3197)
+++ trunk/src/network/ClientInformation.h	2009-06-20 14:27:38 UTC (rev 3198)
@@ -90,7 +90,6 @@
     bool setSynched(bool s);
     bool getSynched();
 
-
   private:
     static ClientInformation *head_;
 

Modified: trunk/src/network/ConnectionManager.cc
===================================================================
--- trunk/src/network/ConnectionManager.cc	2009-06-20 13:26:42 UTC (rev 3197)
+++ trunk/src/network/ConnectionManager.cc	2009-06-20 14:27:38 UTC (rev 3198)
@@ -131,6 +131,7 @@
   bool ConnectionManager::quitListener() {
     quit_=true;
     receiverThread_->join();
+    delete receiverThread_;
     return true;
   }
 
@@ -205,8 +206,8 @@
         if(enet_host_service(server, event, NETWORK_WAIT_TIMEOUT)<0){
           // we should never reach this point
           printf("ConnectionManager: ENet returned with an error\n");
-          quit_=true;
-          printf("waaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaahhhhhhhhhhhhhhhh\n");
+//           quit_=true;
+//           printf("waaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaahhhhhhhhhhhhhhhh\n");
           continue;
           // add some error handling here ========================
         }
@@ -217,13 +218,14 @@
         case ENET_EVENT_TYPE_CONNECT:
 //             printf("====================================================================");
         case ENET_EVENT_TYPE_DISCONNECT:
+//           printf("====================================================================");
         case ENET_EVENT_TYPE_RECEIVE:
-            processData(event);
-            event = new ENetEvent;
+          processData(event);
+          event = new ENetEvent;
           break;
         case ENET_EVENT_TYPE_NONE:
           //receiverThread_->yield();
-          msleep(10);
+          msleep(1);
           break;
       }
 //       usleep(100);

Modified: trunk/src/network/ConnectionManager.h
===================================================================
--- trunk/src/network/ConnectionManager.h	2009-06-20 13:26:42 UTC (rev 3197)
+++ trunk/src/network/ConnectionManager.h	2009-06-20 14:27:38 UTC (rev 3198)
@@ -54,7 +54,7 @@
 {
     const int NETWORK_PORT = 55556;
     const int NETWORK_MAX_CONNECTIONS = 50;
-    const int NETWORK_WAIT_TIMEOUT = 10;
+    const int NETWORK_WAIT_TIMEOUT = 1;
     const int NETWORK_DEFAULT_CHANNEL = 0;
 
   struct _NetworkExport ClientList{

Modified: trunk/src/network/GamestateManager.cc
===================================================================
--- trunk/src/network/GamestateManager.cc	2009-06-20 13:26:42 UTC (rev 3197)
+++ trunk/src/network/GamestateManager.cc	2009-06-20 14:27:38 UTC (rev 3198)
@@ -62,6 +62,10 @@
 
   GamestateManager::~GamestateManager()
   {
+    if( this->reference )
+      delete this->reference;
+    for( std::map<unsigned int, packet::Gamestate*>::iterator it = gamestateQueue.begin(); it != gamestateQueue.end(); it++ )
+      delete (*it).second;
     delete trafficControl_;
   }
 
@@ -132,7 +136,10 @@
     if(client){
 //       COUT(3) << "diffing" << std::endl;
 //       packet::Gamestate* gs1  = gs;
-      gs = gs->diff(client);
+      packet::Gamestate *diffed = gs->diff(client);
+      //packet::Gamestate *gs2 = diffed->undiff(gs);
+//       assert(*gs == *gs2);
+      gs = diffed;
 //       packet::Gamestate* gs2 = gs->undiff(client);
 //       gs = new packet::Gamestate(*gs);
 //       assert(*gs1==*gs2);

Modified: trunk/src/network/Server.cc
===================================================================
--- trunk/src/network/Server.cc	2009-06-20 13:26:42 UTC (rev 3197)
+++ trunk/src/network/Server.cc	2009-06-20 14:27:38 UTC (rev 3198)
@@ -127,6 +127,15 @@
   * This function closes the server
   */
   void Server::close() {
+    ClientInformation *temp = ClientInformation::getBegin();
+    ClientInformation *temp2;
+    // disconnect all connected clients
+    while( temp )
+    {
+      temp2 = temp;
+      temp = temp->next();
+      disconnectClient( temp2 );
+    }
     connection->quitListener();
     return;
   }
@@ -197,7 +206,7 @@
       assert(event->type != ENET_EVENT_TYPE_NONE);
       switch( event->type ) {
       case ENET_EVENT_TYPE_CONNECT:
-        COUT(3) << "processing event_Type_connect" << std::endl;
+        COUT(4) << "processing event_Type_connect" << std::endl;
         addClient(event);
         break;
       case ENET_EVENT_TYPE_DISCONNECT:
@@ -303,6 +312,7 @@
       temp=temp->next();
       // gs gets automatically deleted by enet callback
     }
+    delete del;
     return true;
   }
 
@@ -380,16 +390,9 @@
     ClientInformation *client = ClientInformation::findClient(&event->peer->address);
     if(!client)
       return false;
-    gamestates_->removeClient(client);
-
-// inform all the listeners
-    ObjectList<ClientConnectionListener>::iterator listener = ObjectList<ClientConnectionListener>::begin();
-    while(listener){
-      listener->clientDisconnected(client->getID());
-      listener++;
-    }
-
-    return ClientInformation::removeClient(event->peer);
+    else
+      disconnectClient( client );
+    return true;
   }
 
   void Server::disconnectClient(int clientID){
@@ -397,9 +400,17 @@
     if(client)
       disconnectClient(client);
   }
+  
   void Server::disconnectClient( ClientInformation *client){
     connection->disconnectClient(client);
     gamestates_->removeClient(client);
+// inform all the listeners
+    ObjectList<ClientConnectionListener>::iterator listener = ObjectList<ClientConnectionListener>::begin();
+    while(listener){
+      listener->clientDisconnected(client->getID());
+      ++listener;
+    }
+    delete client; //remove client from list
   }
 
   bool Server::chat(const std::string& message){

Modified: trunk/src/network/TrafficControl.cc
===================================================================
--- trunk/src/network/TrafficControl.cc	2009-06-20 13:26:42 UTC (rev 3197)
+++ trunk/src/network/TrafficControl.cc	2009-06-20 14:27:38 UTC (rev 3198)
@@ -136,6 +136,8 @@
 
 	void TrafficControl::ack(unsigned int clientID, unsigned int gamestateID)
 	{
+    if ( !this->bActive_ )
+      return;
 	  std::list<obj>::iterator itvec;  // iterator to iterate through the acked objects
 
     //assertions to make sure the maps already exist
@@ -188,7 +190,7 @@
   */
   void TrafficControl::updateClientListTemp(std::list<obj>& list)
   {
-    clientListTemp_[currentClientID][currentGamestateID] = std::list<obj>(list);
+    clientListTemp_[currentClientID][currentGamestateID] = list;
   }
 
   /**
@@ -226,34 +228,34 @@
 	void TrafficControl::evaluateList(unsigned int clientID, std::list<obj>& list)
 	{
 
-	  //now the sorting
+    if( bActive_ )
+    {
+      //now the sorting
 
-	  //compare listToProcess vs clientListPerm
-    //if listToProcess contains new Objects, add them to clientListPerm
-    std::list<obj>::iterator itvec;
+      //compare listToProcess vs clientListPerm
+      //if listToProcess contains new Objects, add them to clientListPerm
+      std::list<obj>::iterator itvec;
     
-    std::map<unsigned int, objInfo >& objectListPerm = clientListPerm_[clientID];
+      std::map<unsigned int, objInfo >& objectListPerm = clientListPerm_[clientID];
     
-	  for( itvec=list.begin(); itvec != list.end(); itvec++)
-	  {
-	    if ( objectListPerm.find( (*itvec).objID) != objectListPerm.end() )
+      for( itvec=list.begin(); itvec != list.end(); itvec++)
       {
+        if ( objectListPerm.find( (*itvec).objID) != objectListPerm.end() )
+        {
         // we already have the object in our map
         //obj bleibt in liste und permanente prio wird berechnet
-        objectListPerm[(*itvec).objID].objDiffGS = currentGamestateID - objectListPerm[(*itvec).objID].objCurGS;
-        continue;//check next objId
-      }
-      else
-      {
+          objectListPerm[(*itvec).objID].objDiffGS = currentGamestateID - objectListPerm[(*itvec).objID].objCurGS;
+          continue;//check next objId
+        }
+        else
+        {
         // insert the object into clientListPerm
-        insertinClientListPerm(clientID,*itvec);
-        continue;//check next objId
+          insertinClientListPerm(clientID,*itvec);
+          continue;//check next objId
+        }
       }
-    }
-	  //end compare listToProcess vs clientListPerm
-
-    if( bActive_ )
-    {
+    //end compare listToProcess vs clientListPerm
+      
       //sort copied list according to priorities
       // use boost bind here because we need to pass a memberfunction to stl sort
 //       sort( list.begin(), list.end(), boost::bind(&TrafficControl::prioritySort, this, clientID, _1, _2) );
@@ -274,10 +276,11 @@
       //now sort again after objDataOffset
 //       sort(list.begin(), list.end(), boost::bind(&TrafficControl::dataSort, this, _1, _2) );
       list.sort( boost::bind(&TrafficControl::dataSort, this, _1, _2) );
+      
+      //diese Funktion updateClientList muss noch gemacht werden
+      updateClientListTemp(list);
+      //end of sorting
     }
-    //diese Funktion updateClientList muss noch gemacht werden
-    updateClientListTemp(list);
-    //end of sorting
   }
 
   void TrafficControl::printList(std::list<obj>& list, unsigned int clientID)

Modified: trunk/src/network/packet/Acknowledgement.cc
===================================================================
--- trunk/src/network/packet/Acknowledgement.cc	2009-06-20 13:26:42 UTC (rev 3197)
+++ trunk/src/network/packet/Acknowledgement.cc	2009-06-20 14:27:38 UTC (rev 3198)
@@ -63,7 +63,7 @@
 }
 
 bool Acknowledgement::process(){
-COUT(6) << "processing ACK with ID: " << getAckID() << endl;
+  COUT(5) << "processing ACK with ID: " << getAckID() << endl;
   bool b = GamestateHandler::ackGamestate(getAckID(), clientID_);
   delete this;
   return b;

Modified: trunk/src/network/packet/Gamestate.cc
===================================================================
--- trunk/src/network/packet/Gamestate.cc	2009-06-20 13:26:42 UTC (rev 3197)
+++ trunk/src/network/packet/Gamestate.cc	2009-06-20 14:27:38 UTC (rev 3198)
@@ -78,6 +78,8 @@
 
 Gamestate::~Gamestate()
 {
+  if( header_ )
+    delete header_;
 }
 
 bool Gamestate::collectData(int id, uint8_t mode)
@@ -97,6 +99,7 @@
   }
   
   // create the header object
+  assert( header_ == 0 );
   header_ = new GamestateHeader(data_);
 
   //start collect data synchronisable by synchronisable
@@ -136,6 +139,7 @@
   //start write gamestate header
   header_->setDataSize( currentsize );
   header_->setID( id );
+  header_->setBaseID( GAMESTATEID_INITIAL );
   header_->setDiffed( false );
   header_->setComplete( true );
   header_->setCompressed( false );
@@ -206,7 +210,6 @@
     }
   }
 #endif
-
   return true;
 }
 
@@ -319,7 +322,7 @@
   return true;
 }
 
-Gamestate *Gamestate::diff(Gamestate *base)
+/*Gamestate *Gamestate::diff(Gamestate *base)
 {
   assert(data_);
   assert(!header_->isCompressed());
@@ -354,8 +357,73 @@
   g->flags_=flags_;
   g->packetDirection_ = packetDirection_;
   return g;
+}*/
+
+Gamestate *Gamestate::diff(Gamestate *base)
+{
+  assert(this && base); assert(data_ && base->data_);
+  assert(!header_->isCompressed() && !base->header_->isCompressed());
+  assert(!header_->isDiffed());
+  
+  uint8_t *basep = GAMESTATE_START(base->data_);
+  uint8_t *gs = GAMESTATE_START(this->data_);
+  uint32_t dest_length = header_->getDataSize();
+  
+  if(dest_length==0)
+    return NULL;
+  
+  uint8_t *ndata = new uint8_t[dest_length*sizeof(uint8_t)+GamestateHeader::getSize()];
+  uint8_t *dest = GAMESTATE_START(ndata);
+  
+  rawDiff( dest, gs, basep, header_->getDataSize(), base->header_->getDataSize() );
+#ifndef NDEBUG
+  uint8_t *dest2 = new uint8_t[dest_length];
+  rawDiff( dest2, dest, basep, header_->getDataSize(), base->header_->getDataSize() );
+  assert( memcmp( dest2, gs, dest_length) == 0 );
+#endif
+
+  Gamestate *g = new Gamestate(ndata, getClientID());
+  assert(g->header_);
+  *(g->header_) = *header_;
+  g->header_->setDiffed( true );
+  g->header_->setBaseID( base->getID() );
+  g->flags_=flags_;
+  g->packetDirection_ = packetDirection_;
+  assert(g->isDiffed());
+  assert(!g->isCompressed());
+  return g;
 }
 
+Gamestate *Gamestate::undiff(Gamestate *base)
+{
+  assert(this && base); assert(data_ && base->data_);
+  assert(!header_->isCompressed() && !base->header_->isCompressed());
+  assert(header_->isDiffed());
+  
+  uint8_t *basep = GAMESTATE_START(base->data_);
+  uint8_t *gs = GAMESTATE_START(this->data_);
+  uint32_t dest_length = header_->getDataSize();
+  
+  if(dest_length==0)
+    return NULL;
+  
+  uint8_t *ndata = new uint8_t[dest_length*sizeof(uint8_t)+GamestateHeader::getSize()];
+  uint8_t *dest = ndata + GamestateHeader::getSize();
+  
+  rawDiff( dest, gs, basep, header_->getDataSize(), base->header_->getDataSize() );
+  
+  Gamestate *g = new Gamestate(ndata, getClientID());
+  assert(g->header_);
+  *(g->header_) = *header_;
+  g->header_->setDiffed( false );
+  g->flags_=flags_;
+  g->packetDirection_ = packetDirection_;
+  assert(!g->isDiffed());
+  assert(!g->isCompressed());
+  return g;
+}
+
+
 // Gamestate *Gamestate::diff(Gamestate *base)
 // {
 //   assert(data_);
@@ -408,6 +476,33 @@
 //   return g;
 // }
 
+
+void Gamestate::rawDiff( uint8_t* newdata, uint8_t* data, uint8_t* basedata, uint32_t datalength, uint32_t baselength)
+{
+  uint64_t* gd = (uint64_t*)data;
+  uint64_t* bd = (uint64_t*)basedata;
+  uint64_t* nd = (uint64_t*)newdata;
+  
+  unsigned int i;
+  for( i=0; i<datalength/8; i++ )
+  {
+    if( i<baselength/8 )
+      *(nd+i) = *(gd+i) ^ *(bd+i);  // xor the data
+    else
+      *(nd+i) = *(gd+i); // just copy over the data
+  }
+  unsigned int j;
+  // now process the rest (when datalength isn't a multiple of 4)
+  for( j = 8*(datalength/8); j<datalength; j++ )
+  {
+    if( j<baselength )
+      *(newdata+j) = *(data+j) ^ *(basedata+j); // xor
+    else
+      *(newdata+j) = *(data+j); // just copy
+  }
+  assert(j==datalength);
+}
+
 Gamestate* Gamestate::doSelection(unsigned int clientID, unsigned int targetSize){
   assert(data_);
   std::list<obj>::iterator it;
@@ -477,7 +572,7 @@
 }
 
 
-Gamestate *Gamestate::undiff(Gamestate *base)
+/*Gamestate *Gamestate::undiff(Gamestate *base)
 {
   assert(this && base);assert(data_);
   assert(header_->isDiffed());
@@ -513,9 +608,8 @@
   assert(!g->isDiffed());
   assert(!g->isCompressed());
   return g;
-}
+}*/
 
-
 uint32_t Gamestate::calcGamestateSize(int32_t id, uint8_t mode)
 {
   uint32_t size=0;

Modified: trunk/src/network/packet/Gamestate.h
===================================================================
--- trunk/src/network/packet/Gamestate.h	2009-06-20 13:26:42 UTC (rev 3197)
+++ trunk/src/network/packet/Gamestate.h	2009-06-20 14:27:38 UTC (rev 3198)
@@ -123,6 +123,7 @@
 
     // Packet functions
   private:
+    void rawDiff( uint8_t* newdata, uint8_t* data, uint8_t* basedata, uint32_t datalength, uint32_t baselength);
     virtual uint32_t getSize() const;
     virtual inline bool process();
 

Modified: trunk/src/network/synchronisable/Synchronisable.cc
===================================================================
--- trunk/src/network/synchronisable/Synchronisable.cc	2009-06-20 13:26:42 UTC (rev 3197)
+++ trunk/src/network/synchronisable/Synchronisable.cc	2009-06-20 14:27:38 UTC (rev 3198)
@@ -97,10 +97,14 @@
   Synchronisable::~Synchronisable(){
     // delete callback function objects
     if(!Identifier::isCreatingHierarchy()){
+      // remove object from the static objectMap
+      if (this->objectMode_ != 0x0 && (Host::running() && Host::isServer()))
+        deletedObjects_.push(objectID);
+      // delete all Synchronisable Variables from syncList ( which are also in stringList )
       for(std::vector<SynchronisableVariableBase*>::iterator it = syncList.begin(); it!=syncList.end(); it++)
         delete (*it);
-      if (this->objectMode_ != 0x0 && (Host::running() && Host::isServer()))
-        deletedObjects_.push(objectID);
+      syncList.clear();
+      stringList.clear();
     }
     std::map<uint32_t, Synchronisable*>::iterator it;
     it = objectMap_.find(objectID);
@@ -173,6 +177,8 @@
     no->classID=header.getClassID();
     COUT(4) << "fabricate objectID: " << no->objectID << " classID: " << no->classID << std::endl;
           // update data and create object/entity...
+    assert( Synchronisable::objectMap_.find(header.getObjectID()) == Synchronisable::objectMap_.end() );
+    Synchronisable::objectMap_[header.getObjectID()] = no;
     bool b = no->updateData(mem, mode, true);
     assert(b);
     if (b)
@@ -212,13 +218,14 @@
     if (it1 != objectMap_.end())
       return it1->second;
 
-    ObjectList<Synchronisable>::iterator it;
-    for(it = ObjectList<Synchronisable>::begin(); it; ++it){
-      if( it->getObjectID()==objectID ){
-        objectMap_[objectID] = *it;
-        return *it;
-      }
-    }
+//     ObjectList<Synchronisable>::iterator it;
+//     for(it = ObjectList<Synchronisable>::begin(); it; ++it){
+//       if( it->getObjectID()==objectID ){
+//         objectMap_[objectID] = *it;
+//         return *it;
+//       }
+//     }
+    // if the objects not in the map it should'nt exist at all anymore
     return NULL;
   }
 

Modified: trunk/src/orxonox/gamestates/GSDedicated.cc
===================================================================
--- trunk/src/orxonox/gamestates/GSDedicated.cc	2009-06-20 13:26:42 UTC (rev 3197)
+++ trunk/src/orxonox/gamestates/GSDedicated.cc	2009-06-20 14:27:38 UTC (rev 3198)
@@ -32,19 +32,40 @@
 #include "util/Sleep.h"
 #include "core/Clock.h"
 #include "core/CommandLine.h"
+#include "core/CommandExecutor.h"
 #include "core/Game.h"
 #include "core/GameMode.h"
 #include "network/Server.h"
 
+#include <iostream>
+#include <iomanip>
+#include <boost/bind.hpp>
+
+#ifndef ORXONOX_PLATFORM_WINDOWS
+#include <termios.h>
+#endif
+
+
 namespace orxonox
 {
+    const unsigned int MAX_COMMAND_LENGTH = 255;
+    
     AddGameState(GSDedicated, "dedicated");
+    
+    termios* GSDedicated::originalTerminalSettings_;
 
     GSDedicated::GSDedicated(const std::string& name)
         : GameState(name)
         , server_(0)
         , timeSinceLastUpdate_(0)
+        , closeThread_(false)
+        , inputIterator_(0)
+        , cleanLine_(true)
+        , cursorX_(0)
+        , cursorY_(0)
     {
+        this->commandLine_ = new unsigned char[MAX_COMMAND_LENGTH];
+//         memset( this->commandLine_, 0, MAX_COMMAND_LENGTH );
     }
 
     GSDedicated::~GSDedicated()
@@ -54,6 +75,13 @@
     void GSDedicated::activate()
     {
         GameMode::setHasServer(true);
+        
+        this->inputThread_ = new boost::thread(boost::bind(&GSDedicated::inputThread, this));
+        
+#ifndef ORXONOX_PLATFORM_WINDOWS
+        this->originalTerminalSettings_ = new termios;
+        this->setTerminalMode();
+#endif
 
         this->server_ = new Server(CommandLine::getValue("port"));
         COUT(0) << "Loading scene in server mode" << std::endl;
@@ -65,26 +93,210 @@
     {
         this->server_->close();
         delete this->server_;
+        
+        closeThread_ = true;
+#ifndef ORXONOX_PLATFORM_WINDOWS
+        std::cout << "\033[0G\033[K";
+        std::cout.flush();
+        resetTerminalMode();
+        delete this->originalTerminalSettings_;
+#endif
+        //inputThread_->join();
 
         GameMode::setHasServer(false);
     }
 
     void GSDedicated::update(const Clock& time)
     {
-//        static float startTime = time.getSecondsPrecise();
-//        static int nrOfTicks = 0;
         timeSinceLastUpdate_ += time.getDeltaTime();
         if (timeSinceLastUpdate_ >= NETWORK_PERIOD)
         {
-//            ++nrOfTicks;
-//            COUT(0) << "estimated ticks/sec: " << nrOfTicks/(time.getSecondsPrecise()-startTime) << endl;
             timeSinceLastUpdate_ -= static_cast<unsigned int>(timeSinceLastUpdate_ / NETWORK_PERIOD) * NETWORK_PERIOD;
             server_->update(time);
         }
         else
         {
-            usleep((int)((NETWORK_PERIOD - timeSinceLastUpdate_) * 1000 * 1000));
+            usleep((unsigned int)((NETWORK_PERIOD - timeSinceLastUpdate_)*1000*1000 ));
+            usleep(NETWORK_PERIOD*1000*1000); // NOTE: this is to throttle the non-network framerate
 //            COUT(0) << "sleeping for " << (int)((NETWORK_PERIOD - timeSinceLastUpdate_) * 1000 * 1000) << " usec" << endl;
         }
+        processQueue();
+        printLine();
     }
+    
+    void GSDedicated::inputThread()
+    {
+        unsigned char c;
+        unsigned int  escapeChar=0;
+        while(!closeThread_)
+        {
+            c = getchar();
+            {
+//                 boost::recursive_mutex::scoped_lock(this->inputLineMutex_);
+                if ( inputIterator_>=MAX_COMMAND_LENGTH-1 && c!='\n' )
+                    continue;
+                if( escapeChar > 0 )
+                {
+                    if( c == '[' )
+                    {
+                        escapeChar = 2;
+                        continue;
+                    }
+                    else if ( escapeChar == 2 )
+                    {
+                        switch (c)
+                        {
+                            case 'A': //keyup
+                                
+                                break;
+                            case 'B': //keydown
+                                
+                                break;
+                            case 'C': //keyright
+                                if(cursorX_<inputIterator_)
+                                    ++cursorX_;
+                                break;
+                            case 'D': //keyleft
+                                if(cursorX_>0)
+                                    --cursorX_;
+                                break;
+                            default: //not supported...
+//                                 std::cout << endl << c << endl;
+                                break;
+                        }
+                        escapeChar = 0;
+                    }
+                }
+                else // not in escape sequence mode
+                {
+                    switch (c)
+                    {
+                        case '\n':
+                            this->cleanLine_ = true;
+                            {
+                                boost::recursive_mutex::scoped_lock(this->inputQueueMutex_);
+                                boost::recursive_mutex::scoped_lock(this->inputLineMutex_);
+                                this->commandQueue_.push( std::string((const char*)this->commandLine_,inputIterator_) );
+                            }
+                            memset( this->commandLine_, 0, inputIterator_ );
+                            inputIterator_ = 0;
+                            this->cursorX_ = 0;
+                            this->cursorY_ = 0;
+                            std::cout << endl;
+                            break;
+                        case 127: // backspace
+                        case '\b':
+                            deleteCharacter( this->cursorX_ );
+                            break;
+                        case '\t':
+                        {
+//                             boost::recursive_mutex::scoped_lock(this->inputLineMutex_);
+                            std::cout << endl << CommandExecutor::hint( std::string((const char*)this->commandLine_,inputIterator_) ) << endl;
+                            strncpy((char*)this->commandLine_, CommandExecutor::complete( std::string((const char*)this->commandLine_,inputIterator_) ).c_str(), MAX_COMMAND_LENGTH);
+                            inputIterator_ = strlen((const char*)this->commandLine_);
+                            break;
+                        }
+                        case '\033': // 1. escape character
+                            escapeChar = 1;
+                            break;
+                        default:
+                            insertCharacter( this->cursorX_, c );
+                            break;
+                    }
+                }
+            }
+        }
+    }
+    
+    void GSDedicated::printLine()
+    {
+#ifndef ORXONOX_PLATFORM_WINDOWS
+        // set cursor to the begining of the line and erase the line
+        std::cout << "\033[0G\033[K";
+//         boost::recursive_mutex::scoped_lock(this->inputLineMutex_);
+        // print status line
+        std::cout << std::fixed << std::setprecision(2) << std::setw(5) << Game::getInstance().getAvgFPS() << " fps, " << std::setprecision(2) << std::setw(5) << Game::getInstance().getAvgTickTime() << " ms avg ticktime # ";
+        //save cursor position
+        std::cout << "\033[s";
+        //print commandLine buffer
+        std::cout << std::string((const char*)this->commandLine_, inputIterator_);
+        //restore cursor position and move it cursorX_ to the right
+        std::cout << "\033[u";
+        if( this->cursorX_ > 0 )
+            std::cout << "\033[" << this->cursorX_ << "C";
+        std::cout.flush();
+#endif
+    }
+    
+    void GSDedicated::processQueue()
+    {
+        std::string tempstr;
+        {
+            boost::recursive_mutex::scoped_lock lock1(this->inputQueueMutex_);
+            while(true)
+            {
+                if ( !this->commandQueue_.empty() )
+                {
+                    tempstr = this->commandQueue_.front();
+                    this->commandQueue_.pop();
+                    lock1.unlock();
+                }
+                else
+                    break;
+                CommandExecutor::execute(tempstr, true);
+            }
+        }
+    }
+    
+    void GSDedicated::setTerminalMode()
+    {
+#ifndef ORXONOX_PLATFORM_WINDOWS
+        termios new_settings;
+     
+        tcgetattr(0,this->originalTerminalSettings_);
+        new_settings = *this->originalTerminalSettings_;
+        new_settings.c_lflag &= ~( ICANON | ECHO );
+//         new_settings.c_lflag |= ( ISIG | IEXTEN );
+        new_settings.c_cc[VTIME] = 0;
+        new_settings.c_cc[VMIN] = 1;
+        tcsetattr(0,TCSANOW,&new_settings);
+        COUT(0) << endl;
+//       atexit(&GSDedicated::resetTerminalMode);
+#endif
+    }
+    
+    void GSDedicated::resetTerminalMode()
+    {
+#ifndef ORXONOX_PLATFORM_WINDOWS
+        tcsetattr(0, TCSANOW, GSDedicated::originalTerminalSettings_);
+#endif
+    }
+    
+    void GSDedicated::insertCharacter( unsigned int position, char c )
+    {
+//         std::cout << endl << (unsigned int)c << endl;
+        // check that we do not exceed MAX_COMMAND_LENGTH
+        if( inputIterator_+1 < MAX_COMMAND_LENGTH )
+        {
+            // if cursor not at end of line then move the rest of the line
+            if( position != this->inputIterator_ )
+                    memmove( this->commandLine_+position+1, this->commandLine_+position, this->inputIterator_-position);
+//             boost::recursive_mutex::scoped_lock(this->inputLineMutex_);
+            this->commandLine_[position] = c;
+            ++this->cursorX_;
+            ++this->inputIterator_;
+        }
+    }
+    void GSDedicated::deleteCharacter( unsigned int position )
+    {
+//         boost::recursive_mutex::scoped_lock(this->inputLineMutex_);
+        if ( this->inputIterator_>0 && position>0 )
+        {
+            if ( position != this->inputIterator_ )
+                memmove( this->commandLine_+position-1, this->commandLine_+position, this->inputIterator_-position);
+            --this->cursorX_;
+            --this->inputIterator_;
+        }
+    }
+    
 }

Modified: trunk/src/orxonox/gamestates/GSDedicated.h
===================================================================
--- trunk/src/orxonox/gamestates/GSDedicated.h	2009-06-20 13:26:42 UTC (rev 3197)
+++ trunk/src/orxonox/gamestates/GSDedicated.h	2009-06-20 14:27:38 UTC (rev 3198)
@@ -33,9 +33,17 @@
 
 #include "core/GameState.h"
 #include "network/NetworkPrereqs.h"
+#include <queue>
+#include <cstring>
+#include <boost/thread/thread.hpp>
+#include <boost/thread/mutex.hpp>
+#include <boost/thread/recursive_mutex.hpp>
 
+struct termios;
+
 namespace orxonox
 {
+    
     class _OrxonoxExport GSDedicated : public GameState
     {
     public:
@@ -47,8 +55,30 @@
         void update(const Clock& time);
 
     private:
-        Server* server_;
-        float   timeSinceLastUpdate_;
+        void inputThread();
+        void printLine();
+        void processQueue();
+        void setTerminalMode();
+        static void resetTerminalMode();
+        
+        void insertCharacter( unsigned int position, char c );
+        void deleteCharacter( unsigned int position );
+        
+        Server*                 server_;
+        float                   timeSinceLastUpdate_;
+        
+        boost::thread           *inputThread_;
+        boost::recursive_mutex  inputLineMutex_;
+        boost::recursive_mutex  inputQueueMutex_;
+        bool                    closeThread_;
+        bool                    cleanLine_;
+        unsigned char*          commandLine_;
+        unsigned int            inputIterator_;
+        std::queue<std::string> commandQueue_;
+        static termios*         originalTerminalSettings_;
+        
+        unsigned int            cursorX_;
+        unsigned int            cursorY_;
     };
 }
 

Modified: trunk/src/util/OutputBuffer.cc
===================================================================
--- trunk/src/util/OutputBuffer.cc	2009-06-20 13:26:42 UTC (rev 3197)
+++ trunk/src/util/OutputBuffer.cc	2009-06-20 14:27:38 UTC (rev 3198)
@@ -35,8 +35,6 @@
 
 namespace orxonox
 {
-    const int OUTPUTBUFFER_MAX_LINE_LENGTH = 16384; //! The maximal number of lines that can be stored within the OutputBuffer.
-
     /**
         @brief Adds a new listener to the list.
         @param listener The new listener
@@ -104,11 +102,8 @@
     */
     bool OutputBuffer::getLine(std::string* output)
     {
-        char line[OUTPUTBUFFER_MAX_LINE_LENGTH];
+        std::getline(this->stream_, *output);
 
-        this->stream_.getline(line, OUTPUTBUFFER_MAX_LINE_LENGTH);
-        (*output) = std::string(line);
-
         bool eof = this->stream_.eof();
         bool fail = this->stream_.fail();
 

Modified: trunk/src/util/SignalHandler.cc
===================================================================
--- trunk/src/util/SignalHandler.cc	2009-06-20 13:26:42 UTC (rev 3197)
+++ trunk/src/util/SignalHandler.cc	2009-06-20 14:27:38 UTC (rev 3198)
@@ -106,11 +106,6 @@
      */
     void SignalHandler::sigHandler( int sig )
     {
-      for ( SignalCallbackList::iterator it = SignalHandler::getInstance().callbackList.begin(); it != SignalHandler::getInstance().callbackList.end(); it++  )
-      {
-        (*(it->cb))( it->someData );
-      }
-
       std::string sigName = "UNKNOWN";
 
       switch ( sig )
@@ -125,7 +120,19 @@
           sigName = "SIGILL";
           break;
       }
+      // if the signalhandler has already been destroyed then don't do anything
+      if( SignalHandler::singletonRef_s == 0 )
+      {
+        COUT(0) << "recieved signal " << sigName.c_str() << std::endl << "can't write backtrace because SignalHandler already destroyed" << std::endl;
+        exit(EXIT_FAILURE);
+      }
 
+      for ( SignalCallbackList::iterator it = SignalHandler::getInstance().callbackList.begin(); it != SignalHandler::getInstance().callbackList.end(); it++  )
+      {
+        (*(it->cb))( it->someData );
+      }
+
+
       COUT(0) << "recieved signal " << sigName.c_str() << std::endl << "try to write backtrace to file orxonox_crash.log" << std::endl;
 
       int sigPipe[2];




More information about the Orxonox-commit mailing list