Main Page | Modules | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

osg::RemoteAspect Class Reference
[Cluster]

Remote aspect controll class. More...

#include <OSGRemoteAspect.h>

List of all members.

Remote aspect functionaliy

typedef std::map< UInt32,
UInt32
clStoreMap
typedef clStoreMap::iterator clStoreIt
*void receiveSync (Connection &connection, bool applyToChangelist=false)
void sendSync (Connection &connection, ChangeList *changeList=NULL)
void registerCreated (const FieldContainerType &type, const Functor &func)
void registerDestroyed (const FieldContainerType &type, const Functor &func)
void registerChanged (const FieldContainerType &type, const Functor &func)
static void addFieldFilter (UInt32 typeId, BitVector mask)
static void subFieldFilter (UInt32 typeId, BitVector mask)
static void restoreChangeList (ChangeList *tocl)
static void storeChangeList (ChangeList *cl)
static UInt32 getStoreSize (void)
static clStoreMapgetStore (void)

member

*UInt32 _aspectId
LocalFCMapT _localFC
RemoteFCMapT _remoteFC
LocalTypeMapT _localType
IdSetT _sentFC
IdSetT _receivedFC
IdSetT _mappedFC
IdSetT _mappedType
UInt32 _remoteAspectId
std::vector< Functor_createdFunctors
std::vector< Functor_destroyedFunctors
std::vector< Functor_changedFunctors
StatCollector_statistics
static FieldFilterT _fieldFilter
static std::map< UInt32, UInt32_clStore

static elements

*static bool _defaultCreatedFunction (FieldContainerPtr &fcp, RemoteAspect *aspect)
static bool _defaultDestroyedFunction (FieldContainerPtr &fcp, RemoteAspect *aspect)
static bool _defaultChangedFunction (FieldContainerPtr &fcp, RemoteAspect *aspect)
static StatElemDesc< StatTimeElemstatSyncTime

Public Types

typedef ArgsCollector< RemoteAspect * > FunctorArgs
typedef TypedFunctor2Base<
bool, CPtrRefCallArg< FieldContainerPtr >,
FunctorArgs
Functor
typedef std::map< UInt64,
UInt32
LocalFCMapT
typedef std::map< UInt32,
UInt64
RemoteFCMapT
typedef std::map< UInt32,
UInt32
LocalTypeMapT
typedef std::set< UInt32IdSetT
typedef std::map< UInt32,
BitVector
FieldFilterT
typedef std::map< UInt32,
BitVector
FieldMaskMapT
enum  DataTypes {
  SYNCENDED = 1, CREATED = 2, DESTROYED = 3, NEWTYPE = 4,
  CHANGED = 5, ADDREFED = 6, SUBREFED = 7, IDMAPPING = 8
}

Public Member Functions

Constructors
RemoteAspect (UInt32 aspectId=0)
virtual ~RemoteAspect (void)
Statistics
*void setStatistics (StatCollector *stat)

Protected Member Functions

protected helper functions
*bool callCreated (FieldContainerPtr &node)
bool callDestroyed (FieldContainerPtr &node)
bool callChanged (FieldContainerPtr &node)

Private Member Functions

 RemoteAspect (const RemoteAspect &source)
RemoteAspectoperator= (const RemoteAspect &source)
Helper functions
*void handleFCMapping (Connection &connection)
void clearFCMapping (UInt32 localId, UInt32 remoteId)
bool getLocalId (UInt32 remoteId, UInt32 &localId)
UInt64 getFullRemoteId (UInt32 remoteId)

Friends

class RemoteAspectFieldContainerMapper


Detailed Description

The RemoteAspecet is used to synchronize changes of FieldContainers with remote hosts. All changes stored in the current change list are send to a Connection.

It is possible to send changes in both directions.

Definition at line 60 of file OSGRemoteAspect.h.


Member Typedef Documentation

typedef ArgsCollector<RemoteAspect *> osg::RemoteAspect::FunctorArgs
 

functor called for changed containers

Definition at line 78 of file OSGRemoteAspect.h.

typedef TypedFunctor2Base<bool, CPtrRefCallArg<FieldContainerPtr>, FunctorArgs > osg::RemoteAspect::Functor
 

Definition at line 81 of file OSGRemoteAspect.h.

typedef std::map<UInt64,UInt32> osg::RemoteAspect::LocalFCMapT
 

Map remote to local id

Definition at line 84 of file OSGRemoteAspect.h.

typedef std::map<UInt32,UInt64> osg::RemoteAspect::RemoteFCMapT
 

Map local to remote id

Definition at line 86 of file OSGRemoteAspect.h.

typedef std::map<UInt32,UInt32> osg::RemoteAspect::LocalTypeMapT
 

Map remote to local type

Definition at line 88 of file OSGRemoteAspect.h.

