Changeset 7163 for code/trunk/src/libraries/network
- Timestamp:
- Aug 11, 2010, 8:55:13 AM (14 years ago)
- Location:
- code/trunk
- Files:
-
- 28 edited
- 6 copied
Legend:
- Unmodified
- Added
- Removed
-
code/trunk
- Property svn:mergeinfo changed
-
code/trunk/src/libraries/network/CMakeLists.txt
r5781 r7163 29 29 GamestateClient.cc 30 30 GamestateHandler.cc 31 LANDiscoverable.cc 32 LANDiscovery.cc 31 33 NetworkFunction.cc 32 34 Host.cc … … 48 50 GamestateManager.h 49 51 Host.h 52 LANDiscoverable.h 53 LANDiscovery.h 50 54 NetworkFunction.h 51 55 NetworkPrecompiledHeaders.h … … 60 64 61 65 ORXONOX_ADD_LIBRARY(network 62 DEFINE_SYMBOL 63 "NETWORK_SHARED_BUILD" 66 TOLUA_FILES 67 Client.h 68 LANDiscovery.h 64 69 PCH_FILE 65 70 NetworkPrecompiledHeaders.h -
code/trunk/src/libraries/network/ChatListener.cc
r5781 r7163 36 36 RegisterRootObject(ChatListener); 37 37 } 38 39 //void ChatListener::incomingChat( const std::string& message, 40 //unsigned int senderID ) 41 //{ 42 //COUT(0) << "Chat: \"" << message << "\"\n"; 43 44 45 //} 46 47 38 48 } 39 49 -
code/trunk/src/libraries/network/ChatListener.h
r5781 r7163 38 38 { 39 39 public: 40 /* constructor, destructor */ 40 41 ChatListener(); 41 42 virtual ~ChatListener() {} 42 43 44 /* What to do with incoming chat */ 43 45 virtual void incomingChat(const std::string& message, unsigned int senderID) = 0; 44 46 }; -
code/trunk/src/libraries/network/Client.cc
r6417 r7163 50 50 #include "FunctionCallManager.h" 51 51 #include "core/CoreIncludes.h" 52 #include "core/CommandLineParser.h" 52 53 #include "core/Game.h" 54 #include "core/ScopedSingletonManager.h" 53 55 54 56 namespace orxonox 55 57 { 56 58 59 ManageScopedSingleton( Client, ScopeID::Root, true ); 57 60 58 61 /** … … 61 64 */ 62 65 Client::Client(): 66 gamestate(0), 63 67 isSynched_(false), 64 68 gameStateFailure_(false), 65 69 timeSinceLastUpdate_(0) 66 70 { 67 } 68 69 /** 70 * Constructor for the Client class 71 * @param address the server address 72 * @param port port of the application on the server 73 */ 74 Client::Client(const std::string& address, int port): 75 isSynched_(false), 76 gameStateFailure_(false), 77 timeSinceLastUpdate_(0) 78 { 79 setPort( port ); 80 setServerAddress( address ); 81 } 82 83 Client::~Client(){ 71 this->setDestination( CommandLineParser::getValue("dest").getString(), CommandLineParser::getValue("port") ); 72 } 73 74 Client::~Client() 75 { 84 76 if ( ClientConnection::isConnected() ) 85 77 closeConnection(); … … 90 82 * @return true/false 91 83 */ 92 bool Client::establishConnection(){ 84 bool Client::establishConnection() 85 { 93 86 Synchronisable::setClient(true); 94 return ClientConnection::establishConnection(); 87 this->gamestate = new GamestateClient(); 88 if( ClientConnection::establishConnection() ) 89 { 90 Host::setActive(true); 91 return true; 92 } 93 else 94 return false; 95 95 } 96 96 … … 99 99 * @return true/false 100 100 */ 101 bool Client::closeConnection(){ 101 bool Client::closeConnection() 102 { 103 assert(this->gamestate); 104 delete this->gamestate; 105 this->gamestate = 0; 106 Host::setActive(false); 102 107 return ClientConnection::closeConnection(); 103 108 } 104 105 bool Client::queuePacket(ENetPacket *packet, int clientID){ 109 110 void Client::setDestination(const std::string& serverAddress, unsigned int port) 111 { 112 ClientConnection::setServerAddress(serverAddress); 113 ClientConnection::setPort(port); 114 } 115 116 bool Client::queuePacket(ENetPacket *packet, int clientID) 117 { 106 118 bool b = ClientConnection::addPacket(packet); 107 119 assert(b); … … 109 121 } 110 122 111 bool Client::processChat(const std::string& message, unsigned int playerID){ 123 bool Client::processChat(const std::string& message, unsigned int playerID) 124 { 112 125 // COUT(1) << "Player " << playerID << ": " << message << std::endl; 113 126 return true; 114 127 } 115 128 116 void Client::printRTT(){ 129 void Client::printRTT() 130 { 117 131 COUT(0) << "Round trip time to server is " << ClientConnection::getRTT() << " ms" << endl; 118 132 } … … 123 137 * @return result(true/false) 124 138 */ 125 bool Client::chat(const std::string& message){ 139 bool Client::chat(const std::string& message) 140 { 126 141 packet::Chat *m = new packet::Chat(message, Host::getPlayerID()); 127 142 return m->send(); … … 133 148 * @param time 134 149 */ 135 void Client::update(const Clock& time){ 150 void Client::update(const Clock& time) 151 { 136 152 //this steers our network frequency 137 153 timeSinceLastUpdate_+=time.getDeltaTime(); … … 143 159 { 144 160 COUT(4) << "popping partial gamestate: " << std::endl; 145 packet::Gamestate *gs = gamestate .getGamestate();161 packet::Gamestate *gs = gamestate->getGamestate(); 146 162 //assert(gs); <--- there might be the case that no data has to be sent, so its commented out now 147 163 if(gs){ … … 157 173 158 174 Connection::processQueue(); 159 if(gamestate .processGamestates())175 if(gamestate->processGamestates()) 160 176 { 161 177 if(!isSynched_) 162 178 isSynched_=true; 163 179 } 164 gamestate .cleanup();180 gamestate->cleanup(); 165 181 Connection::sendPackets(); 166 182 … … 184 200 } 185 201 202 203 186 204 } -
code/trunk/src/libraries/network/Client.h
r5961 r7163 47 47 48 48 #include "util/UtilPrereqs.h" 49 #include "util/Singleton.h" 49 50 #include "ClientConnection.h" 50 51 #include "GamestateClient.h" 51 52 #include "Host.h" 53 #include "LANDiscovery.h" 54 #include "packet/ServerInformation.h" 52 55 56 // tolua_begin 53 57 namespace orxonox 54 58 { 59 // tolua_end 55 60 /** 56 61 Client *client; … … 60 65 * 61 66 */ 62 class _NetworkExport Client : public Host, public ClientConnection{ 67 class _NetworkExport Client // tolua_export 68 : public Host, protected ClientConnection, public Singleton<Client> 69 { // tolua_export 70 friend class Singleton<Client>; 63 71 public: 64 72 Client(); 65 Client(const std::string& address, int port);66 73 ~Client(); 74 75 static Client* getInstance(){ return singletonPtr_s; } // tolua_export 67 76 68 77 bool establishConnection(); 78 void setDestination( const std::string& serverAddress, unsigned int port ); // tolua_export 69 79 bool closeConnection(); 70 80 bool queuePacket(ENetPacket *packet, int clientID); … … 81 91 virtual bool isServer_(){return false;} 82 92 83 GamestateClient gamestate; 93 static Client* singletonPtr_s; 94 GamestateClient* gamestate; 84 95 bool isSynched_; 85 96 86 97 bool gameStateFailure_; 87 98 float timeSinceLastUpdate_; 88 }; 99 }; // tolua_export 89 100 90 101 91 } 102 } // tolua_export 92 103 93 104 #endif /* _Client_H__ */ -
code/trunk/src/libraries/network/Connection.cc
r6417 r7163 36 36 namespace orxonox 37 37 { 38 Connection *Connection::instance_=0;38 // Connection *Connection::instance_=0; 39 39 40 40 Connection::Connection(): 41 41 host_(0) 42 42 { 43 assert(instance_==0);44 Connection::instance_=this;43 // assert(instance_==0); 44 // Connection::instance_=this; 45 45 enet_initialize(); 46 46 atexit(enet_deinitialize); … … 48 48 49 49 Connection::~Connection(){ 50 Connection::instance_=0;50 // Connection::instance_=0; 51 51 } 52 52 … … 67 67 68 68 bool Connection::sendPackets() { 69 if ( !Connection::instance_ ||this->host_==NULL )69 if ( /*!Connection::instance_ || */this->host_==NULL ) 70 70 return false; 71 71 enet_host_flush(this->host_); -
code/trunk/src/libraries/network/Connection.h
r6417 r7163 61 61 protected: 62 62 Connection(); 63 static Connection* getInstance(){ return Connection::instance_; }63 // static Connection* getInstance(){ return Connection::instance_; } 64 64 65 65 int service(ENetEvent* event); … … 75 75 ENetAddress *bindAddress_; 76 76 77 static Connection *instance_;77 // static Connection *instance_; 78 78 79 79 }; -
code/trunk/src/libraries/network/GamestateClient.cc
r6417 r7163 161 161 assert(b); 162 162 } 163 if(gs->isDiffed()){ 164 packet::Gamestate *base = gamestateMap_[gs->getBaseID()]; 165 if(!base){ 166 COUT(3) << "could not find base gamestate id: " << gs->getBaseID() << endl; 167 delete gs; 168 return 0; 169 } 170 // assert(base); //TODO: fix this 171 packet::Gamestate *undiffed = gs->undiff(base); 172 delete gs; 173 gs=undiffed; 174 COUT(5) << "successfully undiffed gamestate id: " << undiffed->getID() << std::endl; 163 if(gs->isDiffed()) 164 { 165 assert(0); 166 // packet::Gamestate *base = gamestateMap_[gs->getBaseID()]; 167 // if(!base) 168 // { 169 // COUT(0) << "could not find base gamestate id: " << gs->getBaseID() << endl; 170 // assert(0); 171 // delete gs; 172 // return 0; 173 // } 174 // packet::Gamestate *undiffed = gs->undiff(base); 175 // delete gs; 176 // gs=undiffed; 177 // COUT(5) << "successfully undiffed gamestate id: " << undiffed->getID() << std::endl; 175 178 } 176 179 if(gs->spreadData(0x2)) … … 178 181 else 179 182 { 180 COUT(3) << "could not spread gamestate" << endl; 183 COUT(0) << "could not spread gamestate" << endl; 184 assert(0); 181 185 return NULL; 182 186 } -
code/trunk/src/libraries/network/GamestateManager.cc
r6417 r7163 43 43 #include <cassert> 44 44 #include <queue> 45 #include "util/Clock.h" 45 46 // #include <boost/thread/mutex.hpp> 46 47 … … 158 159 159 160 clientGamestates.push(0); 160 finishGamestate( cid, &clientGamestates.back(), client, reference );161 finishGamestate( cid, clientGamestates.back(), client, reference ); 161 162 //FunctorMember<GamestateManager>* functor = 162 163 // ExecutorMember<GamestateManager>* executor = createExecutor( createFunctor(&GamestateManager::finishGamestate, this) ); … … 180 181 181 182 182 void GamestateManager::finishGamestate( unsigned int clientID, packet::Gamestate* *destgamestate, packet::Gamestate* base, packet::Gamestate* gamestate ) {183 void GamestateManager::finishGamestate( unsigned int clientID, packet::Gamestate*& destgamestate, packet::Gamestate* base, packet::Gamestate* gamestate ) { 183 184 //why are we searching the same client's gamestate id as we searched in 184 185 //Server::sendGameState? … … 186 187 //chose wheather the next gamestate is the first or not 187 188 188 packet::Gamestate *gs = gamestate->doSelection(clientID, 20000); 189 // packet::Gamestate *gs = new packet::Gamestate(*gamestate); 189 // packet::Gamestate *gs = gamestate->doSelection(clientID, 20000); 190 // packet::Gamestate* gs = new packet::Gamestate(*gamestate); 191 // packet::Gamestate* gs = gamestate; 192 packet::Gamestate *gs = new packet::Gamestate(*gamestate); //TODO: is this neccessary ? 190 193 // packet::Gamestate *gs = new packet::Gamestate(); 191 194 // gs->collectData( id_, 0x1 ); … … 193 196 gamestateMap_[clientID][gamestate->getID()]=gs; 194 197 // this->threadMutex_->unlock(); 198 Clock clock; 199 clock.capture(); 195 200 196 201 if(base) 197 202 { 198 199 // COUT(3) << "diffing" << std::endl; 200 // packet::Gamestate* gs1 = gs; 201 packet::Gamestate *diffed = gs->diff(base); 202 //packet::Gamestate *gs2 = diffed->undiff(gs); 203 // assert(*gs == *gs2); 204 gs = diffed; 205 // packet::Gamestate* gs2 = gs->undiff(client); 206 // gs = new packet::Gamestate(*gs); 207 // assert(*gs1==*gs2); 208 } 209 else{ 203 packet::Gamestate *diffed1 = gs->diffVariables(base); 204 if( diffed1->getDataSize() == 0 ) 205 { 206 delete diffed1; 207 destgamestate = 0; 208 return; 209 } 210 gs = diffed1; 211 } 212 else 213 { 210 214 gs = new packet::Gamestate(*gs); 211 215 } … … 214 218 bool b = gs->compressData(); 215 219 assert(b); 216 // COUT(4) << "sending gamestate with id " << gs->getID(); 220 clock.capture(); 221 COUT(0) << "diff time: " << clock.getDeltaTime() << endl; 222 // COUT(5) << "sending gamestate with id " << gs->getID(); 217 223 // if(gamestate->isDiffed()) 218 // COUT(4) << " and baseid " << gs->getBaseID() << endl;224 // COUT(5) << " and baseid " << gs->getBaseID() << endl; 219 225 // else 220 // COUT(4) << endl;226 // COUT(5) << endl; 221 227 gs->setClientID(clientID); 222 *destgamestate = gs;228 destgamestate = gs; 223 229 } 224 230 -
code/trunk/src/libraries/network/GamestateManager.h
r5781 r7163 76 76 void sendGamestates(); 77 77 // packet::Gamestate *popGameState(unsigned int clientID); 78 void finishGamestate( unsigned int clientID, packet::Gamestate* *destgamestate, packet::Gamestate* base, packet::Gamestate* gamestate );78 void finishGamestate( unsigned int clientID, packet::Gamestate*& destgamestate, packet::Gamestate* base, packet::Gamestate* gamestate ); 79 79 80 80 bool getSnapshot(); -
code/trunk/src/libraries/network/Host.cc
r5961 r7163 38 38 namespace orxonox { 39 39 40 SetConsoleCommandShortcut(Host, Chat);40 SetConsoleCommandShortcut(Host, Chat); 41 41 42 Host *Host::instance_=0; 42 // Host* Host::instance_=0; 43 uint32_t Host::clientID_s=0; 44 uint32_t Host::shipID_s=-1; 45 std::vector<Host*> Host::instances_s; 43 46 44 /**45 * @brief Constructor: assures that only one reference will be created and sets the pointer46 */47 Host::Host()48 {49 clientID_=0;50 assert(instance_==0);51 instance_=this;52 this->printRTTCC_ = createConsoleCommand( createFunctor(&Host::printRTT, this), "printRTT");53 CommandExecutor::addConsoleCommandShortcut( this->printRTTCC_ );54 }47 /** 48 * @brief Constructor: assures that only one reference will be created and sets the pointer 49 */ 50 Host::Host() 51 { 52 // assert(instance_==0); 53 instances_s.push_back(this); 54 this->printRTTCC_ = createConsoleCommand( createFunctor(&Host::printRTT, this), "printRTT" ); 55 CommandExecutor::addConsoleCommandShortcut( this->printRTTCC_ ); 56 this->bIsActive_ = false; 57 } 55 58 56 59 57 /** 58 * @brief Destructor: resets the instance pointer to 0 59 */ 60 Host::~Host() 61 { 62 instance_=0; 63 if( this->printRTTCC_ ) 64 delete this->printRTTCC_; 65 } 60 /** 61 * @brief Destructor: resets the instance pointer to 0 62 */ 63 Host::~Host() 64 { 65 assert( std::find( instances_s.begin(), instances_s.end(), this )!=instances_s.end() ); 66 instances_s.erase(std::find( instances_s.begin(), instances_s.end(), this )); 67 if( this->printRTTCC_ ) 68 delete this->printRTTCC_; 69 } 66 70 67 /** 68 * This function is used to add an enetpacket to be sent to another peer 69 * @param packet Packet to be added 70 * @param clientID ID of the client the packet should be sent to 71 * @return success? 72 */ 73 bool Host::addPacket(ENetPacket *packet, int clientID){ 74 if(instance_) 75 return instance_->queuePacket(packet, clientID); 76 else 77 return false; 78 } 71 /** 72 * This function is used to add an enetpacket to be sent to another peer 73 * @param packet Packet to be added 74 * @param clientID ID of the client the packet should be sent to 75 * @return success? 76 */ 77 bool Host::addPacket(ENetPacket *packet, int clientID) 78 { 79 bool result = true; 80 for( std::vector<Host*>::iterator it = instances_s.begin(); it!=instances_s.end(); ++it ) 81 { 82 if( (*it)->isActive() ) 83 { 84 if( !(*it)->queuePacket(packet, clientID) ) 85 result = false; 86 } 87 } 88 return result; 89 } 79 90 80 /** 81 * This function returns the ID of the player 82 * @return playerID 83 */ 84 unsigned int Host::getPlayerID(){ 85 if(!instance_) 86 return 0; 87 return instance_->clientID_; 88 } 91 bool Host::Chat(const std::string& message) 92 { 93 if(instances_s.size()==0) 94 { 95 for (ObjectList<ChatListener>::iterator it = ObjectList<ChatListener>::begin(); it != ObjectList<ChatListener>::end(); ++it) 96 it->incomingChat(message, 0); 97 return true; 98 } 99 else 100 { 101 bool result = true; 102 for( std::vector<Host*>::iterator it = instances_s.begin(); it!=instances_s.end(); ++it ) 103 { 104 if( (*it)->isActive() ) 105 { 106 if( !(*it)->chat(message) ) 107 result = false; 108 } 109 } 110 return result; 111 } 112 } 89 113 90 bool Host::Chat(const std::string& message){ 91 if(!instance_) 114 bool Host::Broadcast(const std::string& message) 115 { 116 if(instances_s.size()==0) 117 { 118 for (ObjectList<ChatListener>::iterator it = ObjectList<ChatListener>::begin(); it != ObjectList<ChatListener>::end(); ++it) 119 it->incomingChat(message, CLIENTID_UNKNOWN); 120 return true; 121 } 122 else 123 { 124 bool result = true; 125 for( std::vector<Host*>::iterator it = instances_s.begin(); it!=instances_s.end(); ++it ) 126 { 127 if( (*it)->isActive() ) 128 { 129 if( !(*it)->broadcast(message) ) 130 result = false; 131 } 132 } 133 return result; 134 } 135 } 136 137 bool Host::incomingChat(const std::string& message, unsigned int playerID) 92 138 { 93 139 for (ObjectList<ChatListener>::iterator it = ObjectList<ChatListener>::begin(); it != ObjectList<ChatListener>::end(); ++it) 94 it->incomingChat(message, 0); 95 return true; 140 it->incomingChat(message, playerID); 141 142 bool result = true; 143 for( std::vector<Host*>::iterator it = instances_s.begin(); it!=instances_s.end(); ++it ) 144 { 145 if( (*it)->isActive() ) 146 { 147 if( !(*it)->processChat(message, playerID) ) 148 result = false; 149 } 150 } 151 return result; 96 152 } 97 return instance_->chat(message);98 }99 153 100 bool Host::Broadcast(const std::string& message){ 101 if(!instance_) 154 bool Host::isServer() 102 155 { 103 for (ObjectList<ChatListener>::iterator it = ObjectList<ChatListener>::begin(); it != ObjectList<ChatListener>::end(); ++it) 104 it->incomingChat(message, CLIENTID_UNKNOWN); 105 return true; 156 for (std::vector<Host*>::iterator it=instances_s.begin(); it!=instances_s.end(); ++it ) 157 { 158 if( (*it)->isServer_() ) 159 return true; 160 } 161 return false; 106 162 } 107 else108 return instance_->broadcast(message);109 }110 111 bool Host::incomingChat(const std::string& message, unsigned int playerID){112 for (ObjectList<ChatListener>::iterator it = ObjectList<ChatListener>::begin(); it != ObjectList<ChatListener>::end(); ++it)113 it->incomingChat(message, playerID);114 115 return instance_->processChat(message, playerID);116 }117 163 118 164 }//namespace orxonox -
code/trunk/src/libraries/network/Host.h
r6073 r7163 33 33 #include "core/CorePrereqs.h" 34 34 35 #include <vector> 36 35 37 namespace orxonox { 36 38 37 39 const unsigned int CLIENTID_SERVER = 0; 38 const unsigned int NETWORK_FREQUENCY = 30;40 const unsigned int NETWORK_FREQUENCY = 25; 39 41 const float NETWORK_PERIOD = 1.0f/NETWORK_FREQUENCY; 40 42 … … 49 51 class _NetworkExport Host{ 50 52 private: 51 //TODO add the ese functions or adequate53 //TODO add these functions or adequate 52 54 //virtual bool processChat(packet::Chat *message, unsigned int clientID)=0; 53 55 //virtual bool sendChat(packet::Chat *chat)=0; … … 63 65 Host(); 64 66 virtual ~Host(); 65 static Host *instance_; 66 unsigned int clientID_; 67 unsigned int shipID_; 67 void setActive( bool bActive ){ bIsActive_ = bActive; } 68 // static Host *instance_; 68 69 69 70 public: 70 static bool running(){return instance_!=0;} 71 // static Host* getInstance(){ return instance_; } 72 static bool running(){ return instances_s.size(); } 71 73 static bool addPacket(ENetPacket *packet, int clientID=0); 72 74 //static bool chat(std::string& message); 73 75 // static bool receiveChat(packet::Chat *message, unsigned int clientID); 74 static unsigned int getPlayerID() ;75 static unsigned int getShipID(){return instance_->shipID_;}76 static void setClientID(unsigned int id){ instance_->clientID_= id; }77 static void setShipID(unsigned int id){ instance_->shipID_= id; }78 static bool isServer() { return instance_->isServer_(); }76 static unsigned int getPlayerID(){ return clientID_s; } 77 static unsigned int getShipID(){return shipID_s;} 78 static void setClientID(unsigned int id){ clientID_s = id; } 79 static void setShipID(unsigned int id){ shipID_s = id; } 80 static bool isServer(); 79 81 static bool Chat(const std::string& message); 80 82 static bool Broadcast(const std::string& message); 81 83 static bool incomingChat(const std::string& message, unsigned int playerID); 82 84 virtual void printRTT()=0; 85 bool isActive(){ return bIsActive_; } 83 86 private: 84 87 ConsoleCommand* printRTTCC_; 88 static uint32_t clientID_s; 89 static uint32_t shipID_s; 90 static std::vector<Host*> instances_s; 91 bool bIsActive_; 85 92 }; 86 93 -
code/trunk/src/libraries/network/NetworkPrereqs.h
r6417 r7163 64 64 namespace orxonox 65 65 { 66 static const unsigned int GAMESTATEID_INITIAL = static_cast<unsigned int>(-1); 67 static const unsigned int CLIENTID_UNKNOWN = static_cast<unsigned int>(-2); 66 static const unsigned int GAMESTATEID_INITIAL = static_cast<unsigned int>(-1); 67 static const unsigned int CLIENTID_UNKNOWN = static_cast<unsigned int>(-2); 68 extern const char* LAN_DISCOVERY_MESSAGE; 69 extern const char* LAN_DISCOVERY_ACK; 70 static const unsigned int LAN_DISCOVERY_PORT = 55557; 68 71 } 69 72 -
code/trunk/src/libraries/network/Server.cc
r6417 r7163 69 69 * 70 70 */ 71 Server::Server() { 71 Server::Server() 72 { 72 73 this->timeSinceLastUpdate_=0; 73 74 } 74 75 75 Server::Server(int port){ 76 Server::Server(int port) 77 { 76 78 this->setPort( port ); 77 79 this->timeSinceLastUpdate_=0; … … 83 85 * @param bindAddress Address to listen on 84 86 */ 85 Server::Server(int port, const std::string& bindAddress) { 87 Server::Server(int port, const std::string& bindAddress) 88 { 86 89 this->setPort( port ); 87 90 this->setBindAddress( bindAddress ); … … 92 95 * @brief Destructor 93 96 */ 94 Server::~Server(){ 97 Server::~Server() 98 { 95 99 } 96 100 … … 98 102 * This function opens the server by creating the listener thread 99 103 */ 100 void Server::open() { 104 void Server::open() 105 { 106 Host::setActive(true); 101 107 COUT(4) << "opening server" << endl; 102 108 this->openListener(); 109 LANDiscoverable::setActivity(true); 103 110 return; 104 111 } … … 107 114 * This function closes the server 108 115 */ 109 void Server::close() { 116 void Server::close() 117 { 118 Host::setActive(false); 110 119 COUT(4) << "closing server" << endl; 111 120 this->disconnectClients(); 112 121 this->closeListener(); 122 LANDiscoverable::setActivity(false); 113 123 return; 114 124 } 115 125 116 bool Server::processChat(const std::string& message, unsigned int playerID){ 126 bool Server::processChat(const std::string& message, unsigned int playerID) 127 { 117 128 ClientInformation *temp = ClientInformation::getBegin(); 118 129 packet::Chat *chat; … … 134 145 * @param time time since last tick 135 146 */ 136 void Server::update(const Clock& time) { 147 void Server::update(const Clock& time) 148 { 137 149 // receive incoming packets 138 150 Connection::processQueue(); 151 // receive and process incoming discovery packets 152 LANDiscoverable::update(); 139 153 140 154 if ( ClientInformation::hasClients() ) … … 157 171 } 158 172 159 bool Server::queuePacket(ENetPacket *packet, int clientID){ 173 bool Server::queuePacket(ENetPacket *packet, int clientID) 174 { 160 175 return ServerConnection::addPacket(packet, clientID); 161 176 } … … 164 179 * @brief: returns ping time to client in milliseconds 165 180 */ 166 unsigned int Server::getRTT(unsigned int clientID){ 181 unsigned int Server::getRTT(unsigned int clientID) 182 { 167 183 assert(ClientInformation::findClient(clientID)); 168 184 return ClientInformation::findClient(clientID)->getRTT(); … … 178 194 * @brief: return packet loss ratio to client (scales from 0 to 1) 179 195 */ 180 double Server::getPacketLoss(unsigned int clientID){ 196 double Server::getPacketLoss(unsigned int clientID) 197 { 181 198 assert(ClientInformation::findClient(clientID)); 182 199 return ClientInformation::findClient(clientID)->getPacketLoss(); … … 186 203 * takes a new snapshot of the gamestate and sends it to the clients 187 204 */ 188 void Server::updateGamestate() { 205 void Server::updateGamestate() 206 { 189 207 if( ClientInformation::getBegin()==NULL ) 190 208 //no client connected … … 208 226 * sends the gamestate 209 227 */ 210 bool Server::sendGameState() { 228 bool Server::sendGameState() 229 { 211 230 // COUT(5) << "Server: starting function sendGameState" << std::endl; 212 231 // ClientInformation *temp = ClientInformation::getBegin(); … … 244 263 } 245 264 246 bool Server::sendObjectDeletes(){ 265 bool Server::sendObjectDeletes() 266 { 247 267 ClientInformation *temp = ClientInformation::getBegin(); 248 268 if( temp == NULL ) … … 257 277 // COUT(3) << "sending DeleteObjects" << std::endl; 258 278 while(temp != NULL){ 259 if( !(temp->getSynched()) ){ 279 if( !(temp->getSynched()) ) 280 { 260 281 COUT(5) << "Server: not sending gamestate" << std::endl; 261 282 temp=temp->next(); … … 276 297 277 298 278 void Server::addPeer(ENetEvent *event){ 299 void Server::addPeer(ENetEvent *event) 300 { 279 301 static unsigned int newid=1; 280 302 281 303 COUT(2) << "Server: adding client" << std::endl; 282 304 ClientInformation *temp = ClientInformation::insertBack(new ClientInformation); 283 if(!temp){ 305 if(!temp) 306 { 284 307 COUT(2) << "Server: could not add client" << std::endl; 285 308 } … … 310 333 } 311 334 312 bool Server::createClient(int clientID){ 335 bool Server::createClient(int clientID) 336 { 313 337 ClientInformation *temp = ClientInformation::findClient(clientID); 314 if(!temp){ 338 if(!temp) 339 { 315 340 COUT(2) << "Conn.Man. could not create client with id: " << clientID << std::endl; 316 341 return false; … … 345 370 } 346 371 347 void Server::disconnectClient( ClientInformation *client ){ 372 void Server::disconnectClient( ClientInformation *client ) 373 { 348 374 ServerConnection::disconnectClient( client ); 349 375 GamestateManager::removeClient(client); … … 352 378 } 353 379 354 bool Server::chat(const std::string& message){ 380 bool Server::chat(const std::string& message) 381 { 355 382 return this->sendChat(message, Host::getPlayerID()); 356 383 } 357 384 358 bool Server::broadcast(const std::string& message){ 385 bool Server::broadcast(const std::string& message) 386 { 359 387 return this->sendChat(message, CLIENTID_UNKNOWN); 360 388 } 361 389 362 bool Server::sendChat(const std::string& message, unsigned int clientID){ 390 bool Server::sendChat(const std::string& message, unsigned int clientID) 391 { 363 392 ClientInformation *temp = ClientInformation::getBegin(); 364 393 packet::Chat *chat; 365 while(temp){ 394 while(temp) 395 { 366 396 chat = new packet::Chat(message, clientID); 367 397 chat->setClientID(temp->getID()); … … 377 407 } 378 408 379 void Server::syncClassid(unsigned int clientID) { 409 void Server::syncClassid(unsigned int clientID) 410 { 380 411 int failures=0; 381 412 packet::ClassID *classid = new packet::ClassID(); -
code/trunk/src/libraries/network/Server.h
r6417 r7163 37 37 #include "GamestateManager.h" 38 38 #include "ServerConnection.h" 39 #include "LANDiscoverable.h" 39 40 40 41 namespace orxonox … … 45 46 * It implements all functions necessary for a Server 46 47 */ 47 class _NetworkExport Server : public Host, public ServerConnection, public GamestateManager {48 class _NetworkExport Server : public Host, public ServerConnection, public GamestateManager, public LANDiscoverable{ 48 49 public: 49 50 Server(); -
code/trunk/src/libraries/network/ServerConnection.cc
r6417 r7163 94 94 95 95 bool ServerConnection::addPacketAll(ENetPacket *packet) { 96 if ( !Connection::getInstance() )97 return false;98 enet_host_broadcast( Connection::get Instance()->getHost(), 0, packet);96 // if ( !Connection::getInstance() ) 97 // return false; 98 enet_host_broadcast( Connection::getHost(), 0, packet); 99 99 return true; 100 100 } -
code/trunk/src/libraries/network/ServerConnection.h
r6417 r7163 56 56 bool openListener(); 57 57 bool closeListener(); 58 staticbool addPacket(ENetPacket *packet, unsigned int ID);59 staticbool addPacketAll(ENetPacket *packet);58 bool addPacket(ENetPacket *packet, unsigned int ID); 59 bool addPacketAll(ENetPacket *packet); 60 60 virtual void disconnectClient(ClientInformation *client); 61 61 void disconnectClient(int clientID); -
code/trunk/src/libraries/network/packet/CMakeLists.txt
r5929 r7163 11 11 Welcome.cc 12 12 COMPILATION_END 13 ServerInformation.cc 13 14 ) 14 15 … … 23 24 Gamestate.h 24 25 Packet.h 26 ServerInformation.h 25 27 Welcome.h 26 28 ) -
code/trunk/src/libraries/network/packet/Chat.cc
r6417 r7163 37 37 38 38 #define PACKET_FLAGS_CHAT PacketFlag::Reliable 39 40 /* Some lengths */ 39 41 #define _PACKETID 0 40 42 const int _PLAYERID = _PACKETID + sizeof(Type::Value); … … 45 47 : Packet() 46 48 { 49 /* Add chat flag to packet flags */ 47 50 flags_ = flags_ | PACKET_FLAGS_CHAT; 51 52 /* set message length to length of input string + 1 */ 48 53 messageLength_ = message.length()+1; 54 55 /* allocate memory for the data */ 49 56 data_=new unsigned char[ getSize() ]; 57 50 58 *(Type::Value *)(data_ + _PACKETID ) = Type::Chat; 51 59 *(unsigned int *)(data_ + _PLAYERID ) = playerID; 52 60 *(unsigned int *)(data_ + _MESSAGELENGTH ) = messageLength_; 61 62 /* cast the hell out of the message string, and copy it into the 63 * data buffer. 64 */ 53 65 memcpy( data_+_MESSAGE, static_cast<void*>(const_cast<char*>(message.c_str())), messageLength_ ); 54 66 } -
code/trunk/src/libraries/network/packet/Chat.h
r6073 r7163 41 41 { 42 42 public: 43 /* constructors */ 43 44 Chat( const std::string& message, unsigned int playerID ); 44 45 Chat( uint8_t* data, unsigned int clientID ); 46 47 /* destructor */ 45 48 ~Chat(); 46 49 50 /* get size of packet */ 47 51 inline unsigned int getSize() const; 52 53 /* process chat message packet and remove it afterwards */ 48 54 bool process(); 49 55 56 /* Get the length of the message (not the full size of the packet) */ 50 57 unsigned int getMessageLength(){ return messageLength_; }; 58 59 /* return message content */ 51 60 unsigned char *getMessage(); 61 52 62 private: 63 64 /* Message length */ 53 65 uint32_t messageLength_; 66 67 /* Client ID (an integral value for identification) */ 54 68 unsigned int clientID_; 55 69 }; -
code/trunk/src/libraries/network/packet/ClassID.cc
r6417 r7163 65 65 tempQueue.push( std::pair<unsigned int, std::string>(network_id, classname) ); 66 66 ++nrOfClasses; 67 packetSize += (classname.size()+1)+sizeof( uint32_t)+sizeof(uint32_t);67 packetSize += (classname.size()+1)+sizeof(network_id)+sizeof(uint32_t); 68 68 } 69 69 … … 80 80 // now save all classids and classnames 81 81 std::pair<uint32_t, std::string> tempPair; 82 uint32_t tempsize = 2*sizeof(uint32_t); // packetid and nrOfClasses 82 83 while( !tempQueue.empty() ){ 83 84 tempPair = tempQueue.front(); … … 87 88 memcpy(temp+2*sizeof(uint32_t), tempPair.second.c_str(), tempPair.second.size()+1); 88 89 temp+=2*sizeof(uint32_t)+tempPair.second.size()+1; 90 tempsize+=2*sizeof(uint32_t)+tempPair.second.size()+1; 89 91 } 92 assert(tempsize==packetSize); 90 93 91 94 COUT(5) << "classid packetSize is " << packetSize << endl; … … 111 114 for(unsigned int i=0; i<nrOfClasses; i++){ 112 115 totalsize += 2*sizeof(uint32_t) + *(uint32_t*)(temp + sizeof(uint32_t)); 116 temp += 2*sizeof(uint32_t) + *(uint32_t*)(temp + sizeof(uint32_t)); 113 117 } 114 118 return totalsize; … … 141 145 COUT(3) << "processing classid: " << networkID << " name: " << classname << " id: " << id << std::endl; 142 146 if(id==NULL){ 143 COUT(0) << "Rec ieved a bad classname" << endl;147 COUT(0) << "Received a bad classname" << endl; 144 148 abort(); 145 149 } -
code/trunk/src/libraries/network/packet/Gamestate.cc
r6417 r7163 45 45 #define PACKET_FLAG_GAMESTATE PacketFlag::Reliable 46 46 47 48 Gamestate::Gamestate() 47 inline bool memzero( uint8_t* data, uint32_t datalength) 48 { 49 uint64_t* d = (uint64_t*)data; 50 51 for( unsigned int i=0; i<datalength/8; i++ ) 52 { 53 if( *(d+i) != 0 ) 54 return false; 55 } 56 // now process the rest (when datalength isn't a multiple of 4) 57 for( unsigned int j = 8*(datalength/8); j<datalength; j++ ) 58 { 59 if( *(data+j) != 0 ) 60 return false; 61 } 62 return true; 63 } 64 65 66 Gamestate::Gamestate(): 67 header_(0) 49 68 { 50 69 flags_ = flags_ | PACKET_FLAG_GAMESTATE; 51 header_ = 0; 52 } 70 } 71 53 72 54 73 Gamestate::Gamestate(uint8_t *data, unsigned int clientID): 55 74 Packet(data, clientID) 56 75 { 57 76 flags_ = flags_ | PACKET_FLAG_GAMESTATE; … … 59 78 } 60 79 80 61 81 Gamestate::Gamestate(uint8_t *data) 62 82 { 63 83 flags_ = flags_ | PACKET_FLAG_GAMESTATE; 64 data_ =data;84 data_ = data; 65 85 header_ = new GamestateHeader(data_); 66 86 } 67 87 88 68 89 Gamestate::Gamestate(const Gamestate& g) : 69 Packet( *(Packet*)&g ) 90 Packet( *(Packet*)&g ), nrOfVariables_(0) 70 91 { 71 92 flags_ = flags_ | PACKET_FLAG_GAMESTATE; 72 93 header_ = new GamestateHeader(data_); 94 sizes_ = g.sizes_; 73 95 } 74 96 … … 79 101 delete header_; 80 102 } 103 81 104 82 105 bool Gamestate::collectData(int id, uint8_t mode) … … 91 114 return false; 92 115 data_ = new uint8_t[size + GamestateHeader::getSize()]; 93 if(!data_){ 116 if(!data_) 117 { 94 118 COUT(2) << "GameStateManager: could not allocate memory" << std::endl; 95 119 return false; … … 101 125 102 126 //start collect data synchronisable by synchronisable 103 uint8_t *mem =data_;127 uint8_t *mem = data_; // in this stream store all data of the variables and the headers of the synchronisable 104 128 mem += GamestateHeader::getSize(); 105 129 ObjectList<Synchronisable>::iterator it; 106 for(it = ObjectList<Synchronisable>::begin(); it; ++it){ 130 for(it = ObjectList<Synchronisable>::begin(); it; ++it) 131 { 107 132 108 133 // tempsize=it->getSize(id, mode); 109 134 110 tempsize = it->getData(mem, id, mode);135 tempsize = it->getData(mem, this->sizes_, id, mode); 111 136 if ( tempsize != 0 ) 112 137 dataVector_.push_back( obj(it->getObjectID(), it->getCreatorID(), tempsize, mem-data_) ); 113 138 114 139 #ifndef NDEBUG 115 if(currentsize+tempsize > size){ 140 if(currentsize+tempsize > size) 141 { 116 142 assert(0); // if we don't use multithreading this part shouldn't be neccessary 117 143 // start allocate additional memory … … 148 174 } 149 175 176 150 177 bool Gamestate::spreadData(uint8_t mode) 151 178 { … … 153 180 assert(data_); 154 181 assert(!header_->isCompressed()); 155 assert(!header_->isDiffed());156 182 uint8_t *mem=data_+GamestateHeader::getSize(); 157 183 Synchronisable *s; 158 184 159 185 // update the data of the objects we received 160 while(mem < data_+GamestateHeader::getSize()+header_->getDataSize()){ 186 while(mem < data_+GamestateHeader::getSize()+header_->getDataSize()) 187 { 161 188 SynchronisableHeader objectheader(mem); 162 189 … … 170 197 else 171 198 { 172 mem += objectheader.getDataSize() ;199 mem += objectheader.getDataSize() + ( objectheader.isDiffed() ? SynchronisableHeaderLight::getSize() : SynchronisableHeader::getSize() ); 173 200 } 174 201 } … … 181 208 // In debug mode, check first, whether there are no duplicate objectIDs 182 209 #ifndef NDEBUG 183 if(this->getID()%1000==0){ 210 if(this->getID()%1000==1) 211 { 184 212 std::list<uint32_t> v1; 185 213 ObjectList<Synchronisable>::iterator it; 186 for (it = ObjectList<Synchronisable>::begin(); it != ObjectList<Synchronisable>::end(); ++it) { 187 if (it->getObjectID() == OBJECTID_UNKNOWN) { 188 if (it->objectMode_ != 0x0) { 214 for (it = ObjectList<Synchronisable>::begin(); it != ObjectList<Synchronisable>::end(); ++it) 215 { 216 if (it->getObjectID() == OBJECTID_UNKNOWN) 217 { 218 if (it->objectMode_ != 0x0) 219 { 189 220 COUT(0) << "Found object with OBJECTID_UNKNOWN on the client with objectMode != 0x0!" << std::endl; 190 221 COUT(0) << "Possible reason for this error: Client created a synchronized object without the Server's approval." << std::endl; … … 193 224 } 194 225 } 195 else { 226 else 227 { 196 228 std::list<uint32_t>::iterator it2; 197 for (it2 = v1.begin(); it2 != v1.end(); ++it2) { 198 if (it->getObjectID() == *it2) { 229 for (it2 = v1.begin(); it2 != v1.end(); ++it2) 230 { 231 if (it->getObjectID() == *it2) 232 { 199 233 COUT(0) << "Found duplicate objectIDs on the client!" << std::endl 200 234 << "Are you sure you don't create a Sychnronisable objcect with 'new' \ … … 211 245 } 212 246 247 213 248 uint32_t Gamestate::getSize() const 214 249 { … … 222 257 } 223 258 224 bool Gamestate::operator==(packet::Gamestate gs){ 259 260 bool Gamestate::operator==(packet::Gamestate gs) 261 { 225 262 uint8_t *d1 = data_+GamestateHeader::getSize(); 226 263 uint8_t *d2 = gs.data_+GamestateHeader::getSize(); … … 233 270 } 234 271 272 235 273 bool Gamestate::process() 236 274 { 237 275 return GamestateHandler::addGamestate(this, getClientID()); 238 276 } 239 240 277 241 278 … … 253 290 int retval; 254 291 retval = compress( dest, &buffer, source, (uLong)(header_->getDataSize()) ); 255 switch ( retval ) { 292 switch ( retval ) 293 { 256 294 case Z_OK: COUT(5) << "G.St.Man: compress: successfully compressed" << std::endl; break; 257 295 case Z_MEM_ERROR: COUT(1) << "G.St.Man: compress: not enough memory available in gamestate.compress" << std::endl; return false; … … 270 308 header_->setCompSize( buffer ); 271 309 header_->setCompressed( true ); 272 COUT( 5) << "gamestate compress datasize: " << header_->getDataSize() << " compsize: " << header_->getCompSize() << std::endl;310 COUT(0) << "gamestate compress datasize: " << header_->getDataSize() << " compsize: " << header_->getCompSize() << std::endl; 273 311 return true; 274 312 } 313 314 275 315 bool Gamestate::decompressData() 276 316 { … … 289 329 uLongf length=bufsize; 290 330 retval = uncompress( dest, &length, source, (uLong)compsize ); 291 switch ( retval ) { 331 switch ( retval ) 332 { 292 333 case Z_OK: COUT(5) << "successfully decompressed" << std::endl; break; 293 334 case Z_MEM_ERROR: COUT(1) << "not enough memory available" << std::endl; return false; … … 301 342 delete temp; 302 343 303 if (this->bDataENetAllocated_){ 344 if (this->bDataENetAllocated_) 345 { 304 346 // Memory was allocated by ENet. --> We let it be since enet_packet_destroy will 305 347 // deallocated it anyway. So data and packet stay together. 306 348 this->bDataENetAllocated_ = false; 307 349 } 308 else{ 350 else 351 { 309 352 // We allocated the memory in the first place (unlikely). So we destroy the old data 310 353 // and overwrite it with the new decompressed data. … … 320 363 } 321 364 322 /*Gamestate *Gamestate::diff(Gamestate *base) 323 { 324 assert(data_); 325 assert(!header_->isCompressed()); 365 366 Gamestate* Gamestate::diffVariables(Gamestate *base) 367 { 368 assert(this && base); assert(data_ && base->data_); 369 assert(!header_->isCompressed() && !base->header_->isCompressed()); 326 370 assert(!header_->isDiffed()); 327 GamestateHeader diffHeader(base->data_); 328 uint8_t *basep = GAMESTATE_START(base->data_), *gs = GAMESTATE_START(this->data_); 329 uint32_t of=0; // pointers offset 330 uint32_t dest_length=0; 331 dest_length=header_->getDataSize(); 332 if(dest_length==0) 333 return NULL; 334 uint8_t *ndata = new uint8_t[dest_length*sizeof(uint8_t)+GamestateHeader::getSize()]; 335 uint8_t *dest = ndata + GamestateHeader::getSize(); 336 while(of < diffHeader.getDataSize() && of < header_->getDataSize()){ 337 *(dest+of)=*(basep+of)^*(gs+of); // do the xor 338 ++of; 339 } 340 if(diffHeader.getDataSize()!=header_->getDataSize()){ 341 uint8_t n=0; 342 if(diffHeader.getDataSize() < header_->getDataSize()){ 343 while(of<dest_length){ 344 *(dest+of)=n^*(gs+of); 345 of++; 346 } 347 } 348 } 349 350 Gamestate *g = new Gamestate(ndata, getClientID()); 371 372 373 // *** first do a raw diff of the two gamestates 374 375 uint8_t *baseData = GAMESTATE_START(base->data_); 376 uint8_t *origData = GAMESTATE_START(this->data_); 377 uint32_t origLength = header_->getDataSize(); 378 uint32_t baseLength = base->header_->getDataSize(); 379 380 assert( origLength && baseLength ); 381 382 uint8_t *nData = new uint8_t[origLength + GamestateHeader::getSize() + sizeof(uint32_t)*this->nrOfVariables_]; // this is the maximum size needed in the worst case 383 uint8_t *dest = GAMESTATE_START(nData); 384 385 uint32_t baseOffset = 0; //offset in the diffed stream 386 uint32_t origOffset = 0; //offset in the new stream with removed 0's 387 std::vector<uint32_t>::iterator sizes = this->sizes_.begin(); 388 389 while( origOffset < origLength ) 390 { 391 //iterate through all objects 392 393 SynchronisableHeader h(origData+origOffset); 394 395 // Find (if possible) the current object in the datastream of the old gamestate 396 // Start at the current offset position 397 if(baseOffset >= baseLength) 398 baseOffset = 0; 399 uint8_t* temp = baseData + baseOffset; 400 uint32_t objectID = h.getObjectID(); 401 assert(temp < baseData+baseLength); 402 assert(dest < nData + origLength + GamestateHeader::getSize() + sizeof(uint32_t)*this->nrOfVariables_); 403 assert(sizes != this->sizes_.end()); 404 while ( temp < baseData+baseLength ) 405 { 406 SynchronisableHeader htemp(temp); 407 assert( htemp.getDataSize()!=0 ); 408 if ( htemp.getObjectID() == objectID ) 409 { 410 assert( h.getClassID() == htemp.getClassID() ); 411 goto DODIFF; 412 } 413 // { 414 // SynchronisableHeader htemp2(temp+htemp.getDataSize()+SynchronisableHeader::getSize()); 415 // if( temp+htemp.getDataSize()+SynchronisableHeader::getSize() < baseData+baseLength ) 416 // { 417 // assert(htemp2.getClassID()<500); 418 // assert(htemp2.getDataSize()!=0 && htemp2.getDataSize()<1000); 419 // assert(htemp2.isDiffed()==false); 420 // } 421 // } 422 temp += htemp.getDataSize()+SynchronisableHeader::getSize(); 423 424 } 425 // If not found start looking at the beginning 426 assert( temp==baseData+baseLength ); 427 temp = baseData; 428 // { 429 // SynchronisableHeader htemp2(temp); 430 // if( temp < baseData+baseLength ) 431 // { 432 // assert(htemp2.getClassID()<500); 433 // assert(htemp2.getDataSize()!=0 && htemp2.getDataSize()<1000); 434 // assert(htemp2.isDiffed()==false); 435 // } 436 // } 437 while ( temp < baseData+baseOffset ) 438 { 439 SynchronisableHeader htemp(temp); 440 if ( htemp.getObjectID() == objectID ) 441 { 442 assert( h.getClassID() == htemp.getClassID() ); 443 goto DODIFF; 444 } 445 // { 446 // SynchronisableHeader htemp2(temp+htemp.getDataSize()+SynchronisableHeader::getSize()); 447 // if( temp+htemp.getDataSize()+SynchronisableHeader::getSize() < baseData+baseLength ) 448 // { 449 // assert(htemp2.getClassID()<500); 450 // assert(htemp2.getDataSize()!=0 && htemp2.getDataSize()<1000); 451 // assert(htemp2.isDiffed()==false); 452 // } 453 // } 454 temp += htemp.getDataSize()+SynchronisableHeader::getSize(); 455 } 456 // Object is new, thus never transmitted -> just copy over 457 goto DOCOPY; 458 459 460 DODIFF: 461 { 462 // COUT(4) << "dodiff" << endl; 463 // if(baseOffset==0) 464 // { 465 // assert(origOffset==0); 466 // } 467 uint32_t objectOffset = SynchronisableHeader::getSize(); // offset inside the object in the origData and baseData 468 // Check whether the whole object stayed the same 469 if( memcmp( origData+origOffset+objectOffset, temp+objectOffset, h.getDataSize()) == 0 ) 470 { 471 // COUT(4) << "skip object" << Synchronisable::getSynchronisable(h.getObjectID())->getIdentifier()->getName() << endl; 472 origOffset += objectOffset+ h.getDataSize(); // skip the whole object 473 baseOffset = temp + h.getDataSize()+SynchronisableHeader::getSize() - baseData; 474 sizes += Synchronisable::getSynchronisable(h.getObjectID())->getNrOfVariables(); 475 } 476 else 477 { 478 // if( Synchronisable::getSynchronisable(h.getObjectID())->getIdentifier()->getName() == "Bot" ) 479 // COUT(0) << "blub" << endl; 480 // COUT(4) << "object diff: " << Synchronisable::getSynchronisable(h.getObjectID())->getIdentifier()->getName() << endl; 481 // COUT(4) << "diff " << h.getObjectID() << ":"; 482 // Now start to diff the Object 483 SynchronisableHeaderLight h2(dest); 484 h2 = h; // copy over the objectheader 485 VariableID variableID = 0; 486 uint32_t newObjectOffset = SynchronisableHeaderLight::getSize(); 487 // iterate through all variables 488 while( objectOffset < h.getDataSize()+SynchronisableHeader::getSize() ) 489 { 490 // check whether variable changed and write id and copy over variable to the new stream 491 // otherwise skip variable 492 assert(sizes != this->sizes_.end()); 493 uint32_t varSize = *sizes; 494 assert( varSize == Synchronisable::getSynchronisable(h.getObjectID())->getVarSize(variableID) ); 495 if ( varSize != 0 ) 496 { 497 if ( memcmp(origData+origOffset+objectOffset, temp+objectOffset, varSize) != 0 ) 498 { 499 // COUT(4) << "copy variable" << endl; 500 *(VariableID*)(dest+newObjectOffset) = variableID; // copy over the variableID 501 newObjectOffset += sizeof(VariableID); 502 memcpy( dest+newObjectOffset, origData+origOffset+objectOffset, varSize ); 503 newObjectOffset += varSize; 504 objectOffset += varSize; 505 } 506 else 507 { 508 // COUT(4) << "skip variable" << endl; 509 objectOffset += varSize; 510 } 511 } 512 // else 513 // COUT(4) << "varsize 0" << endl; 514 515 ++variableID; 516 ++sizes; 517 } 518 519 if( Synchronisable::getSynchronisable(h.getObjectID())->getNrOfVariables() != variableID ) 520 sizes += Synchronisable::getSynchronisable(h.getObjectID())->getNrOfVariables() - variableID; 521 // COUT(4) << endl; 522 h2.setDiffed(true); 523 h2.setDataSize(newObjectOffset-SynchronisableHeaderLight::getSize()); 524 assert(objectOffset == h.getDataSize()+SynchronisableHeader::getSize()); 525 origOffset += objectOffset; 526 // baseOffset += temp + h.getDataSize()+SynchronisableHeader::getSize() - baseData; 527 //baseOffset += objectOffset; 528 // SynchronisableHeader htemp(temp); 529 // baseOffset += SynchronisableHeader::getSize() + htemp.getDataSize(); 530 // { 531 // SynchronisableHeader htemp2( baseData+(temp-baseData+objectOffset) ); 532 // if( baseData+(temp-baseData+objectOffset) < baseData+baseLength ) 533 // { 534 // assert(htemp2.getClassID()<500); 535 // assert(htemp2.getDataSize()!=0 && htemp2.getDataSize()<1000); 536 // assert(htemp2.isDiffed()==false); 537 // } 538 // } 539 baseOffset = temp-baseData + objectOffset; 540 dest += newObjectOffset; 541 } 542 543 continue; 544 } 545 546 DOCOPY: 547 { 548 // COUT(4) << "docopy" << endl; 549 // Just copy over the whole Object 550 memcpy( dest, origData+origOffset, h.getDataSize()+SynchronisableHeader::getSize() ); 551 dest += h.getDataSize()+SynchronisableHeader::getSize(); 552 origOffset += h.getDataSize()+SynchronisableHeader::getSize(); 553 assert( Synchronisable::getSynchronisable(h.getObjectID()) ); 554 // COUT(4) << "copy " << h.getObjectID() << endl; 555 // COUT(4) << "copy " << h.getObjectID() << ":"; 556 //sizes += Synchronisable::getSynchronisable(h.getObjectID())->getNrOfVariables(); 557 for( unsigned int i = 0; i < Synchronisable::getSynchronisable(h.getObjectID())->getNrOfVariables(); ++i ) 558 { 559 // COUT(4) << " " << *sizes; 560 ++sizes; 561 } 562 // COUT(4) << endl; 563 assert(sizes != this->sizes_.end() || origOffset>=origLength); 564 continue; 565 } 566 } 567 568 569 Gamestate *g = new Gamestate(nData, getClientID()); 570 assert(g->header_); 351 571 *(g->header_) = *header_; 352 g->header_->setDiffed( true );353 572 g->header_->setBaseID( base->getID() ); 573 g->header_->setDataSize(dest - nData - GamestateHeader::getSize()); 354 574 g->flags_=flags_; 355 575 g->packetDirection_ = packetDirection_; 576 assert(!g->isCompressed()); 356 577 return g; 357 }*/ 358 359 Gamestate *Gamestate::diff(Gamestate *base) 578 } 579 580 581 Gamestate* Gamestate::diffData(Gamestate *base) 360 582 { 361 583 assert(this && base); assert(data_ && base->data_); … … 393 615 } 394 616 395 Gamestate *Gamestate::undiff(Gamestate *base) 617 618 Gamestate* Gamestate::undiff(Gamestate *base) 396 619 { 397 620 assert(this && base); assert(data_ && base->data_); … … 423 646 424 647 425 // Gamestate *Gamestate::diff(Gamestate *base)426 // {427 // assert(data_);428 // assert(!header_->isCompressed());429 // assert(!header_->isDiffed());430 // GamestateHeader diffHeader(base->data_);431 // uint8_t *basep = GAMESTATE_START(base->data_), *gs = GAMESTATE_START(this->data_);432 // uint32_t of=0; // pointers offset433 // uint32_t dest_length=0;434 // dest_length=header_->getDataSize();435 // if(dest_length==0)436 // return NULL;437 // uint8_t *ndata = new uint8_t[dest_length*sizeof(uint8_t)+GamestateHeader::getSize()];438 // uint8_t *dest = ndata + GamestateHeader::getSize();439 //440 //441 // // LOOP-UNROLLED DIFFING442 // uint32_t *dest32 = (uint32_t*)dest, *base32 = (uint32_t*)basep, *gs32 = (uint32_t*)gs;443 // // diff in 4-byte steps444 // while( of < (uint32_t)(header_->getDataSize())/4 ){445 // if( of < (uint32_t)(diffHeader.getDataSize())/4 )446 // {447 // *(dest32+of)=*(base32+of) ^ *(gs32+of); // do the xor448 // ++of;449 // }450 // else451 // {452 // *(dest32+of)=*(gs32+of); // same as 0 ^ *(gs32+of)453 // ++of;454 // }455 // }456 // for( unsigned int of2 = 0; of2 < header_->getDataSize()%4; ++of2 )457 // {458 // if( of*4+of2 < diffHeader.getDataSize() )459 // {460 // *(dest+4*of+of2)=*(basep+4*of+of2) ^ *(gs+4*of+of2); // do the xor461 // }462 // else463 // {464 // *(dest+4*of+of2)=*(gs+4*of+of2); // same as 0 ^ *(gs32+of)465 // }466 // }467 //468 // Gamestate *g = new Gamestate(ndata, getClientID());469 // *(g->header_) = *header_;470 // g->header_->setDiffed( true );471 // g->header_->setBaseID( base->getID() );472 // g->flags_=flags_;473 // g->packetDirection_ = packetDirection_;474 // return g;475 // }476 477 478 648 void Gamestate::rawDiff( uint8_t* newdata, uint8_t* data, uint8_t* basedata, uint32_t datalength, uint32_t baselength) 479 649 { … … 501 671 assert(j==datalength); 502 672 } 673 503 674 504 675 Gamestate* Gamestate::doSelection(unsigned int clientID, unsigned int targetSize){ … … 529 700 // COUT(0) << "myvector contains:"; 530 701 // for ( itt=dataVector_.begin() ; itt!=dataVector_.end(); itt++ ) 531 // COUT(0) << ' '<< (*itt).objID;702 // COUT(0) << " " << (*itt).objID; 532 703 // COUT(0) << endl; 533 704 for(it=dataVector_.begin(); it!=dataVector_.end();){ 534 705 SynchronisableHeader oldobjectheader(origdata); 535 706 SynchronisableHeader newobjectheader(newdata); 536 if ( it->objSize == 0 )707 if ( (*it).objSize == 0 ) 537 708 { 538 709 ++it; 539 710 continue; 540 711 } 541 objectsize = oldobjectheader.getDataSize() ;712 objectsize = oldobjectheader.getDataSize()+SynchronisableHeader::getSize(); 542 713 objectOffset=SynchronisableHeader::getSize(); //skip the size and the availableData variables in the objectheader 543 if ( it->objID == oldobjectheader.getObjectID() ){714 if ( (*it).objID == oldobjectheader.getObjectID() ){ 544 715 memcpy(newdata, origdata, objectsize); 545 assert(newobjectheader.isDataAvailable()==true);546 716 ++it; 547 717 }else{ 548 718 newobjectheader = oldobjectheader; 549 newobjectheader.setDataAvailable(false);550 719 memset(newdata+objectOffset, 0, objectsize-objectOffset); 551 720 } … … 559 728 { 560 729 SynchronisableHeader oldobjectheader(origdata); 561 objectsize = oldobjectheader.getDataSize() ;730 objectsize = oldobjectheader.getDataSize()+SynchronisableHeader::getSize(); 562 731 origdata += objectsize; 563 732 origsize += objectsize; … … 571 740 572 741 573 /*Gamestate *Gamestate::undiff(Gamestate *base)574 {575 assert(this && base);assert(data_);576 assert(header_->isDiffed());577 assert(!header_->isCompressed() && !base->header_->isCompressed());578 uint8_t *basep = GAMESTATE_START(base->data_);579 uint8_t *gs = GAMESTATE_START(this->data_);580 uint32_t of=0; // pointers offset581 uint32_t dest_length=0;582 dest_length=header_->getDataSize();583 if(dest_length==0)584 return NULL;585 uint8_t *ndata = new uint8_t[dest_length*sizeof(uint8_t)+GamestateHeader::getSize()];586 uint8_t *dest = ndata + GamestateHeader::getSize();587 while(of < base->header_->getDataSize() && of < header_->getDataSize()){588 *(dest+of)=*(basep+of)^*(gs+of); // do the xor589 ++of;590 }591 if(base->header_->getDataSize()!=header_->getDataSize()){592 uint8_t n=0;593 if(base->header_->getDataSize() < header_->getDataSize()){594 while(of < dest_length){595 *(dest+of)=n^*(gs+of);596 of++;597 }598 }599 }600 Gamestate *g = new Gamestate(ndata, getClientID());601 assert(g->header_);602 *(g->header_) = *header_;603 g->header_->setDiffed( false );604 g->flags_=flags_;605 g->packetDirection_ = packetDirection_;606 assert(!g->isDiffed());607 assert(!g->isCompressed());608 return g;609 }*/610 611 742 uint32_t Gamestate::calcGamestateSize(int32_t id, uint8_t mode) 612 743 { 613 uint32_t size=0; 744 uint32_t size = 0; 745 uint32_t nrOfVariables = 0; 614 746 // get the start of the Synchronisable list 615 747 ObjectList<Synchronisable>::iterator it; 616 748 // get total size of gamestate 617 for(it = ObjectList<Synchronisable>::begin(); it; ++it) 749 for(it = ObjectList<Synchronisable>::begin(); it; ++it){ 618 750 size+=it->getSize(id, mode); // size of the actual data of the synchronisable 751 nrOfVariables += it->getNrOfVariables(); 752 } 753 // COUT(0) << "allocating " << nrOfVariables << " ints" << endl; 754 this->sizes_.reserve(nrOfVariables); 619 755 return size; 620 756 } 757 621 758 622 759 } //namespace packet -
code/trunk/src/libraries/network/packet/Gamestate.h
r6073 r7163 36 36 #include <cstring> 37 37 #include <list> 38 #include <vector> 38 39 39 40 #include "util/CRC32.h" … … 113 114 inline bool isCompressed() const { return header_->isCompressed(); } 114 115 inline int32_t getBaseID() const { return header_->getBaseID(); } 115 Gamestate *diff(Gamestate *base); 116 inline uint32_t getDataSize() const { return header_->getDataSize(); } 117 Gamestate* diffVariables(Gamestate *base); 118 Gamestate* diffData(Gamestate *base); 116 119 Gamestate *undiff(Gamestate *base); 117 120 Gamestate* doSelection(unsigned int clientID, unsigned int targetSize); … … 123 126 private: 124 127 void rawDiff( uint8_t* newdata, uint8_t* data, uint8_t* basedata, uint32_t datalength, uint32_t baselength); 128 inline uint32_t findObject( const SynchronisableHeader& header, uint8_t* mem, uint32_t dataLength, uint32_t startPosition = 0 ); 125 129 virtual uint32_t getSize() const; 126 130 virtual inline bool process(); 127 128 private:129 131 uint32_t calcGamestateSize(int32_t id, uint8_t mode=0x0); 130 std::list<obj> dataVector_; 131 GamestateHeader* header_; 132 133 std::list<obj> dataVector_; 134 GamestateHeader* header_; 135 std::vector<uint32_t> sizes_; 136 uint32_t nrOfVariables_; 132 137 }; 133 138 -
code/trunk/src/libraries/network/packet/Packet.cc
r6417 r7163 62 62 std::map<size_t, Packet *> Packet::packetMap_; 63 63 64 Packet::Packet(){ 64 Packet::Packet() 65 { 65 66 flags_ = PACKET_FLAG_DEFAULT; 66 67 packetDirection_ = Direction::Outgoing; … … 71 72 } 72 73 73 void blub(ENetPacket *packet){ 74 COUT(4) << "blubb" << std::endl; 75 } 76 77 Packet::Packet(uint8_t *data, unsigned int clientID){ 74 Packet::Packet(uint8_t *data, unsigned int clientID) 75 { 78 76 flags_ = PACKET_FLAG_DEFAULT; 79 77 packetDirection_ = Direction::Incoming; -
code/trunk/src/libraries/network/synchronisable/Serialise.h
r6417 r7163 38 38 #include "util/TypeTraits.h" 39 39 #include "core/CorePrereqs.h" 40 #include "core/CoreIncludes.h" 41 #include "core/SmartPtr.h" 40 42 41 43 namespace orxonox{ … … 72 74 return *(uint32_t*)(mem) == variable->getObjectID(); 73 75 else 76 return variable == variable->getSynchronisable(*(uint32_t*)(mem)); 77 } 78 79 // These functions implement loading / saving / etc. for SmartPtr<T> 80 81 /** @brief returns the size of the objectID needed to synchronise the pointer */ 82 template <class T> inline uint32_t returnSize( const SmartPtr<T>& variable ) 83 { 84 return sizeof(uint32_t); 85 } 86 87 /** @brief reads the objectID of a pointer out of the bytestream and increases the mem pointer */ 88 template <class T> inline void loadAndIncrease( const SmartPtr<T>& variable, uint8_t*& mem ) 89 { 90 // *const_cast<typename Loki::TypeTraits<T*>::UnqualifiedType*>(&variable) = dynamic_cast<T*>(variable->getSynchronisable( *(uint32_t*)(mem) )); 91 *const_cast<typename Loki::TypeTraits<SmartPtr<T> >::UnqualifiedType*>(&variable) = orxonox_cast<T*>(T::getSynchronisable(*(uint32_t*)(mem))); 92 mem += returnSize( variable ); 93 } 94 95 /** @brief saves the objectID of a pointer into the bytestream and increases the mem pointer */ 96 template <class T> inline void saveAndIncrease( const SmartPtr<T>& variable, uint8_t*& mem ) 97 { 98 if ( variable.get() ) 99 *(uint32_t*)(mem) = static_cast<uint32_t>(variable->getObjectID()); 100 else 101 *(uint32_t*)(mem) = OBJECTID_UNKNOWN; 102 mem += returnSize( variable ); 103 } 104 105 /** @brief checks whether the objectID of the variable is the same as in the bytestream */ 106 template <class T> inline bool checkEquality( const SmartPtr<T>& variable, uint8_t* mem ) 107 { 108 if ( variable.get() ) 109 return *(uint32_t*)(mem) == variable->getObjectID(); 110 else 111 return *(uint32_t*)(mem) == OBJECTID_UNKNOWN; 112 } 113 114 // These functions implement loading / saving / etc. for WeakPtr<T> 115 116 /** @brief returns the size of the objectID needed to synchronise the pointer */ 117 template <class T> inline uint32_t returnSize( const WeakPtr<T>& variable ) 118 { 119 return sizeof(uint32_t); 120 } 121 122 /** @brief reads the objectID of a pointer out of the bytestream and increases the mem pointer */ 123 template <class T> inline void loadAndIncrease( const WeakPtr<T>& variable, uint8_t*& mem ) 124 { 125 // *const_cast<typename Loki::TypeTraits<T*>::UnqualifiedType*>(&variable) = dynamic_cast<T*>(variable->getSynchronisable( *(uint32_t*)(mem) )); 126 *const_cast<typename Loki::TypeTraits<SmartPtr<T> >::UnqualifiedType*>(&variable) = orxonox_cast<T*>(T::getSynchronisable(*(uint32_t*)(mem))); 127 mem += returnSize( variable ); 128 } 129 130 /** @brief saves the objectID of a pointer into the bytestream and increases the mem pointer */ 131 template <class T> inline void saveAndIncrease( const WeakPtr<T>& variable, uint8_t*& mem ) 132 { 133 if ( variable.get() ) 134 *(uint32_t*)(mem) = static_cast<uint32_t>(variable->getObjectID()); 135 else 136 *(uint32_t*)(mem) = OBJECTID_UNKNOWN; 137 mem += returnSize( variable ); 138 } 139 140 /** @brief checks whether the objectID of the variable is the same as in the bytestream */ 141 template <class T> inline bool checkEquality( const WeakPtr<T>& variable, uint8_t* mem ) 142 { 143 if ( variable.get() ) 144 return *(uint32_t*)(mem) == variable->getObjectID(); 145 else 74 146 return *(uint32_t*)(mem) == OBJECTID_UNKNOWN; 75 147 } -
code/trunk/src/libraries/network/synchronisable/Synchronisable.cc
r6417 r7163 49 49 * Initializes all Variables and sets the right objectID_ 50 50 */ 51 Synchronisable::Synchronisable(BaseObject* creator ){ 51 Synchronisable::Synchronisable(BaseObject* creator ) 52 { 52 53 RegisterRootObject(Synchronisable); 53 54 static uint32_t idCounter=0; 54 55 objectMode_=0x1; // by default do not send data to server 55 if ( GameMode::isMaster() || ( Host::running() && Host::isServer() ))56 if ( GameMode::isMaster()/* || ( Host::running() && Host::isServer() )*/ ) 56 57 { 57 58 this->setObjectID( idCounter++ ); … … 73 74 else 74 75 this->creatorID_ = OBJECTID_UNKNOWN; 75 76 /*searchcreatorID:77 if (creator)78 {79 Synchronisable* synchronisable_creator = orxonox_cast<Synchronisable*>(creator);80 if (synchronisable_creator && synchronisable_creator->objectMode_)81 {82 this->creatorID = synchronisable_creator->getScene()->getObjectID();83 }84 else if (creator != creator->getCreator())85 {86 creator = creator->getCreator();87 goto searchcreatorID;88 }89 }*/90 76 } 91 77 … … 94 80 * Delete all callback objects and remove objectID_ from the objectMap_ 95 81 */ 96 Synchronisable::~Synchronisable(){ 82 Synchronisable::~Synchronisable() 83 { 97 84 // delete callback function objects 98 85 if(!Identifier::isCreatingHierarchy()){ … … 101 88 deletedObjects_.push(objectID_); 102 89 } 103 // delete all Synchronisable Variables from syncList ( which are also in stringList)104 for(std::vector<SynchronisableVariableBase*>::iterator it = syncList .begin(); it!=syncList.end(); it++)90 // delete all Synchronisable Variables from syncList_ ( which are also in stringList_ ) 91 for(std::vector<SynchronisableVariableBase*>::iterator it = syncList_.begin(); it!=syncList_.end(); it++) 105 92 delete (*it); 106 syncList .clear();107 stringList .clear();93 syncList_.clear(); 94 stringList_.clear(); 108 95 std::map<uint32_t, Synchronisable*>::iterator it; 109 96 it = objectMap_.find(objectID_); … … 118 105 * @param b true if this object is located on a client or on a server 119 106 */ 120 void Synchronisable::setClient(bool b){ 107 void Synchronisable::setClient(bool b) 108 { 121 109 if(b) // client 122 110 state_=0x2; … … 135 123 { 136 124 SynchronisableHeader header(mem); 137 138 if(!header.isDataAvailable()) 139 { 140 mem += header.getDataSize(); 141 return 0; 142 } 125 assert( !header.isDiffed() ); 143 126 144 127 COUT(4) << "fabricating object with id: " << header.getObjectID() << std::endl; … … 160 143 if (!synchronisable_creator) 161 144 { 162 mem += header.getDataSize() ; //.TODO: this suckz.... remove size from header145 mem += header.getDataSize()+SynchronisableHeader::getSize(); //.TODO: this suckz.... remove size from header 163 146 assert(0); // TODO: uncomment this if we have a clean objecthierarchy (with destruction of children of objects) ^^ 164 147 return 0; … … 177 160 no->setClassID(header.getClassID()); 178 161 assert(no->creatorID_ == header.getCreatorID()); 162 if( creator ) 163 bo->setLevel(creator->getLevel()); // Note: this ensures that the level is known on the client for child objects of the scene (and the scene itself) 179 164 //assert(no->classID_ == header.getClassID()); 180 165 COUT(4) << "fabricate objectID_: " << no->objectID_ << " classID_: " << no->classID_ << std::endl; … … 196 181 * @return true/false 197 182 */ 198 bool Synchronisable::deleteObject(uint32_t objectID_){ 183 bool Synchronisable::deleteObject(uint32_t objectID_) 184 { 199 185 if(!getSynchronisable(objectID_)) 200 186 return false; … … 213 199 * @return pointer to the Synchronisable with the objectID_ 214 200 */ 215 Synchronisable* Synchronisable::getSynchronisable(uint32_t objectID_){ 201 Synchronisable* Synchronisable::getSynchronisable(uint32_t objectID_) 202 { 216 203 std::map<uint32_t, Synchronisable*>::iterator it1; 217 204 it1 = objectMap_.find(objectID_); 218 205 if (it1 != objectMap_.end()) 219 206 return it1->second; 220 221 // ObjectList<Synchronisable>::iterator it;222 // for(it = ObjectList<Synchronisable>::begin(); it; ++it){223 // if( it->getObjectID()==objectID_ ){224 // objectMap_[objectID_] = *it;225 // return *it;226 // }227 // }228 207 // if the objects not in the map it should'nt exist at all anymore 229 208 return NULL; … … 245 224 * @return true: if !doSync or if everything was successfully saved 246 225 */ 247 uint32_t Synchronisable::getData(uint8_t*& mem, int32_t id, uint8_t mode){ 226 uint32_t Synchronisable::getData(uint8_t*& mem, std::vector<uint32_t>& sizes, int32_t id, uint8_t mode) 227 { 228 unsigned int test = 0; 248 229 if(mode==0x0) 249 230 mode=state_; … … 253 234 uint32_t tempsize = 0; 254 235 #ifndef NDEBUG 236 uint8_t* oldmem = mem; 255 237 if (this->classID_==0) 256 238 COUT(3) << "classid 0 " << this->getIdentifier()->getName() << std::endl; … … 270 252 // end copy header 271 253 272 273 COUT(5) << "Synchronisable getting data from objectID_: " << objectID_ << " classID_: " << classID_ << std::endl;254 CCOUT(5) << "getting data from objectID_: " << objectID_ << ", classID_: " << classID_ << std::endl; 255 // COUT(4) << "objectid: " << this->objectID_ << ":"; 274 256 // copy to location 275 for(i=syncList.begin(); i!=syncList.end(); ++i){ 276 tempsize += (*i)->getData( mem, mode ); 257 for(i=syncList_.begin(); i!=syncList_.end(); ++i) 258 { 259 uint32_t varsize = (*i)->getData( mem, mode ); 260 // COUT(4) << " " << varsize; 261 tempsize += varsize; 262 sizes.push_back(varsize); 263 ++test; 277 264 //tempsize += (*i)->getSize( mode ); 278 265 } 279 280 tempsize += SynchronisableHeader::getSize(); 266 // COUT(4) << endl; 267 281 268 header.setObjectID( this->objectID_ ); 282 269 header.setCreatorID( this->creatorID_ ); 283 270 header.setClassID( this->classID_ ); 284 header.setDataAvailable( true );285 271 header.setDataSize( tempsize ); 272 assert( tempsize == mem-oldmem-SynchronisableHeader::getSize() ); 273 assert( test == this->getNrOfVariables() ); 274 header.setDiffed(false); 275 tempsize += SynchronisableHeader::getSize(); 286 276 287 277 #ifndef NDEBUG … … 300 290 * @return true/false 301 291 */ 302 bool Synchronisable::updateData(uint8_t*& mem, uint8_t mode, bool forceCallback){ 292 bool Synchronisable::updateData(uint8_t*& mem, uint8_t mode, bool forceCallback) 293 { 303 294 if(mode==0x0) 304 295 mode=state_; 305 std::vector<SynchronisableVariableBase *>::iterator i;306 if(syncList.empty()){296 if(syncList_.empty()) 297 { 307 298 assert(0); 308 COUT( 4) << "Synchronisable::updateData syncListis empty" << std::endl;299 COUT(2) << "Synchronisable::updateData syncList_ is empty" << std::endl; 309 300 return false; 310 301 } … … 312 303 uint8_t* data=mem; 313 304 // start extract header 314 SynchronisableHeader syncHeader(mem); 315 assert(syncHeader.getObjectID()==this->objectID_); 316 assert(syncHeader.getCreatorID()==this->creatorID_); 317 assert(syncHeader.getClassID()==this->classID_); 318 if(syncHeader.isDataAvailable()==false){ 319 mem += syncHeader.getDataSize(); 320 return true; 321 } 322 323 mem += SynchronisableHeader::getSize(); 324 // stop extract header 305 SynchronisableHeaderLight syncHeaderLight(mem); 306 assert(syncHeaderLight.getObjectID()==this->getObjectID()); 325 307 326 308 //COUT(5) << "Synchronisable: objectID_ " << syncHeader.getObjectID() << ", classID_ " << syncHeader.getClassID() << " size: " << syncHeader.getDataSize() << " synchronising data" << std::endl; 327 for(i=syncList.begin(); i!=syncList.end(); i++) 328 { 329 assert( mem <= data+syncHeader.getDataSize() ); // always make sure we don't exceed the datasize in our stream 330 (*i)->putData( mem, mode, forceCallback ); 331 } 332 assert(mem == data+syncHeader.getDataSize()); 309 if( !syncHeaderLight.isDiffed() ) 310 { 311 SynchronisableHeader syncHeader2(mem); 312 assert( this->getClassID() == syncHeader2.getClassID() ); 313 assert( this->getCreatorID() == syncHeader2.getCreatorID() ); 314 mem += SynchronisableHeader::getSize(); 315 std::vector<SynchronisableVariableBase *>::iterator i; 316 for(i=syncList_.begin(); i!=syncList_.end(); i++) 317 { 318 assert( mem <= data+syncHeader2.getDataSize()+SynchronisableHeader::getSize() ); // always make sure we don't exceed the datasize in our stream 319 (*i)->putData( mem, mode, forceCallback ); 320 } 321 assert(mem == data+syncHeaderLight.getDataSize()+SynchronisableHeader::getSize() ); 322 } 323 else 324 { 325 mem += SynchronisableHeaderLight::getSize(); 326 // COUT(0) << "objectID: " << this->objectID_ << endl; 327 while( mem < data+syncHeaderLight.getDataSize()+SynchronisableHeaderLight::getSize() ) 328 { 329 VariableID varID = *(VariableID*)mem; 330 // COUT(0) << "varID: " << varID << endl; 331 assert( varID < syncList_.size() ); 332 mem += sizeof(VariableID); 333 syncList_[varID]->putData( mem, mode, forceCallback ); 334 } 335 assert(mem == data+syncHeaderLight.getDataSize()+SynchronisableHeaderLight::getSize() ); 336 } 333 337 return true; 334 338 } … … 340 344 * @return amount of bytes 341 345 */ 342 uint32_t Synchronisable::getSize(int32_t id, uint8_t mode){ 343 int tsize=SynchronisableHeader::getSize(); 346 uint32_t Synchronisable::getSize(int32_t id, uint8_t mode) 347 { 348 uint32_t tsize=SynchronisableHeader::getSize(); 344 349 if (mode==0x0) 345 350 mode=state_; … … 349 354 tsize += this->dataSize_; 350 355 std::vector<SynchronisableVariableBase*>::iterator i; 351 for(i=stringList.begin(); i!=stringList.end(); ++i){ 356 for(i=stringList_.begin(); i!=stringList_.end(); ++i) 357 { 352 358 tsize += (*i)->getSize( mode ); 353 359 } … … 360 366 * @return true/false 361 367 */ 362 bool Synchronisable::doSync(int32_t id, uint8_t mode){ 368 bool Synchronisable::doSync(int32_t id, uint8_t mode) 369 { 363 370 if(mode==0x0) 364 371 mode=state_; 365 return ( (this->objectMode_ & mode)!=0 && (!syncList.empty() ) ); 366 } 367 368 /** 369 * This function looks at the header located in the bytestream and checks wheter objectID_ and classID_ match with the Synchronisables ones 370 * @param mem pointer to the bytestream 371 */ 372 bool Synchronisable::isMyData(uint8_t* mem) 373 { 374 SynchronisableHeader header(mem); 375 assert(header.getObjectID()==this->objectID_); 376 return header.isDataAvailable(); 372 return ( (this->objectMode_ & mode)!=0 && (!syncList_.empty() ) ); 377 373 } 378 374 … … 385 381 * @param mode same as in registerVar 386 382 */ 387 void Synchronisable::setSyncMode(uint8_t mode){ 383 void Synchronisable::setSyncMode(uint8_t mode) 384 { 388 385 assert(mode==0x0 || mode==0x1 || mode==0x2 || mode==0x3); 389 386 this->objectMode_=mode; … … 397 394 else 398 395 sv = new SynchronisableVariable<std::string>(variable, mode, cb); 399 syncList.push_back(sv); 400 stringList.push_back(sv); 396 syncList_.push_back(sv); 397 stringList_.push_back(sv); 398 } 399 400 template <> void Synchronisable::unregisterVariable( std::string& variable ) 401 { 402 bool unregistered_nonexistent_variable = true; 403 std::vector<SynchronisableVariableBase*>::iterator it = syncList_.begin(); 404 while(it!=syncList_.end()) 405 { 406 if( ((*it)->getReference()) == &variable ) 407 { 408 delete (*it); 409 syncList_.erase(it); 410 unregistered_nonexistent_variable = false; 411 break; 412 } 413 else 414 ++it; 415 } 416 assert(unregistered_nonexistent_variable == false); 417 418 it = stringList_.begin(); 419 while(it!=stringList_.end()) 420 { 421 if( ((*it)->getReference()) == &variable ) 422 { 423 delete (*it); 424 stringList_.erase(it); 425 return; 426 } 427 else 428 ++it; 429 } 430 unregistered_nonexistent_variable = true; 431 assert(unregistered_nonexistent_variable == false); //if we reach this point something went wrong: 432 // the variable has not been registered before 401 433 } 402 434 -
code/trunk/src/libraries/network/synchronisable/Synchronisable.h
r6417 r7163 37 37 #include <map> 38 38 #include <queue> 39 #include <set> 39 40 40 41 #include "util/mbool.h" … … 64 65 }; 65 66 } 67 68 typedef uint8_t VariableID; 66 69 67 70 /** … … 71 74 * in an emulated bitset. 72 75 * Bit 1 to 31 store the size of the Data the synchronisable consumes in the stream 73 * Bit 32 is a bool and defines whether the data is actually stored or is just filled up with 076 * Bit 32 is a bool and defines whether the variables are stored in diff mode 74 77 * Byte 5 to 8: objectID_ 75 78 * Byte 9 to 12: classID_ … … 77 80 */ 78 81 class _NetworkExport SynchronisableHeader{ 82 friend class SynchronisableHeaderLight; 79 83 private: 80 uint8_t *data_;84 uint8_t* data_; 81 85 public: 82 86 SynchronisableHeader(uint8_t* data) 83 87 { data_ = data; } 84 88 inline static uint32_t getSize() 85 { return 1 6; }86 inline uint 32_t getDataSize() const87 { return (*(uint 32_t*)data_) & 0x7FFFFFFF; } //only use the first 31bits88 inline void setDataSize(uint 32_t size)89 { *(uint 32_t*)(data_) = (size & 0x7FFFFFFF) | (*(uint32_t*)(data_) & 0x80000000 ); }90 inline bool isD ataAvailable() const91 { return ( (*(uint 32_t*)data_) & 0x80000000 ) == 0x80000000; }92 inline void setD ataAvailable( bool b)93 { *(uint 32_t*)(data_) = (b << 31) | (*(uint32_t*)(data_) & 0x7FFFFFFF ); }89 { return 14; } 90 inline uint16_t getDataSize() const 91 { return (*(uint16_t*)data_) & 0x7FFF; } //only use the first 15 bits 92 inline void setDataSize(uint16_t size) 93 { *(uint16_t*)(data_) = (size & 0x7FFF) | (*(uint16_t*)(data_) & 0x8000 ); } 94 inline bool isDiffed() const 95 { return ( (*(uint16_t*)data_) & 0x8000 ) == 0x8000; } 96 inline void setDiffed( bool b) 97 { *(uint16_t*)(data_) = (b << 15) | (*(uint16_t*)(data_) & 0x7FFF ); } 94 98 inline uint32_t getObjectID() const 95 { return *(uint32_t*)(data_+ 4); }99 { return *(uint32_t*)(data_+2); } 96 100 inline void setObjectID(uint32_t objectID_) 97 { *(uint32_t*)(data_+ 4) = objectID_; }101 { *(uint32_t*)(data_+2) = objectID_; } 98 102 inline uint32_t getClassID() const 99 { return *(uint32_t*)(data_+ 8); }103 { return *(uint32_t*)(data_+6); } 100 104 inline void setClassID(uint32_t classID_) 101 { *(uint32_t*)(data_+ 8) = classID_; }105 { *(uint32_t*)(data_+6) = classID_; } 102 106 inline uint32_t getCreatorID() const 103 { return *(uint32_t*)(data_+1 2); }107 { return *(uint32_t*)(data_+10); } 104 108 inline void setCreatorID(uint32_t creatorID_) 105 { *(uint32_t*)(data_+1 2) = creatorID_; }109 { *(uint32_t*)(data_+10) = creatorID_; } 106 110 inline void operator=(SynchronisableHeader& h) 107 111 { memcpy(data_, h.data_, getSize()); } 108 112 }; 109 113 114 /** 115 * @brief: stores information about a Synchronisable (light version) 116 * 117 * This class stores the information about a Synchronisable (objectID_, dataSize) 118 * in an emulated bitset. 119 * Bit 1 to 31 store the size of the Data the synchronisable consumes in the stream 120 * Bit 32 is a bool and defines whether the variables are stored in diff mode 121 * Byte 5 to 8: objectID_ 122 */ 123 class _NetworkExport SynchronisableHeaderLight{ 124 private: 125 uint8_t* data_; 126 public: 127 SynchronisableHeaderLight(uint8_t* data) 128 { data_ = data; } 129 inline static uint32_t getSize() 130 { return 6; } 131 inline uint16_t getDataSize() const 132 { return (*(uint16_t*)data_) & 0x7FFF; } //only use the first 31 bits 133 inline void setDataSize(uint16_t size) 134 { *(uint16_t*)(data_) = (size & 0x7FFFFFFF) | (*(uint16_t*)(data_) & 0x8000 ); } 135 inline bool isDiffed() const 136 { return ( (*(uint16_t*)data_) & 0x8000 ) == 0x8000; } 137 inline void setDiffed( bool b) 138 { *(uint16_t*)(data_) = (b << 15) | (*(uint16_t*)(data_) & 0x7FFF ); } 139 inline uint32_t getObjectID() const 140 { return *(uint32_t*)(data_+2); } 141 inline void setObjectID(uint32_t objectID_) 142 { *(uint32_t*)(data_+2) = objectID_; } 143 inline void operator=(SynchronisableHeader& h) 144 { memcpy(data_, h.data_, getSize()); } 145 }; 110 146 111 147 /** … … 134 170 135 171 void setSyncMode(uint8_t mode); 172 173 inline uint32_t getNrOfVariables(){ return this->syncList_.size(); } 174 inline uint32_t getVarSize( VariableID ID ) 175 { return this->syncList_[ID]->getSize(state_); } 136 176 137 177 protected: 138 178 Synchronisable(BaseObject* creator); 139 179 template <class T> void registerVariable(T& variable, uint8_t mode=0x1, NetworkCallbackBase *cb=0, bool bidirectional=false); 180 template <class T> void registerVariable(std::set<T>& variable, uint8_t mode=0x1, NetworkCallbackBase *cb=0, bool bidirectional=false); 181 template <class T> void unregisterVariable(T& var); 140 182 141 183 void setPriority(unsigned int freq){ objectFrequency_ = freq; } … … 143 185 144 186 private: 145 uint32_t getData(uint8_t*& me n, int32_t id, uint8_t mode=0x0);187 uint32_t getData(uint8_t*& mem, std::vector<uint32_t>& sizes, int32_t id, uint8_t mode); 146 188 uint32_t getSize(int32_t id, uint8_t mode=0x0); 147 189 bool updateData(uint8_t*& mem, uint8_t mode=0x0, bool forceCallback=false); 148 bool isMyData(uint8_t* mem);149 190 bool doSync(int32_t id, uint8_t mode=0x0); 150 191 … … 156 197 uint32_t classID_; 157 198 158 std::vector<SynchronisableVariableBase*> syncList ;159 std::vector<SynchronisableVariableBase*> stringList ;199 std::vector<SynchronisableVariableBase*> syncList_; 200 std::vector<SynchronisableVariableBase*> stringList_; 160 201 uint32_t dataSize_; //size of all variables except strings 161 202 static uint8_t state_; // detemines wheter we are server (default) or client … … 171 212 if (bidirectional) 172 213 { 173 syncList .push_back(new SynchronisableVariableBidirectional<T>(variable, mode, cb));174 this->dataSize_ += syncList .back()->getSize(state_);214 syncList_.push_back(new SynchronisableVariableBidirectional<T>(variable, mode, cb)); 215 this->dataSize_ += syncList_.back()->getSize(state_); 175 216 } 176 217 else 177 218 { 178 syncList .push_back(new SynchronisableVariable<T>(variable, mode, cb));219 syncList_.push_back(new SynchronisableVariable<T>(variable, mode, cb)); 179 220 if ( this->state_ == mode ) 180 this->dataSize_ += syncList .back()->getSize(state_);221 this->dataSize_ += syncList_.back()->getSize(state_); 181 222 } 182 223 } 224 225 template <class T> void Synchronisable::unregisterVariable(T& variable){ 226 std::vector<SynchronisableVariableBase*>::iterator it = syncList_.begin(); 227 while(it!=syncList_.end()){ 228 if( ((*it)->getReference()) == &variable ){ 229 this->dataSize_ -= (*it)->getSize(Synchronisable::state_); 230 delete (*it); 231 syncList_.erase(it); 232 return; 233 } 234 else 235 it++; 236 } 237 bool unregistered_nonexistent_variable = false; 238 assert(unregistered_nonexistent_variable); //if we reach this point something went wrong: 239 // the variable has not been registered before 240 } 241 242 template <class T> void Synchronisable::registerVariable( std::set<T>& variable, uint8_t mode, NetworkCallbackBase *cb, bool bidirectional) 243 { 244 SynchronisableVariableBase* sv; 245 if (bidirectional) 246 sv = new SynchronisableVariableBidirectional<std::set<T> >(variable, mode, cb); 247 else 248 sv = new SynchronisableVariable<std::set<T> >(variable, mode, cb); 249 syncList_.push_back(sv); 250 stringList_.push_back(sv); 251 } 183 252 184 253 template <> _NetworkExport void Synchronisable::registerVariable( std::string& variable, uint8_t mode, NetworkCallbackBase *cb, bool bidirectional); 254 // template <class T> _NetworkExport void Synchronisable::registerVariable<std::set<T> >( std::set<T>& variable, uint8_t mode, NetworkCallbackBase *cb, bool bidirectional); 255 template <> _NetworkExport void Synchronisable::unregisterVariable( std::string& variable ); 185 256 186 257
Note: See TracChangeset
for help on using the changeset viewer.