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

OSGRemoteAspect.cpp

Go to the documentation of this file.
00001 /*---------------------------------------------------------------------------*\
00002  *                                OpenSG                                     *
00003  *                                                                           *
00004  *                                                                           *
00005  *             Copyright (C) 2000-2002 by the OpenSG Forum                   *
00006  *                                                                           *
00007  *                            www.opensg.org                                 *
00008  *                                                                           *
00009  *   contact: dirk@opensg.org, gerrit.voss@vossg.org, jbehr@zgdv.de          *
00010  *                                                                           *
00011 \*---------------------------------------------------------------------------*/
00012 /*---------------------------------------------------------------------------*\
00013  *                                License                                    *
00014  *                                                                           *
00015  * This library is free software; you can redistribute it and/or modify it   *
00016  * under the terms of the GNU Library General Public License as published    *
00017  * by the Free Software Foundation, version 2.                               *
00018  *                                                                           *
00019  * This library is distributed in the hope that it will be useful, but       *
00020  * WITHOUT ANY WARRANTY; without even the implied warranty of                *
00021  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU         *
00022  * Library General Public License for more details.                          *
00023  *                                                                           *
00024  * You should have received a copy of the GNU Library General Public         *
00025  * License along with this library; if not, write to the Free Software       *
00026  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.                 *
00027  *                                                                           *
00028 \*---------------------------------------------------------------------------*/
00029 /*---------------------------------------------------------------------------*\
00030  *                                Changes                                    *
00031  *                                                                           *
00032  *                                                                           *
00033  *                                                                           *
00034  *                                                                           *
00035  *                                                                           *
00036  *                                                                           *
00037 \*---------------------------------------------------------------------------*/
00038 
00039 #include <stdlib.h>
00040 #include <stdio.h>
00041 
00042 #include "OSGConfig.h"
00043 #include "OSGClusterException.h"
00044 #include "OSGFieldDescription.h"
00045 #include "OSGRemoteAspect.h"
00046 #include "OSGFieldContainer.h"
00047 #include "OSGLog.h"
00048 #include "OSGGeometry.h"
00049 #include "OSGTextureChunk.h"
00050 #include "OSGCubeTextureChunk.h"
00051 #include "OSGWindow.h"
00052 #include "OSGMaterial.h"
00053 #include "OSGVertexProgramChunk.h"
00054 #include "OSGFragmentProgramChunk.h"
00055 
00056 #include <map>
00057 
00058 OSG_USING_NAMESPACE
00059 
00072 RemoteAspect::FieldFilterT  RemoteAspect::_fieldFilter;
00073 std::map<UInt32, UInt32>    RemoteAspect::_clStore;
00074 
00075 StatElemDesc<StatTimeElem> RemoteAspect::statSyncTime
00076     ("remoteSyncTime", "time for scenegraph distribution");
00077 
00078 /*-------------------------------------------------------------------------*/
00079 /*                            constructor destructor                       */
00080 
00083 RemoteAspect::RemoteAspect(UInt32 aspectId) :
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 }
00126 
00129 RemoteAspect::~RemoteAspect(void)
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 }
00182 
00183 /*-------------------------------------------------------------------------*/
00184 /*                          Remote aspect functionaliy                     */
00185 
00193 void RemoteAspect::receiveSync(Connection &connection, bool applyToChangelist)
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 }
00501 
00506 void RemoteAspect::sendSync(Connection &connection, ChangeList *changeList)
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 }
00695 
00701 void RemoteAspect::registerCreated(const FieldContainerType &type,
00702                                    const Functor &func)
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 }
00714 
00720 void RemoteAspect::registerDestroyed(const FieldContainerType &type,
00721                                      const Functor &func)
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 }
00731 
00737 void RemoteAspect::registerChanged(const FieldContainerType &type,
00738                                    const Functor &func)
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 }
00749 
00752 void RemoteAspect::addFieldFilter( UInt32 typeId,BitVector mask)
00753 {
00754     _fieldFilter[typeId] |= mask;
00755 }
00756 
00759 void RemoteAspect::subFieldFilter( UInt32 typeId,BitVector mask)
00760 {
00761     _fieldFilter[typeId] &= ~mask;
00762 }
00763 
00766 void RemoteAspect::restoreChangeList(ChangeList *tocl)
00767 {
00768     for(clStoreIt i = _clStore.begin();i != _clStore.end(); ++i)
00769     {
00770         UInt32 id = (*i).first;
00771         FieldContainerPtr fc = FieldContainerFactory::the()->getContainer(id);
00772         if(fc != NullFC)
00773         {
00774             tocl->addCreated(id);
00775             for(UInt32 j=0;j<(*i).second;++j)
00776                 tocl->addAddRefd(fc);
00777             tocl->addChanged(fc, FieldBits::AllFields);
00778         }
00779     }
00780 }
00781 
00784 void RemoteAspect::storeChangeList(ChangeList *cl)
00785 {
00786     // created
00787     for(ChangeList::idrefd_const_iterator i = cl->beginCreated(); i != cl->endCreated(); ++i)
00788     {
00789         clStoreIt ci = _clStore.find(*i);
00790         if(ci == _clStore.end())
00791             _clStore.insert(std::pair<UInt32, UInt32>(*i, 0));
00792     }
00793 
00794     // addRef
00795     for(ChangeList::idrefd_const_iterator i = cl->beginAddRefd(); i != cl->endAddRefd(); ++i)
00796     {
00797         clStoreIt ci = _clStore.find(*i);
00798         if(ci != _clStore.end())
00799             (*ci).second++;
00800         //else
00801         //    FWARNING(("Called addRef on a not created fieldcontainer!\n"));
00802     }
00803     
00804     // subRef
00805     for(ChangeList::idrefd_const_iterator i = cl->beginSubRefd(); i != cl->endSubRefd(); ++i)
00806     {
00807         clStoreIt ci = _clStore.find(*i);
00808         if(ci != _clStore.end())
00809             (*ci).second--;
00810         //else
00811         //    FWARNING(("Called subRef on a not created fieldcontainer!\n"));
00812     }
00813     
00814     // destroyed
00815     for(ChangeList::idrefd_const_iterator i = cl->beginDestroyed(); i != cl->endDestroyed(); ++i)
00816     {
00817         clStoreIt ci = _clStore.find(*i);
00818         if(ci != _clStore.end())
00819             _clStore.erase(ci);
00820     }
00821 }
00822 
00823 UInt32 RemoteAspect::getStoreSize(void)
00824 {
00825     return _clStore.size();
00826 }
00827 
00828 RemoteAspect::clStoreMap &RemoteAspect::getStore(void)
00829 {
00830     return _clStore;
00831 }
00832 
00833 /*-------------------------------------------------------------------------*/
00834 /*                          statistics                                     */
00835 
00838 void RemoteAspect::setStatistics(StatCollector *statistics)
00839 {
00840     _statistics = statistics;
00841 }
00842 
00843 /*-------------------------------------------------------------------------*/
00844 /*                        protected helpers                                */
00845 
00850 bool RemoteAspect::callCreated(FieldContainerPtr &fcp)
00851 {
00852     bool    result;
00853     UInt32  uiFunctorIndex = fcp->getType().getId();
00854 
00855     if(uiFunctorIndex < _createdFunctors.size())
00856     {
00857         result = _createdFunctors[uiFunctorIndex].call(fcp, this);
00858     }
00859     else
00860     {
00861         result = _defaultCreatedFunction(fcp, this);
00862     }
00863 
00864     return result;
00865 }
00866 
00871 bool RemoteAspect::callDestroyed(FieldContainerPtr &fcp)
00872 {
00873     bool    result;
00874     UInt32  uiFunctorIndex = fcp->getType().getId();
00875 
00876     if(uiFunctorIndex < _destroyedFunctors.size())
00877     {
00878         result = _destroyedFunctors[uiFunctorIndex].call(fcp, this);
00879     }
00880     else
00881     {
00882         result = _defaultDestroyedFunction(fcp, this);
00883     }
00884 
00885     return result;
00886 }
00887 
00892 bool RemoteAspect::callChanged(FieldContainerPtr &fcp)
00893 {
00894     bool    result;
00895     UInt32  uiFunctorIndex = fcp->getType().getId();
00896 
00897     if(uiFunctorIndex < _changedFunctors.size())
00898     {
00899         result = _changedFunctors[uiFunctorIndex].call(fcp, this);
00900     }
00901     else
00902     {
00903         result = _defaultChangedFunction(fcp, this);
00904     }
00905 
00906     return result;
00907 }
00908 
00912 void RemoteAspect::handleFCMapping(Connection &connection)
00913 {
00914     UInt8  cmd;
00915     UInt32 remoteId;
00916     UInt32 remoteAspect;
00917     RemoteFCMapT::iterator remoteFCI;
00918 
00919     for(remoteFCI = _remoteFC.begin() ;
00920         remoteFCI != _remoteFC.end() ;
00921         ++remoteFCI)
00922     {
00923         remoteId     = (UInt32)(remoteFCI->second);
00924         remoteAspect = (UInt32)(remoteFCI->second>>32);
00925 
00926         cmd = IDMAPPING;
00927         connection.putValue(cmd);
00928         connection.putValue(remoteFCI->first);
00929         connection.putValue(remoteAspect);
00930         connection.putValue(remoteId);
00931 
00932         _mappedFC.insert(remoteFCI->first);
00933     }
00934     _remoteFC.clear();
00935 }
00936 
00939 void RemoteAspect::clearFCMapping(UInt32 localId,UInt32 remoteId)
00940 {
00941     _mappedFC.erase(localId);
00942     _sentFC.erase(localId);
00943     _receivedFC.erase(localId);
00944 
00945     if(!remoteId)
00946     {
00947         RemoteFCMapT::iterator remoteFCI=_remoteFC.find(localId);
00948         if(remoteFCI != _remoteFC.end())
00949             remoteId=static_cast<UInt32>(remoteFCI->second);
00950     }
00951     
00952     RemoteFCMapT::iterator remoteFCI=_remoteFC.find(localId);
00953     if(remoteFCI != _remoteFC.end())
00954         _remoteFC.erase(remoteFCI);
00955 
00956     LocalFCMapT::iterator localFCI=_localFC.find(remoteId);
00957     if(localFCI != _localFC.end())
00958         _localFC.erase(localFCI);
00959     
00960 }
00961 
00964 bool RemoteAspect::getLocalId(UInt32  remoteId,
00965                               UInt32 &localId)
00966 {
00967     UInt64 fullRemoteId = getFullRemoteId(remoteId);
00968     LocalFCMapT::iterator localFCI=_localFC.find(fullRemoteId);
00969 
00970     if( localFCI != _localFC.end() )
00971     {
00972         localId=localFCI->second;
00973         return true;
00974     }
00975     else
00976     {
00977         return false;
00978     }
00979 }
00980 
00981 UInt64 RemoteAspect::getFullRemoteId(UInt32 fcId)
00982 {
00983     UInt64 remoteId=_remoteAspectId;
00984     remoteId<<=32;
00985     remoteId|=fcId;
00986     return remoteId;
00987 }
00988 
00989 /*-------------------------------------------------------------------------*\
00990  -  private                                                                -
00991 \*-------------------------------------------------------------------------*/
00992 #ifdef __sgi
00993 /* fcp is used only if the FDEBUG macro is not removed by the
00994    proprocessor. Switch off error for unused fcp parameter. */
00995 #pragma set woff 3201
00996 #endif
00997 
01000 bool RemoteAspect::_defaultCreatedFunction(FieldContainerPtr &fcp, RemoteAspect *)
01001 {
01002     FDEBUG(("Created:%s %d\n", 
01003             fcp->getType().getName().str(),
01004             fcp.getFieldContainerId()))
01005     return true;
01006 }
01007 
01010 bool RemoteAspect::_defaultDestroyedFunction(FieldContainerPtr &fcp,
01011                                              RemoteAspect *)
01012 {
01013     FDEBUG(("Destroyed:%s %d\n",
01014             fcp->getType().getName().str(),
01015             fcp.getFieldContainerId()))
01016     return true;
01017 }
01018 
01021 bool RemoteAspect::_defaultChangedFunction(FieldContainerPtr &fcp, RemoteAspect *)
01022 {
01023     FDEBUG(("Changed:%s %d\n", 
01024             fcp->getType().getName().str(),
01025             fcp.getFieldContainerId()))
01026     return true;
01027 }
01028 
01029 #ifdef __sgi
01030 #pragma reset woff 3201
01031 #endif
01032 
01036 UInt32 RemoteAspectFieldContainerMapper::map(UInt32 uiId)
01037 {
01038     UInt32  mappedId;
01039     RemoteAspect::LocalFCMapT::iterator i;
01040 
01041     i = _remoteAspect->_localFC.find(
01042         _remoteAspect->getFullRemoteId(uiId));
01043     if(i == _remoteAspect->_localFC.end())
01044     {
01045         SWARNING << "Can't find container id:" << uiId << std::endl;
01046         mappedId = 0;
01047     }
01048     else
01049     {
01050         mappedId = i->second;
01051     }
01052 
01053     FDEBUG(("Map: %d to %d\n", uiId, mappedId)) 
01054 
01055     return mappedId;
01056 }
01057 
01058 /*-------------------------------------------------------------------------*/
01059 /*                              cvs id's                                   */
01060 
01061 #ifdef __sgi
01062 #pragma set woff 1174
01063 #endif
01064 #ifdef OSG_LINUX_ICC
01065 #pragma warning(disable : 177)
01066 #endif
01067 
01068 namespace
01069 {
01070     static Char8    cvsid_cpp[] = "@(#)$Id:$";
01071     static Char8    cvsid_hpp[] = OSGREMOTEASPECT_HEADER_CVSID;
01072 }

Generated on Thu Aug 25 04:09:07 2005 for OpenSG by  doxygen 1.4.3