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

OSGDepthFirstStateAction.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 //----------------------------------------------------------------------------
00040 //    Includes
00041 //----------------------------------------------------------------------------
00042 
00043 #include "OSGDepthFirstStateAction.h"
00044 
00045 OSG_USING_NAMESPACE
00046 
00047 //==== PUBLIC ================================================================
00048 
00049 #ifdef OSG_NEWACTION_STATISTICS
00050 
00051 //----------------------------------------------------------------------------
00052 //    Statistics
00053 //----------------------------------------------------------------------------
00054 
00055 StatElemDesc<StatIntElem>
00056 DepthFirstStateAction::statStateClones  ("DepthFirstState::stateClones",
00057                                          "Number of state clones created"     );
00058 StatElemDesc<StatIntElem>
00059 DepthFirstStateAction::statStateRestores("DepthFirstState::statStateRestores",
00060                                          "Number of state restores"           );
00061 
00062 #endif /* OSG_NEWACTION_STATISTICS */
00063 
00064 //----------------------------------------------------------------------------
00065 //    Destructor
00066 //----------------------------------------------------------------------------
00067 
00071 DepthFirstStateAction::~DepthFirstStateAction(void)
00072 {
00073 }
00074 
00075 //----------------------------------------------------------------------------
00076 //    Create
00077 //----------------------------------------------------------------------------
00078 
00082 DepthFirstStateAction *
00083 DepthFirstStateAction::create(void)
00084 {
00085     return new DepthFirstStateAction();
00086 }
00087 
00088 //----------------------------------------------------------------------------
00089 //    Apply
00090 //----------------------------------------------------------------------------
00091 
00092 DepthFirstStateAction::ResultE
00093 DepthFirstStateAction::apply(NodePtr pRoot)
00094 {
00095     ResultE result = NewActionTypes::Continue;
00096 
00097     startEvent();
00098 
00099     result = startActors();
00100 
00101     if(result & NewActionTypes::Quit)
00102         return result;
00103 
00104     _itInitialState = getState  ();
00105     _itActiveState  = cloneState();
00106 
00107     // gained refs: active, root
00108     incRefCount(_itActiveState, 2);
00109 
00110     _nodeStack.push_back(NodeStackEntry(pRoot, _itActiveState, 1));
00111 
00112     if((_extendLeaveActors.empty() == true) &&
00113        (_basicLeaveActors .empty() == true)    )
00114     {
00115         result = traverseEnter();
00116     }
00117     else
00118     {
00119         result = traverseEnterLeave();
00120     }
00121 
00122     setState(_itInitialState);
00123 
00124     // lost refs: active, current node
00125     decRefCount(_itActiveState, 2);
00126 
00127     _itActiveState   = _itInitialState;
00128     _stateClonedFlag = true;
00129 
00130     _nodeStack         .clear();
00131 #ifndef OSG_NEWACTION_STATESLOTINTERFACE
00132     _stateStore        .clear();
00133 #endif
00134     _stateRefCountStore.clear();
00135 
00136     if(result & NewActionTypes::Quit)
00137         return result;
00138 
00139     result = stopActors();
00140 
00141     stopEvent();
00142 
00143     return result;
00144 }
00145 
00146 //==== PROTECTED =============================================================
00147 //----------------------------------------------------------------------------
00148 //    Constructors
00149 //----------------------------------------------------------------------------
00150 
00154 DepthFirstStateAction::DepthFirstStateAction(void)
00155     : Inherited          (     ),
00156       _nodeStack         (     ),
00157       _stateRefCountStore(     ),
00158 #ifndef OSG_NEWACTION_STATESLOTINTERFACE
00159       _stateStore        (     ),
00160 #endif
00161       _itInitialState    (     ),
00162       _itActiveState     (     ),
00163       _stateClonedFlag   (false),
00164       _extendEnterActors (     ),
00165       _extendLeaveActors (     ),
00166       _basicEnterActors  (     ),
00167       _basicLeaveActors  (     )
00168 {
00169 }
00170 
00171 //----------------------------------------------------------------------------
00172 //    Events
00173 //----------------------------------------------------------------------------
00174 
00180 void
00181 DepthFirstStateAction::addExtendEvent(ExtendActorBase *pActor, UInt32 actorIndex)
00182 {
00183     ExtendActorStoreIt itActors  = beginExtend();
00184     ExtendActorStoreIt endActors = beginExtend() + actorIndex;
00185 
00186     ExtendActorStoreIt itEnter   = _extendEnterActors.begin();
00187     ExtendActorStoreIt itLeave   = _extendLeaveActors.begin();
00188 
00189     for(; itActors != endActors; ++itActors)
00190     {
00191         if((*itActors)->getEnterNodeFlag() == true)
00192             ++itEnter;
00193 
00194         if((*itActors)->getLeaveNodeFlag() == true)
00195             ++itLeave;
00196     }
00197 
00198     if(pActor->getEnterNodeFlag() == true)
00199         _extendEnterActors.insert(itEnter, pActor);
00200 
00201     if(pActor->getLeaveNodeFlag() == true)
00202         _extendLeaveActors.insert(itLeave, pActor);
00203 }
00204 
00208 void
00209 DepthFirstStateAction::subExtendEvent(ExtendActorBase *pActor, UInt32 actorIndex)
00210 {
00211     ExtendActorStoreIt itEnter  = _extendEnterActors.begin();
00212     ExtendActorStoreIt endEnter = _extendEnterActors.end  ();
00213 
00214     ExtendActorStoreIt itLeave  = _extendLeaveActors.begin();
00215     ExtendActorStoreIt endLeave = _extendLeaveActors.end  ();
00216 
00217     for(; itEnter != endEnter; ++itEnter)
00218     {
00219         if(*itEnter == pActor)
00220         {
00221             _extendEnterActors.erase(itEnter);
00222 
00223             break;
00224         }
00225     }
00226 
00227     for(; itLeave != endLeave; ++itLeave)
00228     {
00229         if(*itLeave == pActor)
00230         {
00231             _extendLeaveActors.erase(itLeave);
00232 
00233             break;
00234         }
00235     }
00236 }
00237 
00243 void
00244 DepthFirstStateAction::addBasicEvent(BasicActorBase *pActor, UInt32 actorIndex)
00245 {
00246     BasicActorStoreIt itActors  = beginBasic();
00247     BasicActorStoreIt endActors = beginBasic() + actorIndex;
00248 
00249     BasicActorStoreIt itEnter   = _basicEnterActors.begin();
00250     BasicActorStoreIt itLeave   = _basicLeaveActors.begin();
00251 
00252     for(; itActors != endActors; ++itActors)
00253     {
00254         if((*itActors)->getEnterNodeFlag() == true)
00255             ++itEnter;
00256 
00257         if((*itActors)->getLeaveNodeFlag() == true)
00258             ++itLeave;
00259     }
00260 
00261     if(pActor->getEnterNodeFlag() == true)
00262         _basicEnterActors.insert(itEnter, pActor);
00263 
00264     if(pActor->getLeaveNodeFlag() == true)
00265         _basicLeaveActors.insert(itLeave, pActor);
00266 }
00267 
00271 void
00272 DepthFirstStateAction::subBasicEvent(BasicActorBase *pActor, UInt32 actorIndex)
00273 {
00274     BasicActorStoreIt itEnter  = _basicEnterActors.begin();
00275     BasicActorStoreIt endEnter = _basicEnterActors.end  ();
00276 
00277     BasicActorStoreIt itLeave  = _basicLeaveActors.begin();
00278     BasicActorStoreIt endLeave = _basicLeaveActors.end  ();
00279 
00280     for(; itEnter != endEnter; ++itEnter)
00281     {
00282         if(*itEnter == pActor)
00283         {
00284             _basicEnterActors.erase(itEnter);
00285 
00286             break;
00287         }
00288     }
00289 
00290     for(; itLeave != endLeave; ++itLeave)
00291     {
00292         if(*itLeave == pActor)
00293         {
00294             _basicLeaveActors.erase(itLeave);
00295 
00296             break;
00297         }
00298     }
00299 }
00300 
00301 void
00302 DepthFirstStateAction::startEvent(void)
00303 {
00304     Inherited::startEvent();
00305 
00306 #ifdef OSG_NEWACTION_STATISTICS
00307     getStatistics()->getElem(statStateClones  )->reset();
00308     getStatistics()->getElem(statStateRestores)->reset();
00309 #endif /* OSG_NEWACTION_STATISTICS */
00310 }
00311 
00312 void
00313 DepthFirstStateAction::stopEvent(void)
00314 {
00315     Inherited::stopEvent();
00316 }
00317 
00318 
00322 void
00323 DepthFirstStateAction::beginEditStateEvent(ActorBase *pActor, UInt32 actorId)
00324 {
00325     if(_stateClonedFlag == false)
00326     {
00327 #ifdef OSG_NEWACTION_STATISTICS
00328         getStatistics()->getElem(statStateClones)->inc();
00329 #endif /* OSG_NEWACTION_STATISTICS */
00330 
00331         _stateClonedFlag = true;
00332 
00333         StateRefCountStoreIt itClonedState = cloneState();
00334 
00335         // gained refs: active and current node
00336         incRefCount(itClonedState, 2);
00337 
00338         // lost refs: active and current node
00339         decRefCount(_itActiveState, 2);
00340 
00341         _nodeStack.back().setStateRefCount(itClonedState);
00342 
00343         _itActiveState = itClonedState;
00344     }
00345 }
00346 
00350 void
00351 DepthFirstStateAction::endEditStateEvent(ActorBase *pActor, UInt32 actorId)
00352 {
00353 }
00354 
00355 //==== PRIVATE ===============================================================
00356 //----------------------------------------------------------------------------
00357 //    Helper Methods
00358 //----------------------------------------------------------------------------
00359 
00360 DepthFirstStateAction::ResultE
00361 DepthFirstStateAction::traverseEnter(void)
00362 {
00363     ResultE              result          = NewActionTypes::Continue;
00364     NodePtr              pNode;
00365     Int32                nodePass;        // pass over current node
00366     UInt32               multiPasses;     // requested passes over current node
00367     StateRefCountStoreIt itStateRefCount; // state for current node
00368 
00369     while((_nodeStack.empty() == false) && !(result & NewActionTypes::Quit))
00370     {
00371         pNode           = _nodeStack.back().getNode         ();
00372         nodePass        = _nodeStack.back().getPassCount    ();
00373         itStateRefCount = _nodeStack.back().getStateRefCount();
00374 
00375 #ifdef OSG_NEWACTION_STATISTICS
00376         getStatistics()->getElem(statNodesEnter)->inc();
00377 #endif /* OSG_NEWACTION_STATISTICS */
00378 
00379         if(itStateRefCount != _itActiveState)
00380         {
00381 #ifdef OSG_NEWACTION_STATISTICS
00382             getStatistics()->getElem(statStateRestores)->inc();
00383 #endif /* OSG_NEWACTION_STATISTICS */
00384 
00385             setState(itStateRefCount);
00386 
00387             // gained refs: active
00388             incRefCount(itStateRefCount);
00389 
00390             // lost refs: active
00391             decRefCount(_itActiveState);
00392 
00393             _itActiveState = itStateRefCount;
00394         }
00395 
00396         _stateClonedFlag = false;
00397 
00398         getChildrenList().setParentNode(pNode);
00399 
00400         result      = enterNode   (pNode, static_cast<UInt32>(nodePass - 1));
00401         multiPasses = getNumPasses(                                        );
00402 
00403         _nodeStack.pop_back();
00404 
00405         // only initial pass (nodePass == 1) can request multiPasses
00406         if((nodePass == 1) && (multiPasses > 1))
00407         {
00408             for(; multiPasses > 1; --multiPasses)
00409             {
00410                 // gained refs: additional pass
00411                 incRefCount(_itActiveState);
00412                 
00413                 _nodeStack.push_back(
00414                     NodeStackEntry(pNode, _itActiveState, multiPasses));
00415             }
00416         }
00417         
00418         pushChildren(pNode, result);
00419 
00420         // lost refs: current node
00421         decRefCount(_itActiveState);
00422     }
00423 
00424     return result;
00425 }
00426 
00427 DepthFirstStateAction::ResultE
00428 DepthFirstStateAction::traverseEnterLeave(void)
00429 {
00430     ResultE              result          = NewActionTypes::Continue;
00431     Int32                nodePass;        // pass over current node
00432     UInt32               multiPasses;     // requested passes over current node
00433     NodePtr              pNode;
00434     StateRefCountStoreIt itStateRefCount;
00435 
00436     while((_nodeStack.empty() == false) && !(result & NewActionTypes::Quit))
00437     {
00438         pNode           = _nodeStack.back().getNode         ();
00439         nodePass        = _nodeStack.back().getPassCount    ();
00440         itStateRefCount = _nodeStack.back().getStateRefCount();
00441 
00442         if(itStateRefCount != _itActiveState)
00443         {
00444 #ifdef OSG_NEWACTION_STATISTICS
00445             getStatistics()->getElem(statStateRestores)->inc();
00446 #endif /* OSG_NEWACTION_STATISTICS */
00447 
00448             setState(itStateRefCount);
00449 
00450             // gained refs: active
00451             incRefCount(itStateRefCount);
00452 
00453             // lost refs: active
00454             decRefCount(_itActiveState);
00455 
00456             _itActiveState = itStateRefCount;
00457         }
00458 
00459         getChildrenList().setParentNode(pNode);
00460 
00461         if(nodePass > 0)
00462         {
00463             // positive pass -> enter node
00464             
00465 #ifdef OSG_NEWACTION_STATISTICS
00466             getStatistics()->getElem(statNodesEnter)->inc();
00467 #endif /* OSG_NEWACTION_STATISTICS */
00468             
00469             _stateClonedFlag = false;
00470 
00471             result      = enterNode   (pNode, static_cast<UInt32>(nodePass - 1));
00472             multiPasses = getNumPasses(                                        );
00473 
00474             // only initial pass (nodePass == 1) can request multiPass.
00475             if((nodePass == 1) && (multiPasses > 1))
00476             {
00477                 // remove current node from stack
00478                 _nodeStack.pop_back();
00479                 
00480                 for(; multiPasses > 1; -- multiPasses)
00481                 {
00482                     // gained refs: addtional passs
00483                     incRefCount(_itActiveState);
00484                     
00485                     _nodeStack.push_back(
00486                         NodeStackEntry(pNode, _itActiveState, multiPasses));
00487                 }
00488                 
00489                 // readd current node - with negative pass -> leave
00490                 _nodeStack.push_back(
00491                     NodeStackEntry(pNode, _itActiveState, -nodePass));
00492             }
00493             else
00494             {
00495                 // change current node passCount to negative -> leave
00496                 _nodeStack.back().setPassCount(-nodePass);
00497             }
00498             
00499             pushChildren(pNode, result);
00500         }
00501         else
00502         {
00503             // negative pass -> leave node
00504 
00505 #ifdef OSG_NEWACTION_STATISTICS
00506             getStatistics()->getElem(statNodesLeave)->inc();
00507 #endif /* OSG_NEWACTION_STATISTICS */
00508             
00509             _stateClonedFlag = true;
00510 
00511             result = leaveNode(pNode, static_cast<UInt32>(-nodePass - 1));
00512 
00513             _nodeStack.pop_back();
00514 
00515             // lost refs: current node
00516             decRefCount(_itActiveState);
00517         }
00518     }
00519 
00520     return result;
00521 }
00522 
00523 void
00524 DepthFirstStateAction::pushChildren(const NodePtr &pNode, ResultE result)
00525 {
00526     if(result & (NewActionTypes::Skip  |
00527                  NewActionTypes::Break |
00528                  NewActionTypes::Quit   ))
00529     {
00530         setChildrenListEnabled(false);
00531         setNumPasses          (1    );
00532 
00533         getExtraChildrenList().clear();
00534 
00535         return;
00536     }
00537 
00538     ChildrenList      &cl  = getChildrenList     ();
00539     ExtraChildrenList &ecl = getExtraChildrenList();
00540 
00541     if(getChildrenListEnabled() == true)
00542     {
00543         for(UInt32 i = 0, size = cl.getSize(); i < size; ++i)
00544         {
00545             if(( cl.getActive(i)                                 == true  ) &&
00546                ( cl.getChild (i)                                 != NullFC) &&
00547                ((cl.getChild (i)->getTravMask() & getTravMask()) != 0     )   )
00548             {
00549                 // gained refs: child
00550                 incRefCount(_itActiveState);
00551 
00552                 _nodeStack.push_back(
00553                     NodeStackEntry(cl.getChild(i), _itActiveState, 1));
00554             }
00555         }
00556     }
00557     else
00558     {
00559         MFNodePtr::const_iterator itChildren  = pNode->getMFChildren()->begin();
00560         MFNodePtr::const_iterator endChildren = pNode->getMFChildren()->end  ();
00561 
00562         for(; itChildren != endChildren; ++itChildren)
00563         {
00564             if((  *itChildren                                  != NullFC) &&
00565                (((*itChildren)->getTravMask() & getTravMask()) != 0     )   )
00566             {
00567                 // gained refs: child
00568                 incRefCount(_itActiveState);
00569 
00570                 _nodeStack.push_back(
00571                     NodeStackEntry(*itChildren, _itActiveState, 1));
00572             }
00573         }
00574     }
00575 
00576     for(UInt32 i = 0, size = ecl.getSize(); i < size; ++i)
00577     {
00578         if(( ecl.getActive(i)                                 == true  ) &&
00579            ( ecl.getChild (i)                                 != NullFC) &&
00580            ((ecl.getChild (i)->getTravMask() & getTravMask()) != 0     )   )
00581         {
00582             // gained refs: extra child
00583             incRefCount(_itActiveState);
00584 
00585             _nodeStack.push_back(
00586                 NodeStackEntry(ecl.getChild(i), _itActiveState, 1));
00587         }
00588     }
00589 
00590     setChildrenListEnabled(false);
00591     ecl.clear             (     );
00592     setNumPasses          (1    );
00593 }
00594 
00595 /*------------------------------------------------------------------------*/
00596 /*                              cvs id's                                  */
00597 
00598 #ifdef OSG_SGI_CC
00599 #pragma set woff 1174
00600 #endif
00601 
00602 #ifdef OSG_LINUX_ICC
00603 #pragma warning(disable : 177)
00604 #endif
00605 
00606 namespace
00607 {
00608     static Char8 cvsid_cpp       [] = "@(#)$Id: OSGDepthFirstStateAction.cpp,v 1.2 2004/09/17 14:09:42 neumannc Exp $";
00609     static Char8 cvsid_hpp       [] = OSGDEPTHFIRSTSTATEACTION_HEADER_CVSID;
00610     static Char8 cvsid_inl       [] = OSGDEPTHFIRSTSTATEACTION_INLINE_CVSID;
00611 }
00612 
00613 #ifdef OSG_LINUX_ICC
00614 #pragma warning(enable : 177)
00615 #endif
00616 
00617 #ifdef OSG_SGI_CC
00618 #pragma reset woff 1174
00619 #endif

Generated on Thu Aug 25 04:02:47 2005 for OpenSG by  doxygen 1.4.3