Changeset 2245 for code/branches/network64/src/network
- Timestamp:
- Nov 22, 2008, 11:54:48 AM (16 years ago)
- Location:
- code/branches/network64/src/network
- Files:
-
- 2 added
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
code/branches/network64/src/network/NetworkPrereqs.h
r2171 r2245 70 70 class GamestateManager; 71 71 class GamestateHandler; 72 class NetworkCallbackBase; 72 73 class PacketBuffer; 73 74 class Server; 74 75 class ServerFrameListener; 75 76 class Synchronisable; 77 class SynchronisableVariableBase; 78 template <class T> class SynchronisableVariable; 79 template <class T> class SynchronisableVariableBidirectional; 76 80 struct ClientList; 77 81 struct PacketEnvelope; 78 82 struct QueueItem; 79 83 struct syncData; 80 struct synchronisableVariable;81 84 namespace packet{ 82 85 class Gamestate; -
code/branches/network64/src/network/synchronisable/CMakeLists.txt
r2211 r2245 1 1 SET( SRC_FILES 2 2 Synchronisable.cc 3 SynchronisableVariable.cc 3 4 ) 4 5 -
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 } -
code/branches/network64/src/network/synchronisable/Synchronisable.h
r2211 r2245 35 35 #include <map> 36 36 #include <queue> 37 #include "util/Integers.h" 37 #include <cassert> 38 #include "util/Math.h" 39 #include "util/mbool.h" 38 40 #include "core/OrxonoxClass.h" 39 #include "core/XMLIncludes.h" 41 // TODO: this has to be removed 42 // #include <OgreLight.h> 43 // #include "OrxonoxPrereqs.h" 44 // ============================ 40 45 #include "NetworkCallback.h" 41 #include " util/Integers.h"46 #include "SynchronisableVariable.h" 42 47 43 #define REGISTERDATA(varname, ...) \48 /*#define REGISTERDATA(varname, ...) \ 44 49 registerVariable((void*)&varname, sizeof(varname), DATA, __VA_ARGS__) 45 50 #define REGISTERSTRING(stringname, ...) \ 46 registerVariable(&stringname, stringname.length()+1, STRING, __VA_ARGS__) 51 registerVariable(&stringname, stringname.length()+1, STRING, __VA_ARGS__)*/ 47 52 48 53 namespace orxonox … … 50 55 static const unsigned int OBJECTID_UNKNOWN = (unsigned int)-1; 51 56 52 namespace direction{53 enum syncdirection{57 namespace objectDirection{ 58 enum objectdirection{ 54 59 toclient=0x1, 55 60 toserver=0x2, 56 bidirectional=0x3, 57 serverMaster=0x3, 58 clientMaster=0x7 61 bidirectional=0x3 59 62 }; 60 63 } 61 62 namespace syncmode{63 enum mode{64 once=0,65 always=166 };67 }68 69 enum variableType{70 DATA,71 STRING,72 };73 64 74 65 struct _NetworkExport synchronisableHeader{ … … 80 71 }; 81 72 82 struct _NetworkExport synchronisableVariable{83 size_t size;84 uint8_t mode; // this determines in which direction the variable gets synchronised85 void *var;86 variableType type;87 NetworkCallbackBase *callback;88 void *varBuffer;89 uint8_t varReference;90 };91 73 92 74 /** … … 101 83 virtual ~Synchronisable(); 102 84 103 104 virtual bool create();105 85 static void setClient(bool b); 106 86 … … 115 95 protected: 116 96 Synchronisable(BaseObject* creator); 117 void registerVariable(void *var, int size, variableType t, uint8_t mode=0x1, NetworkCallbackBase *cb=0); 118 void unregisterVariable(void *var); 97 // void registerVariable(void *var, int size, variableType t, uint8_t mode=0x1, NetworkCallbackBase *cb=0); 98 template <class T> void registerVariable(T& variable, uint8_t mode=0x1, NetworkCallbackBase *cb=0, bool bidirectional=false); 99 template <class T> void unregisterVariable(T& var); 119 100 void setObjectMode(uint8_t mode); 120 101 void setObjectFrequency(unsigned int freq){ objectFrequency_ = freq; } … … 133 114 unsigned int classID; 134 115 135 std::list< synchronisableVariable *> *syncList;116 std::list<SynchronisableVariableBase*> syncList; 136 117 static uint8_t state_; // detemines wheter we are server (default) or client 137 118 bool backsync_; // if true the variables with mode > 1 will be synchronised to server (client -> server) … … 141 122 static std::queue<unsigned int> deletedObjects_; 142 123 }; 124 125 template <class T> void Synchronisable::registerVariable(T& variable, uint8_t mode, NetworkCallbackBase *cb, bool bidirectional) 126 { 127 if (bidirectional) 128 syncList.push_back(new SynchronisableVariableBidirectional<const T>(variable, mode, cb)); 129 else 130 syncList.push_back(new SynchronisableVariable<const T>(variable, mode, cb)); 131 } 132 133 template <class T> void Synchronisable::unregisterVariable(T& var){ 134 std::list<SynchronisableVariableBase*>::iterator it = syncList.begin(); 135 while(it!=syncList.end()){ 136 if( ((*it)->getReference()) == &var ){ 137 delete (*it); 138 syncList.erase(it); 139 return; 140 } 141 else 142 it++; 143 } 144 bool unregistered_nonexistent_variable = false; 145 assert(unregistered_nonexistent_variable); //if we reach this point something went wrong: 146 // the variable has not been registered before 147 } 148 149 // ================= Specialisation declarations 150 template <> void Synchronisable::registerVariable( const ColourValue& variable, uint8_t mode, NetworkCallbackBase* cb, bool bidirectional);template <> void Synchronisable::registerVariable( const ColourValue& variable, uint8_t mode, NetworkCallbackBase* cb, bool bidirectional); 151 template <> void Synchronisable::registerVariable( ColourValue& variable, uint8_t mode, NetworkCallbackBase* cb, bool bidirectional); 152 template <> void Synchronisable::registerVariable( const Vector2& variable, uint8_t mode, NetworkCallbackBase* cb, bool bidirectional); 153 template <> void Synchronisable::registerVariable( Vector2& variable, uint8_t mode, NetworkCallbackBase* cb, bool bidirectional); 154 template <> void Synchronisable::registerVariable( const Vector3& variable, uint8_t mode, NetworkCallbackBase* cb, bool bidirectional); 155 template <> void Synchronisable::registerVariable( Vector3& variable, uint8_t mode, NetworkCallbackBase* cb, bool bidirectional); 156 template <> void Synchronisable::registerVariable( const Vector4& variable, uint8_t mode, NetworkCallbackBase* cb, bool bidirectional); 157 template <> void Synchronisable::registerVariable( Vector4& variable, uint8_t mode, NetworkCallbackBase* cb, bool bidirectional); 158 template <> void Synchronisable::registerVariable( mbool& variable, uint8_t mode, NetworkCallbackBase* cb, bool bidirectional); 159 template <> void Synchronisable::registerVariable( const Quaternion& variable, uint8_t mode, NetworkCallbackBase* cb, bool bidirectional); 160 template <> void Synchronisable::registerVariable( Quaternion& variable, uint8_t mode, NetworkCallbackBase* cb, bool bidirectional); 161 // template <> void Synchronisable::registerVariable( LODParticle::LOD& variable, uint8_t mode, NetworkCallbackBase* cb, bool bidirectional); 162 // template <> void Synchronisable::registerVariable( Ogre::Light::LightTypes& variable, uint8_t mode, NetworkCallbackBase* cb, bool bidirectional); 143 163 } 144 164
Note: See TracChangeset
for help on using the changeset viewer.