#include <OSGRemoteAspect.h>
It is possible to send changes in both directions.
Definition at line 60 of file OSGRemoteAspect.h.
|
|
functor called for changed containers Definition at line 78 of file OSGRemoteAspect.h. |
|
|
Definition at line 81 of file OSGRemoteAspect.h. |
|
|
Map remote to local id Definition at line 84 of file OSGRemoteAspect.h. |
|
|
Map local to remote id Definition at line 86 of file OSGRemoteAspect.h. |
|
|
Map remote to local type Definition at line 88 of file OSGRemoteAspect.h. |
|
|
id set Definition at line 91 of file OSGRemoteAspect.h. |
|
|
Field filter map Definition at line 94 of file OSGRemoteAspect.h. |
|
|
Definition at line 95 of file OSGRemoteAspect.h. |
|
|
Definition at line 126 of file OSGRemoteAspect.h. |
|
|
Definition at line 127 of file OSGRemoteAspect.h. |
|
|
Message types Definition at line 65 of file OSGRemoteAspect.h. 00066 { 00067 SYNCENDED =1, 00068 CREATED =2, 00069 DESTROYED =3, 00070 NEWTYPE =4, 00071 CHANGED =5, 00072 ADDREFED =6, 00073 SUBREFED =7, 00074 IDMAPPING =8 00075 };
|
|
|
|
Destructor Definition at line 129 of file OSGRemoteAspect.cpp. References _receivedFC, callDestroyed(), osg::AttachmentContainerPtr::dcast(), osg::NodePtr::dcast(), osg::FieldContainerFactory::getContainer(), osg::NullFC, osg::subRefCP(), and osg::FieldContainerFactory::the(). 00130 { 00131 FieldContainerFactory *factory = FieldContainerFactory::the(); 00132 IdSetT::iterator i; 00133 FieldContainerPtr fcPtr; 00134 NodePtr node; 00135 WindowPtr window; 00136 00137 // subRef received field container 00138 for(i = _receivedFC.begin(); i != _receivedFC.end(); i++) 00139 { 00140 fcPtr = factory->getContainer(*i); 00141 if(fcPtr != NullFC) 00142 { 00143 callDestroyed(fcPtr); 00144 00145 // currently it is not save to subref all 00146 // containers because we don't know whether 00147 // they are referenced by other nodes. 00148 // It's only save to remove nodes without parents 00149 node = NodePtr::dcast(fcPtr); 00150 if(node != NullFC) 00151 { 00152 if(node->getParent() == NullFC) 00153 { 00154 do 00155 { 00156 subRefCP(fcPtr); 00157 fcPtr = factory->getContainer(*i); 00158 } while(fcPtr != NullFC); 00159 } 00160 } 00161 window = WindowPtr::dcast(fcPtr); 00162 if(window != NullFC) 00163 { 00164 do 00165 { 00166 subRefCP(fcPtr); 00167 fcPtr = factory->getContainer(*i); 00168 } while(fcPtr != NullFC); 00169 } 00170 /* 00171 // subref twice because we have two addrefs on reate 00172 // It is not possible to subref until the node is removed 00173 // because if this node is referenced by another node 00174 // then we will have a crash if we try to subref this 00175 // other node. 00176 subRefCP(fcPtr); 00177 subRefCP(fcPtr); 00178 */ 00179 } 00180 } 00181 }
|
|
|
|
|
||||||||||||
|
receiveSync reads changes from the given connection and applies them to the current thread aspect. Functors for registered types are called, if they occure in the sync stream.
Definition at line 193 of file OSGRemoteAspect.cpp. References _aspectId, _localFC, _localType, _receivedFC, osg::RemoteAspectFieldContainerMapper::_remoteAspect, _remoteAspectId, _remoteFC, _statistics, osg::addRefCP(), ADDREFED, osg::beginEditCP(), callChanged(), callCreated(), callDestroyed(), CHANGED, osg::changedCP(), clearFCMapping(), CREATED, osg::FieldContainerType::createFieldContainer(), osg::AttachmentContainerPtr::dcast(), DESTROYED, osg::endEditCP(), FDEBUG, osg::FieldContainerFactory::findType(), osg::BinaryDataHandler::get(), osg::Field::getCardinality(), osg::TypeBase::getCName(), osg::FieldContainerFactory::getContainer(), osg::StatCollector::getElem(), osg::FieldContainerPtrBase::getFieldContainerId(), getFullRemoteId(), osg::TypeBase::getId(), getLocalId(), osg::FieldDescription::getName(), osg::FieldContainerType::getNumFieldDescs(), osg::Field::getType(), osg::BinaryDataHandler::getValue(), IDMAPPING, NEWTYPE, osg::NullFC, osg::Connection::selectChannel(), osg::FieldContainerFactory::setMapper(), SFATAL, osg::FieldType::SINGLE_FIELD, statSyncTime, osg::IDString::str(), osg::subRefCP(), SUBREFED, SWARNING, SYNCENDED, and osg::FieldContainerFactory::the(). Referenced by osg::ClusterServer::doSync(). 00194 { 00195 bool finish = false; 00196 UInt8 cmd; 00197 UInt32 remoteTypeId; 00198 UInt32 localTypeId; 00199 UInt32 remoteId; 00200 UInt32 localId; 00201 UInt32 localAspect; 00202 std::string name; 00203 FieldContainerFactory *factory = FieldContainerFactory::the(); 00204 FieldContainerType *fcType; 00205 FieldContainerPtr fcPtr; 00206 BitVector mask; 00207 RemoteAspectFieldContainerMapper mapper; 00208 UInt64 fullRemoteId; 00209 LocalTypeMapT::iterator localTypeI; 00210 LocalFCMapT::iterator localFCI; 00211 UInt32 len; 00212 00213 // hack. No materialchange after image chagne 00214 std::vector<MaterialPtr> materials; 00215 00216 if(_statistics) 00217 { 00218 _statistics->getElem(statSyncTime)->start(); 00219 } 00220 00221 connection.selectChannel(); 00222 connection.getValue(_remoteAspectId); 00223 00224 // register mapper into factory 00225 mapper._remoteAspect = this; 00226 factory->setMapper(&mapper); 00227 do 00228 { 00229 connection.getValue(cmd); 00230 switch(cmd) 00231 { 00232 case NEWTYPE: 00233 { 00234 connection.getValue(remoteTypeId); 00235 connection.getValue(name); 00236 00237 // find local type 00238 fcType = FieldContainerFactory::the()->findType(name.c_str()); 00239 if(!fcType) 00240 { 00241 SWARNING << "Unknown Type: " << name << std::endl; 00242 } 00243 else 00244 { 00245 localTypeId = FieldContainerFactory::the()->findType(name.c_str())->getId(); 00246 00247 // insert remote type id into map 00248 _localType[remoteTypeId] = localTypeId; 00249 } 00250 break; 00251 } 00252 00253 case CREATED: 00254 { 00255 connection.getValue(remoteTypeId); 00256 connection.getValue(remoteId); 00257 localTypeI = _localType.find(remoteTypeId); 00258 if(localTypeI == _localType.end()) 00259 { 00260 SWARNING << 00261 "Unknown TypeID: " << 00262 remoteTypeId << 00263 " for remote id " << 00264 remoteId << 00265 std::endl; 00266 } 00267 else 00268 { 00269 UInt64 fullRemoteId=getFullRemoteId(remoteId); 00270 if(_localFC.find(fullRemoteId) == _localFC.end()) 00271 { 00272 localTypeId = localTypeI->second; 00273 fcType = factory->findType(localTypeId); 00274 fcPtr = fcType->createFieldContainer(); 00275 00276 // remove this node, when aspect is removed 00277 _receivedFC.insert(fcPtr.getFieldContainerId()); 00278 00279 // local <-> remote mapping 00280 _localFC[fullRemoteId] = fcPtr.getFieldContainerId(); 00281 _remoteFC[fcPtr.getFieldContainerId()] = fullRemoteId; 00282 00283 // make shure, client will not subref to zero 00284 addRefCP(fcPtr); 00285 addRefCP(fcPtr); 00286 callCreated(fcPtr); 00287 } 00288 else 00289 { 00290 FDEBUG(("FC already created %d\n",remoteId)); 00291 } 00292 } 00293 break; 00294 } 00295 00296 case DESTROYED: 00297 { 00298 connection.getValue(remoteId); 00299 if(getLocalId(remoteId,localId)) 00300 { 00301 clearFCMapping(localId,remoteId); 00302 fcPtr = factory->getContainer(localId); 00303 if(fcPtr != NullFC) 00304 { 00305 callDestroyed(fcPtr); 00306 00307 // remove all references to avoid multiple 00308 // removes. 00309 // The changelist does not contain changes 00310 // if the container was removed in this frame. 00311 // So when a pointerfield is set to NullFC 00312 // the new value is not transfered to the 00313 // server. 00314 FieldContainerType &fcType = fcPtr->getType(); 00315 for(UInt32 i = 1; i <= fcType.getNumFieldDescs(); ++i) 00316 { 00317 FieldDescription *desc = fcPtr->getType().getFieldDescription(i); 00318 // ignore beacon fields. I don't know any clean 00319 // solution. In CamearDecorator the acces method 00320 // to beacon is overloaded. As a result, if the 00321 // beacon field in the decorator is modified, 00322 // the decorated camera is modified. In most 00323 // cases this is OK, but not in this case. 00324 if(strcmp(desc->getName().str(),"beacon")==0) 00325 continue; 00326 Field *fieldPtr = fcPtr->getField(i); 00327 const FieldType &fType = fieldPtr->getType(); 00328 const char *ptrStr = strstr(fType.getCName(), "Ptr"); 00329 if(ptrStr && strlen(ptrStr) == 3) 00330 { 00331 if(fieldPtr->getCardinality() == FieldType::SINGLE_FIELD) 00332 { 00333 ((SFFieldContainerPtr *)fieldPtr)->setValue(NullFC); 00334 } 00335 else 00336 { 00337 ((MFFieldContainerPtr *) fieldPtr)->clear(); 00338 } 00339 } 00340 } 00341 00342 // subref until the factory hat no 00343 // knolage of the node 00344 do 00345 { 00346 subRefCP(fcPtr); 00347 fcPtr = factory->getContainer(localId); 00348 } while(fcPtr != NullFC); 00349 } 00350 } 00351 else 00352 { 00353 SWARNING << 00354 "Can't destroy unknown FC:" << 00355 remoteId << " " << 00356 std::endl; 00357 } 00358 break; 00359 } 00360 00361 case CHANGED: 00362 { 00363 connection.getValue(remoteId); 00364 connection.getValue(mask); 00365 connection.getValue(len); 00366 00367 if(getLocalId(remoteId,localId)) 00368 { 00369 fcPtr = factory->getContainer(localId); 00370 00371 if(applyToChangelist) 00372 { 00373 beginEditCP(fcPtr, mask); 00374 } 00375 00376 /* 00377 for(int i=0;i<fcPtr->getType().getNumFieldDescs();i++) 00378 { 00379 FieldDescription *desc=fcPtr->getType().getFieldDescription(i+1); 00380 if(desc->getFieldMask() & mask) 00381 cout<< "changed field: " << desc->getName() << std::endl; 00382 } 00383 */ 00384 fcPtr->copyFromBin(connection, mask); 00385 if(applyToChangelist) 00386 { 00387 endEditCP(fcPtr, mask); 00388 } 00389 else 00390 { 00391 // do we need to call this? 00392 changedCP(fcPtr, mask); 00393 } 00394 MaterialPtr mat=MaterialPtr::dcast(fcPtr); 00395 if(mat != NullFC) 00396 materials.push_back(mat); 00397 callChanged(fcPtr); 00398 } 00399 else 00400 { 00401 char dummy; 00402 00403 SWARNING << 00404 "Can't change unknown FC:" << 00405 remoteId << " skip " << len << " bytes." << 00406 std::endl; 00407 while(len--) 00408 connection.get(&dummy,1); 00409 } 00410 break; 00411 } 00412 00413 case SYNCENDED: 00414 { 00415 finish = true; 00416 break; 00417 } 00418 00419 case ADDREFED: 00420 { 00421 connection.getValue(remoteId); 00422 if(getLocalId(remoteId,localId)) 00423 { 00424 fcPtr = factory->getContainer(localId); 00425 FDEBUG(("AddRef: %s ID:%d\n", 00426 fcPtr->getType().getName().str(), 00427 fcPtr.getFieldContainerId())) 00428 addRefCP(fcPtr); 00429 } 00430 else 00431 { 00432 FDEBUG(("Can't addref unknown FC:%d\n", remoteId)); 00433 } 00434 break; 00435 } 00436 00437 case SUBREFED: 00438 { 00439 connection.getValue(remoteId); 00440 if(getLocalId(remoteId,localId)) 00441 { 00442 fcPtr = factory->getContainer(localId); 00443 FDEBUG(("SubRef: %s ID:%d\n", 00444 fcPtr->getType().getName().str(), 00445 fcPtr.getFieldContainerId())) 00446 #if 0 00447 //ignore until solution is found for subrefs in destructors 00448 subRefCP(fcPtr); 00449 #endif 00450 } 00451 else 00452 { 00453 FDEBUG(("Can't subref unknown FC:%d\n", remoteId)); 00454 } 00455 break; 00456 } 00457 case IDMAPPING: 00458 { 00459 connection.getValue(remoteId); 00460 connection.getValue(localAspect); 00461 connection.getValue(localId); 00462 if(localAspect != _aspectId) 00463 { 00464 SFATAL << "ID mapping for wrong aspect" << std::endl; 00465 } 00466 00467 // local <-> remote mapping 00468 fullRemoteId = getFullRemoteId(remoteId); 00469 _localFC[fullRemoteId] = localId; 00470 break; 00471 } 00472 default: 00473 { 00474 SFATAL << "Unknown tag:" << (int) cmd << std::endl; 00475 throw RemoteSyncError(); 00476 } 00477 } 00478 } 00479 while(!finish); 00480 00481 // chunks don't tell the material if they where changed. 00482 // This causes problems if textures are loaded after 00483 // the first matieral change. The Material is not aware 00484 // of a trasnparency. 00485 // Force rebuildState. 00486 for(std::vector<MaterialPtr>::iterator mI=materials.begin(); 00487 mI != materials.end(); 00488 ++mI) 00489 { 00490 changedCP(*mI); 00491 } 00492 00493 // unregister mapper into factory 00494 factory->setMapper(NULL); 00495 00496 if(_statistics) 00497 { 00498 _statistics->getElem(statSyncTime)->stop(); 00499 } 00500 }
|
|
||||||||||||
|
All changes from changeList are send to the connecteion except the fields which are filtered. Filters are used to avoid transmission of local states. e.g. GL variables. Definition at line 506 of file OSGRemoteAspect.cpp. References _aspectId, _fieldFilter, _mappedFC, _mappedType, _sentFC, _statistics, ADDREFED, osg::ChangeList::beginAddRefd(), osg::ChangeList::beginChanged(), osg::ChangeList::beginCreated(), osg::ChangeList::beginDestroyed(), osg::ChangeList::beginSubRefd(), CHANGED, clearFCMapping(), CREATED, DESTROYED, osg::ChangeList::endAddRefd(), osg::ChangeList::endChanged(), osg::ChangeList::endCreated(), osg::ChangeList::endDestroyed(), osg::ChangeList::endSubRefd(), FDEBUG, osg::BinaryDataHandler::flush(), osg::FieldContainerFactory::getContainer(), osg::StatCollector::getElem(), osg::FieldContainerPtrBase::getFieldContainerId(), handleFCMapping(), NEWTYPE, osg::NullFC, osg::BinaryDataHandler::putValue(), statSyncTime, SUBREFED, SYNCENDED, and osg::FieldContainerFactory::the(). Referenced by osg::ClusterWindow::frameInit(). 00507 { 00508 ChangeList::changed_const_iterator changedI; 00509 ChangeList::idrefd_const_iterator createdI; 00510 ChangeList::idrefd_const_iterator destroyedI; 00511 ChangeList::refd_const_iterator addRefedI; 00512 ChangeList::refd_const_iterator subRefedI; 00513 FieldFilterT::iterator filterI; 00514 FieldContainerFactory *fcFactory = FieldContainerFactory::the(); 00515 FieldContainerPtr fcPtr; 00516 UInt32 typeId; 00517 BitVector mask; 00518 UInt8 cmd; 00519 std::string typeName; 00520 FieldMaskMapT::iterator sentFCI; 00521 FieldMaskMapT changedMap; 00522 FieldMaskMapT::iterator changedMapI; 00523 UInt32 len; 00524 00525 if(_statistics) 00526 { 00527 _statistics->getElem(statSyncTime)->start(); 00528 } 00529 00530 if(!changeList) 00531 { 00532 changeList = OSG::Thread::getCurrentChangeList(); 00533 } 00534 00535 // tell my aspect id 00536 connection.putValue(_aspectId); 00537 00538 handleFCMapping(connection); 00539 00540 // created fct 00541 for(createdI = changeList->beginCreated(); 00542 createdI != changeList->endCreated(); createdI++) 00543 { 00544 fcPtr = fcFactory->getContainer(*createdI); 00545 if(fcPtr == NullFC) 00546 { 00547 continue; 00548 } 00549 00550 typeId = fcPtr->getTypeId(); 00551 00552 // type unknown by remote context ? 00553 if(_mappedType.count(typeId) == 0) 00554 { 00555 // mark type as known 00556 _mappedType.insert(typeId); 00557 00558 // send new type 00559 cmd = NEWTYPE; 00560 typeName = fcPtr->getType().getName().str(); 00561 connection.putValue(cmd); 00562 connection.putValue(typeId); 00563 connection.putValue(typeName); 00564 } 00565 00566 cmd = CREATED; 00567 connection.putValue(cmd); 00568 connection.putValue(typeId); 00569 connection.putValue(*createdI); 00570 00571 // sent container to create 00572 _sentFC.insert(*createdI); 00573 // fc is known by remote 00574 _mappedFC.insert(*createdI); 00575 00576 } 00577 00578 // destroy fct 00579 for(destroyedI = changeList->beginDestroyed(); 00580 destroyedI != changeList->endDestroyed(); destroyedI++) 00581 { 00582 UInt32 id = (*destroyedI); 00583 00584 // is it a known container 00585 if(_mappedFC.count(id)) 00586 { 00587 clearFCMapping(id,0); 00588 cmd = DESTROYED; 00589 connection.putValue(cmd); 00590 connection.putValue(id); 00591 } 00592 } 00593 00594 // changed fields 00595 // first create a condensed map, where each container is stored 00596 // only once 00597 for(changedI = changeList->beginChanged(); 00598 changedI != changeList->endChanged(); 00599 changedI++) 00600 { 00601 changedMapI = changedMap.find(changedI->first); 00602 if(changedMapI == changedMap.end()) 00603 { 00604 changedMap.insert(std::pair < UInt32, 00605 BitVector > (changedI->first, changedI->second)); 00606 } 00607 else 00608 { 00609 changedMapI->second |= changedI->second; 00610 } 00611 } 00612 00613 for(FieldMaskMapT::iterator condensedI = changedMap.begin(); 00614 condensedI != changedMap.end(); 00615 ++condensedI) 00616 { 00617 if(_mappedFC.count(condensedI->first)==0) 00618 continue; 00619 00620 FieldContainerPtr fcPtr = 00621 FieldContainerFactory::the()->getContainer(condensedI->first); 00622 00623 // ignore removed containers 00624 if(fcPtr == NullFC) 00625 continue; 00626 mask = condensedI->second; 00627 00628 // apply field filter 00629 filterI = _fieldFilter.find(fcPtr->getType().getId()); 00630 if(filterI != _fieldFilter.end()) 00631 { 00632 FDEBUG(("SyncFieldFilter: :%s \n", 00633 fcPtr->getType().getName().str() )) 00634 mask &= TypeTraits<BitVector>::BitsSet ^ filterI->second; 00635 } 00636 00637 if(mask) 00638 { 00639 // send changes 00640 condensedI->second |= mask; 00641 cmd = CHANGED; 00642 connection.putValue(cmd); 00643 connection.putValue(condensedI->first); // id 00644 connection.putValue(mask); // mask 00645 len = fcPtr->getBinSize(mask); 00646 connection.putValue(len); 00647 fcPtr->copyToBin(connection, mask); 00648 FDEBUG(("Changed: %s ID:%d Mask:%lld\n", 00649 fcPtr->getType().getName().str(), 00650 fcPtr.getFieldContainerId(), 00651 mask)) 00652 } 00653 } 00654 00655 // addref 00656 for(addRefedI = changeList->beginAddRefd(); 00657 addRefedI != changeList->endAddRefd(); 00658 ++addRefedI) 00659 { 00660 UInt32 id = (*addRefedI); 00661 00662 if(_mappedFC.count(id)==0) 00663 continue; 00664 cmd = ADDREFED; 00665 connection.putValue(cmd); 00666 connection.putValue(id); 00667 } 00668 00669 // subref 00670 for(subRefedI = changeList->beginSubRefd(); 00671 subRefedI != changeList->endSubRefd(); 00672 ++subRefedI) 00673 { 00674 UInt32 id = (*subRefedI); 00675 00676 // ignore addrefs for unknown fcs 00677 if(_mappedFC.count(id)==0) 00678 continue; 00679 cmd = SUBREFED; 00680 connection.putValue(cmd); 00681 connection.putValue(id); 00682 } 00683 00684 cmd = SYNCENDED; 00685 connection.putValue(cmd); 00686 00687 // write buffer 00688 connection.flush(); 00689 00690 if(_statistics) 00691 { 00692 _statistics->getElem(statSyncTime)->stop(); 00693 } 00694 }
|
|
||||||||||||
|
The given functor is called when a create of the specified type is received.
Definition at line 701 of file OSGRemoteAspect.cpp. References _createdFunctors, _defaultCreatedFunction(), osg::TypeBase::getId(), and osg::osgTypedFunctionFunctor2CPtrRef(). 00703 { 00704 while(type.getId() >= _createdFunctors.size()) 00705 { 00706 _createdFunctors.push_back( 00707 osgTypedFunctionFunctor2CPtrRef 00708 <bool,FieldContainerPtr,RemoteAspect * > 00709 (&_defaultCreatedFunction)); 00710 } 00711 00712 _createdFunctors[type.getId()] = func; 00713 }
|
|
||||||||||||
|
The given functor is called when a destroy of the specified type is received.
Definition at line 720 of file OSGRemoteAspect.cpp. References _defaultDestroyedFunction(), _destroyedFunctors, osg::TypeBase::getId(), and osg::osgTypedFunctionFunctor2CPtrRef(). 00722 { 00723 while(type.getId() >= _destroyedFunctors.size()) 00724 { 00725 _destroyedFunctors.push_back(osgTypedFunctionFunctor2CPtrRef < bool, 00726 FieldContainerPtr, RemoteAspect * > (&_defaultDestroyedFunction)); 00727 } 00728 00729 _destroyedFunctors[type.getId()] = func; 00730 }
|
|
||||||||||||
|
The given functor is called when a change of the specified type is received.
Definition at line 737 of file OSGRemoteAspect.cpp. References _changedFunctors, _defaultChangedFunction(), osg::TypeBase::getId(), and osg::osgTypedFunctionFunctor2CPtrRef(). Referenced by osg::ClusterServer::start(). 00739 { 00740 while(type.getId() >= _changedFunctors.size()) 00741 { 00742 _changedFunctors.push_back(osgTypedFunctionFunctor2CPtrRef < bool, 00743 FieldContainerPtr, 00744 RemoteAspect * > (&_defaultChangedFunction)); 00745 } 00746 00747 _changedFunctors[type.getId()] = func; 00748 }
|
|