osg::RemoteAspect Class Reference
[Cluster]

Remote aspect controll class. More...

#include <OSGRemoteAspect.h>

List of all members.

Remote aspect functionaliy



typedef std::map< UInt32, UInt32clStoreMap
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)
static void createCurrentStateChangeList (const FieldContainerPtr &start, ChangeList *cl)

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 StatElemDesc< StatTimeElemstatSyncTime
static bool _defaultCreatedFunction (FieldContainerPtr &fcp, RemoteAspect *aspect)
static bool _defaultDestroyedFunction (FieldContainerPtr &fcp, RemoteAspect *aspect)
static bool _defaultChangedFunction (FieldContainerPtr &fcp, RemoteAspect *aspect)

Public Types

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

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

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.

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

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.

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

Definition at line 127 of file OSGRemoteAspect.h.


Member Enumeration Documentation

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 84 of file OSGRemoteAspect.cpp.

References _fieldFilter, osg::FieldContainerFactory::endTypes(), osg::WindowBase::getClassType(), osg::FragmentProgramChunkBase::getClassType(), osg::VertexProgramChunkBase::getClassType(), osg::CubeTextureChunkBase::getClassType(), osg::TextureChunkBase::getClassType(), osg::SurfaceBase::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, osg::SurfaceBase::SurfaceGLIdFieldMask, and osg::FieldContainerFactory::the().

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

RemoteAspect::~RemoteAspect ( void   )  [virtual]

Destructor

Definition at line 132 of file OSGRemoteAspect.cpp.

References _receivedFC, callDestroyed(), osg::AttachmentContainerPtr::dcast(), osg::NodePtr::dcast(), osg::FieldContainerFactory::getContainer(), osg::NullFC, osg::subRefCP(), and osg::FieldContainerFactory::the().

00133 {
00134     FieldContainerFactory   *factory = FieldContainerFactory::the();
00135     IdSetT::iterator        i;
00136     FieldContainerPtr       fcPtr;
00137     NodePtr                 node;
00138     WindowPtr               window;
00139 
00140     // subRef received field container
00141     for(i = _receivedFC.begin(); i != _receivedFC.end(); i++)
00142     {
00143         fcPtr = factory->getContainer(*i);
00144         if(fcPtr != NullFC)
00145         {
00146             callDestroyed(fcPtr);
00147 
00148             // currently it is not save to subref all
00149             // containers because we don't know whether
00150             // they are referenced by other nodes.
00151             // It's only save to remove nodes without parents
00152             node = NodePtr::dcast(fcPtr);
00153             if(node != NullFC)
00154             {
00155                 if(node->getParent() == NullFC)
00156                 {
00157                     do
00158                     {
00159                         subRefCP(fcPtr);
00160                         fcPtr = factory->getContainer(*i);
00161                     } while(fcPtr != NullFC);
00162                 }
00163             }
00164             window = WindowPtr::dcast(fcPtr);
00165             if(window != NullFC)
00166             {
00167                 do
00168                 {
00169                     subRefCP(fcPtr);
00170                     fcPtr = factory->getContainer(*i);
00171                 } while(fcPtr != NullFC);
00172             }
00173             /*
00174             // subref twice because we have two addrefs on reate
00175             // It is not possible to subref until the node is removed
00176             // because if this node is referenced by another node
00177             // then we will have a crash if we try to subref this
00178             // other node.
00179             subRefCP(fcPtr);
00180             subRefCP(fcPtr);
00181             */
00182         }
00183     }
00184 }

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 196 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(), 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(), 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().