typedef std::set<UInt32> osg::RemoteAspect::IdSetT
 

id set

Definition at line 91 of file OSGRemoteAspect.h.

typedef std::map<UInt32,BitVector> osg::RemoteAspect::FieldFilterT
 

Field filter map

Definition at line 94 of file OSGRemoteAspect.h.

typedef std::map<UInt32,BitVector> osg::RemoteAspect::FieldMaskMapT
 

Definition at line 95 of file OSGRemoteAspect.h.

typedef std::map<UInt32, UInt32> osg::RemoteAspect::clStoreMap
 

Definition at line 126 of file OSGRemoteAspect.h.

typedef clStoreMap::iterator osg::RemoteAspect::clStoreIt
 

Definition at line 127 of file OSGRemoteAspect.h.


Member Enumeration Documentation

enum osg::RemoteAspect::DataTypes
 

Message types

Enumerator:
SYNCENDED 
CREATED 
DESTROYED 
NEWTYPE 
CHANGED 
ADDREFED 
SUBREFED 
IDMAPPING 

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     };


Constructor & Destructor Documentation

RemoteAspect::RemoteAspect UInt32  aspectId = 0  ) 
 

Constructor

Definition at line 83 of file OSGRemoteAspect.cpp.

References _fieldFilter, osg::FieldContainerFactory::beginTypes(), osg::FieldContainerFactory::endTypes(), osg::WindowBase::getClassType(), osg::FragmentProgramChunkBase::getClassType(), osg::VertexProgramChunkBase::getClassType(), osg::CubeTextureChunkBase::getClassType(), osg::TextureChunkBase::getClassType(), osg::GeometryBase::getClassType(), osg::TypeBase::getId(), osg::ProgramChunkBase::GLIdFieldMask, osg::TextureChunkBase::GLIdFieldMask, osg::GeometryBase::GLIdFieldMask, osg::WindowBase::GlObjectEventCounterFieldMask, osg::WindowBase::GlObjectLastRefreshFieldMask, osg::WindowBase::GlObjectLastReinitializeFieldMask, and osg::FieldContainerFactory::the().

00083                                           :
00084     _aspectId(aspectId),
00085 
00086     _localFC(),
00087     _remoteFC(),
00088     _localType(),
00089 
00090     _sentFC(),
00091     _receivedFC(),
00092     _mappedFC(),
00093     _mappedType(),
00094 
00095     _createdFunctors(),
00096     _destroyedFunctors(),
00097     _changedFunctors(),
00098     _statistics(NULL)
00099 {
00100     FieldContainerFactory::TypeMapIterator  typeI;
00101 
00102     // initialize field filter
00103     _fieldFilter[Geometry::getClassType().getId()] = 
00104         Geometry::GLIdFieldMask;
00105     _fieldFilter[TextureChunk::getClassType().getId()] = 
00106         TextureChunk::GLIdFieldMask;
00107     _fieldFilter[CubeTextureChunk::getClassType().getId()] = 
00108         CubeTextureChunk::GLIdFieldMask;
00109     _fieldFilter[VertexProgramChunk::getClassType().getId()] = 
00110         VertexProgramChunk::GLIdFieldMask;
00111     _fieldFilter[FragmentProgramChunk::getClassType().getId()] = 
00112         FragmentProgramChunk::GLIdFieldMask;
00113 
00114     for(typeI = FieldContainerFactory::the()->beginTypes();
00115             typeI != FieldContainerFactory::the()->endTypes(); ++typeI)
00116     {
00117         if(typeI->second->isDerivedFrom(Window::getClassType()))
00118         {
00119             _fieldFilter[typeI->second->getId()
00120                     ] = Window::GlObjectEventCounterFieldMask |
00121                 Window::GlObjectLastRefreshFieldMask |
00122                 Window::GlObjectLastReinitializeFieldMask;
00123         }
00124     }
00125 }

RemoteAspect::~RemoteAspect void   )  [virtual]
 

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 }

osg::RemoteAspect::RemoteAspect const RemoteAspect source  )  [private]
 


Member Function Documentation

void RemoteAspect::receiveSync Connection connection,
bool  applyToChangelist = false
 

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.

See also:
registerCreated registerChanged registerDeleted

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 }

void RemoteAspect::sendSync Connection connection,
ChangeList changeList = NULL
 

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 }

void RemoteAspect::registerCreated const FieldContainerType type,
const Functor func
 

The given functor is called when a create of the specified type is received.

See also:
receiveSync

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 }

void RemoteAspect::registerDestroyed const FieldContainerType type,
const Functor func
 

The given functor is called when a destroy of the specified type is received.

See also:
receiveSync

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 }

void RemoteAspect::registerChanged const FieldContainerType type,
const Functor func
 

The given functor is called when a change of the specified type is received.

See also:
receiveSync

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 }

void RemoteAspe