[Orxonox-commit 1732] r6450 - in code/branches/network2/src/libraries/network: . packet synchronisable
scheusso at orxonox.net
scheusso at orxonox.net
Mon Jan 18 00:05:57 CET 2010
Author: scheusso
Date: 2010-01-18 00:05:57 +0100 (Mon, 18 Jan 2010)
New Revision: 6450
Modified:
code/branches/network2/src/libraries/network/GamestateClient.cc
code/branches/network2/src/libraries/network/GamestateManager.cc
code/branches/network2/src/libraries/network/Host.h
code/branches/network2/src/libraries/network/packet/Gamestate.cc
code/branches/network2/src/libraries/network/packet/Gamestate.h
code/branches/network2/src/libraries/network/packet/Packet.cc
code/branches/network2/src/libraries/network/synchronisable/Synchronisable.cc
code/branches/network2/src/libraries/network/synchronisable/Synchronisable.h
Log:
further traffic reduction:
- synchronisableheaders are now smaller( by 2 bytes per header )
- variableID of SynchronisableVariables are now uint8_t -> max 256 synchronised variables per Synchronisable
Modified: code/branches/network2/src/libraries/network/GamestateClient.cc
===================================================================
--- code/branches/network2/src/libraries/network/GamestateClient.cc 2010-01-17 10:49:48 UTC (rev 6449)
+++ code/branches/network2/src/libraries/network/GamestateClient.cc 2010-01-17 23:05:57 UTC (rev 6450)
@@ -160,24 +160,28 @@
bool b = gs->decompressData();
assert(b);
}
-// if(gs->isDiffed()){
+ if(gs->isDiffed())
+ {
+ assert(0);
// packet::Gamestate *base = gamestateMap_[gs->getBaseID()];
-// if(!base){
-// COUT(3) << "could not find base gamestate id: " << gs->getBaseID() << endl;
+// if(!base)
+// {
+// COUT(0) << "could not find base gamestate id: " << gs->getBaseID() << endl;
+// assert(0);
// delete gs;
// return 0;
// }
-// // assert(base); //TODO: fix this
// packet::Gamestate *undiffed = gs->undiff(base);
// delete gs;
// gs=undiffed;
// COUT(5) << "successfully undiffed gamestate id: " << undiffed->getID() << std::endl;
-// }
+ }
if(gs->spreadData(0x2))
return gs;
else
{
- COUT(3) << "could not spread gamestate" << endl;
+ COUT(0) << "could not spread gamestate" << endl;
+ assert(0);
return NULL;
}
}
Modified: code/branches/network2/src/libraries/network/GamestateManager.cc
===================================================================
--- code/branches/network2/src/libraries/network/GamestateManager.cc 2010-01-17 10:49:48 UTC (rev 6449)
+++ code/branches/network2/src/libraries/network/GamestateManager.cc 2010-01-17 23:05:57 UTC (rev 6450)
@@ -189,7 +189,7 @@
// packet::Gamestate *gs = gamestate->doSelection(clientID, 20000);
// packet::Gamestate* gs = new packet::Gamestate(*gamestate);
// packet::Gamestate* gs = gamestate;
- packet::Gamestate *gs = new packet::Gamestate(*gamestate);
+ packet::Gamestate *gs = new packet::Gamestate(*gamestate); //TODO: is this neccessary ?
// packet::Gamestate *gs = new packet::Gamestate();
// gs->collectData( id_, 0x1 );
// this->threadMutex_->lock();
@@ -200,25 +200,17 @@
if(base)
{
-
-// COUT(3) << "diffing" << std::endl;
-// packet::Gamestate* gs1 = gs;
- packet::Gamestate *diffed = gs->diff(base);
- if( diffed->getDataSize() == 0 )
+ packet::Gamestate *diffed1 = gs->diffVariables(base);
+ if( diffed1->getDataSize() == 0 )
{
- delete diffed;
+ delete diffed1;
destgamestate = 0;
return;
}
- else
- gs = diffed;
- //packet::Gamestate *gs2 = diffed->undiff(gs);
-// assert(*gs == *gs2);
-// packet::Gamestate* gs2 = gs->undiff(client);
-// gs = new packet::Gamestate(*gs);
-// assert(*gs1==*gs2);
+ gs = diffed1;
}
- else{
+ else
+ {
gs = new packet::Gamestate(*gs);
}
Modified: code/branches/network2/src/libraries/network/Host.h
===================================================================
--- code/branches/network2/src/libraries/network/Host.h 2010-01-17 10:49:48 UTC (rev 6449)
+++ code/branches/network2/src/libraries/network/Host.h 2010-01-17 23:05:57 UTC (rev 6450)
@@ -35,7 +35,7 @@
namespace orxonox {
const unsigned int CLIENTID_SERVER = 0;
- const unsigned int NETWORK_FREQUENCY = 30;
+ const unsigned int NETWORK_FREQUENCY = 25;
const float NETWORK_PERIOD = 1.0f/NETWORK_FREQUENCY;
/**
Modified: code/branches/network2/src/libraries/network/packet/Gamestate.cc
===================================================================
--- code/branches/network2/src/libraries/network/packet/Gamestate.cc 2010-01-17 10:49:48 UTC (rev 6449)
+++ code/branches/network2/src/libraries/network/packet/Gamestate.cc 2010-01-17 23:05:57 UTC (rev 6450)
@@ -180,7 +180,6 @@
assert(data_);
assert(!header_->isCompressed());
uint8_t *mem=data_+GamestateHeader::getSize();
- bool diffed = header_->isDiffed();
Synchronisable *s;
// update the data of the objects we received
@@ -193,11 +192,11 @@
{
if (!GameMode::isMaster())
{
- Synchronisable::fabricate(mem, diffed, mode);
+ Synchronisable::fabricate(mem, mode);
}
else
{
- mem += objectheader.getDataSize()+SynchronisableHeader::getSize();
+ mem += objectheader.getDataSize() + ( objectheader.isDiffed() ? SynchronisableHeaderLight::getSize() : SynchronisableHeader::getSize() );
}
}
else
@@ -364,7 +363,7 @@
}
-Gamestate *Gamestate::diff(Gamestate *base)
+Gamestate* Gamestate::diffVariables(Gamestate *base)
{
assert(this && base); assert(data_ && base->data_);
assert(!header_->isCompressed() && !base->header_->isCompressed());
@@ -380,7 +379,6 @@
assert( origLength && baseLength );
- COUT(0) << "newSize: " << origLength + GamestateHeader::getSize() + sizeof(uint32_t)*this->nrOfVariables_ << endl;
uint8_t *nData = new uint8_t[origLength + GamestateHeader::getSize() + sizeof(uint32_t)*this->nrOfVariables_]; // this is the maximum size needed in the worst case
uint8_t *dest = GAMESTATE_START(nData);
@@ -447,10 +445,10 @@
{
// COUT(4) << "diff " << h.getObjectID() << ":";
// Now start to diff the Object
- SynchronisableHeader h2(dest);
+ SynchronisableHeaderLight h2(dest);
h2 = h; // copy over the objectheader
- uint32_t variableID = 0;
- uint32_t newObjectOffset = SynchronisableHeader::getSize();
+ VariableID variableID = 0;
+ uint32_t newObjectOffset = SynchronisableHeaderLight::getSize();
// iterate through all variables
while( objectOffset < h.getDataSize()+SynchronisableHeader::getSize() )
{
@@ -464,8 +462,8 @@
if ( memcmp(origData+origOffset+objectOffset, temp+objectOffset, varSize) != 0 )
{
// COUT(4) << " c" << varSize;
- *(uint32_t*)(dest+newObjectOffset) = variableID; // copy over the variableID
- newObjectOffset += sizeof(uint32_t);
+ *(VariableID*)(dest+newObjectOffset) = variableID; // copy over the variableID
+ newObjectOffset += sizeof(VariableID);
memcpy( dest+newObjectOffset, origData+origOffset+objectOffset, varSize );
newObjectOffset += varSize;
objectOffset += varSize;
@@ -484,7 +482,7 @@
sizes += Synchronisable::getSynchronisable(h.getObjectID())->getNrOfVariables() - variableID;
// COUT(4) << endl;
h2.setDiffed(true);
- h2.setDataSize(newObjectOffset-SynchronisableHeader::getSize());
+ h2.setDataSize(newObjectOffset-SynchronisableHeaderLight::getSize());
assert(objectOffset == h.getDataSize()+SynchronisableHeader::getSize());
origOffset += objectOffset;
baseOffset += temp + h.getDataSize()+SynchronisableHeader::getSize() - baseData;
@@ -519,17 +517,109 @@
Gamestate *g = new Gamestate(nData, getClientID());
assert(g->header_);
*(g->header_) = *header_;
- g->header_->setDiffed( true );
g->header_->setBaseID( base->getID() );
g->header_->setDataSize(dest - nData - GamestateHeader::getSize());
g->flags_=flags_;
g->packetDirection_ = packetDirection_;
+ assert(!g->isCompressed());
+ return g;
+}
+
+
+Gamestate* Gamestate::diffData(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 );
+ delete dest2;
+#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;
+}
+
+
+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;
Modified: code/branches/network2/src/libraries/network/packet/Gamestate.h
===================================================================
--- code/branches/network2/src/libraries/network/packet/Gamestate.h 2010-01-17 10:49:48 UTC (rev 6449)
+++ code/branches/network2/src/libraries/network/packet/Gamestate.h 2010-01-17 23:05:57 UTC (rev 6450)
@@ -114,7 +114,9 @@
inline bool isCompressed() const { return header_->isCompressed(); }
inline int32_t getBaseID() const { return header_->getBaseID(); }
inline uint32_t getDataSize() const { return header_->getDataSize(); }
- Gamestate *diff(Gamestate *base);
+ Gamestate* diffVariables(Gamestate *base);
+ Gamestate* diffData(Gamestate *base);
+ Gamestate *undiff(Gamestate *base);
Gamestate* doSelection(unsigned int clientID, unsigned int targetSize);
bool compressData();
bool decompressData();
Modified: code/branches/network2/src/libraries/network/packet/Packet.cc
===================================================================
--- code/branches/network2/src/libraries/network/packet/Packet.cc 2010-01-17 10:49:48 UTC (rev 6449)
+++ code/branches/network2/src/libraries/network/packet/Packet.cc 2010-01-17 23:05:57 UTC (rev 6450)
@@ -70,10 +70,6 @@
bDataENetAllocated_ = false;
}
-void blub(ENetPacket *packet){
- COUT(4) << "blubb" << std::endl;
-}
-
Packet::Packet(uint8_t *data, unsigned int clientID){
flags_ = PACKET_FLAG_DEFAULT;
packetDirection_ = Direction::Incoming;
Modified: code/branches/network2/src/libraries/network/synchronisable/Synchronisable.cc
===================================================================
--- code/branches/network2/src/libraries/network/synchronisable/Synchronisable.cc 2010-01-17 10:49:48 UTC (rev 6449)
+++ code/branches/network2/src/libraries/network/synchronisable/Synchronisable.cc 2010-01-17 23:05:57 UTC (rev 6450)
@@ -131,9 +131,10 @@
* @param mode defines the mode, how the data should be loaded
* @return pointer to the newly created synchronisable
*/
- Synchronisable *Synchronisable::fabricate(uint8_t*& mem, bool diffed, uint8_t mode)
+ Synchronisable *Synchronisable::fabricate(uint8_t*& mem, uint8_t mode)
{
SynchronisableHeader header(mem);
+ assert( !header.isDiffed() );
COUT(4) << "fabricating object with id: " << header.getObjectID() << std::endl;
@@ -307,45 +308,44 @@
mode=state_;
if(syncList_.empty()){
assert(0);
- COUT(4) << "Synchronisable::updateData syncList_ is empty" << std::endl;
+ COUT(2) << "Synchronisable::updateData syncList_ is empty" << std::endl;
return false;
}
uint8_t* data=mem;
// start extract header
- SynchronisableHeader syncHeader(mem);
- assert(syncHeader.getObjectID()==this->objectID_);
- assert(syncHeader.getCreatorID()==this->creatorID_);
- assert(syncHeader.getClassID()==this->classID_);
+ SynchronisableHeaderLight syncHeaderLight(mem);
+ assert(syncHeaderLight.getObjectID()==this->getObjectID());
- mem += SynchronisableHeader::getSize();
- // stop extract header
-
//COUT(5) << "Synchronisable: objectID_ " << syncHeader.getObjectID() << ", classID_ " << syncHeader.getClassID() << " size: " << syncHeader.getDataSize() << " synchronising data" << std::endl;
- if( !syncHeader.isDiffed() )
+ if( !syncHeaderLight.isDiffed() )
{
+ SynchronisableHeader syncHeader2(mem);
+ assert( this->getClassID() == syncHeader2.getClassID() );
+ assert( this->getCreatorID() == syncHeader2.getCreatorID() );
+ mem += SynchronisableHeader::getSize();
std::vector<SynchronisableVariableBase *>::iterator i;
for(i=syncList_.begin(); i!=syncList_.end(); i++)
{
- assert( mem <= data+syncHeader.getDataSize()+SynchronisableHeader::getSize() ); // always make sure we don't exceed the datasize in our stream
+ assert( mem <= data+syncHeader2.getDataSize()+SynchronisableHeader::getSize() ); // always make sure we don't exceed the datasize in our stream
(*i)->putData( mem, mode, forceCallback );
}
+ assert(mem == data+syncHeaderLight.getDataSize()+SynchronisableHeader::getSize() );
}
else
{
- COUT(0) << "objectID: " << this->objectID_ << endl;
- while( mem < data+syncHeader.getDataSize()+SynchronisableHeader::getSize() )
+ mem += SynchronisableHeaderLight::getSize();
+// COUT(0) << "objectID: " << this->objectID_ << endl;
+ while( mem < data+syncHeaderLight.getDataSize()+SynchronisableHeaderLight::getSize() )
{
- uint32_t varID = *(uint32_t*)mem;
- COUT(0) << "varID: " << varID << endl;
- if( varID == 22 )
- COUT(6) << " blub " << endl;
+ VariableID varID = *(VariableID*)mem;
+// COUT(0) << "varID: " << varID << endl;
assert( varID < syncList_.size() );
- mem += sizeof(uint32_t);
+ mem += sizeof(VariableID);
syncList_[varID]->putData( mem, mode, forceCallback );
}
+ assert(mem == data+syncHeaderLight.getDataSize()+SynchronisableHeaderLight::getSize() );
}
- assert(mem == data+syncHeader.getDataSize()+SynchronisableHeader::getSize() );
return true;
}
Modified: code/branches/network2/src/libraries/network/synchronisable/Synchronisable.h
===================================================================
--- code/branches/network2/src/libraries/network/synchronisable/Synchronisable.h 2010-01-17 10:49:48 UTC (rev 6449)
+++ code/branches/network2/src/libraries/network/synchronisable/Synchronisable.h 2010-01-17 23:05:57 UTC (rev 6450)
@@ -63,6 +63,8 @@
VeryLow = 100
};
}
+
+ typedef uint8_t VariableID;
/**
* @brief: stores information about a Synchronisable
@@ -76,33 +78,34 @@
* Byte 13 to 16: creatorID_
*/
class _NetworkExport SynchronisableHeader{
+ friend class SynchronisableHeaderLight;
private:
- uint8_t *data_;
+ uint8_t* data_;
public:
SynchronisableHeader(uint8_t* data)
{ data_ = data; }
inline static uint32_t getSize()
- { return 16; }
- inline uint32_t getDataSize() const
- { return (*(uint32_t*)data_) & 0x7FFFFFFF; } //only use the first 31 bits
- inline void setDataSize(uint32_t size)
- { *(uint32_t*)(data_) = (size & 0x7FFFFFFF) | (*(uint32_t*)(data_) & 0x80000000 ); }
+ { return 14; }
+ inline uint16_t getDataSize() const
+ { return (*(uint16_t*)data_) & 0x7FFF; } //only use the first 31 bits
+ inline void setDataSize(uint16_t size)
+ { *(uint16_t*)(data_) = (size & 0x7FFFFFFF) | (*(uint16_t*)(data_) & 0x8000 ); }
inline bool isDiffed() const
- { return ( (*(uint32_t*)data_) & 0x80000000 ) == 0x80000000; }
+ { return ( (*(uint16_t*)data_) & 0x8000 ) == 0x8000; }
inline void setDiffed( bool b)
- { *(uint32_t*)(data_) = (b << 31) | (*(uint32_t*)(data_) & 0x7FFFFFFF ); }
+ { *(uint16_t*)(data_) = (b << 15) | (*(uint16_t*)(data_) & 0x7FFF ); }
inline uint32_t getObjectID() const
- { return *(uint32_t*)(data_+4); }
+ { return *(uint32_t*)(data_+2); }
inline void setObjectID(uint32_t objectID_)
- { *(uint32_t*)(data_+4) = objectID_; }
+ { *(uint32_t*)(data_+2) = objectID_; }
inline uint32_t getClassID() const
- { return *(uint32_t*)(data_+8); }
+ { return *(uint32_t*)(data_+6); }
inline void setClassID(uint32_t classID_)
- { *(uint32_t*)(data_+8) = classID_; }
+ { *(uint32_t*)(data_+6) = classID_; }
inline uint32_t getCreatorID() const
- { return *(uint32_t*)(data_+12); }
+ { return *(uint32_t*)(data_+10); }
inline void setCreatorID(uint32_t creatorID_)
- { *(uint32_t*)(data_+12) = creatorID_; }
+ { *(uint32_t*)(data_+10) = creatorID_; }
inline void operator=(SynchronisableHeader& h)
{ memcpy(data_, h.data_, getSize()); }
};
@@ -118,24 +121,24 @@
*/
class _NetworkExport SynchronisableHeaderLight{
private:
- uint8_t *data_;
+ uint8_t* data_;
public:
- SynchronisableHeader(uint8_t* data)
+ SynchronisableHeaderLight(uint8_t* data)
{ data_ = data; }
inline static uint32_t getSize()
- { return 16; }
- inline uint32_t getDataSize() const
- { return (*(uint32_t*)data_) & 0x7FFFFFFF; } //only use the first 31 bits
- inline void setDataSize(uint32_t size)
- { *(uint32_t*)(data_) = (size & 0x7FFFFFFF) | (*(uint32_t*)(data_) & 0x80000000 ); }
+ { return 6; }
+ inline uint16_t getDataSize() const
+ { return (*(uint16_t*)data_) & 0x7FFF; } //only use the first 31 bits
+ inline void setDataSize(uint16_t size)
+ { *(uint16_t*)(data_) = (size & 0x7FFFFFFF) | (*(uint16_t*)(data_) & 0x8000 ); }
inline bool isDiffed() const
- { return ( (*(uint32_t*)data_) & 0x80000000 ) == 0x80000000; }
+ { return ( (*(uint16_t*)data_) & 0x8000 ) == 0x8000; }
inline void setDiffed( bool b)
- { *(uint32_t*)(data_) = (b << 31) | (*(uint32_t*)(data_) & 0x7FFFFFFF ); }
+ { *(uint16_t*)(data_) = (b << 15) | (*(uint16_t*)(data_) & 0x7FFF ); }
inline uint32_t getObjectID() const
- { return *(uint32_t*)(data_+4); }
+ { return *(uint32_t*)(data_+2); }
inline void setObjectID(uint32_t objectID_)
- { *(uint32_t*)(data_+4) = objectID_; }
+ { *(uint32_t*)(data_+2) = objectID_; }
inline void operator=(SynchronisableHeader& h)
{ memcpy(data_, h.data_, getSize()); }
};
@@ -152,7 +155,7 @@
static void setClient(bool b);
- static Synchronisable *fabricate(uint8_t*& mem, bool diffed, uint8_t mode=0x0);
+ static Synchronisable *fabricate(uint8_t*& mem, uint8_t mode=0x0);
static bool deleteObject(uint32_t objectID_);
static Synchronisable *getSynchronisable(uint32_t objectID_);
static unsigned int getNumberOfDeletedObject(){ return deletedObjects_.size(); }
@@ -167,7 +170,7 @@
void setSyncMode(uint8_t mode);
inline uint32_t getNrOfVariables(){ return this->syncList_.size(); }
- inline uint32_t getVarSize( uint32_t ID )
+ inline uint32_t getVarSize( VariableID ID )
{ return this->syncList_[ID]->getSize(state_); }
protected:
More information about the Orxonox-commit
mailing list