00197 {
00198     bool                                finish = false;
00199     UInt8                               cmd;
00200     UInt32                              remoteTypeId;
00201     UInt32                              localTypeId;
00202     UInt32                              remoteId;
00203     UInt32                              localId;
00204     UInt32                              localAspect;
00205     std::string                         name;
00206     FieldContainerFactory               *factory = FieldContainerFactory::the();
00207     FieldContainerType                  *fcType;
00208     FieldContainerPtr                   fcPtr;
00209     BitVector                           mask;
00210     RemoteAspectFieldContainerMapper    mapper;
00211     UInt64                              fullRemoteId;
00212     LocalTypeMapT::iterator             localTypeI;
00213     LocalFCMapT::iterator               localFCI;
00214     UInt32                              len;
00215 
00216     // hack. No materialchange after image chagne
00217     std::vector<std::pair<FieldContainerPtr,BitVector> > changedFCs;
00218 
00219     if(_statistics)
00220     {
00221         _statistics->getElem(statSyncTime)->start();
00222     }
00223 
00224     connection.selectChannel();
00225     connection.getValue(_remoteAspectId);
00226 
00227     // register mapper into factory
00228     mapper._remoteAspect = this;
00229     factory->setMapper(&mapper);
00230     do
00231     {
00232         connection.getValue(cmd);
00233         switch(cmd)
00234         {
00235         case NEWTYPE:
00236             {
00237                 connection.getValue(remoteTypeId);
00238                 connection.getValue(name);
00239 
00240                 // find local type
00241                 fcType = FieldContainerFactory::the()->findType(name.c_str());
00242                 if(!fcType)
00243                 {
00244                     SWARNING << "Unknown Type: " << name << std::endl;
00245                 }
00246                 else
00247                 {
00248                     localTypeId = FieldContainerFactory::the()->findType(name.c_str())->getId();
00249 
00250                     // insert remote type id into map
00251                     _localType[remoteTypeId] = localTypeId;
00252                 }
00253                 break;
00254             }
00255 
00256         case CREATED:
00257             {
00258                 connection.getValue(remoteTypeId);
00259                 connection.getValue(remoteId);
00260                 localTypeI = _localType.find(remoteTypeId);
00261                 if(localTypeI == _localType.end())
00262                 {
00263                     SWARNING <<
00264                         "Unknown TypeID: " <<
00265                         remoteTypeId <<
00266                         " for remote id " <<
00267                         remoteId <<
00268                         std::endl;
00269                 }
00270                 else
00271                 {
00272                     UInt64 fullRemoteId=getFullRemoteId(remoteId);
00273                     if(_localFC.find(fullRemoteId) == _localFC.end())
00274                     {
00275                         localTypeId = localTypeI->second;
00276                         fcType = factory->findType(localTypeId);
00277                         fcPtr = fcType->createFieldContainer();
00278                         
00279                         // remove this node, when aspect is removed
00280                         _receivedFC.insert(fcPtr.getFieldContainerId());
00281                         
00282                         // local <-> remote mapping
00283                         _localFC[fullRemoteId] = fcPtr.getFieldContainerId();
00284                         _remoteFC[fcPtr.getFieldContainerId()] = fullRemoteId;
00285                         
00286                         // make shure, client will not subref to zero
00287                         addRefCP(fcPtr);
00288                         addRefCP(fcPtr);
00289                         callCreated(fcPtr);
00290                     }
00291                     else
00292                     {
00293                         FDEBUG(("FC already created %d\n",remoteId));
00294                     }
00295                 }
00296                 break;
00297             }
00298 
00299         case DESTROYED:
00300             {
00301                 connection.getValue(remoteId);
00302                 if(getLocalId(remoteId,localId))
00303                 {
00304                     clearFCMapping(localId,remoteId);
00305                     fcPtr = factory->getContainer(localId);
00306                     if(fcPtr != NullFC)
00307                     {
00308                         callDestroyed(fcPtr);
00309 
00310                         // remove all references to avoid multiple
00311                         // removes.
00312                         // The changelist does not contain changes
00313                         // if the container was removed in this frame.
00314                         // So when a pointerfield is set to NullFC
00315                         // the new value is not transfered to the
00316                         // server.
00317                         FieldContainerType &fcType = fcPtr->getType();
00318                         for(UInt32 i = 1; i <= fcType.getNumFieldDescs(); ++i)
00319                         {
00320                             FieldDescription *desc = fcPtr->getType().getFieldDescription(i);
00321                             // ignore beacon fields. I don't know any clean
00322                             // solution. In CamearDecorator the acces method
00323                             // to beacon is overloaded. As a result, if the
00324                             // beacon field in the decorator is modified,
00325                             // the decorated camera is modified. In most
00326                             // cases this is OK, but not in this case.
00327                             if(strcmp(desc->getName().str(),"beacon")==0)
00328                                 continue;
00329                             Field *fieldPtr = fcPtr->getField(i);
00330                             const FieldType &fType = fieldPtr->getType();
00331                             const char *ptrStr = strstr(fType.getCName(), "Ptr");
00332                             if(ptrStr && strlen(ptrStr) == 3)
00333                             {
00334                                 if(fieldPtr->getCardinality() == FieldType::SINGLE_FIELD)
00335                                 {
00336                                     ((SFFieldContainerPtr *)fieldPtr)->setValue(NullFC);
00337                                 }
00338                                 else 
00339                                 {
00340                                     ((MFFieldContainerPtr *) fieldPtr)->clear();
00341                                 }
00342                             }
00343                         }
00344 
00345                         // subref until the factory hat no 
00346                         // knowlage of the node
00347                         // we can do this here because in sendSync the destroys are coming
00348                         // after the changes, that's important because if
00349                         // rebuildState would be called
00350                         // after the StateChunk has been destroyed this would lead to some
00351                         // problems because the StateChunk is also referenced
00352                         // in the state and in the next rebuildState of the material
00353                         // the old already invalid chunk ptr is destroyed again!
00354                         do
00355                         {
00356                             subRefCP(fcPtr);
00357                             fcPtr = factory->getContainer(localId);
00358                         }
00359                         while(fcPtr != NullFC);
00360                     }
00361                 }
00362                 else
00363                 {
00364                     SWARNING <<
00365                         "Can't destroy unknown FC:" <<
00366                         remoteId << " " <<
00367                         std::endl;
00368                 }
00369                 break;
00370             }
00371 
00372         case CHANGED:
00373             {
00374                 connection.getValue(remoteId);
00375                 connection.getValue(mask);
00376                 connection.getValue(len);
00377 
00378                 if(getLocalId(remoteId,localId))
00379                 {
00380                     fcPtr = factory->getContainer(localId);
00381 
00382                     if(applyToChangelist)
00383                     {
00384                         beginEditCP(fcPtr, mask);
00385                     }
00386 
00387                     /*
00388                     for(int i=0;i<fcPtr->getType().getNumFieldDescs();i++)
00389                     {
00390                         FieldDescription *desc=fcPtr->getType().getFieldDescription(i+1);
00391                         if(desc->getFieldMask() & mask)
00392                             cout<< "changed field: " << desc->getName() << std::endl;
00393                     }
00394                     */
00395                     fcPtr->copyFromBin(connection, mask);
00396                     if(applyToChangelist)
00397                     {
00398                         endEditCP(fcPtr, mask);
00399                     }
00400                     else
00401                     {
00402                         // do we need to call this?
00403                         changedCP(fcPtr, mask);
00404                     }
00405                     changedFCs.push_back(
00406                         std::pair<FieldContainerPtr,BitVector>(
00407                             fcPtr,mask));
00408                 }
00409                 else
00410                 {
00411                     char dummy;
00412 
00413                     SWARNING <<
00414                         "Can't change unknown FC:" <<
00415                         remoteId << " skip " << len << " bytes." <<
00416                         std::endl;
00417                     while(len--)
00418                         connection.get(&dummy,1);
00419                 }
00420                 break;
00421             }
00422 
00423         case SYNCENDED:
00424             {
00425                 finish = true;
00426                 break;
00427             }
00428 
00429         case ADDREFED:
00430             {
00431                 connection.getValue(remoteId);
00432                 if(getLocalId(remoteId,localId))
00433                 {
00434                     fcPtr = factory->getContainer(localId);
00435                     FDEBUG(("AddRef: %s ID:%d\n", 
00436                             fcPtr->getType().getName().str(),
00437                             fcPtr.getFieldContainerId())) 
00438                     addRefCP(fcPtr);
00439                 }
00440                 else
00441                 {
00442                     FDEBUG(("Can't addref unknown FC:%d\n", remoteId));
00443                 }
00444                 break;
00445             }
00446 
00447         case SUBREFED:
00448             {
00449                 connection.getValue(remoteId);
00450                 if(getLocalId(remoteId,localId))
00451                 {
00452                     fcPtr = factory->getContainer(localId);
00453                     FDEBUG(("SubRef: %s ID:%d\n", 
00454                             fcPtr->getType().getName().str(),
00455                             fcPtr.getFieldContainerId()))
00456 #if 0
00457                     //ignore until solution is found for subrefs in destructors
00458                     subRefCP(fcPtr);
00459 #endif
00460                 }
00461                 else
00462                 {
00463                     FDEBUG(("Can't subref unknown FC:%d\n", remoteId));
00464                 }
00465                 break;
00466             }
00467         case IDMAPPING:
00468             {
00469                 connection.getValue(remoteId);
00470                 connection.getValue(localAspect);
00471                 connection.getValue(localId);
00472                 if(localAspect != _aspectId)
00473                 {
00474                     SFATAL << "ID mapping for wrong aspect" << std::endl;
00475                 }
00476 
00477                 // local <-> remote mapping
00478                 fullRemoteId = getFullRemoteId(remoteId);
00479                 _localFC[fullRemoteId] = localId;
00480                 break;
00481             }
00482         default:
00483             {
00484                 SFATAL << "Unknown tag:" << (int) cmd << std::endl;
00485                 throw RemoteSyncError();
00486             }
00487         }
00488     } 
00489     while(!finish);
00490 
00491     // call changed for all changed field containers after all values
00492     // are set
00493     for(std::vector<std::pair<FieldContainerPtr,BitVector> >::iterator cI=changedFCs.begin();
00494         cI != changedFCs.end();
00495         ++cI) 
00496     {
00497         changedCP(cI->first,cI->second);
00498         callChanged(cI->first);
00499     }
00500 
00501     // unregister mapper into factory
00502     factory->setMapper(NULL);
00503 
00504     if(_statistics)
00505     {
00506         _statistics->getElem(statSyncTime)->stop();
00507     }
00508 }

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 514 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().

