fixed: auto_ptr -> unique_ptr
[opensg.git] / Source / System / Cluster / Base / OSGRemoteAspect.cpp
blob49f89bcd1277636356b03c54101ed72d05111e10
1 /*---------------------------------------------------------------------------*\
2 * OpenSG *
3 * *
4 * *
5 * Copyright (C) 2000-2002 by the OpenSG Forum *
6 * *
7 * www.opensg.org *
8 * *
9 * contact: dirk@opensg.org, gerrit.voss@vossg.org, jbehr@zgdv.de *
10 * *
11 \*---------------------------------------------------------------------------*/
12 /*---------------------------------------------------------------------------*\
13 * License *
14 * *
15 * This library is free software; you can redistribute it and/or modify it *
16 * under the terms of the GNU Library General Public License as published *
17 * by the Free Software Foundation, version 2. *
18 * *
19 * This library is distributed in the hope that it will be useful, but *
20 * WITHOUT ANY WARRANTY; without even the implied warranty of *
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
22 * Library General Public License for more details. *
23 * *
24 * You should have received a copy of the GNU Library General Public *
25 * License along with this library; if not, write to the Free Software *
26 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *
27 * *
28 \*---------------------------------------------------------------------------*/
29 /*---------------------------------------------------------------------------*\
30 * Changes *
31 * *
32 * *
33 * *
34 * *
35 * *
36 * *
37 \*---------------------------------------------------------------------------*/
39 #include <stdlib.h>
40 #include <stdio.h>
42 #include "OSGConfig.h"
43 #include "OSGClusterException.h"
44 #include "OSGFieldDescriptionBase.h"
45 #include "OSGRemoteAspect.h"
46 #include "OSGLog.h"
47 #include "OSGWindow.h"
48 #include "OSGMaterial.h"
49 #include "OSGConnection.h"
50 #include "OSGStatCollector.h"
52 #include <map>
54 #define OSG_REMOTE_ASPECT_SILENT 1
56 OSG_USING_NAMESPACE
58 /** \class OSG::RemoteAspect
59 * \ingroup GrpSystemCluster
60 * \brief Remote aspect controll class
62 * The RemoteAspecet is used to synchronize changes of FieldContainers
63 * with remote hosts. All changes stored in the current change list
64 * are send to a Connection.
66 * It is possible to send changes in both directions.
68 **/
70 RemoteAspect::FieldFilter RemoteAspect::_fieldFilter;
72 StatElemDesc<StatTimeElem> RemoteAspect::statSyncTime
73 ("remoteSyncTime", "time for scenegraph distribution");
75 /*-------------------------------------------------------------------------*/
76 /* constructor destructor */
78 /*! Constructor
81 RemoteAspect::RemoteAspect(UInt32 aspectId) :
82 _aspectId(aspectId),
84 _localFC(),
85 _remoteFC(),
86 _localType(),
88 _sentFC(),
89 _receivedFC(),
90 _mappedFC(),
91 _mappedType(),
93 _remoteAspectId(0),
95 _createdFunctors(),
96 _destroyedFunctors(),
97 _changedFunctors(),
98 _statistics(NULL)
102 /*! Destructor
104 RemoteAspect::~RemoteAspect(void)
106 FieldContainerFactoryBase *pFactory = FieldContainerFactory::the();
107 IdSetT::iterator i;
109 FieldContainer *fcPtr = NULL;
111 // subRef received field container
112 for(i = _receivedFC.begin(); i != _receivedFC.end(); i++)
114 fcPtr = pFactory->getContainer(*i);
116 if(fcPtr != NULL)
118 callDestroyed(fcPtr);
120 fcPtr->resolveLinks();
124 // subRef received field container
125 for(i = _receivedFC.begin(); i != _receivedFC.end(); i++)
127 fcPtr = pFactory->getContainer(*i);
129 if(fcPtr != NULL)
133 fcPtr->subReferenceUnresolved();
134 fcPtr = pFactory->getContainer(*i);
136 } while(fcPtr != NULL);
141 /*-------------------------------------------------------------------------*/
142 /* Remote aspect functionaliy */
144 /*! \e receiveSync reads changes from the given connection and
145 * applies them to the current thread aspect.
146 * Functors for registered types are called, if they occur in the
147 * sync stream.
149 * \see registerCreated registerChanged registerDeleted
152 void RemoteAspect::receiveSync(Connection &connection, bool applyToChangelist)
154 bool finish = false;
155 UInt8 cmd;
156 FieldContainerFactoryBase *fcFactory = FieldContainerFactory::the();
157 FieldContainerVector newContainers;
158 RemoteAspectFieldContainerMapper mapper;
159 ChangeList *pChangeList =
160 Thread::getCurrentChangeList();
162 if(_statistics)
164 _statistics->getElem(statSyncTime)->start();
167 connection.selectChannel();
168 connection.getValue(_remoteAspectId);
170 // register mapper into factory
171 mapper._remoteAspect = this;
173 fcFactory->setMapper(&mapper);
177 connection.getValue(cmd);
179 switch(cmd)
181 case SYNCENDED:
183 finish = true;
185 #ifndef OSG_REMOTE_ASPECT_SILENT
186 SLOG << "Receive SYNCENDED\n";
187 #endif
189 break;
191 case NEWTYPE:
193 receiveNewType(connection, fcFactory);
195 break;
197 case CREATED:
199 receiveCreated(connection, fcFactory, newContainers);
201 break;
203 case CHANGED:
205 receiveChanged(connection, fcFactory);
207 break;
209 case ADDREFED:
211 receiveAddRefed(connection, fcFactory, pChangeList);
213 break;
215 case SUBREFED:
217 receiveSubRefed(connection, fcFactory, pChangeList);
219 break;
221 case IDMAPPING:
223 receiveIdMapping(connection);
225 break;
227 default:
229 SFATAL << "Unknown tag:" << Int32(cmd) << std::endl;
230 throw RemoteSyncError();
234 while(!finish);
236 #ifndef OSG_REMOTE_ASPECT_SILENT
237 PLOG << std::flush;
238 #endif
240 pChangeList->commitDelayedSubRefs();
242 #ifdef OSG_DEBUG
243 FieldContainerVector::const_iterator fcIt = newContainers.begin();
244 FieldContainerVector::const_iterator fcEnd = newContainers.end ();
246 for(; fcIt != fcEnd; ++fcIt)
248 if((*fcIt)->getRefCount() <= 1)
250 SWARNING << "New container type '" << (*fcIt)->getType().getName()
251 << "' local id '" << (*fcIt)->getId()
252 << "' remote id '"
253 << static_cast<UInt32>(_remoteFC[(*fcIt)->getId()])
254 << "' dies because of missing ref counts."
255 << std::endl;
258 #endif // OSG_DEBUG
260 if(applyToChangelist)
262 Thread::getCurrentChangeList()->commitChanges(ChangedOrigin::Sync);
264 else
266 Thread::getCurrentChangeList()->commitChangesAndClear(ChangedOrigin::Sync);
269 // unregister mapper into factory
270 fcFactory->setMapper(NULL);
272 if(_statistics)
274 _statistics->getElem(statSyncTime)->stop();
278 /*! All changes from changeList are send to the connecteion except
279 * the fields which are filtered. Filters are used to avoid transmission
280 * of local states. e.g. GL variables.
283 void RemoteAspect::sendSync(Connection &connection, ChangeList *changeList)
285 FieldContainerFactoryBase *fcFactory = FieldContainerFactory::the();
287 if(_statistics)
289 _statistics->getElem(statSyncTime)->start();
292 if(!changeList)
294 changeList = OSG::Thread::getCurrentChangeList();
297 // tell my aspect id
298 connection.putValue(_aspectId);
300 sendIdMapping(connection);
302 ChangeList::ChangedStoreConstIt changedIt = changeList->beginCreated();
303 ChangeList::ChangedStoreConstIt changedEnd = changeList->endCreated ();
305 for(; changedIt != changedEnd; ++changedIt)
307 UInt32 localId = (*changedIt)->uiContainerId;
308 FieldContainer *fcPtr = fcFactory->getContainer(localId);
310 // fcPtr might be locally destroyed already or
311 // cluster local, no need to transmit it
312 if((fcPtr == NULL ) ||
313 (0x0000 == (fcPtr->getFieldFlags()->_bNamespaceMask &
314 FCLocal::Cluster )) )
316 continue;
319 if((*changedIt)->uiEntryDesc == ContainerChangeEntry::Create)
321 sendCreated(connection, fcPtr);
325 changedIt = changeList->begin();
326 changedEnd = changeList->end ();
328 for(; changedIt != changedEnd; ++changedIt)
330 UInt32 localId = (*changedIt)->uiContainerId;
331 FieldContainer *fcPtr = fcFactory->getContainer(localId);
333 // fcPtr might be cluster local, no need to transmit it.
334 // but we need to transmit subrefs for locally destroyed container
335 // so this test is different from the one above!
336 if((fcPtr != NULL ) &&
337 (0x0000 == (fcPtr->getFieldFlags()->_bNamespaceMask &
338 FCLocal::Cluster )) )
340 continue;
343 if((*changedIt)->uiEntryDesc == ContainerChangeEntry::AddReference)
345 sendAddRefed(connection, fcPtr, localId);
347 else if((*changedIt)->uiEntryDesc == ContainerChangeEntry::SubReference)
349 sendSubRefed(connection, fcPtr, localId);
351 else if((*changedIt)->uiEntryDesc == ContainerChangeEntry::Change &&
352 fcPtr != NULL )
354 sendChanged(connection, fcPtr, (*changedIt)->whichField);
358 UInt8 cmd = SYNCENDED;
359 connection.putValue(cmd);
361 #ifndef OSG_REMOTE_ASPECT_SILENT
362 SLOG << "Send SYNCENDED" << std::endl;
363 #endif
365 // write buffer
366 connection.flush();
368 if(_statistics)
370 _statistics->getElem(statSyncTime)->stop();
374 /*! The given functor is called when a create of the specified type
375 * is received.
377 * \see receiveSync
380 void RemoteAspect::registerCreated(const FieldContainerType &type,
381 const Functor &func)
383 while(type.getId() >= _createdFunctors.size())
385 _createdFunctors.push_back(&_defaultCreatedFunction);
388 _createdFunctors[type.getId()] = func;
391 /*! The given functor is called when a destroy of the specified type
392 * is received.
394 * \see receiveSync
397 void RemoteAspect::registerDestroyed(const FieldContainerType &type,
398 const Functor &func)
400 while(type.getId() >= _destroyedFunctors.size())
402 _destroyedFunctors.push_back(&_defaultDestroyedFunction);
405 _destroyedFunctors[type.getId()] = func;
408 /*! The given functor is called when a change of the specified type
409 * is received.
411 * \see receiveSync
414 void RemoteAspect::registerChanged(const FieldContainerType &type,
415 const Functor &func)
417 while(type.getId() >= _changedFunctors.size())
419 _changedFunctors.push_back(&_defaultChangedFunction);
422 _changedFunctors[type.getId()] = func;
425 /*! add a new field filter. The given fieldmaks will not be transfered
428 /*-------------------------------------------------------------------------*/
429 /* statistics */
431 /*! add a new field filter. The given fieldmaks will not be transfered
433 void RemoteAspect::addFieldFilter(UInt32 typeId, BitVector mask)
435 _fieldFilter[typeId] |= mask;
438 /*! remove the filter for the given type and mask
440 void RemoteAspect::subFieldFilter(UInt32 typeId, BitVector mask)
442 _fieldFilter[typeId] &= ~mask;
445 /*! Set statistics collector
448 void RemoteAspect::setStatistics(StatCollector *statistics)
450 OSG::setRefd(_statistics, statistics);
453 /*-------------------------------------------------------------------------*/
454 /* protected helpers */
456 /*! Call created functor for a given FieldContainer
458 * \see registerCreated
461 bool RemoteAspect::callCreated(FieldContainer * const fcp)
463 bool result;
464 UInt32 uiFunctorIndex = fcp->getType().getId();
466 if(uiFunctorIndex < _createdFunctors.size())
468 result = _createdFunctors[uiFunctorIndex](fcp, this);
470 else
472 result = _defaultCreatedFunction(fcp, this);
475 return result;
478 /*! Call destroyed functor for a given FieldContainer
480 * \see registerDestroyed
483 bool RemoteAspect::callDestroyed(FieldContainer * const fcp)
485 bool result;
486 UInt32 uiFunctorIndex = fcp->getType().getId();
488 if(uiFunctorIndex < _destroyedFunctors.size())
490 result = _destroyedFunctors[uiFunctorIndex](fcp, this);
492 else
494 result = _defaultDestroyedFunction(fcp, this);
497 return result;
500 /*! Call changed functor for a given FieldContainer
502 * \see registerChanged
505 bool RemoteAspect::callChanged(FieldContainer * const fcp)
507 bool result;
508 UInt32 uiFunctorIndex = fcp->getType().getId();
510 if(uiFunctorIndex < _changedFunctors.size())
512 result = _changedFunctors[uiFunctorIndex](fcp, this);
514 else
516 result = _defaultChangedFunction(fcp, this);
519 return result;
522 /*-------------------------------------------------------------------------*/
523 /* Receive Helper Functions */
525 void RemoteAspect::receiveNewType(Connection &con,
526 FieldContainerFactoryBase *fcFactory)
528 UInt32 remoteTypeId = 0;
529 UInt32 localTypeId = 0;
530 std::string typeName;
532 con.getValue(remoteTypeId);
533 con.getValue(typeName);
535 FieldContainerType *fcType = fcFactory->findType(typeName.c_str());
537 if(fcType != NULL)
539 localTypeId = fcType->getId();
541 _localType[remoteTypeId] = localTypeId;
543 else
545 SWARNING << "Unrecognized remote type '" << typeName
546 << "' remote type id '" << remoteTypeId
547 << "'." << std::endl;
550 #ifndef OSG_REMOTE_ASPECT_SILENT
551 SLOG << "Receive NEWTYPE: type name '" << typeName
552 << "' type id (r/l) '" << remoteTypeId
553 << "/" << localTypeId << "'\n";
554 #endif
557 void RemoteAspect::receiveCreated(Connection &con,
558 FieldContainerFactoryBase *fcFactory,
559 FieldContainerVector &newContainers)
561 UInt32 remoteTypeId = 0;
562 UInt32 localTypeId = 0;
563 UInt32 remoteId = 0;
565 con.getValue(remoteTypeId);
566 con.getValue(remoteId);
568 LocalTypeMapT::const_iterator localTypeIt = _localType.find(remoteTypeId);
569 FieldContainerType *fcType = NULL;
570 FieldContainerUnrecPtr fcPtr = NULL;
572 if(localTypeIt != _localType.end())
574 UInt64 fullRemoteId = getFullRemoteId(remoteId);
576 if(_localFC.find(fullRemoteId) == _localFC.end())
578 localTypeId = localTypeIt->second;
579 fcType = fcFactory->findType(localTypeId);
580 fcPtr = fcType->createContainer();
582 // remove this node, when aspect is removed
583 _receivedFC.insert(fcPtr->getId());
585 // local <-> remote mapping
586 _localFC [fullRemoteId ] = fcPtr->getId();
587 _remoteFC[fcPtr->getId()] = fullRemoteId;
589 callCreated(fcPtr);
591 newContainers.push_back(fcPtr);
593 #ifndef OSG_REMOTE_ASPECT_SILENT
594 SLOG << "Receive CREATED: type (r/l) '" << remoteTypeId
595 << "/" << localTypeId
596 << "' id (r/l) '" << remoteId << "/"
597 << (fcPtr != NULL ? fcPtr->getId() : 0)
598 << "' type name '"
599 << (fcType != NULL ? fcType->getName() : "")
600 << "'\n";
601 #endif
603 else
605 SWARNING << "Already created a local container ("
606 << _localFC[fullRemoteId] << ") for "
607 << "remote container id '" << remoteId
608 << "'" << std::endl;
611 else
613 SWARNING << "Unknown (remote) type id '" << remoteTypeId
614 << "' for (remote) container id '" << remoteId
615 << "'" << std::endl;
619 void RemoteAspect::receiveChanged(Connection &con,
620 FieldContainerFactoryBase *fcFactory)
622 UInt32 remoteId = 0;
623 UInt32 localId = 0;
624 BitVector fieldMask = 0;
625 UInt32 len = 0;
626 FieldContainer *fcPtr = NULL;
628 con.getValue(remoteId);
629 con.getValue(fieldMask);
630 con.getValue(len);
632 if(getLocalId(remoteId, localId))
634 fcPtr = fcFactory->getContainer(localId);
636 #ifndef OSG_REMOTE_ASPECT_SILENT
637 SLOG << "Receive CHANGED: id (r/l) '" << remoteId
638 << "/" << localId
639 << "' mask '0x"
640 << std::hex << fieldMask << std::dec
641 << "' len '" << len
642 << "' type name '"
643 << (fcPtr != NULL ? fcPtr->getType().getName() : "")
644 << "'\n";
645 #endif
647 if(fcPtr == NULL)
649 clearFCMapping(localId, remoteId);
651 char dummy;
653 while(len--)
654 con.get(&dummy, 1);
656 else
658 fcPtr->copyFromBin(con, fieldMask);
660 callChanged(fcPtr);
663 else
665 char dummy;
667 SWARNING << "Can not do CHANGED for unknown FC remote id "
668 << remoteId
669 << " skip "
670 << len
671 << " bytes."
672 << std::endl;
674 while(len--)
675 con.get(&dummy, 1);
679 void RemoteAspect::receiveAddRefed(Connection &con,
680 FieldContainerFactoryBase *fcFactory,
681 ChangeList *pChangeList)
683 UInt32 remoteId = 0;
684 UInt32 localId = 0;
685 FieldContainer *fcPtr = NULL;
687 con.getValue(remoteId);
689 if(getLocalId(remoteId, localId))
691 fcPtr = fcFactory->getContainer(localId);
693 #ifndef OSG_REMOTE_ASPECT_SILENT
694 SLOG << "Receive ADDREFED: id (r/l) '" << remoteId
695 << "/" << localId << "' type name '"
696 << (fcPtr != NULL ? fcPtr->getType().getName() : "")
697 << "'\n";
698 #endif
700 if(fcPtr == NULL)
702 clearFCMapping(localId, remoteId);
704 else
706 RecordedRefCountPolicy::addRef(fcPtr);
709 else
711 SWARNING << "Can not do ADDREFED for unknown FC remote id "
712 << remoteId << std::endl;
716 void RemoteAspect::receiveSubRefed(Connection &con,
717 FieldContainerFactoryBase *fcFactory,
718 ChangeList *pChangeList)
720 UInt32 remoteId = 0;
721 UInt32 localId = 0;
722 FieldContainer *fcPtr = NULL;
724 con.getValue(remoteId);
726 if(getLocalId(remoteId, localId))
728 fcPtr = fcFactory->getContainer(localId);
730 #ifndef OSG_REMOTE_ASPECT_SILENT
731 SLOG << "Receive SUBREFED: id (r/l) '" << remoteId
732 << "/" << localId << "' type name '"
733 << (fcPtr != NULL ? fcPtr->getType().getName() : "")
734 << "'\n";
735 #endif
737 if(fcPtr == NULL)
739 clearFCMapping(localId, remoteId);
741 else
743 pChangeList->addDelayedSubRef<RecordedRefCountPolicy>(fcPtr);
746 else
748 SWARNING << "Can not do SUBREFED for unknown FC remote id "
749 << remoteId << std::endl;
753 void RemoteAspect::receiveIdMapping(Connection &con)
755 UInt32 remoteId = 0;
756 UInt32 localId = 0;
757 UInt32 localAspect = 0;
759 con.getValue(remoteId);
760 con.getValue(localAspect);
761 con.getValue(localId);
763 #ifndef OSG_REMOTE_ASPECT_SILENT
764 SLOG << "Receive IDMAPPING: id (r/l) '" << remoteId
765 << "/" << localId
766 << "' local aspect '" << localAspect
767 << "'\n";
768 #endif
770 if(localAspect != _aspectId)
772 SFATAL << "ID mapping for wrong aspect" << std::endl;
775 // local <-> remote mapping
776 UInt64 fullRemoteId = getFullRemoteId(remoteId);
777 _localFC[fullRemoteId] = localId;
780 /*-------------------------------------------------------------------------*/
781 /* Send Helper Functions */
783 void RemoteAspect::sendCreated(Connection &con,
784 FieldContainer *fcPtr)
786 UInt8 cmd = 0;
787 UInt32 localTypeId = fcPtr->getTypeId();
788 UInt32 localId = fcPtr->getId();
790 if(_mappedType.count(localTypeId) == 0)
792 _mappedType.insert(localTypeId);
794 const std::string &typeName = fcPtr->getType().getName();
796 #ifndef OSG_REMOTE_ASPECT_SILENT
797 SLOG << "Send NEWTYPE: type name '" << typeName
798 << "' type id '" << localTypeId
799 << "'\n";
800 #endif
802 cmd = NEWTYPE;
803 con.putValue(cmd);
804 con.putValue(localTypeId);
805 con.putValue(typeName);
808 #ifndef OSG_REMOTE_ASPECT_SILENT
809 SLOG << "Send CREATED: type name '" << fcPtr->getType().getName()
810 << "' type id '" << localTypeId
811 << "' id '" << localId
812 << "'\n";
813 #endif
815 cmd = CREATED;
816 con.putValue(cmd);
817 con.putValue(localTypeId);
818 con.putValue(localId);
820 // sent container to create
821 _sentFC.insert(localId);
823 // fc is known by remote
824 _mappedFC.insert(localId);
827 void RemoteAspect::sendChanged(Connection &con,
828 FieldContainer *fcPtr,
829 BitVector changedMask)
831 UInt32 localId = fcPtr->getId();
833 if(_mappedFC.count(localId) == 0)
835 #ifndef OSG_REMOTE_ASPECT_SILENT
836 SLOG << "Container id '" << localId
837 << "' type '" << fcPtr->getType().getName()
838 << "' is not transmitted, dropping 'CHANGED'"
839 << std::endl;
840 #endif
841 return;
844 BitVector fieldMask =
845 changedMask & fcPtr->getFieldFlags()->_bClusterLocalFlags;
847 // apply field filter
848 FieldFilter::const_iterator filterI =
849 _fieldFilter.find(fcPtr->getType().getId());
851 if(filterI != _fieldFilter.end())
853 fieldMask &= TypeTraits<BitVector>::BitsSet ^ filterI->second;
856 if(fieldMask)
858 UInt8 cmd = CHANGED;
859 UInt32 len = UInt32(fcPtr->getBinSize(fieldMask));
861 #ifndef OSG_REMOTE_ASPECT_SILENT
862 SLOG << "Send CHANGED: type name '" << fcPtr->getType().getName()
863 << "' type id '" << fcPtr->getType().getId()
864 << "' id '" << localId
865 << "' mask '0x" << std::hex << fieldMask << std::dec
866 << "' len '" << len
867 << "'\n";
868 #endif
870 con.putValue(cmd );
871 con.putValue(localId ); // id
872 con.putValue(fieldMask); // mask
873 con.putValue(len );
875 fcPtr->copyToBin(con, fieldMask);
879 void RemoteAspect::sendAddRefed(Connection &con,
880 FieldContainer *fcPtr,
881 UInt32 localId)
883 if(_mappedFC.count(localId) == 0)
885 #ifndef OSG_REMOTE_ASPECT_SILENT
886 SLOG << "Container type '"
887 << (fcPtr != NULL ? fcPtr->getType().getName() : "")
888 << "' id '" << localId
889 << "' is not transmitted, dropping 'ADDREF'"
890 << std::endl;
891 #endif
892 return;
895 #ifndef OSG_REMOTE_ASPECT_SILENT
896 SLOG << "Send ADDREFD: type name '"
897 << (fcPtr != NULL ? fcPtr->getType().getName() : "")
898 << "' id '" << localId << "'\n";
899 #endif
901 UInt8 cmd = ADDREFED;
902 con.putValue(cmd );
903 con.putValue(localId);
906 void RemoteAspect::sendSubRefed(Connection &con,
907 FieldContainer *fcPtr,
908 UInt32 localId)
910 if(_mappedFC.count(localId) == 0)
912 #ifndef OSG_REMOTE_ASPECT_SILENT
913 SLOG << "Container type '"
914 << (fcPtr != NULL ? fcPtr->getType().getName() : "")
915 << "' id '" << localId
916 << "' is not transmitted, dropping 'SUBREF'"
917 << std::endl;
918 #endif
919 return;
922 #ifndef OSG_REMOTE_ASPECT_SILENT
923 SLOG << "Send SUBREFD: type name '"
924 << (fcPtr != NULL ? fcPtr->getType().getName() : "")
925 << "' id '" << localId << "'\n";
926 #endif
928 UInt8 cmd = SUBREFED;
929 con.putValue(cmd );
930 con.putValue(localId);
933 /*! This is called if a fc was edited that was created by another
934 aspect
936 void RemoteAspect::sendIdMapping(Connection &con)
938 UInt8 cmd = IDMAPPING;
939 UInt32 remoteId;
940 UInt32 remoteAspect;
941 RemoteFCMapT::const_iterator remoteFCIt = _remoteFC.begin();
942 RemoteFCMapT::const_iterator remoteFCEnd = _remoteFC.end ();
944 for(; remoteFCIt != remoteFCEnd; ++remoteFCIt)
946 remoteId = UInt32(remoteFCIt->second);
947 remoteAspect = UInt32(remoteFCIt->second >> 32);
949 #ifndef OSG_REMOTE_ASPECT_SILENT
950 SLOG << "Send IDMAPPING: localId '" << remoteFCIt->first
951 << "' remoteAspect '" << remoteAspect
952 << "' remoteId '" << remoteId
953 << "'\n";
954 #endif
956 con.putValue(cmd );
957 con.putValue(remoteFCIt->first);
958 con.putValue(remoteAspect );
959 con.putValue(remoteId );
961 _mappedFC.insert(remoteFCIt->first);
964 _remoteFC.clear();
967 /*-------------------------------------------------------------------------*/
968 /* Helper Functions */
970 /*! clear maps from local id
973 void RemoteAspect::clearFCMapping(UInt32 localId,UInt32 remoteId)
975 _mappedFC.erase(localId);
976 _sentFC .erase(localId);
978 _receivedFC.erase(localId);
980 if(!remoteId)
982 RemoteFCMapT::iterator remoteFCI=_remoteFC.find(localId);
984 if(remoteFCI != _remoteFC.end())
985 remoteId=static_cast<UInt32>(remoteFCI->second);
988 RemoteFCMapT::iterator remoteFCI=_remoteFC.find(localId);
990 if(remoteFCI != _remoteFC.end())
991 _remoteFC.erase(remoteFCI);
993 LocalFCMapT::iterator localFCI=_localFC.find(remoteId);
995 if(localFCI != _localFC.end())
996 _localFC.erase(localFCI);
999 /*! get local id mapped from remote id
1002 bool RemoteAspect::getLocalId(UInt32 remoteId,
1003 UInt32 &localId)
1005 UInt64 fullRemoteId = getFullRemoteId(remoteId);
1006 LocalFCMapT::iterator localFCI = _localFC.find(fullRemoteId);
1008 if( localFCI != _localFC.end() )
1010 localId=localFCI->second;
1011 return true;
1013 else
1015 return false;
1019 UInt64 RemoteAspect::getFullRemoteId(UInt32 fcId)
1021 UInt64 remoteId=_remoteAspectId;
1023 remoteId <<= 32;
1024 remoteId |= fcId;
1026 return remoteId;
1029 /*-------------------------------------------------------------------------*\
1030 - private -
1031 \*-------------------------------------------------------------------------*/
1033 #ifdef __sgi
1034 /* fcp is used only if the FDEBUG macro is not removed by the
1035 proprocessor. Switch off error for unused fcp parameter. */
1036 #pragma set woff 3201
1037 #endif
1039 /*! Default create functor
1042 bool RemoteAspect::_defaultCreatedFunction(FieldContainer * const fcp,
1043 RemoteAspect * )
1045 FDEBUG(("Created:%s %d\n",
1046 fcp->getType().getCName(),
1047 fcp->getId()))
1049 return true;
1052 /*! Default destroyed functor
1055 bool RemoteAspect::_defaultDestroyedFunction(FieldContainer * const fcp,
1056 RemoteAspect * )
1058 FDEBUG(("Destroyed:%s %d\n",
1059 fcp->getType().getCName(),
1060 fcp->getId()))
1062 return true;
1065 /*! Default changed functor
1068 bool RemoteAspect::_defaultChangedFunction(FieldContainer * const fcp,
1069 RemoteAspect * )
1071 FDEBUG(("Changed:%s %d\n",
1072 fcp->getType().getCName(),
1073 fcp->getId()))
1075 return true;
1078 #ifdef __sgi
1079 #pragma reset woff 3201
1080 #endif
1082 /*! Field container id mapper. This mapper maps remote field
1083 * container id to local ids.
1086 UInt32 RemoteAspectFieldContainerMapper::map(UInt32 uiId) const
1088 UInt32 mappedId;
1089 RemoteAspect::LocalFCMapT::const_iterator i;
1091 i = _remoteAspect->_localFC.find(_remoteAspect->getFullRemoteId(uiId));
1093 if(i == _remoteAspect->_localFC.end())
1095 SWARNING << "Can't find container id:" << uiId << std::endl;
1096 mappedId = 0;
1098 else
1100 mappedId = i->second;
1103 FDEBUG(("Map: %d to %d\n", uiId, mappedId))
1105 return mappedId;