Changeset 6449 for code/branches/network2/src
- Timestamp:
- Jan 17, 2010, 11:49:48 AM (15 years ago)
- Location:
- code/branches/network2/src/libraries/network
- Files:
-
- 8 edited
Legend:
- Unmodified
- Added
- Removed
-
code/branches/network2/src/libraries/network/GamestateClient.cc
r6417 r6449 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 this171 packet::Gamestate *undiffed = gs->undiff(base);172 delete gs;173 gs=undiffed;174 COUT(5) << "successfully undiffed gamestate id: " << undiffed->getID() << std::endl;175 }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; 175 // } 176 176 if(gs->spreadData(0x2)) 177 177 return gs; -
code/branches/network2/src/libraries/network/GamestateManager.cc
r6417 r6449 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); 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) … … 200 205 // packet::Gamestate* gs1 = gs; 201 206 packet::Gamestate *diffed = gs->diff(base); 207 if( diffed->getDataSize() == 0 ) 208 { 209 delete diffed; 210 destgamestate = 0; 211 return; 212 } 213 else 214 gs = diffed; 202 215 //packet::Gamestate *gs2 = diffed->undiff(gs); 203 216 // assert(*gs == *gs2); 204 gs = diffed;205 217 // packet::Gamestate* gs2 = gs->undiff(client); 206 218 // gs = new packet::Gamestate(*gs); … … 214 226 bool b = gs->compressData(); 215 227 assert(b); 216 // COUT(4) << "sending gamestate with id " << gs->getID(); 228 clock.capture(); 229 COUT(0) << "diff time: " << clock.getDeltaTime() << endl; 230 // COUT(5) << "sending gamestate with id " << gs->getID(); 217 231 // if(gamestate->isDiffed()) 218 // COUT(4) << " and baseid " << gs->getBaseID() << endl;232 // COUT(5) << " and baseid " << gs->getBaseID() << endl; 219 233 // else 220 // COUT(4) << endl;234 // COUT(5) << endl; 221 235 gs->setClientID(clientID); 222 *destgamestate = gs;236 destgamestate = gs; 223 237 } 224 238 -
code/branches/network2/src/libraries/network/GamestateManager.h
r5781 r6449 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/branches/network2/src/libraries/network/packet/Gamestate.cc
r6417 r6449 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(); 183 bool diffed = header_->isDiffed(); 157 184 Synchronisable *s; 158 185 159 186 // update the data of the objects we received 160 while(mem < data_+GamestateHeader::getSize()+header_->getDataSize()){ 187 while(mem < data_+GamestateHeader::getSize()+header_->getDataSize()) 188 { 161 189 SynchronisableHeader objectheader(mem); 162 190 … … 166 194 if (!GameMode::isMaster()) 167 195 { 168 Synchronisable::fabricate(mem, mode);196 Synchronisable::fabricate(mem, diffed, mode); 169 197 } 170 198 else 171 199 { 172 mem += objectheader.getDataSize() ;200 mem += objectheader.getDataSize()+SynchronisableHeader::getSize(); 173 201 } 174 202 } … … 181 209 // In debug mode, check first, whether there are no duplicate objectIDs 182 210 #ifndef NDEBUG 183 if(this->getID()%1000==0){ 211 if(this->getID()%1000==1) 212 { 184 213 std::list<uint32_t> v1; 185 214 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) { 215 for (it = ObjectList<Synchronisable>::begin(); it != ObjectList<Synchronisable>::end(); ++it) 216 { 217 if (it->getObjectID() == OBJECTID_UNKNOWN) 218 { 219 if (it->objectMode_ != 0x0) 220 { 189 221 COUT(0) << "Found object with OBJECTID_UNKNOWN on the client with objectMode != 0x0!" << std::endl; 190 222 COUT(0) << "Possible reason for this error: Client created a synchronized object without the Server's approval." << std::endl; … … 193 225 } 194 226 } 195 else { 227 else 228 { 196 229 std::list<uint32_t>::iterator it2; 197 for (it2 = v1.begin(); it2 != v1.end(); ++it2) { 198 if (it->getObjectID() == *it2) { 230 for (it2 = v1.begin(); it2 != v1.end(); ++it2) 231 { 232 if (it->getObjectID() == *it2) 233 { 199 234 COUT(0) << "Found duplicate objectIDs on the client!" << std::endl 200 235 << "Are you sure you don't create a Sychnronisable objcect with 'new' \ … … 211 246 } 212 247 248 213 249 uint32_t Gamestate::getSize() const 214 250 { … … 222 258 } 223 259 224 bool Gamestate::operator==(packet::Gamestate gs){ 260 261 bool Gamestate::operator==(packet::Gamestate gs) 262 { 225 263 uint8_t *d1 = data_+GamestateHeader::getSize(); 226 264 uint8_t *d2 = gs.data_+GamestateHeader::getSize(); … … 233 271 } 234 272 273 235 274 bool Gamestate::process() 236 275 { 237 276 return GamestateHandler::addGamestate(this, getClientID()); 238 277 } 239 240 278 241 279 … … 253 291 int retval; 254 292 retval = compress( dest, &buffer, source, (uLong)(header_->getDataSize()) ); 255 switch ( retval ) { 293 switch ( retval ) 294 { 256 295 case Z_OK: COUT(5) << "G.St.Man: compress: successfully compressed" << std::endl; break; 257 296 case Z_MEM_ERROR: COUT(1) << "G.St.Man: compress: not enough memory available in gamestate.compress" << std::endl; return false; … … 270 309 header_->setCompSize( buffer ); 271 310 header_->setCompressed( true ); 272 COUT( 5) << "gamestate compress datasize: " << header_->getDataSize() << " compsize: " << header_->getCompSize() << std::endl;311 COUT(0) << "gamestate compress datasize: " << header_->getDataSize() << " compsize: " << header_->getCompSize() << std::endl; 273 312 return true; 274 313 } 314 315 275 316 bool Gamestate::decompressData() 276 317 { … … 289 330 uLongf length=bufsize; 290 331 retval = uncompress( dest, &length, source, (uLong)compsize ); 291 switch ( retval ) { 332 switch ( retval ) 333 { 292 334 case Z_OK: COUT(5) << "successfully decompressed" << std::endl; break; 293 335 case Z_MEM_ERROR: COUT(1) << "not enough memory available" << std::endl; return false; … … 301 343 delete temp; 302 344 303 if (this->bDataENetAllocated_){ 345 if (this->bDataENetAllocated_) 346 { 304 347 // Memory was allocated by ENet. --> We let it be since enet_packet_destroy will 305 348 // deallocated it anyway. So data and packet stay together. 306 349 this->bDataENetAllocated_ = false; 307 350 } 308 else{ 351 else 352 { 309 353 // We allocated the memory in the first place (unlikely). So we destroy the old data 310 354 // and overwrite it with the new decompressed data. … … 320 364 } 321 365 322 /*Gamestate *Gamestate::diff(Gamestate *base)323 {324 assert(data_);325 assert(!header_->isCompressed());326 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 offset330 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 xor338 ++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());351 *(g->header_) = *header_;352 g->header_->setDiffed( true );353 g->header_->setBaseID( base->getID() );354 g->flags_=flags_;355 g->packetDirection_ = packetDirection_;356 return g;357 }*/358 366 359 367 Gamestate *Gamestate::diff(Gamestate *base) … … 363 371 assert(!header_->isDiffed()); 364 372 365 uint8_t *basep = GAMESTATE_START(base->data_); 366 uint8_t *gs = GAMESTATE_START(this->data_); 367 uint32_t dest_length = header_->getDataSize(); 368 369 if(dest_length==0) 370 return NULL; 371 372 uint8_t *ndata = new uint8_t[dest_length*sizeof(uint8_t)+GamestateHeader::getSize()]; 373 uint8_t *dest = GAMESTATE_START(ndata); 374 375 rawDiff( dest, gs, basep, header_->getDataSize(), base->header_->getDataSize() ); 376 #ifndef NDEBUG 377 uint8_t *dest2 = new uint8_t[dest_length]; 378 rawDiff( dest2, dest, basep, header_->getDataSize(), base->header_->getDataSize() ); 379 assert( memcmp( dest2, gs, dest_length) == 0 ); 380 delete dest2; 381 #endif 382 383 Gamestate *g = new Gamestate(ndata, getClientID()); 373 374 // *** first do a raw diff of the two gamestates 375 376 uint8_t *baseData = GAMESTATE_START(base->data_); 377 uint8_t *origData = GAMESTATE_START(this->data_); 378 uint32_t origLength = header_->getDataSize(); 379 uint32_t baseLength = base->header_->getDataSize(); 380 381 assert( origLength && baseLength ); 382 383 COUT(0) << "newSize: " << origLength + GamestateHeader::getSize() + sizeof(uint32_t)*this->nrOfVariables_ << endl; 384 uint8_t *nData = new uint8_t[origLength + GamestateHeader::getSize() + sizeof(uint32_t)*this->nrOfVariables_]; // this is the maximum size needed in the worst case 385 uint8_t *dest = GAMESTATE_START(nData); 386 387 uint32_t baseOffset = 0; //offset in the diffed stream 388 uint32_t origOffset = 0; //offset in the new stream with removed 0's 389 std::vector<uint32_t>::iterator sizes = this->sizes_.begin(); 390 391 while( origOffset < origLength ) 392 { 393 //iterate through all objects 394 395 SynchronisableHeader h(origData+origOffset); 396 397 // Find (if possible) the current object in the datastream of the old gamestate 398 // Start at the current offset position 399 if(baseOffset >= baseLength) 400 baseOffset = 0; 401 uint8_t* temp = baseData + baseOffset; 402 uint32_t objectID = h.getObjectID(); 403 assert(temp < baseData+baseLength); 404 assert(dest < nData + origLength + GamestateHeader::getSize() + sizeof(uint32_t)*this->nrOfVariables_); 405 assert(sizes != this->sizes_.end()); 406 while ( temp < baseData+baseLength ) 407 { 408 SynchronisableHeader htemp(temp); 409 if ( htemp.getObjectID() == objectID ) 410 { 411 assert( h.getClassID() == htemp.getClassID() ); 412 goto DODIFF; 413 } 414 temp += htemp.getDataSize()+SynchronisableHeader::getSize(); 415 } 416 // If not found start looking at the beginning 417 temp = baseData; 418 while ( temp < baseData+baseOffset ) 419 { 420 SynchronisableHeader htemp(temp); 421 if ( htemp.getObjectID() == objectID ) 422 { 423 assert( h.getClassID() == htemp.getClassID() ); 424 goto DODIFF; 425 } 426 temp += htemp.getDataSize()+SynchronisableHeader::getSize(); 427 } 428 // Object is new, thus never transmitted -> just copy over 429 goto DOCOPY; 430 431 432 DODIFF: 433 { 434 // if(baseOffset==0) 435 // { 436 // assert(origOffset==0); 437 // } 438 uint32_t objectOffset = SynchronisableHeader::getSize(); // offset inside the object in the origData and baseData 439 // Check whether the whole object stayed the same 440 if( memcmp( origData+origOffset+objectOffset, temp+objectOffset, h.getDataSize()) == 0 ) 441 { 442 origOffset += objectOffset+ h.getDataSize(); // skip the whole object 443 baseOffset = temp + h.getDataSize()+SynchronisableHeader::getSize() - baseData; 444 sizes += Synchronisable::getSynchronisable(h.getObjectID())->getNrOfVariables(); 445 } 446 else 447 { 448 // COUT(4) << "diff " << h.getObjectID() << ":"; 449 // Now start to diff the Object 450 SynchronisableHeader h2(dest); 451 h2 = h; // copy over the objectheader 452 uint32_t variableID = 0; 453 uint32_t newObjectOffset = SynchronisableHeader::getSize(); 454 // iterate through all variables 455 while( objectOffset < h.getDataSize()+SynchronisableHeader::getSize() ) 456 { 457 // check whether variable changed and write id and copy over variable to the new stream 458 // otherwise skip variable 459 assert(sizes != this->sizes_.end()); 460 uint32_t varSize = *sizes; 461 assert( varSize == Synchronisable::getSynchronisable(h.getObjectID())->getVarSize(variableID) ); 462 if ( varSize != 0 ) 463 { 464 if ( memcmp(origData+origOffset+objectOffset, temp+objectOffset, varSize) != 0 ) 465 { 466 // COUT(4) << " c" << varSize; 467 *(uint32_t*)(dest+newObjectOffset) = variableID; // copy over the variableID 468 newObjectOffset += sizeof(uint32_t); 469 memcpy( dest+newObjectOffset, origData+origOffset+objectOffset, varSize ); 470 newObjectOffset += varSize; 471 objectOffset += varSize; 472 } 473 else 474 { 475 // COUT(4) << " s" << varSize; 476 objectOffset += varSize; 477 } 478 } 479 480 ++variableID; 481 ++sizes; 482 } 483 if( Synchronisable::getSynchronisable(h.getObjectID())->getNrOfVariables() != variableID ) 484 sizes += Synchronisable::getSynchronisable(h.getObjectID())->getNrOfVariables() - variableID; 485 // COUT(4) << endl; 486 h2.setDiffed(true); 487 h2.setDataSize(newObjectOffset-SynchronisableHeader::getSize()); 488 assert(objectOffset == h.getDataSize()+SynchronisableHeader::getSize()); 489 origOffset += objectOffset; 490 baseOffset += temp + h.getDataSize()+SynchronisableHeader::getSize() - baseData; 491 dest += newObjectOffset; 492 } 493 494 continue; 495 } 496 497 DOCOPY: 498 { 499 // Just copy over the whole Object 500 memcpy( dest, origData+origOffset, h.getDataSize()+SynchronisableHeader::getSize() ); 501 dest += h.getDataSize()+SynchronisableHeader::getSize(); 502 origOffset += h.getDataSize()+SynchronisableHeader::getSize(); 503 assert( Synchronisable::getSynchronisable(h.getObjectID()) ); 504 // COUT(4) << "copy " << h.getObjectID() << endl; 505 // COUT(4) << "copy " << h.getObjectID() << ":"; 506 //sizes += Synchronisable::getSynchronisable(h.getObjectID())->getNrOfVariables(); 507 for( unsigned int i = 0; i < Synchronisable::getSynchronisable(h.getObjectID())->getNrOfVariables(); ++i ) 508 { 509 // COUT(4) << " " << *sizes; 510 ++sizes; 511 } 512 // COUT(4) << endl; 513 assert(sizes != this->sizes_.end() || origOffset>=origLength); 514 continue; 515 } 516 } 517 518 519 Gamestate *g = new Gamestate(nData, getClientID()); 384 520 assert(g->header_); 385 521 *(g->header_) = *header_; 386 522 g->header_->setDiffed( true ); 387 523 g->header_->setBaseID( base->getID() ); 524 g->header_->setDataSize(dest - nData - GamestateHeader::getSize()); 388 525 g->flags_=flags_; 389 526 g->packetDirection_ = packetDirection_; … … 393 530 } 394 531 395 Gamestate *Gamestate::undiff(Gamestate *base)396 {397 assert(this && base); assert(data_ && base->data_);398 assert(!header_->isCompressed() && !base->header_->isCompressed());399 assert(header_->isDiffed());400 401 uint8_t *basep = GAMESTATE_START(base->data_);402 uint8_t *gs = GAMESTATE_START(this->data_);403 uint32_t dest_length = header_->getDataSize();404 405 if(dest_length==0)406 return NULL;407 408 uint8_t *ndata = new uint8_t[dest_length*sizeof(uint8_t)+GamestateHeader::getSize()];409 uint8_t *dest = ndata + GamestateHeader::getSize();410 411 rawDiff( dest, gs, basep, header_->getDataSize(), base->header_->getDataSize() );412 413 Gamestate *g = new Gamestate(ndata, getClientID());414 assert(g->header_);415 *(g->header_) = *header_;416 g->header_->setDiffed( false );417 g->flags_=flags_;418 g->packetDirection_ = packetDirection_;419 assert(!g->isDiffed());420 assert(!g->isCompressed());421 return g;422 }423 424 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 void Gamestate::rawDiff( uint8_t* newdata, uint8_t* data, uint8_t* basedata, uint32_t datalength, uint32_t baselength)479 {480 uint64_t* gd = (uint64_t*)data;481 uint64_t* bd = (uint64_t*)basedata;482 uint64_t* nd = (uint64_t*)newdata;483 484 unsigned int i;485 for( i=0; i<datalength/8; i++ )486 {487 if( i<baselength/8 )488 *(nd+i) = *(gd+i) ^ *(bd+i); // xor the data489 else490 *(nd+i) = *(gd+i); // just copy over the data491 }492 unsigned int j;493 // now process the rest (when datalength isn't a multiple of 4)494 for( j = 8*(datalength/8); j<datalength; j++ )495 {496 if( j<baselength )497 *(newdata+j) = *(data+j) ^ *(basedata+j); // xor498 else499 *(newdata+j) = *(data+j); // just copy500 }501 assert(j==datalength);502 }503 532 504 533 Gamestate* Gamestate::doSelection(unsigned int clientID, unsigned int targetSize){ … … 529 558 // COUT(0) << "myvector contains:"; 530 559 // for ( itt=dataVector_.begin() ; itt!=dataVector_.end(); itt++ ) 531 // COUT(0) << ' '<< (*itt).objID;560 // COUT(0) << " " << (*itt).objID; 532 561 // COUT(0) << endl; 533 562 for(it=dataVector_.begin(); it!=dataVector_.end();){ 534 563 SynchronisableHeader oldobjectheader(origdata); 535 564 SynchronisableHeader newobjectheader(newdata); 536 if ( it->objSize == 0 )565 if ( (*it).objSize == 0 ) 537 566 { 538 567 ++it; 539 568 continue; 540 569 } 541 objectsize = oldobjectheader.getDataSize() ;570 objectsize = oldobjectheader.getDataSize()+SynchronisableHeader::getSize(); 542 571 objectOffset=SynchronisableHeader::getSize(); //skip the size and the availableData variables in the objectheader 543 if ( it->objID == oldobjectheader.getObjectID() ){572 if ( (*it).objID == oldobjectheader.getObjectID() ){ 544 573 memcpy(newdata, origdata, objectsize); 545 assert(newobjectheader.isDataAvailable()==true);546 574 ++it; 547 575 }else{ 548 576 newobjectheader = oldobjectheader; 549 newobjectheader.setDataAvailable(false);550 577 memset(newdata+objectOffset, 0, objectsize-objectOffset); 551 578 } … … 559 586 { 560 587 SynchronisableHeader oldobjectheader(origdata); 561 objectsize = oldobjectheader.getDataSize() ;588 objectsize = oldobjectheader.getDataSize()+SynchronisableHeader::getSize(); 562 589 origdata += objectsize; 563 590 origsize += objectsize; … … 571 598 572 599 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 600 uint32_t Gamestate::calcGamestateSize(int32_t id, uint8_t mode) 612 601 { 613 uint32_t size=0; 602 uint32_t size = 0; 603 uint32_t nrOfVariables = 0; 614 604 // get the start of the Synchronisable list 615 605 ObjectList<Synchronisable>::iterator it; 616 606 // get total size of gamestate 617 for(it = ObjectList<Synchronisable>::begin(); it; ++it) 607 for(it = ObjectList<Synchronisable>::begin(); it; ++it){ 618 608 size+=it->getSize(id, mode); // size of the actual data of the synchronisable 609 nrOfVariables += it->getNrOfVariables(); 610 } 611 // COUT(0) << "allocating " << nrOfVariables << " ints" << endl; 612 this->sizes_.reserve(nrOfVariables); 619 613 return size; 620 614 } 615 621 616 622 617 } //namespace packet -
code/branches/network2/src/libraries/network/packet/Gamestate.h
r6073 r6449 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(); } 116 inline uint32_t getDataSize() const { return header_->getDataSize(); } 115 117 Gamestate *diff(Gamestate *base); 116 Gamestate *undiff(Gamestate *base);117 118 Gamestate* doSelection(unsigned int clientID, unsigned int targetSize); 118 119 bool compressData(); … … 123 124 private: 124 125 void rawDiff( uint8_t* newdata, uint8_t* data, uint8_t* basedata, uint32_t datalength, uint32_t baselength); 126 inline uint32_t findObject( const SynchronisableHeader& header, uint8_t* mem, uint32_t dataLength, uint32_t startPosition = 0 ); 125 127 virtual uint32_t getSize() const; 126 128 virtual inline bool process(); 127 128 private:129 129 uint32_t calcGamestateSize(int32_t id, uint8_t mode=0x0); 130 std::list<obj> dataVector_; 131 GamestateHeader* header_; 130 131 std::list<obj> dataVector_; 132 GamestateHeader* header_; 133 std::vector<uint32_t> sizes_; 134 uint32_t nrOfVariables_; 132 135 }; 133 136 -
code/branches/network2/src/libraries/network/synchronisable/Serialise.h
r6417 r6449 72 72 return *(uint32_t*)(mem) == variable->getObjectID(); 73 73 else 74 return *(uint32_t*)(mem) == OBJECTID_UNKNOWN;74 return variable == variable->getSynchronisable(*(uint32_t*)(mem)); 75 75 } 76 76 } -
code/branches/network2/src/libraries/network/synchronisable/Synchronisable.cc
r6417 r6449 101 101 deletedObjects_.push(objectID_); 102 102 } 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++)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++) 105 105 delete (*it); 106 syncList .clear();107 stringList .clear();106 syncList_.clear(); 107 stringList_.clear(); 108 108 std::map<uint32_t, Synchronisable*>::iterator it; 109 109 it = objectMap_.find(objectID_); … … 132 132 * @return pointer to the newly created synchronisable 133 133 */ 134 Synchronisable *Synchronisable::fabricate(uint8_t*& mem, uint8_t mode)134 Synchronisable *Synchronisable::fabricate(uint8_t*& mem, bool diffed, uint8_t mode) 135 135 { 136 136 SynchronisableHeader header(mem); 137 138 if(!header.isDataAvailable())139 {140 mem += header.getDataSize();141 return 0;142 }143 137 144 138 COUT(4) << "fabricating object with id: " << header.getObjectID() << std::endl; … … 160 154 if (!synchronisable_creator) 161 155 { 162 mem += header.getDataSize() ; //.TODO: this suckz.... remove size from header156 mem += header.getDataSize()+SynchronisableHeader::getSize(); //.TODO: this suckz.... remove size from header 163 157 assert(0); // TODO: uncomment this if we have a clean objecthierarchy (with destruction of children of objects) ^^ 164 158 return 0; … … 245 239 * @return true: if !doSync or if everything was successfully saved 246 240 */ 247 uint32_t Synchronisable::getData(uint8_t*& mem, int32_t id, uint8_t mode){ 241 uint32_t Synchronisable::getData(uint8_t*& mem, std::vector<uint32_t>& sizes, int32_t id, uint8_t mode){ 242 unsigned int test = 0; 248 243 if(mode==0x0) 249 244 mode=state_; … … 253 248 uint32_t tempsize = 0; 254 249 #ifndef NDEBUG 250 uint8_t* oldmem = mem; 255 251 if (this->classID_==0) 256 252 COUT(3) << "classid 0 " << this->getIdentifier()->getName() << std::endl; … … 270 266 // end copy header 271 267 272 273 COUT(5) << "Synchronisable getting data from objectID_: " << objectID_ << " classID_: " << classID_ << std::endl;268 CCOUT(5) << "getting data from objectID_: " << objectID_ << ", classID_: " << classID_ << std::endl; 269 // COUT(4) << "objectid: " << this->objectID_ << ":"; 274 270 // copy to location 275 for(i=syncList.begin(); i!=syncList.end(); ++i){ 276 tempsize += (*i)->getData( mem, mode ); 271 for(i=syncList_.begin(); i!=syncList_.end(); ++i){ 272 uint32_t varsize = (*i)->getData( mem, mode ); 273 // COUT(4) << " " << varsize; 274 tempsize += varsize; 275 sizes.push_back(varsize); 276 ++test; 277 277 //tempsize += (*i)->getSize( mode ); 278 278 } 279 280 tempsize += SynchronisableHeader::getSize(); 279 // COUT(4) << endl; 280 281 281 header.setObjectID( this->objectID_ ); 282 282 header.setCreatorID( this->creatorID_ ); 283 283 header.setClassID( this->classID_ ); 284 header.setDataAvailable( true );285 284 header.setDataSize( tempsize ); 285 assert( tempsize == mem-oldmem-SynchronisableHeader::getSize() ); 286 assert( test == this->getNrOfVariables() ); 287 header.setDiffed(false); 288 tempsize += SynchronisableHeader::getSize(); 286 289 287 290 #ifndef NDEBUG … … 303 306 if(mode==0x0) 304 307 mode=state_; 305 std::vector<SynchronisableVariableBase *>::iterator i; 306 if(syncList.empty()){ 308 if(syncList_.empty()){ 307 309 assert(0); 308 COUT(4) << "Synchronisable::updateData syncList is empty" << std::endl;310 COUT(4) << "Synchronisable::updateData syncList_ is empty" << std::endl; 309 311 return false; 310 312 } … … 316 318 assert(syncHeader.getCreatorID()==this->creatorID_); 317 319 assert(syncHeader.getClassID()==this->classID_); 318 if(syncHeader.isDataAvailable()==false){319 mem += syncHeader.getDataSize();320 return true;321 }322 320 323 321 mem += SynchronisableHeader::getSize(); … … 325 323 326 324 //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()); 325 if( !syncHeader.isDiffed() ) 326 { 327 std::vector<SynchronisableVariableBase *>::iterator i; 328 for(i=syncList_.begin(); i!=syncList_.end(); i++) 329 { 330 assert( mem <= data+syncHeader.getDataSize()+SynchronisableHeader::getSize() ); // always make sure we don't exceed the datasize in our stream 331 (*i)->putData( mem, mode, forceCallback ); 332 } 333 } 334 else 335 { 336 COUT(0) << "objectID: " << this->objectID_ << endl; 337 while( mem < data+syncHeader.getDataSize()+SynchronisableHeader::getSize() ) 338 { 339 uint32_t varID = *(uint32_t*)mem; 340 COUT(0) << "varID: " << varID << endl; 341 if( varID == 22 ) 342 COUT(6) << " blub " << endl; 343 assert( varID < syncList_.size() ); 344 mem += sizeof(uint32_t); 345 syncList_[varID]->putData( mem, mode, forceCallback ); 346 } 347 } 348 assert(mem == data+syncHeader.getDataSize()+SynchronisableHeader::getSize() ); 333 349 return true; 334 350 } … … 341 357 */ 342 358 uint32_t Synchronisable::getSize(int32_t id, uint8_t mode){ 343 int tsize=SynchronisableHeader::getSize();359 uint32_t tsize=SynchronisableHeader::getSize(); 344 360 if (mode==0x0) 345 361 mode=state_; … … 349 365 tsize += this->dataSize_; 350 366 std::vector<SynchronisableVariableBase*>::iterator i; 351 for(i=stringList .begin(); i!=stringList.end(); ++i){367 for(i=stringList_.begin(); i!=stringList_.end(); ++i){ 352 368 tsize += (*i)->getSize( mode ); 353 369 } … … 363 379 if(mode==0x0) 364 380 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(); 381 return ( (this->objectMode_ & mode)!=0 && (!syncList_.empty() ) ); 377 382 } 378 383 … … 397 402 else 398 403 sv = new SynchronisableVariable<std::string>(variable, mode, cb); 399 syncList .push_back(sv);400 stringList .push_back(sv);404 syncList_.push_back(sv); 405 stringList_.push_back(sv); 401 406 } 402 407 -
code/branches/network2/src/libraries/network/synchronisable/Synchronisable.h
r6417 r6449 71 71 * in an emulated bitset. 72 72 * 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 073 * Bit 32 is a bool and defines whether the variables are stored in diff mode 74 74 * Byte 5 to 8: objectID_ 75 75 * Byte 9 to 12: classID_ … … 88 88 inline void setDataSize(uint32_t size) 89 89 { *(uint32_t*)(data_) = (size & 0x7FFFFFFF) | (*(uint32_t*)(data_) & 0x80000000 ); } 90 inline bool isD ataAvailable() const90 inline bool isDiffed() const 91 91 { return ( (*(uint32_t*)data_) & 0x80000000 ) == 0x80000000; } 92 inline void setD ataAvailable( bool b)92 inline void setDiffed( bool b) 93 93 { *(uint32_t*)(data_) = (b << 31) | (*(uint32_t*)(data_) & 0x7FFFFFFF ); } 94 94 inline uint32_t getObjectID() const … … 108 108 }; 109 109 110 /** 111 * @brief: stores information about a Synchronisable (light version) 112 * 113 * This class stores the information about a Synchronisable (objectID_, dataSize) 114 * in an emulated bitset. 115 * Bit 1 to 31 store the size of the Data the synchronisable consumes in the stream 116 * Bit 32 is a bool and defines whether the variables are stored in diff mode 117 * Byte 5 to 8: objectID_ 118 */ 119 class _NetworkExport SynchronisableHeaderLight{ 120 private: 121 uint8_t *data_; 122 public: 123 SynchronisableHeader(uint8_t* data) 124 { data_ = data; } 125 inline static uint32_t getSize() 126 { return 16; } 127 inline uint32_t getDataSize() const 128 { return (*(uint32_t*)data_) & 0x7FFFFFFF; } //only use the first 31 bits 129 inline void setDataSize(uint32_t size) 130 { *(uint32_t*)(data_) = (size & 0x7FFFFFFF) | (*(uint32_t*)(data_) & 0x80000000 ); } 131 inline bool isDiffed() const 132 { return ( (*(uint32_t*)data_) & 0x80000000 ) == 0x80000000; } 133 inline void setDiffed( bool b) 134 { *(uint32_t*)(data_) = (b << 31) | (*(uint32_t*)(data_) & 0x7FFFFFFF ); } 135 inline uint32_t getObjectID() const 136 { return *(uint32_t*)(data_+4); } 137 inline void setObjectID(uint32_t objectID_) 138 { *(uint32_t*)(data_+4) = objectID_; } 139 inline void operator=(SynchronisableHeader& h) 140 { memcpy(data_, h.data_, getSize()); } 141 }; 110 142 111 143 /** … … 121 153 static void setClient(bool b); 122 154 123 static Synchronisable *fabricate(uint8_t*& mem, uint8_t mode=0x0);155 static Synchronisable *fabricate(uint8_t*& mem, bool diffed, uint8_t mode=0x0); 124 156 static bool deleteObject(uint32_t objectID_); 125 157 static Synchronisable *getSynchronisable(uint32_t objectID_); … … 134 166 135 167 void setSyncMode(uint8_t mode); 168 169 inline uint32_t getNrOfVariables(){ return this->syncList_.size(); } 170 inline uint32_t getVarSize( uint32_t ID ) 171 { return this->syncList_[ID]->getSize(state_); } 136 172 137 173 protected: … … 143 179 144 180 private: 145 uint32_t getData(uint8_t*& me n, int32_t id, uint8_t mode=0x0);181 uint32_t getData(uint8_t*& mem, std::vector<uint32_t>& sizes, int32_t id, uint8_t mode); 146 182 uint32_t getSize(int32_t id, uint8_t mode=0x0); 147 183 bool updateData(uint8_t*& mem, uint8_t mode=0x0, bool forceCallback=false); 148 bool isMyData(uint8_t* mem);149 184 bool doSync(int32_t id, uint8_t mode=0x0); 150 185 … … 156 191 uint32_t classID_; 157 192 158 std::vector<SynchronisableVariableBase*> syncList ;159 std::vector<SynchronisableVariableBase*> stringList ;193 std::vector<SynchronisableVariableBase*> syncList_; 194 std::vector<SynchronisableVariableBase*> stringList_; 160 195 uint32_t dataSize_; //size of all variables except strings 161 196 static uint8_t state_; // detemines wheter we are server (default) or client … … 171 206 if (bidirectional) 172 207 { 173 syncList .push_back(new SynchronisableVariableBidirectional<T>(variable, mode, cb));174 this->dataSize_ += syncList .back()->getSize(state_);208 syncList_.push_back(new SynchronisableVariableBidirectional<T>(variable, mode, cb)); 209 this->dataSize_ += syncList_.back()->getSize(state_); 175 210 } 176 211 else 177 212 { 178 syncList .push_back(new SynchronisableVariable<T>(variable, mode, cb));213 syncList_.push_back(new SynchronisableVariable<T>(variable, mode, cb)); 179 214 if ( this->state_ == mode ) 180 this->dataSize_ += syncList .back()->getSize(state_);215 this->dataSize_ += syncList_.back()->getSize(state_); 181 216 } 182 217 }
Note: See TracChangeset
for help on using the changeset viewer.