00515 {
00516     ChangeList::changed_const_iterator  changedI;
00517     ChangeList::idrefd_const_iterator   createdI;
00518     ChangeList::idrefd_const_iterator   destroyedI;
00519     ChangeList::refd_const_iterator     addRefedI;
00520     ChangeList::refd_const_iterator     subRefedI;
00521     FieldFilterT::iterator              filterI;
00522     FieldContainerFactory               *fcFactory = FieldContainerFactory::the();
00523     FieldContainerPtr                   fcPtr;
00524     UInt32                              typeId;
00525     BitVector                           mask;
00526     UInt8                               cmd;
00527     std::string                         typeName;
00528     FieldMaskMapT::iterator             sentFCI;
00529     FieldMaskMapT                       changedMap;
00530     FieldMaskMapT::iterator             changedMapI;
00531     UInt32                              len;
00532 
00533     if(_statistics)
00534     {
00535         _statistics->getElem(statSyncTime)->start();
00536     }
00537 
00538     if(!changeList)
00539     {
00540         changeList = OSG::Thread::getCurrentChangeList();
00541     }
00542 
00543     // tell my aspect id
00544     connection.putValue(_aspectId);
00545 
00546     handleFCMapping(connection);
00547 
00548     // created fct
00549     for(createdI = changeList->beginCreated();
00550         createdI != changeList->endCreated(); createdI++)
00551     {
00552         fcPtr = fcFactory->getContainer(*createdI);
00553         if(fcPtr == NullFC)
00554         {
00555             continue;
00556         }
00557 
00558         typeId = fcPtr->getTypeId();
00559 
00560         // type unknown by remote context ?
00561         if(_mappedType.count(typeId) == 0)
00562         {
00563             // mark type as known
00564             _mappedType.insert(typeId);
00565 
00566             // send new type
00567             cmd = NEWTYPE;
00568             typeName = fcPtr->getType().getName().str();
00569             connection.putValue(cmd);
00570             connection.putValue(typeId);
00571             connection.putValue(typeName);
00572         }
00573 
00574         cmd = CREATED;
00575         connection.putValue(cmd);
00576         connection.putValue(typeId);
00577         connection.putValue(*createdI);
00578 
00579         // sent container to create
00580         _sentFC.insert(*createdI);
00581         // fc is known by remote
00582         _mappedFC.insert(*createdI);
00583 
00584     }
00585 
00586     // changed fields
00587     // first create a condensed map, where each container is stored
00588     // only once
00589     for(changedI = changeList->beginChanged();
00590         changedI != changeList->endChanged(); 
00591         changedI++)
00592     {
00593         changedMapI = changedMap.find(changedI->first);
00594         if(changedMapI == changedMap.end())
00595         {
00596             changedMap.insert(std::pair < UInt32,
00597                                           BitVector > (changedI->first, changedI->second));
00598         }
00599         else
00600         {
00601             changedMapI->second |= changedI->second;
00602         }
00603     }
00604 
00605     for(FieldMaskMapT::iterator condensedI = changedMap.begin();
00606         condensedI != changedMap.end();
00607         ++condensedI)
00608     {
00609         if(_mappedFC.count(condensedI->first)==0)
00610             continue;
00611 
00612         FieldContainerPtr fcPtr = 
00613             FieldContainerFactory::the()->getContainer(condensedI->first);
00614 
00615         // ignore removed containers
00616         if(fcPtr == NullFC)
00617             continue;
00618         mask = condensedI->second;
00619 
00620         // apply field filter
00621         filterI = _fieldFilter.find(fcPtr->getType().getId());
00622         if(filterI != _fieldFilter.end())
00623         {
00624             FDEBUG(("SyncFieldFilter: :%s \n", 
00625                     fcPtr->getType().getName().str() )) 
00626             mask &= TypeTraits<BitVector>::BitsSet ^ filterI->second;
00627         }
00628 
00629         if(mask)
00630         {
00631             // send changes
00632             condensedI->second |= mask;
00633             cmd = CHANGED;
00634             connection.putValue(cmd);
00635             connection.putValue(condensedI->first); // id
00636             connection.putValue(mask);              // mask
00637             len = fcPtr->getBinSize(mask);
00638             connection.putValue(len);
00639             fcPtr->copyToBin(connection, mask);
00640             FDEBUG(("Changed: %s ID:%d Mask:%lld\n", 
00641                     fcPtr->getType().getName().str(),
00642                     fcPtr.getFieldContainerId(), 
00643                     mask))
00644         }
00645     }
00646 
00647     // destroy fct
00648     // needs to be called after the changes (see receiveSync for more info)!!!
00649     for(destroyedI = changeList->beginDestroyed();
00650         destroyedI != changeList->endDestroyed(); destroyedI++)
00651     {
00652         UInt32  id = (*destroyedI);
00653 
00654         // is it a known container
00655         if(_mappedFC.count(id))
00656         {
00657             clearFCMapping(id,0);
00658             cmd = DESTROYED;
00659             connection.putValue(cmd);
00660             connection.putValue(id);
00661         }
00662     }
00663 
00664     // addref
00665     for(addRefedI = changeList->beginAddRefd();
00666         addRefedI != changeList->endAddRefd();
00667         ++addRefedI)
00668     {
00669         UInt32  id = (*addRefedI);
00670 
00671         if(_mappedFC.count(id)==0)
00672             continue;
00673         cmd = ADDREFED;
00674         connection.putValue(cmd);
00675         connection.putValue(id);
00676     }
00677 
00678     // subref
00679     for(subRefedI = changeList->beginSubRefd();
00680         subRefedI != changeList->endSubRefd();
00681         ++subRefedI)
00682     {
00683         UInt32  id = (*subRefedI);
00684 
00685         // ignore addrefs for unknown fcs
00686         if(_mappedFC.count(id)==0)
00687             continue;
00688         cmd = SUBREFED;
00689         connection.putValue(cmd);
00690         connection.putValue(id);
00691     }
00692 
00693     cmd = SYNCENDED;
00694     connection.putValue(cmd);
00695 
00696     // write buffer
00697     connection.flush();
00698 
00699     if(_statistics)
00700     {
00701         _statistics->getElem(statSyncTime)->stop();
00702     }
00703 }

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 710 of file OSGRemoteAspect.cpp.

