[Orxonox-commit 43] r2749 - in branches/network/src: core network network/packet network/synchronisable

scheusso at orxonox.net scheusso at orxonox.net
Thu Mar 5 13:54:28 CET 2009


Author: scheusso
Date: 2009-03-05 13:54:27 +0100 (Thu, 05 Mar 2009)
New Revision: 2749

Modified:
   branches/network/src/core/Factory.cc
   branches/network/src/core/Factory.h
   branches/network/src/network/ConnectionManager.cc
   branches/network/src/network/packet/ClassID.cc
   branches/network/src/network/packet/ClassID.h
   branches/network/src/network/synchronisable/Synchronisable.cc
Log:
changed the process of classid (or networkid in the factory) synchronisation:
the packet classid synchronises all classid at once now


Modified: branches/network/src/core/Factory.cc
===================================================================
--- branches/network/src/core/Factory.cc	2009-03-04 21:48:08 UTC (rev 2748)
+++ branches/network/src/core/Factory.cc	2009-03-05 12:54:27 UTC (rev 2749)
@@ -86,12 +86,20 @@
     */
     void Factory::changeNetworkID(Identifier* identifier, const uint32_t oldID, const uint32_t newID)
     {
-        getFactoryPointer()->identifierNetworkIDMap_.erase(oldID);
+//        getFactoryPointer()->identifierNetworkIDMap_.erase(oldID);
         getFactoryPointer()->identifierNetworkIDMap_[newID] = identifier;
 //std::cout << identifier->getName() << ": " << oldID << " -> " << newID << std::endl;
     }
 
     /**
+        @brief Cleans the NetworkID map (needed on clients for correct initialization)
+    */
+    void Factory::cleanNetworkIDs()
+    {
+        getFactoryPointer()->identifierNetworkIDMap_.clear();
+    }
+
+    /**
         @brief Creates the class-hierarchy by creating and destroying one object of each type.
     */
     void Factory::createClassHierarchy()

Modified: branches/network/src/core/Factory.h
===================================================================
--- branches/network/src/core/Factory.h	2009-03-04 21:48:08 UTC (rev 2748)
+++ branches/network/src/core/Factory.h	2009-03-05 12:54:27 UTC (rev 2749)
@@ -62,6 +62,7 @@
             static Identifier* getIdentifier(const uint32_t id);
             static void add(const std::string& name, Identifier* identifier);
             static void changeNetworkID(Identifier* identifier, const uint32_t oldID, const uint32_t newID);
+	    static void cleanNetworkIDs();
             static void createClassHierarchy();
 
             static Factory* getFactoryPointer();    // avoid overriding order problem in the static intialisation process

Modified: branches/network/src/network/ConnectionManager.cc
===================================================================
--- branches/network/src/network/ConnectionManager.cc	2009-03-04 21:48:08 UTC (rev 2748)
+++ branches/network/src/network/ConnectionManager.cc	2009-03-05 12:54:27 UTC (rev 2749)
@@ -45,9 +45,9 @@
 #include <boost/thread/thread.hpp>
 #include <boost/bind.hpp>
 
-#include "core/CoreIncludes.h"
-#include "core/BaseObject.h"
-#include "core/Iterator.h"
+// #include "core/CoreIncludes.h"
+// #include "core/BaseObject.h"
+// #include "core/Iterator.h"
 #include "util/Math.h"
 #include "util/Sleep.h"
 #include "ClientInformation.h"
@@ -302,33 +302,44 @@
    *
    * @param clientID
    */
