Changeset 2132 for code/branches/objecthierarchy/src/network
- Timestamp:
- Nov 4, 2008, 5:12:31 PM (16 years ago)
- Location:
- code/branches/objecthierarchy/src/network
- Files:
-
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
code/branches/objecthierarchy/src/network/Synchronisable.cc
r2112 r2132 50 50 // #include "core/Identifier.h" 51 51 52 #include "Host.h" 52 53 namespace orxonox 53 54 { … … 57 58 std::queue<unsigned int> Synchronisable::deletedObjects_; 58 59 59 int Synchronisable::state_=0x1; // detemines wheter we are server (default) or client60 uint8_t Synchronisable::state_=0x1; // detemines wheter we are server (default) or client 60 61 61 62 /** … … 99 100 for(std::list<synchronisableVariable *>::iterator it = syncList->begin(); it!=syncList->end(); it++) 100 101 delete (*it)->callback; 101 if (this->objectMode_ != 0x0 )102 if (this->objectMode_ != 0x0 && (Host::running() && Host::isServer())) 102 103 deletedObjects_.push(objectID); 103 104 // COUT(3) << "destruct synchronisable +++" << objectID << " | " << classID << std::endl; … … 143 144 * @return pointer to the newly created synchronisable 144 145 */ 145 Synchronisable *Synchronisable::fabricate(uint8_t*& mem, int mode)146 Synchronisable *Synchronisable::fabricate(uint8_t*& mem, uint8_t mode) 146 147 { 147 148 synchronisableHeader *header = (synchronisableHeader *)mem; … … 238 239 * @param cb callback object that should get called, if the value of the variable changes 239 240 */ 240 void Synchronisable::registerVar(void *var, int size, variableType t, int mode, NetworkCallbackBase *cb){241 void Synchronisable::registerVar(void *var, int size, variableType t, uint8_t mode, NetworkCallbackBase *cb){ 241 242 assert( mode==direction::toclient || mode==direction::toserver || mode==direction::serverMaster || mode==direction::clientMaster); 242 243 // create temporary synch.Var struct … … 249 250 if( ( mode & direction::bidirectional ) ) 250 251 { 251 temp->varBuffer = new uint8_t[size]; 252 memcpy(temp->varBuffer, temp->var, size); //now fill the buffer for the first time 252 if(t!=STRING) 253 { 254 temp->varBuffer = new uint8_t[size]; 255 memcpy(temp->varBuffer, temp->var, size); //now fill the buffer for the first time 256 } 257 else 258 { 259 temp->varBuffer=new std::string( *static_cast<std::string*>(var) ); 260 } 253 261 temp->varReference = 0; 254 262 } … … 280 288 * @return true: if !doSync or if everything was successfully saved 281 289 */ 282 bool Synchronisable::getData(uint8_t*& mem, unsigned int id, int mode){ 290 bool Synchronisable::getData(uint8_t*& mem, unsigned int id, uint8_t mode){ 291 if(mode==0x0) 292 mode=state_; 283 293 //if this tick is we dont synchronise, then abort now 284 if(!doSync(id ))294 if(!doSync(id, mode)) 285 295 return true; 286 296 //std::cout << "inside getData" << std::endl; 287 297 unsigned int tempsize = 0; 288 if(mode==0x0)289 mode=state_;290 298 if(classID==0) 291 299 COUT(3) << "classid 0 " << this->getIdentifier()->getName() << std::endl; … … 307 315 header->classID = this->classID; 308 316 header->dataAvailable = true; 309 tempsize +=sizeof(synchronisableHeader);310 mem +=sizeof(synchronisableHeader);317 tempsize += sizeof(synchronisableHeader); 318 mem += sizeof(synchronisableHeader); 311 319 // end copy header 312 320 … … 319 327 continue; // this variable should only be received 320 328 } 329 330 // =========== start bidirectional stuff ============= 321 331 // if the variable gets synchronised bidirectional, then add the reference to the bytestream 322 332 if( ( (*i)->mode & direction::bidirectional ) == direction::bidirectional ) 323 333 { 334 if( ( ((*i)->mode == direction::serverMaster) && (mode == 0x1) ) || \ 335 ( ((*i)->mode == direction::clientMaster) && (mode == 0x2) ) ) 336 { 337 // MASTER 338 if((*i)->type==DATA){ 339 if( memcmp((*i)->var,(*i)->varBuffer,(*i)->size) != 0 ) //check whether the variable changed during the last tick 340 { 341 ((*i)->varReference)++; //the variable changed so increase the refnr 342 memcpy((*i)->varBuffer, (*i)->var, (*i)->size); //set the buffer to the new value 343 } 344 } 345 else //STRING 346 { 347 if( *static_cast<std::string*>((*i)->var) != *static_cast<std::string*>((*i)->varBuffer) ) //the string changed 348 { 349 ((*i)->varReference)++; //the variable changed 350 *static_cast<std::string*>((*i)->varBuffer) = *static_cast<std::string*>((*i)->var); //now set the buffer to the new value 351 } 352 } 353 } 354 // copy the reference number to the stream 324 355 *(uint8_t*)mem = (*i)->varReference; 325 356 mem += sizeof( (*i)->varReference ); 326 357 tempsize += sizeof( (*i)->varReference ); 327 358 } 359 // ================== end bidirectional stuff 360 328 361 switch((*i)->type){ 329 362 case DATA: 330 363 memcpy( (void *)(mem), (void*)((*i)->var), (*i)->size); 331 mem +=(*i)->size;332 tempsize +=(*i)->size;364 mem += (*i)->size; 365 tempsize += (*i)->size; 333 366 break; 334 367 case STRING: 335 368 memcpy( (void *)(mem), (void *)&((*i)->size), sizeof(size_t) ); 336 mem +=sizeof(size_t);369 mem += sizeof(size_t); 337 370 const char *data = ( ( *(std::string *) (*i)->var).c_str()); 338 371 memcpy( mem, (void*)data, (*i)->size); 339 372 COUT(5) << "synchronisable: char: " << (const char *)(mem) << " data: " << data << " string: " << *(std::string *)((*i)->var) << std::endl; 340 mem +=(*i)->size;341 tempsize +=(*i)->size + sizeof(size_t);373 mem += (*i)->size; 374 tempsize += (*i)->size + sizeof(size_t); 342 375 break; 343 376 } … … 354 387 * @return true/false 355 388 */ 356 bool Synchronisable::updateData(uint8_t*& mem, int mode, bool forceCallback){389 bool Synchronisable::updateData(uint8_t*& mem, uint8_t mode, bool forceCallback){ 357 390 if(mode==0x0) 358 391 mode=state_; 359 392 std::list<synchronisableVariable *>::iterator i; 393 //assert(objectMode_!=0x0); 394 //assert( (mode ^ objectMode_) != 0); 360 395 if(syncList->empty()){ 361 396 COUT(4) << "Synchronisable::updateData syncList is empty" << std::endl; … … 367 402 synchronisableHeader *syncHeader = (synchronisableHeader *)mem; 368 403 assert(syncHeader->objectID==this->objectID); 369 // assert(syncHeader->creatorID==this->creatorID); 404 assert(syncHeader->creatorID==this->creatorID); 405 assert(this->classID==syncHeader->classID); //TODO: fix this!!! maybe a problem with the identifier ? 370 406 if(syncHeader->dataAvailable==false){ 371 mem +=syncHeader->size;407 mem += syncHeader->size; 372 408 return true; 373 409 } 374 410 375 mem +=sizeof(synchronisableHeader);411 mem += sizeof(synchronisableHeader); 376 412 // stop extract header 377 assert(this->objectID==syncHeader->objectID);378 // assert(this->classID==syncHeader->classID); //TODO: fix this!!! maybe a problem with the identifier ?379 413 380 414 COUT(5) << "Synchronisable: objectID " << syncHeader->objectID << ", classID " << syncHeader->classID << " size: " << syncHeader->size << " synchronising data" << std::endl; … … 382 416 if( ((*i)->mode ^ mode) == 0 ){ 383 417 COUT(5) << "synchronisable: not updating variable " << std::endl; 418 // if we have a forcecallback then do the callback 384 419 continue; // this variable should only be set 385 420 } 386 421 COUT(5) << "Synchronisable: element size: " << (*i)->size << " type: " << (*i)->type << std::endl; 387 422 bool callback=false; 423 bool master=false; 424 425 if( ( (*i)->mode & direction::bidirectional ) == direction::bidirectional ) 426 { 427 uint8_t refNr = *(uint8_t *)mem; 428 if( ( ((*i)->mode == direction::serverMaster) && (mode == 0x1) ) || \ 429 ( ((*i)->mode == direction::clientMaster) && (mode == 0x2) ) ) 430 { // MASTER 431 master=true; 432 if( refNr != (*i)->varReference || ( memcmp((*i)->var, (*i)->varBuffer, (*i)->size) != 0 ) ) 433 { // DISCARD data 434 if( (*i)->type == DATA ) 435 { 436 mem += sizeof((*i)->varReference) + (*i)->size; 437 } 438 else //STRING 439 { 440 mem += sizeof(size_t) + *(size_t *)mem; 441 } 442 if( forceCallback && (*i)->callback) 443 (*i)->callback->call(); 444 continue; 445 }//otherwise everything is ok and we update the value 446 } 447 else // SLAVE 448 { 449 if( (*i)->varReference == refNr ){ 450 //discard data because it's outdated or not different to what we've got 451 if( (*i)->type == DATA ) 452 { 453 mem += sizeof((*i)->varReference) + (*i)->size; 454 } 455 else //STRING 456 { 457 mem += sizeof(size_t) + *(size_t *)mem; 458 } 459 if( forceCallback && (*i)->callback) 460 (*i)->callback->call(); 461 continue; 462 } 463 else 464 (*i)->varReference = refNr; //copy the reference value for this variable 465 } 466 mem += sizeof((*i)->varReference); 467 } 468 388 469 switch((*i)->type){ 389 470 case DATA: 390 if( ( (*i)->mode & direction::bidirectional ) == direction::bidirectional)471 if((*i)->callback) // check whether this variable changed (but only if callback was set) 391 472 { 392 if( ( mode == 0x1 && (*i)->mode == direction::serverMaster ) || \ 393 ( mode == 0x2 && (*i)->mode == direction::clientMaster ) ) // if true we are master on this variable 394 { 395 uint8_t refNr = *(uint8_t *)mem; 396 if( refNr != (*i)->varReference ) 397 { 398 mem += sizeof((*i)->varReference) + (*i)->size; // the reference for this variable is not recent, discard data 399 break; 400 } 401 } 402 else //we are slave for this variable 403 { 404 (*i)->varReference = *(uint8_t *)mem; //copy the reference value for this variable 405 } 406 mem += sizeof((*i)->varReference); 473 if(memcmp((*i)->var, mem, (*i)->size) != 0) 474 callback=true; 407 475 } 408 if((*i)->callback) // check whether this variable changed (but only if callback was set) 409 if(strncmp((char *)(*i)->var, (char *)mem, (*i)->size)!=0) 410 callback=true; 411 memcpy((void*)(*i)->var, mem, (*i)->size); 412 mem+=(*i)->size; 476 if( master ) 477 { 478 if( callback || memcmp((*i)->var, mem, (*i)->size) != 0 ) 479 //value changed, so set the buffer to the new value 480 memcpy((*i)->varBuffer, mem, (*i)->size); 481 } 482 memcpy((*i)->var, mem, (*i)->size); 483 mem += (*i)->size; 413 484 break; 414 485 case STRING: 415 if( ( (*i)->mode & direction::bidirectional ) == direction::bidirectional ) 486 (*i)->size = *(size_t *)mem; 487 mem += sizeof(size_t); 488 489 if( (*i)->callback) // check whether this string changed 490 if( *static_cast<std::string*>((*i)->var) != std::string((char *)mem) ) 491 callback=true; 492 if( master ) 416 493 { 417 if( ( mode == 0x1 && (*i)->mode == direction::serverMaster ) || \ 418 ( mode == 0x2 && (*i)->mode == direction::clientMaster ) ) // if true we are master for this variable 419 { 420 uint8_t refNr = *(uint8_t *)mem; 421 mem += sizeof( (*i)->varReference ); 422 if( refNr != (*i)->varReference ){ 423 mem += sizeof(size_t) + *(size_t *)mem; // the reference for this variable is not recent, discard data 424 break; 425 } 426 } 427 else //we are slave for this variable 428 { 429 (*i)->varReference = *(uint8_t *)mem; //copy the reference value for this variable 430 } 431 mem += sizeof( (*i)->varReference ); 494 if( callback || *static_cast<std::string*>((*i)->var) != std::string((char *)mem) ) 495 //string changed. set the buffer to the new one 496 *static_cast<std::string*>((*i)->varBuffer)=*static_cast<std::string*>( (void*)(mem+sizeof(size_t)) ); 432 497 } 433 (*i)->size = *(size_t *)mem; 434 COUT(5) << "string size: " << (*i)->size << std::endl; 435 mem += sizeof(size_t); 436 if((*i)->callback) // check whether this string changed 437 if( *(std::string *)((*i)->var) != std::string((char *)mem) ) 438 callback=true; 498 439 499 *((std::string *)((*i)->var)) = std::string((const char*)mem); 440 500 COUT(5) << "synchronisable: char: " << (const char*)mem << " string: " << std::string((const char*)mem) << std::endl; … … 446 506 (*i)->callback->call(); 447 507 } 508 assert(mem == data+syncHeader->size); 448 509 return true; 449 510 } … … 455 516 * @return amount of bytes 456 517 */ 457 uint32_t Synchronisable::getSize(unsigned int id, int mode){ 458 if(!doSync(id)) 459 return 0; 518 uint32_t Synchronisable::getSize(unsigned int id, uint8_t mode){ 460 519 int tsize=sizeof(synchronisableHeader); 461 520 if(mode==0x0) 462 521 mode=state_; 522 if(!doSync(id, mode)) 523 return 0; 463 524 std::list<synchronisableVariable *>::iterator i; 464 525 for(i=syncList->begin(); i!=syncList->end(); i++){ … … 489 550 * @return true/false 490 551 */ 491 bool Synchronisable::doSync(unsigned int id){ 492 return ( (objectMode_&state_)!=0 && (!syncList->empty() ) ); 552 bool Synchronisable::doSync(unsigned int id, uint8_t mode){ 553 if(mode==0x0) 554 mode=state_; 555 return ( (objectMode_&mode)!=0 && (!syncList->empty() ) ); 493 556 } 494 557 495 558 bool Synchronisable::doSelection(unsigned int id){ 496 return ( id==0 || id%objectFrequency_==objectID%objectFrequency_ ) && ((objectMode_&state_)!=0); 559 return true; //TODO: change this 560 //return ( id==0 || id%objectFrequency_==objectID%objectFrequency_ ) && ((objectMode_&state_)!=0); 497 561 } 498 562 … … 510 574 /** 511 575 * This function sets the synchronisation mode of the object 576 * If set to 0x0 variables will not be synchronised at all 512 577 * If set to 0x1 variables will only be synchronised to the client 513 578 * If set to 0x2 variables will only be synchronised to the server … … 515 580 * @param mode same as in registerVar 516 581 */ 517 void Synchronisable::setObjectMode( int mode){582 void Synchronisable::setObjectMode(uint8_t mode){ 518 583 assert(mode==0x0 || mode==0x1 || mode==0x2 || mode==0x3); 519 584 objectMode_=mode; -
code/branches/objecthierarchy/src/network/Synchronisable.h
r2112 r2132 62 62 namespace syncmode{ 63 63 enum mode{ 64 on e=0,64 once=0, 65 65 always=1 66 66 }; … … 81 81 82 82 struct _NetworkExport synchronisableVariable{ 83 unsigned int size;84 int mode; // this determines in which direction the variable gets synchronised83 size_t size; 84 uint8_t mode; // this determines in which direction the variable gets synchronised 85 85 void *var; 86 86 variableType type; … … 98 98 public: 99 99 friend class packet::Gamestate; 100 friend class GamestateClient; 101 friend class Server; 100 // friend class Server; 102 101 virtual ~Synchronisable(); 103 102 … … 106 105 static void setClient(bool b); 107 106 108 static Synchronisable *fabricate(uint8_t*& mem, int mode=0x0);107 static Synchronisable *fabricate(uint8_t*& mem, uint8_t mode=0x0); 109 108 static bool deleteObject(unsigned int objectID); 110 109 static Synchronisable *getSynchronisable(unsigned int objectID); … … 116 115 protected: 117 116 Synchronisable(BaseObject* creator); 118 void registerVar(void *var, int size, variableType t, int mode=1, NetworkCallbackBase *cb=0);119 void setObjectMode( int mode);117 void registerVar(void *var, int size, variableType t, uint8_t mode=0x1, NetworkCallbackBase *cb=0); 118 void setObjectMode(uint8_t mode); 120 119 void setObjectFrequency(unsigned int freq){ objectFrequency_ = freq; } 121 120 122 121 123 122 private: 124 bool getData(uint8_t*& men, unsigned int id, int mode=0x0);125 uint32_t getSize(unsigned int id, int mode=0x0);126 bool updateData(uint8_t*& mem, int mode=0x0, bool forceCallback=false);123 bool getData(uint8_t*& men, unsigned int id, uint8_t mode=0x0); 124 uint32_t getSize(unsigned int id, uint8_t mode=0x0); 125 bool updateData(uint8_t*& mem, uint8_t mode=0x0, bool forceCallback=false); 127 126 bool isMyData(uint8_t* mem); 128 127 bool doSelection(unsigned int id); 129 bool doSync(unsigned int id );128 bool doSync(unsigned int id, uint8_t mode=0x0); 130 129 131 130 unsigned int objectID; … … 134 133 135 134 std::list<synchronisableVariable *> *syncList; 136 static int state_; // detemines wheter we are server (default) or client135 static uint8_t state_; // detemines wheter we are server (default) or client 137 136 bool backsync_; // if true the variables with mode > 1 will be synchronised to server (client -> server) 138 137 unsigned int objectFrequency_; -
code/branches/objecthierarchy/src/network/packet/Gamestate.cc
r2112 r2132 71 71 } 72 72 73 bool Gamestate::collectData(int id, int mode)74 { 75 int tempsize=0, currentsize=0;73 bool Gamestate::collectData(int id, uint8_t mode) 74 { 75 unsigned int tempsize=0, currentsize=0; 76 76 assert(data_==0); 77 int size = calcGamestateSize(id, mode);77 unsigned int size = calcGamestateSize(id, mode); 78 78 79 79 COUT(4) << "G.ST.Man: producing gamestate with id: " << id << std::endl; … … 86 86 } 87 87 88 #ifndef NDEBUG89 std::list<Synchronisable*> slist;90 std::list<Synchronisable*>::iterator iit;91 #endif92 88 //start collect data synchronisable by synchronisable 93 89 uint8_t *mem=data_; … … 98 94 99 95 if(currentsize+tempsize > size){ 96 assert(0); // if we don't use multithreading this part shouldn't be neccessary 100 97 // start allocate additional memory 101 98 COUT(3) << "G.St.Man: need additional memory" << std::endl; … … 110 107 }// stop allocate additional memory 111 108 112 #ifndef NDEBUG113 for(iit=slist.begin(); iit!=slist.end(); iit++)114 assert((*iit)!=*it);115 slist.push_back(*it);116 #endif117 109 118 110 //if(it->doSelection(id)) … … 127 119 //start write gamestate header 128 120 HEADER->packetType = ENUM::Gamestate; 129 assert( *(ENUM::Type *)(data_) == ENUM::Gamestate);130 121 HEADER->datasize = currentsize; 131 122 HEADER->id = id; … … 140 131 } 141 132 142 bool Gamestate::spreadData( int mode)133 bool Gamestate::spreadData(uint8_t mode) 143 134 { 144 135 assert(data_); … … 163 154 bool b = s->updateData(mem, mode); 164 155 assert(b); 165 //if(!s->updateData(mem, mode))166 //return false;167 156 } 168 157 } … … 367 356 assert(it->second->objectID==oldobjectheader->objectID); 368 357 *newobjectheader = *oldobjectheader; 369 objectOffset=sizeof( uint8_t)+sizeof(bool); //skip the size and the availableData variables in the objectheader358 objectOffset=sizeof(synchronisableHeader); //skip the size and the availableData variables in the objectheader 370 359 if(it->second->doSelection(HEADER->id)){ 371 360 newobjectheader->dataAvailable=true; //TODO: probably not neccessary … … 565 554 566 555 567 unsigned int Gamestate::calcGamestateSize(unsigned int id, int mode)568 { 569 int size=0;556 unsigned int Gamestate::calcGamestateSize(unsigned int id, uint8_t mode) 557 { 558 unsigned int size=0; 570 559 // get the start of the Synchronisable list 571 560 ObjectList<Synchronisable>::iterator it; -
code/branches/objecthierarchy/src/network/packet/Gamestate.h
r2112 r2132 69 69 ~Gamestate(); 70 70 71 bool collectData(int id, int mode=0x0);72 bool spreadData( int mode=0x0);71 bool collectData(int id, uint8_t mode=0x0); 72 bool spreadData( uint8_t mode=0x0); 73 73 int getID(); 74 74 bool isDiffed(); … … 90 90 bool operator ==(packet::Gamestate gs); 91 91 private: 92 unsigned int calcGamestateSize(unsigned int id, int mode=0x0);92 unsigned int calcGamestateSize(unsigned int id, uint8_t mode=0x0); 93 93 void removeObject(ObjectListIterator<Synchronisable> &it); 94 94 std::map<unsigned int, Synchronisable*> dataMap_; -
code/branches/objecthierarchy/src/network/packet/Packet.cc
r2112 r2132 53 53 #define _PACKETID 0 54 54 55 std::map< ENetPacket *, Packet *> Packet::packetMap_;55 std::map<size_t, Packet *> Packet::packetMap_; 56 56 57 57 Packet::Packet(){ … … 134 134 // Add the packet to a global list so we can access it again once enet calls our 135 135 // deletePacket method. We can of course only give a one argument function to the ENet C library. 136 packetMap_[ enetPacket_] = this;136 packetMap_[(size_t)(void*)enetPacket_] = this; 137 137 } 138 138 #ifndef NDEBUG … … 208 208 void Packet::deletePacket(ENetPacket *enetPacket){ 209 209 // Get our Packet from a gloabal map with all Packets created in the send() method of Packet. 210 std::map< ENetPacket*, Packet*>::iterator it = packetMap_.find(enetPacket);210 std::map<size_t, Packet*>::iterator it = packetMap_.find((size_t)enetPacket); 211 211 assert(it != packetMap_.end()); 212 212 // Make sure we don't delete it again in the destructor -
code/branches/objecthierarchy/src/network/packet/Packet.h
r2112 r2132 92 92 bool bDataENetAllocated_; 93 93 private: 94 static std::map< ENetPacket *, Packet *> packetMap_;94 static std::map<size_t, Packet *> packetMap_; 95 95 ENetPacket *enetPacket_; 96 96 };
Note: See TracChangeset
for help on using the changeset viewer.