References _createdFunctors, _defaultCreatedFunction(), osg::TypeBase::getId(), and osg::osgTypedFunctionFunctor2CPtrRef().

00712 {
00713     while(type.getId() >= _createdFunctors.size())
00714     {
00715         _createdFunctors.push_back(
00716             osgTypedFunctionFunctor2CPtrRef
00717             <bool,FieldContainerPtr,RemoteAspect * >
00718             (&_defaultCreatedFunction));
00719     }
00720 
00721     _createdFunctors[type.getId()] = func;
00722 }

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 729 of file OSGRemoteAspect.cpp.

References _defaultDestroyedFunction(), _destroyedFunctors, osg::TypeBase::getId(), and osg::osgTypedFunctionFunctor2CPtrRef().

00731 {
00732     while(type.getId() >= _destroyedFunctors.size())
00733     {
00734         _destroyedFunctors.push_back(osgTypedFunctionFunctor2CPtrRef < bool,
00735                                              FieldContainerPtr, RemoteAspect * > (&_defaultDestroyedFunction));
00736     }
00737 
00738     _destroyedFunctors[type.getId()] = func;
00739 }

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 746 of file OSGRemoteAspect.cpp.

References _changedFunctors, _defaultChangedFunction(), osg::TypeBase::getId(), and osg::osgTypedFunctionFunctor2CPtrRef().