+//   void ConnectionManager::syncClassid(unsigned int clientID) {
+//     unsigned int network_id=0, failures=0;
+//     std::string classname;
+//     Identifier *id;
+//     std::map<std::string, Identifier*>::const_iterator it = Factory::getFactoryMapBegin();
+//     while(it != Factory::getFactoryMapEnd()){
+//       id = (*it).second;
+//       if(id == NULL)
+//         continue;
+//       classname = id->getName();
+//       network_id = id->getNetworkID();
+//       if(network_id==0)
+//         COUT(3) << "we got a null class id: " << id->getName() << std::endl;
+//       COUT(4) << "Con.Man:syncClassid:\tnetwork_id: " << network_id << ", classname: " << classname << std::endl;
+// 
+//       packet::ClassID *classid = new packet::ClassID( network_id, classname );
+//       classid->setClientID(clientID);
+//       while(!classid->send() && failures < 10){
+//         failures++;
+//       }
+//       ++it;
+//     }
+//     //sendPackets();
+//     COUT(4) << "syncClassid:\tall synchClassID packets have been sent" << std::endl;
+//   }
+
   void ConnectionManager::syncClassid(unsigned int clientID) {
-    unsigned int network_id=0, failures=0;
-    std::string classname;
-    Identifier *id;
-    std::map<std::string, Identifier*>::const_iterator it = Factory::getFactoryMapBegin();
-    while(it != Factory::getFactoryMapEnd()){
-      id = (*it).second;
-      if(id == NULL)
-        continue;
-      classname = id->getName();
-      network_id = id->getNetworkID();
-      if(network_id==0)
-        COUT(3) << "we got a null class id: " << id->getName() << std::endl;
-      COUT(4) << "Con.Man:syncClassid:\tnetwork_id: " << network_id << ", classname: " << classname << std::endl;
-
-      packet::ClassID *classid = new packet::ClassID( network_id, classname );
-      classid->setClientID(clientID);
-      while(!classid->send() && failures < 10){
-        failures++;
-      }
-      ++it;
+    int failures=0;
+    packet::ClassID *classid = new packet::ClassID();
+    classid->setClientID(clientID);
+    while(!classid->send() && failures < 10){
+      failures++;
     }
-    //sendPackets();
+    assert(failures<10);
     COUT(4) << "syncClassid:\tall synchClassID packets have been sent" << std::endl;
   }
+  
 
-
   void ConnectionManager::disconnectClient(ClientInformation *client){
     {
       boost::recursive_mutex::scoped_lock lock(ConnectionManager::enet_mutex);

Modified: branches/network/src/network/packet/ClassID.cc
===================================================================
--- branches/network/src/network/packet/ClassID.cc	2009-03-04 21:48:08 UTC (rev 2748)
+++ branches/network/src/network/packet/ClassID.cc	2009-03-05 12:54:27 UTC (rev 2749)
@@ -30,55 +30,133 @@
 
 #include "ClassID.h"
 #include "core/CoreIncludes.h"
+#include "core/Factory.h"
 #include <cstring>
+#include <string>
 #include <assert.h>
+#include <map>
+#include <queue>
 
 namespace orxonox {
 namespace packet {
 
 
+#define PACKET_FLAGS_CLASSID  ENET_PACKET_FLAG_RELIABLE
+#define _PACKETID             0
 
-  ClassID::ClassID( uint32_t classID, std::string className )
- : Packet()
-{
+
+ClassID::ClassID( ) : Packet(){
+  Identifier *id;
+  std::string classname;
+  unsigned int nrOfClasses=0; 
+  unsigned int packetSize=2*sizeof(uint32_t); //space for the packetID and for the nrofclasses
+  uint32_t network_id;
   flags_ = flags_ | PACKET_FLAGS_CLASSID;
-  classNameLength_=className.length()+1;
-  assert(getSize());
-  data_=new unsigned char[ getSize() ];
-  assert(data_);
-  *(ENUM::Type *)(data_ + _PACKETID ) = ENUM::ClassID;
-  *(uint32_t *)(data_ + _CLASSID ) = classID;
-  *(uint32_t *)(data_ + _CLASSNAMELENGTH ) = classNameLength_;
-  memcpy( data_+_CLASSNAME, (void *)className.c_str(), classNameLength_ );
+  std::queue<std::pair<uint32_t, std::string> > tempQueue;
+  
+  //calculate total needed size (for all strings and integers)
+  std::map<std::string, Identifier*>::const_iterator it = Factory::getFactoryMapBegin();
+  for(;it != Factory::getFactoryMapEnd();++it){
+    id = (*it).second;
+    if(id == NULL)
+      continue;
+    classname = id->getName();
+    network_id = id->getNetworkID();
+    if(network_id==0)
+      COUT(3) << "we got a null class id: " << id->getName() << std::endl;
+    // now push the network id and the classname to the stack
+    tempQueue.push( std::pair<unsigned int, std::string>(network_id, classname) );
+    ++nrOfClasses;
+    packetSize += (classname.size()+1)+sizeof(uint32_t)+sizeof(uint32_t);
+  }
+  
+  this->data_=new uint8_t[ packetSize ];
+  //set the appropriate packet id
+  assert(this->data_);
+  *(ENUM::Type *)(this->data_ + _PACKETID ) = ENUM::ClassID;
+  
+  uint8_t *temp=data_+sizeof(uint32_t);
+  // save the number of all classes
+  *(uint32_t*)temp = nrOfClasses;
+  temp += sizeof(uint32_t);
+  
+  // now save all classids and classnames
+  std::pair<uint32_t, std::string> tempPair;
+  while( !tempQueue.empty() ){
+    tempPair = tempQueue.front();
+    tempQueue.pop();
+    *(uint32_t*)temp = tempPair.first;
+    *(uint32_t*)(temp+sizeof(uint32_t)) = tempPair.second.size()+1;
+    memcpy(temp+2*sizeof(uint32_t), tempPair.second.c_str(), tempPair.second.size()+1);
+    temp+=2*sizeof(uint32_t)+tempPair.second.size()+1;
+  }
+  
+  COUT(0) << "classid packetSize is " << packetSize << endl;
+  
 }
 
 ClassID::ClassID( uint8_t* data, unsigned int clientID )
   : Packet(data, clientID)
 {
-  memcpy( (void *)&classNameLength_, &data[ _CLASSNAMELENGTH ], sizeof(classNameLength_) );
 }
 
 ClassID::~ClassID()
 {
 }
 
+uint32_t ClassID::getSize() const{
+  uint8_t *temp = data_+sizeof(uint32_t); // packet identification
+  uint32_t totalsize = sizeof(uint32_t); // packet identification
+  uint32_t nrOfClasses = *(uint32_t*)temp;
+  temp += sizeof(uint32_t);
+  totalsize += sizeof(uint32_t); // storage size for nr of all classes
+  
+  for(unsigned int i=0; i<nrOfClasses; i++){
+    totalsize += 2*sizeof(uint32_t) + *(uint32_t*)(temp + sizeof(uint32_t));
+  }
+  return totalsize;
+}
 
+
 bool ClassID::process(){
-  COUT(3) << "processing classid: " << getClassID() << " name: " << getClassName() << std::endl;
-  Identifier *id=ClassByString( std::string(getClassName()) );
-  if(id==NULL){
-    COUT(0) << "Recieved a bad classname" << endl;
-    abort();
+  int nrOfClasses;
+  uint8_t *temp = data_+sizeof(uint32_t); //skip the packetid
+  uint32_t networkID;
+  uint32_t stringsize;
+  unsigned char *classname;
+  
+  
+  //clean the map of network ids
+  Factory::cleanNetworkIDs();
+  
+  COUT(4) << "=== processing classids: " << endl;
+  std::pair<uint32_t, std::string> tempPair;
+  Identifier *id;
+  // read the total number of classes
+  nrOfClasses = *(uint32_t*)temp;
+  temp += sizeof(uint32_t);
+  
+  for( int i=0; i<nrOfClasses; i++){
+    networkID = *(uint32_t*)temp;
+    stringsize = *(uint32_t*)(temp+sizeof(uint32_t));
+    classname = temp+2*sizeof(uint32_t);
+    id=ClassByString( std::string((const char*)classname) );
+    COUT(0) << "processing classid: " << networkID << " name: " << classname << " id: " << id << std::endl;
+    if(id==NULL){
+      COUT(0) << "Recieved a bad classname" << endl;
+      abort();
+    }
+    id->setNetworkID( networkID );
+    temp += 2*sizeof(uint32_t) + stringsize;
   }
-  id->setNetworkID( getClassID() );
   delete this;
   return true;
 }
 
 
-uint32_t ClassID::getClassID(){
-  return *(uint32_t *)(data_ + _CLASSID);
-}
+// uint32_t ClassID::getClassID(){
+//   return *(uint32_t *)(data_ + _CLASSID);
+// }
 
 } //namespace packet
 }//namespace orxonox

Modified: branches/network/src/network/packet/ClassID.h
===================================================================
--- branches/network/src/network/packet/ClassID.h	2009-03-04 21:48:08 UTC (rev 2748)
+++ branches/network/src/network/packet/ClassID.h	2009-03-05 12:54:27 UTC (rev 2749)
@@ -37,11 +37,6 @@
 namespace orxonox {
 namespace packet {
 
-#define PACKET_FLAGS_CLASSID  ENET_PACKET_FLAG_RELIABLE
-#define _PACKETID             0
-#define _CLASSID              _PACKETID + sizeof(ENUM::Type)
-#define _CLASSNAMELENGTH      _CLASSID + sizeof(uint32_t)
-#define _CLASSNAME            _CLASSNAMELENGTH + sizeof(classNameLength_)
   
 /**
 	@author
@@ -49,18 +44,19 @@
 class _NetworkExport ClassID : public Packet
 {
 public:
-  ClassID( uint32_t classID, std::string className );
+  ClassID( );
   ClassID( uint8_t* data, unsigned int clientID );
   ~ClassID();
 
-  inline uint32_t getSize() const{ return sizeof(packet::ENUM::Type) + 2*sizeof(uint32_t) + classNameLength_; }
+  uint32_t getSize() const;
   bool process();
 
-  uint32_t getClassID();
-  uint32_t getClassNameLength(){ return classNameLength_; }
-  const char *getClassName(){ return (const char*)(data_+_CLASSNAME); }
+//   uint32_t getClassID();
+//   uint32_t getClassNameLength(){ return classNameLength_; }
+//   const char *getClassName(){ return (const char*)(data_+_CLASSNAME); }
 private:
-  uint32_t classNameLength_;
+//   uint32_t classNameLength_;
+//   static bool alreadySetOneClassID_;
 };
 
 } //namespace packet

Modified: branches/network/src/network/synchronisable/Synchronisable.cc
===================================================================
--- branches/network/src/network/synchronisable/Synchronisable.cc	2009-03-04 21:48:08 UTC (rev 2748)
+++ branches/network/src/network/synchronisable/Synchronisable.cc	2009-03-05 12:54:27 UTC (rev 2749)
@@ -157,6 +157,8 @@
     Identifier* id = ClassByID(header.getClassID());
     if (!id)
     {
+        for(int i = 0; i<100; i++)
+            COUT(0) << "classid: " << i << " identifier: " << ClassByID(i) << endl;
         COUT(0) << "Assertion failed: id" << std::endl;
         COUT(0) << "Possible reason for this error: Client received a synchronizable object whose class has no factory." << std::endl;
         abort();




More information about the Orxonox-commit mailing list