- Timestamp:
- Nov 22, 2008, 11:54:48 AM (15 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
code/branches/network64/src/network/synchronisable/Synchronisable.cc
r2211 r2245 40 40 41 41 #include "Synchronisable.h" 42 #include "SynchronisableSpecialisations.cc" // this defines all specialisations for registerVariable 42 43 43 44 #include <cstring> … … 78 79 objectID=OBJECTID_UNKNOWN; 79 80 classID = (unsigned int)-1; 80 syncList = new std::list<synchronisableVariable *>;81 81 82 82 … … 114 114 // delete callback function objects 115 115 if(!Identifier::isCreatingHierarchy()){ 116 for(std::list< synchronisableVariable *>::iterator it = syncList->begin(); it!=syncList->end(); it++)117 delete (*it) ->callback;116 for(std::list<SynchronisableVariableBase*>::iterator it = syncList.begin(); it!=syncList.end(); it++) 117 delete (*it); 118 118 if (this->objectMode_ != 0x0 && (Host::running() && Host::isServer())) 119 119 deletedObjects_.push(objectID); … … 127 127 if (it != objectMap_.end()) 128 128 objectMap_.erase(it); 129 }130 131 /**132 * This function gets called after all neccessary data has been passed to the object133 * Overload this function and recall the create function of the parent class134 * @return true/false135 */136 bool Synchronisable::create(){137 this->classID = this->getIdentifier()->getNetworkID();138 // COUT(4) << "creating synchronisable: setting classid from " << this->getIdentifier()->getName() << " to: " << classID << std::endl;139 140 // COUT(3) << "construct synchronisable +++" << objectID << " | " << classID << std::endl;141 // objectMap_[objectID]=this;142 // assert(objectMap_[objectID]==this);143 // assert(objectMap_[objectID]->objectID==objectID);144 return true;145 129 } 146 130 … … 204 188 if (b) 205 189 { 206 b = no->create();190 // b = no->create(); 207 191 assert(b); 208 192 } … … 261 245 * @param cb callback object that should get called, if the value of the variable changes 262 246 */ 263 void Synchronisable::registerVariable(void *var, int size, variableType t, uint8_t mode, NetworkCallbackBase *cb){ 247 248 /* void Synchronisable::registerVariable(void *var, int size, variableType t, uint8_t mode, NetworkCallbackBase *cb){ 264 249 assert( mode==direction::toclient || mode==direction::toserver || mode==direction::serverMaster || mode==direction::clientMaster); 265 250 // create temporary synch.Var struct … … 294 279 } 295 280 #endif 296 } 297 298 void Synchronisable::unregisterVariable(void *var){ 299 std::list<synchronisableVariable *>::iterator it = syncList->begin(); 300 while(it!=syncList->end()){ 301 if( (*it)->var == var ){ 302 delete *it; 303 syncList->erase(it); 304 return; 305 } 306 else 307 it++; 308 } 309 bool unregistered_nonexistent_variable = false; 310 assert(unregistered_nonexistent_variable); //if we reach this point something went wrong: 311 // the variable has not been registered before 312 } 313 281 }*/ 282 314 283 315 284 /** … … 343 312 assert(this->classID==this->getIdentifier()->getNetworkID()); 344 313 // this->classID=this->getIdentifier()->getNetworkID(); // TODO: correct this 345 std::list< synchronisableVariable*>::iterator i;314 std::list<SynchronisableVariableBase*>::iterator i; 346 315 unsigned int size; 347 316 size=getSize(id, mode); … … 361 330 COUT(5) << "Synchronisable getting data from objectID: " << objectID << " classID: " << classID << " length: " << size << std::endl; 362 331 // copy to location 363 for(i=syncList->begin(); i!=syncList->end(); ++i){ 364 if( ((*i)->mode & mode) == 0 ){ 365 COUT(5) << "not getting data: " << std::endl; 366 continue; // this variable should only be received 367 } 368 369 // =========== start bidirectional stuff ============= 370 // if the variable gets synchronised bidirectional, then add the reference to the bytestream 371 if( ( (*i)->mode & direction::bidirectional ) == direction::bidirectional ) 372 { 373 if( ( ((*i)->mode == direction::serverMaster) && (mode == 0x1) ) || \ 374 ( ((*i)->mode == direction::clientMaster) && (mode == 0x2) ) ) 375 { 376 // MASTER 377 if((*i)->type==DATA){ 378 if( memcmp((*i)->var,(*i)->varBuffer,(*i)->size) != 0 ) //check whether the variable changed during the last tick 379 { 380 ((*i)->varReference)++; //the variable changed so increase the refnr 381 memcpy((*i)->varBuffer, (*i)->var, (*i)->size); //set the buffer to the new value 382 } 383 } 384 else //STRING 385 { 386 if( *static_cast<std::string*>((*i)->var) != *static_cast<std::string*>((*i)->varBuffer) ) //the string changed 387 { 388 ((*i)->varReference)++; //the variable changed 389 *static_cast<std::string*>((*i)->varBuffer) = *static_cast<std::string*>((*i)->var); //now set the buffer to the new value 390 } 391 } 392 } 393 // copy the reference number to the stream 394 *(uint8_t*)mem = (*i)->varReference; 395 mem += sizeof( (*i)->varReference ); 396 tempsize += sizeof( (*i)->varReference ); 397 } 398 // ================== end bidirectional stuff 399 400 switch((*i)->type){ 401 case DATA: 402 memcpy( (void *)(mem), (void*)((*i)->var), (*i)->size); 403 mem += (*i)->size; 404 tempsize += (*i)->size; 405 break; 406 case STRING: 407 memcpy( (void *)(mem), (void *)&((*i)->size), sizeof(size_t) ); 408 mem += sizeof(size_t); 409 const char *data = ( ( *(std::string *) (*i)->var).c_str()); 410 memcpy( mem, (void*)data, (*i)->size); 411 COUT(5) << "synchronisable: char: " << (const char *)(mem) << " data: " << data << " string: " << *(std::string *)((*i)->var) << std::endl; 412 mem += (*i)->size; 413 tempsize += (*i)->size + sizeof(size_t); 414 break; 415 } 332 for(i=syncList.begin(); i!=syncList.end(); ++i){ 333 (*i)->getData( mem, mode ); 334 tempsize += (*i)->getSize( mode ); 416 335 } 417 336 assert(tempsize==size); … … 429 348 if(mode==0x0) 430 349 mode=state_; 431 std::list< synchronisableVariable *>::iterator i;350 std::list<SynchronisableVariableBase *>::iterator i; 432 351 //assert(objectMode_!=0x0); 433 352 //assert( (mode ^ objectMode_) != 0); 434 if(syncList ->empty()){353 if(syncList.empty()){ 435 354 COUT(4) << "Synchronisable::updateData syncList is empty" << std::endl; 436 355 return false; 437 356 } 438 357 439 uint8_t *data=mem;358 uint8_t* data=mem; 440 359 // start extract header 441 360 synchronisableHeader *syncHeader = (synchronisableHeader *)mem; … … 452 371 453 372 COUT(5) << "Synchronisable: objectID " << syncHeader->objectID << ", classID " << syncHeader->classID << " size: " << syncHeader->size << " synchronising data" << std::endl; 454 for(i=syncList->begin(); i!=syncList->end() && mem <= data+syncHeader->size; i++){ 455 if( ((*i)->mode ^ mode) == 0 ){ 456 COUT(5) << "synchronisable: not updating variable " << std::endl; 457 // if we have a forcecallback then do the callback 458 continue; // this variable should only be set 459 } 460 COUT(5) << "Synchronisable: element size: " << (*i)->size << " type: " << (*i)->type << std::endl; 461 bool callback=false; 462 bool master=false; 463 464 if( ( (*i)->mode & direction::bidirectional ) == direction::bidirectional ) 465 { 466 uint8_t refNr = *(uint8_t *)mem; 467 if( ( ((*i)->mode == direction::serverMaster) && (mode == 0x1) ) || \ 468 ( ((*i)->mode == direction::clientMaster) && (mode == 0x2) ) ) 469 { // MASTER 470 master=true; 471 if( refNr != (*i)->varReference || ( memcmp((*i)->var, (*i)->varBuffer, (*i)->size) != 0 ) ) 472 { // DISCARD data 473 if( (*i)->type == DATA ) 474 { 475 mem += sizeof((*i)->varReference) + (*i)->size; 476 } 477 else //STRING 478 { 479 mem += sizeof(size_t) + *(size_t *)mem; 480 } 481 if( forceCallback && (*i)->callback) 482 (*i)->callback->call(); 483 continue; 484 }//otherwise everything is ok and we update the value 485 } 486 else // SLAVE 487 { 488 if( (*i)->varReference == refNr ){ 489 //discard data because it's outdated or not different to what we've got 490 if( (*i)->type == DATA ) 491 { 492 mem += sizeof((*i)->varReference) + (*i)->size; 493 } 494 else //STRING 495 { 496 mem += sizeof(size_t) + *(size_t *)mem; 497 } 498 if( forceCallback && (*i)->callback) 499 (*i)->callback->call(); 500 continue; 501 } 502 else 503 (*i)->varReference = refNr; //copy the reference value for this variable 504 } 505 mem += sizeof((*i)->varReference); 506 } 507 508 switch((*i)->type){ 509 case DATA: 510 if((*i)->callback) // check whether this variable changed (but only if callback was set) 511 { 512 if(memcmp((*i)->var, mem, (*i)->size) != 0) 513 callback=true; 514 } 515 if( master ) 516 { 517 if( callback || memcmp((*i)->var, mem, (*i)->size) != 0 ) 518 //value changed, so set the buffer to the new value 519 memcpy((*i)->varBuffer, mem, (*i)->size); 520 } 521 memcpy((*i)->var, mem, (*i)->size); 522 mem += (*i)->size; 523 break; 524 case STRING: 525 (*i)->size = *(size_t *)mem; 526 mem += sizeof(size_t); 527 528 if( (*i)->callback) // check whether this string changed 529 if( *static_cast<std::string*>((*i)->var) != std::string((char *)mem) ) 530 callback=true; 531 if( master ) 532 { 533 if( callback || *static_cast<std::string*>((*i)->var) != std::string((char *)mem) ) 534 //string changed. set the buffer to the new one 535 *static_cast<std::string*>((*i)->varBuffer)=*static_cast<std::string*>( (void*)(mem+sizeof(size_t)) ); 536 } 537 538 *((std::string *)((*i)->var)) = std::string((const char*)mem); 539 COUT(5) << "synchronisable: char: " << (const char*)mem << " string: " << std::string((const char*)mem) << std::endl; 540 mem += (*i)->size; 541 break; 542 } 543 // call the callback function, if defined 544 if((callback || forceCallback) && (*i)->callback) 545 (*i)->callback->call(); 373 for(i=syncList.begin(); i!=syncList.end() && mem <= data+syncHeader->size; i++) 374 { 375 (*i)->putData( mem, mode, forceCallback ); 546 376 } 547 377 assert(mem == data+syncHeader->size); … … 561 391 if(!doSync(id, mode)) 562 392 return 0; 563 std::list<synchronisableVariable *>::iterator i; 564 for(i=syncList->begin(); i!=syncList->end(); i++){ 565 if( ((*i)->mode & mode) == 0 ) 566 continue; // this variable should only be received, so dont add its size to the send-size 567 switch((*i)->type){ 568 case DATA: 569 tsize+=(*i)->size; 570 break; 571 case STRING: 572 tsize+=sizeof(int); 573 (*i)->size=((std::string *)(*i)->var)->length()+1; 574 COUT(5) << "String size: " << (*i)->size << std::endl; 575 tsize+=(*i)->size; 576 break; 577 } 578 if( ( (*i)->mode & direction::bidirectional ) == direction::bidirectional ) 579 { 580 tsize+=sizeof( (*i)->varReference ); 581 } 393 std::list<SynchronisableVariableBase*>::iterator i; 394 for(i=syncList.begin(); i!=syncList.end(); i++){ 395 tsize += (*i)->getSize( mode ); 582 396 } 583 397 return tsize; … … 592 406 if(mode==0x0) 593 407 mode=state_; 594 return ( (objectMode_&mode)!=0 && (!syncList ->empty() ) );408 return ( (objectMode_&mode)!=0 && (!syncList.empty() ) ); 595 409 } 596 410 … … 623 437 objectMode_=mode; 624 438 } 625 439 626 440 627 441 }
Note: See TracChangeset
for help on using the changeset viewer.