Referenced by osg::ClusterServer::start().

00748 {
00749     while(type.getId() >= _changedFunctors.size())
00750     {
00751         _changedFunctors.push_back(osgTypedFunctionFunctor2CPtrRef < bool,
00752                                            FieldContainerPtr,
00753                                            RemoteAspect * > (&_defaultChangedFunction));
00754     }
00755 
00756     _changedFunctors[type.getId()] = func;
00757 }

void RemoteAspect::addFieldFilter ( UInt32  typeId,
BitVector  mask 
) [static]

add a new field filter. The given fieldmaks will not be transfered

Definition at line 761 of file OSGRemoteAspect.cpp.

References _fieldFilter.

Referenced by osg::SHLChunk::onCreate().

00762 {
00763     _fieldFilter[typeId] |= mask;
00764 }

void RemoteAspect::subFieldFilter ( UInt32  typeId,
BitVector  mask 
) [static]

remove the filter for the given type and mask

Definition at line 768 of file OSGRemoteAspect.cpp.

References _fieldFilter.

00769 {
00770     _fieldFilter[typeId] &= ~mask;
00771 }

void RemoteAspect::restoreChangeList ( ChangeList tocl  )  [static]

creates a changelist from the store and merges this to the changelist.

Definition at line 775 of file OSGRemoteAspect.cpp.

References _clStore, osg::ChangeList::addAddRefd(), osg::ChangeList::addChanged(), osg::ChangeList::addCreated(), osg::FieldBits::AllFields, osg::FieldContainerFactory::getContainer(), osg::NullFC, and osg::FieldContainerFactory::the().

Referenced by osg::ChangeList::addChanged().

00776 {
00777     for(clStoreIt i = _clStore.begin();i != _clStore.end(); ++i)
00778     {
00779         UInt32 id = (*i).first;
00780         FieldContainerPtr fc = FieldContainerFactory::the()->getContainer(id);
00781         if(fc != NullFC)
00782         {
00783             tocl->addCreated(id);
00784             for(UInt32 j=0;j<(*i).second;++j)
00785                 tocl->addAddRefd(fc);
00786             tocl->addChanged(fc, FieldBits::AllFields);
00787         }
00788     }
00789 }

void RemoteAspect::storeChangeList ( ChangeList cl  )  [static]

store all created, addRefd, subRefd, destroyed into the clStore.

Definition at line 793 of file OSGRemoteAspect.cpp.

References _clStore, osg::ChangeList::beginAddRefd(), osg::ChangeList::beginCreated(), osg::ChangeList::beginDestroyed(), osg::ChangeList::beginSubRefd(), osg::ChangeList::endAddRefd(), osg::ChangeList::endCreated(), osg::ChangeList::endDestroyed(), and osg::ChangeList::endSubRefd().

Referenced by osg::ChangeList::addChanged().

00794 {
00795     // created
00796     for(ChangeList::idrefd_const_iterator i = cl->beginCreated(); i != cl->endCreated(); ++i)
00797     {
00798         clStoreIt ci = _clStore.find(*i);
00799         if(ci == _clStore.end())
00800             _clStore.insert(std::pair<UInt32, UInt32>(*i, 0));
00801     }
00802 
00803     // addRef
00804     for(ChangeList::idrefd_const_iterator i = cl->beginAddRefd(); i != cl->endAddRefd(); ++i)
00805     {
00806         clStoreIt ci = _clStore.find(*i);
00807         if(ci != _clStore.end())
00808             (*ci).second++;
00809         //else
00810         //    FWARNING(("Called addRef on a not created fieldcontainer!\n"));
00811     }
00812     
00813     // subRef
00814     for(ChangeList::idrefd_const_iterator i = cl->beginSubRefd(); i != cl->endSubRefd(); ++i)
00815     {
00816         clStoreIt ci = _clStore.find(*i);
00817         if(ci != _clStore.end())
00818             (*ci).second--;
00819         //else
00820         //    FWARNING(("Called subRef on a not created fieldcontainer!\n"));
00821     }
00822     
00823     // destroyed
00824     for(ChangeList::idrefd_const_iterator i = cl->beginDestroyed(); i != cl->endDestroyed(); ++i)
00825     {
00826         clStoreIt ci = _clStore.find(*i);
00827         if(ci != _clStore.end())
00828             _clStore.erase(ci);
00829     }
00830 }

UInt32 RemoteAspect::getStoreSize ( void   )  [static]

Definition at line 832 of file OSGRemoteAspect.cpp.

References _clStore.

00833 {
00834     return _clStore.size();
00835 }

RemoteAspect::clStoreMap & RemoteAspect::getStore ( void   )  [static]

Definition at line 837 of file OSGRemoteAspect.cpp.

References _clStore.

00838 {
00839     return _clStore;
00840 }

void RemoteAspect::createCurrentStateChangeList ( const FieldContainerPtr start,
ChangeList cl 
) [static]

Definition at line 842 of file OSGRemoteAspect.cpp.

References osg::ChangeList::addAddRefd(), osg::ChangeList::addChanged(), osg::ChangeList::addCreated(), osg::FieldBits::AllFields, osg::ChangeList::clearAll(), osg::FieldContainerPtrBase::getFieldContainerId(), osg::FieldContainerFactory::getFieldContainerStore(), osg::FieldContainerPtrBase::getRefCount(), osg::NullFC, and osg::FieldContainerFactory::the().

00843 {
00844     if(cl == NULL)
00845         return;
00846 
00847     cl->clearAll();
00848     const std::vector<FieldContainerPtr> &fcs = *FieldContainerFactory::the()->getFieldContainerStore();
00849 
00850     bool found_start = false;
00851     for(unsigned int i=0;i<fcs.size();++i)
00852     {
00853         FieldContainerPtr fc = fcs[i];
00854         if(fc != NullFC)
00855         {
00856             if(fc == start)
00857                 found_start = true;
00858 
00859             if(found_start)
00860             {
00861                 cl->addCreated(fc.getFieldContainerId());
00862                 for(UInt32 j=0;j<fc.getRefCount();++j)
00863                     cl->addAddRefd(fc);
00864                 cl->addChanged(fc, FieldBits::AllFields);
00865             }
00866         }
00867     } 
00868 }

void RemoteAspect::setStatistics ( StatCollector statistics  ) 

Set statistics collector

Definition at line 875 of file OSGRemoteAspect.cpp.

References _statistics.

Referenced by osg::ClusterWindow::init(), and osg::ClusterWindow::setStatistics().

00876 {
00877     _statistics = statistics;
00878 }

bool RemoteAspect::callCreated ( FieldContainerPtr fcp  )  [protected]

Call created functor for a given FieldContainer

See also:
registerCreated

Definition at line 887 of file OSGRemoteAspect.cpp.

References _createdFunctors, and _defaultCreatedFunction().

Referenced by receiveSync().

00888 {
00889     bool    result;
00890     UInt32  uiFunctorIndex = fcp->getType().getId();
00891 
00892     if(uiFunctorIndex < _createdFunctors.size())
00893     {
00894         result = _createdFunctors[uiFunctorIndex].call(fcp, this);
00895     }
00896     else
00897     {
00898         result = _defaultCreatedFunction(fcp, this);
00899     }
00900 
00901     return result;
00902 }

bool RemoteAspect::callDestroyed ( FieldContainerPtr fcp  )  [protected]

Call destroyed functor for a given FieldContainer

See also:
registerDestroyed

Definition at line 908 of file OSGRemoteAspect.cpp.

References _defaultDestroyedFunction(), and _destroyedFunctors.

Referenced by receiveSync(), and ~RemoteAspect().

00909 {
00910     bool    result;
00911     UInt32  uiFunctorIndex = fcp->getType().getId();
00912 
00913     if(uiFunctorIndex < _destroyedFunctors.size())
00914     {
00915         result = _destroyedFunctors[uiFunctorIndex].call(fcp, this);
00916     }
00917     else
00918     {
00919         result = _defaultDestroyedFunction(fcp, this);
00920     }
00921 
00922     return result;
00923 }

bool RemoteAspect::callChanged ( FieldContainerPtr fcp  )  [protected]

Call changed functor for a given FieldContainer

See also:
registerChanged

Definition at line 929 of file OSGRemoteAspect.cpp.

References _changedFunctors, and _defaultChangedFunction().

Referenced by receiveSync().

00930 {
00931     bool    result;
00932     UInt32  uiFunctorIndex = fcp->getType().getId();
00933 
00934     if(uiFunctorIndex < _changedFunctors.size())
00935     {
00936         result = _changedFunctors[uiFunctorIndex].call(fcp, this);
00937     }
00938     else
00939     {
00940         result = _defaultChangedFunction(fcp, this);
00941     }
00942 
00943     return result;
00944 }

void RemoteAspect::handleFCMapping ( Connection connection  )  [private]

This is called if a fc was edited that was created by another aspect

Definition at line 949 of file OSGRemoteAspect.cpp.

References _mappedFC, _remoteFC, IDMAPPING, and osg::BinaryDataHandler::putValue().

Referenced by sendSync().

00950 {
00951     UInt8  cmd;
00952     UInt32 remoteId;
00953     UInt32 remoteAspect;
00954     RemoteFCMapT::iterator remoteFCI;
00955 
00956     for(remoteFCI = _remoteFC.begin() ;
00957         remoteFCI != _remoteFC.end() ;
00958         ++remoteFCI)
00959     {
00960         remoteId     = (UInt32)(remoteFCI->second);
00961         remoteAspect = (UInt32)(remoteFCI->second>>32);
00962 
00963         cmd = IDMAPPING;
00964         connection.putValue(cmd);
00965         connection.putValue(remoteFCI->first);
00966         connection.putValue(remoteAspect);
00967         connection.putValue(remoteId);
00968 
00969         _mappedFC.insert(remoteFCI->first);
00970     }
00971     _remoteFC.clear();
00972 }

void RemoteAspect::clearFCMapping ( UInt32  localId,
UInt32  remoteId 
) [private]

clear maps from local id

Definition at line 976 of file OSGRemoteAspect.cpp.

References _localFC, _mappedFC, _receivedFC, _remoteFC, and _sentFC.

Referenced by receiveSync(), and sendSync().

00977 {
00978     _mappedFC.erase(localId);
00979     _sentFC.erase(localId);
00980     _receivedFC.erase(localId);
00981 
00982     if(!remoteId)
00983     {
00984         RemoteFCMapT::iterator remoteFCI=_remoteFC.find(localId);
00985         if(remoteFCI != _remoteFC.end())
00986             remoteId=static_cast<UInt32>(remoteFCI->second);
00987     }
00988     
00989     RemoteFCMapT::iterator remoteFCI=_remoteFC.find(localId);
00990     if(remoteFCI != _remoteFC.end())
00991         _remoteFC.erase(remoteFCI);
00992 
00993     LocalFCMapT::iterator localFCI=_localFC.find(remoteId);
00994     if(localFCI != _localFC.end())
00995         _localFC.erase(localFCI);
00996     
00997 }

bool RemoteAspect::getLocalId ( UInt32  remoteId,
UInt32 localId 
) [private]

get local id mapped from remote id

Definition at line 1001 of file OSGRemoteAspect.cpp.

References _localFC, and getFullRemoteId().

Referenced by receiveSync().

01003 {
01004     UInt64 fullRemoteId = getFullRemoteId(remoteId);
01005     LocalFCMapT::iterator localFCI=_localFC.find(fullRemoteId);
01006 
01007     if( localFCI != _localFC.end() )
01008     {
01009         localId=localFCI->second;
01010         return true;
01011     }
01012     else
01013     {
01014         return false;
01015     }
01016 }

UInt64 RemoteAspect::getFullRemoteId ( UInt32  remoteId  )  [private]

This is called if a fc was edited that was created by another aspect

Definition at line 1018 of file OSGRemoteAspect.cpp.

References _remoteAspectId.

Referenced by getLocalId(), osg::RemoteAspectFieldContainerMapper::map(), and receiveSync().

01019 {
01020     UInt64 remoteId=_remoteAspectId;
01021     remoteId<<=32;
01022     remoteId|=fcId;
01023     return remoteId;
01024 }

bool RemoteAspect::_defaultCreatedFunction ( FieldContainerPtr fcp,
RemoteAspect aspect 
) [static, private]

Default create functor

Definition at line 1037 of file OSGRemoteAspect.cpp.

References FDEBUG, and osg::FieldContainerPtrBase::getFieldContainerId().

Referenced by callCreated(), and registerCreated().

01038 {
01039     FDEBUG(("Created:%s %d\n", 
01040             fcp->getType().getName().str(),
01041             fcp.getFieldContainerId()))
01042     return true;
01043 }

bool RemoteAspect::_defaultDestroyedFunction ( FieldContainerPtr fcp,
RemoteAspect aspect 
) [static, private]

Default destroyed functor

Definition at line 1047 of file OSGRemoteAspect.cpp.

References FDEBUG, and osg::FieldContainerPtrBase::getFieldContainerId().

Referenced by callDestroyed(), and registerDestroyed().

01049 {
01050     FDEBUG(("Destroyed:%s %d\n",
01051             fcp->getType().getName().str(),
01052             fcp.getFieldContainerId()))
01053     return true;
01054 }

bool RemoteAspect::_defaultChangedFunction ( FieldContainerPtr fcp,
RemoteAspect aspect 
) [static, private]

Default changed functor

Definition at line 1058 of file OSGRemoteAspect.cpp.

References FDEBUG, and osg::FieldContainerPtrBase::getFieldContainerId().

Referenced by callChanged(), and registerChanged().

01059 {
01060     FDEBUG(("Changed:%s %d\n", 
01061             fcp->getType().getName().str(),
01062             fcp.getFieldContainerId()))
01063     return true;
01064 }

RemoteAspect& osg::RemoteAspect::operator= ( const RemoteAspect source  )  [private]


Friends And Related Function Documentation

friend class RemoteAspectFieldContainerMapper [friend]

Definition at line 221 of file OSGRemoteAspect.h.


Member Data Documentation

Aspect id

Definition at line 149 of file OSGRemoteAspect.h.

Referenced by receiveSync(), and sendSync().

remote id to fieldcontainer mapping

Definition at line 152 of file OSGRemoteAspect.h.

Referenced by clearFCMapping(), getLocalId(), osg::RemoteAspectFieldContainerMapper::map(), and receiveSync().

local to remote fieldcontainer mapping

Definition at line 154 of file OSGRemoteAspect.h.

Referenced by clearFCMapping(), handleFCMapping(), and receiveSync().

remote typeid mapping

Definition at line 156 of file OSGRemoteAspect.h.

Referenced by receiveSync().

indicates fc was sent

Definition at line 159 of file OSGRemoteAspect.h.

Referenced by clearFCMapping(), and sendSync().

indicates fc was received

Definition at line 161 of file OSGRemoteAspect.h.

Referenced by clearFCMapping(), receiveSync(), and ~RemoteAspect().

indicates remote knows this fc

Definition at line 164 of file OSGRemoteAspect.h.

Referenced by clearFCMapping(), handleFCMapping(), and sendSync().

indicates mapped type

Definition at line 166 of file OSGRemoteAspect.h.

Referenced by sendSync().

Aspect id

Definition at line 168 of file OSGRemoteAspect.h.

Referenced by getFullRemoteId(), and receiveSync().

fild filter

Definition at line 176 of file OSGRemoteAspect.h.

Referenced by addFieldFilter(), RemoteAspect(), sendSync(), and subFieldFilter().

std::vector<Functor> osg::RemoteAspect::_createdFunctors [protected]

Aspect id

Definition at line 177 of file OSGRemoteAspect.h.

Referenced by callCreated(), and registerCreated().

Aspect id

Definition at line 178 of file OSGRemoteAspect.h.

Referenced by callDestroyed(), and registerDestroyed().

std::vector<Functor> osg::RemoteAspect::_changedFunctors [protected]

Aspect id

Definition at line 179 of file OSGRemoteAspect.h.

Referenced by callChanged(), and registerChanged().

Aspect id

Definition at line 180 of file OSGRemoteAspect.h.

Referenced by receiveSync(), sendSync(), and setStatistics().

std::map< UInt32, UInt32 > RemoteAspect::_clStore [static, protected]

Aspect id

Definition at line 182 of file OSGRemoteAspect.h.

Referenced by getStore(), getStoreSize(), restoreChangeList(), and storeChangeList().

Definition at line 218 of file OSGRemoteAspect.h.

Referenced by receiveSync(), and sendSync().


The documentation for this class was generated from the following files:

Generated on Mon Mar 17 11:11:17 2008 for OpenSG by  doxygen 1.5.5