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

OSGPriorityAction.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 "OSGPriorityAction.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 PriorityAction::statStateClones  ("PriorityAction::stateClones",
00057                                   "Number of state clones created");
00058 StatElemDesc<StatIntElem>
00059 PriorityAction::statStateRestores("PriorityAction::statStateRestores",
00060                                   "Number of state restores"          );
00061 
00062 #endif /* OSG_NEWACTION_STATISTICS */
00063 
00064 //----------------------------------------------------------------------------
00065 //    Destructor
00066 //----------------------------------------------------------------------------
00067 
00068 PriorityAction::~PriorityAction(void)
00069 {
00070 }
00071 
00072 //----------------------------------------------------------------------------
00073 //    Create
00074 //----------------------------------------------------------------------------
00075 
00079 PriorityAction *
00080 PriorityAction::create(void)
00081 {
00082     return new PriorityAction();
00083 }
00084 
00085 //----------------------------------------------------------------------------
00086 //    Apply
00087 //----------------------------------------------------------------------------
00088 
00092 PriorityAction::ResultE
00093 PriorityAction::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     pqPush(NodeQueueEntry(pRoot, PriorityTypeTraits::getZeroElement(),
00111                           1,     _itActiveState                       ));
00112 
00113     result = traverseEnter();
00114 
00115     setState(_itInitialState);
00116 
00117     // lost refs: active, current node
00118     decRefCount(_itActiveState, 2);
00119 
00120     _itActiveState   = _itInitialState;
00121     _stateClonedFlag = true;
00122 
00123     pqClear();
00124 #ifndef OSG_NEWACTION_STATESLOTINTERFACE
00125     _stateStore        .clear();
00126 #endif
00127     _stateRefCountStore.clear();
00128 
00129     if(result & NewActionTypes::Quit)
00130     {
00131         stopActors();
00132         stopEvent ();
00133     }
00134     else
00135     {
00136         result = stopActors();
00137         stopEvent();
00138     }
00139     
00140     return result;
00141 }
00142 
00143 //==== PROTECTED =============================================================
00144 //----------------------------------------------------------------------------
00145 //    Constructors
00146 //----------------------------------------------------------------------------
00147 
00148 PriorityAction::PriorityAction(void)
00149     : Inherited          (     ),
00150       _extendEnterActors (     ),
00151       _basicEnterActors  (     ),
00152       _nodePrioQueue     (     ),
00153       _nodePrioQueueComp (     ),
00154       _stateClonedFlag   (false),
00155 #ifndef OSG_NEWACTION_STATESLOTINTERFACE
00156       _stateStore        (     ),
00157 #endif
00158       _stateRefCountStore(     ),
00159       _itInitialState    (     ),
00160       _itActiveState     (     )
00161 {
00162 }
00163 
00164 //----------------------------------------------------------------------------
00165 //    Events
00166 //----------------------------------------------------------------------------
00167 
00173 void
00174 PriorityAction::addExtendEvent(ExtendActorBase *pActor, UInt32 actorIndex)
00175 {
00176     ExtendActorStoreIt itActors  = beginExtend();
00177     ExtendActorStoreIt endActors = beginExtend() + actorIndex;
00178 
00179     ExtendActorStoreIt itEnter   = _extendEnterActors.begin();
00180 
00181     if(pActor->getEnterNodeFlag() == true)
00182     {
00183         for(; itActors != endActors; ++itActors)
00184         {
00185             if((*itActors)->getEnterNodeFlag() == true)
00186                 ++itEnter;
00187         }
00188 
00189         _extendEnterActors.insert(itEnter, pActor);
00190     }
00191 }
00192 
00196 void
00197 PriorityAction::subExtendEvent(ExtendActorBase *pActor, UInt32 actorIndex)
00198 {
00199     ExtendActorStoreIt itEnter  = _extendEnterActors.begin();
00200     ExtendActorStoreIt endEnter = _extendEnterActors.end  ();
00201 
00202     for(; itEnter != endEnter; ++itEnter)
00203     {
00204         if(*itEnter == pActor)
00205         {
00206             _extendEnterActors.erase(itEnter);
00207 
00208             break;
00209         }
00210     }
00211 }
00212 
00218 void
00219 PriorityAction::addBasicEvent(BasicActorBase *pActor, UInt32 actorIndex)
00220 {
00221     BasicActorStoreIt itActors  = beginBasic();
00222     BasicActorStoreIt endActors = beginBasic() + actorIndex;
00223 
00224     BasicActorStoreIt itEnter   = _basicEnterActors.begin();
00225 
00226     if(pActor->getEnterNodeFlag() == true)
00227     {
00228         for(; itActors != endActors; ++itActors)
00229         {
00230             if((*itActors)->getEnterNodeFlag() == true)
00231                 ++itEnter;
00232         }
00233 
00234         _basicEnterActors.insert(itEnter, pActor);
00235     }
00236 }
00237 
00241 void
00242 PriorityAction::subBasicEvent(BasicActorBase *pActor, UInt32 actorIndex)
00243 {
00244     BasicActorStoreIt itEnter  = _basicEnterActors.begin();
00245     BasicActorStoreIt endEnter = _basicEnterActors.end  ();
00246 
00247     for(; itEnter != endEnter; ++itEnter)
00248     {
00249         if(*itEnter == pActor)
00250         {
00251             _basicEnterActors.erase(itEnter);
00252 
00253             break;
00254         }
00255     }
00256 }
00257 
00258 void
00259 PriorityAction::startEvent(void)
00260 {
00261     Inherited::startEvent();
00262 
00263 #ifdef OSG_NEWACTION_STATISTICS
00264     getStatistics()->getElem(statStateClones  )->reset();
00265     getStatistics()->getElem(statStateRestores)->reset();
00266 #endif /* OSG_NEWACTION_STATISTICS */
00267 }
00268 
00269 void
00270 PriorityAction::stopEvent(void)
00271 {
00272     Inherited::stopEvent();
00273 }
00274 
00278 void
00279 PriorityAction::beginEditStateEvent(ActorBase *pActor, UInt32 actorId)
00280 {
00281     if(_stateClonedFlag == false)
00282     {
00283 #ifdef OSG_NEWACTION_STATISTICS
00284         getStatistics()->getElem(statStateClones)->inc();
00285 #endif /* OSG_NEWACTION_STATISTICS */
00286 
00287         _stateClonedFlag = true;
00288 
00289         StateRefCountStoreIt itClonedState = cloneState();
00290 
00291         // gained refs: active and current node
00292         incRefCount(itClonedState, 2);
00293 
00294         // lost refs: active and current node
00295         decRefCount(_itActiveState, 2);
00296 
00297         _itActiveState = itClonedState;
00298     }
00299 }
00300 
00304 void
00305 PriorityAction::endEditStateEvent(ActorBase *pActor, UInt32 actorId)
00306 {
00307 }
00308 
00309 //==== PRIVATE ===============================================================
00310 //----------------------------------------------------------------------------
00311 //    Helper Methods.
00312 //----------------------------------------------------------------------------
00313 
00318 PriorityAction::ResultE
00319 PriorityAction::traverseEnter(void)
00320 {
00321     ResultE              result          = NewActionTypes::Continue;
00322     NodePtr              pNode;
00323     PriorityType         nodePrio;
00324     UInt32               nodePass;
00325     UInt32               multiPasses;
00326     StateRefCountStoreIt itStateRefCount;
00327 
00328     while((pqEmpty() == false) && !(result & NewActionTypes::Quit))
00329     {
00330         pNode           = pqTop().getNode         ();
00331         nodePrio        = pqTop().getPriority     ();
00332         nodePass        = pqTop().getPassCount    ();
00333         itStateRefCount = pqTop().getStateRefCount();
00334 
00335         if(itStateRefCount != _itActiveState)
00336         {
00337 #ifdef OSG_NEWACTION_STATISTICS
00338             getStatistics()->getElem(statStateRestores)->inc();
00339 #endif /* OSG_NEWACTION_STATISTICS */
00340 
00341             setState(itStateRefCount);
00342 
00343             // gained refs: active
00344             incRefCount(itStateRefCount);
00345 
00346             // lost refs: active
00347             decRefCount(_itActiveState);
00348 
00349             _itActiveState = itStateRefCount;
00350         }
00351 
00352         _stateClonedFlag = false;
00353 
00354         getChildrenList().setParentNode(pNode);
00355 
00356 #ifdef OSG_NEWACTION_STATISTICS
00357         getStatistics()->getElem(statNodesEnter)->inc();
00358 #endif /* OSG_NEWACTION_STATISTICS */
00359 
00360         result      = enterNode   (pNode, nodePass - 1);
00361         multiPasses = getNumPasses(                   );
00362         
00363         pqPop();
00364         
00365         // only initial pass (nodePass == 1) can request multiPasses
00366         if((nodePass == 1) && (multiPasses > 1))
00367         {
00368             for(; multiPasses > 1; --multiPasses)
00369             {
00370                 // gained refs: additional pass
00371                 incRefCount(_itActiveState);
00372                 
00373                 pqPush(NodeQueueEntry(pNode,       nodePrio, 
00374                                       multiPasses, _itActiveState));
00375             }
00376         }
00377 
00378         enqueueChildren(pNode, result);
00379     }
00380 
00381     return result;
00382 }
00383 
00388 void
00389 PriorityAction::enqueueChildren(const NodePtr &pNode, ResultE result)
00390 {
00391     if(result & (NewActionTypes::Skip  |
00392                  NewActionTypes::Break |
00393                  NewActionTypes::Quit   ))
00394     {
00395         setChildrenListEnabled(false);
00396         setNumPasses          (1    );
00397         
00398         getExtraChildrenList().clear();
00399 
00400         // lost refs: current node
00401         decRefCount(_itActiveState);
00402 
00403         return;
00404     }
00405 
00406     ChildrenList      &cl  = getChildrenList     ();
00407     ExtraChildrenList &ecl = getExtraChildrenList();
00408 
00409     if(getChildrenListEnabled() == true)
00410     {
00411         for(UInt32 i = 0, size = cl.getSize(); i < size; ++i)
00412         {
00413             if(( cl.getActive(i)                                 == true  ) &&
00414                ( cl.getChild (i)                                 != NullFC) &&
00415                ((cl.getChild (i)->getTravMask() & getTravMask()) != 0     )   )
00416             {
00417                 // gained refs: child
00418                 incRefCount(_itActiveState);
00419 
00420                 pqPush(NodeQueueEntry(cl.getChild(i), cl.getPriority(i),
00421                                       1,              _itActiveState    ));
00422             }
00423         }
00424     }
00425     else
00426     {
00427         MFNodePtr::const_iterator itChildren  = pNode->getMFChildren()->begin();
00428         MFNodePtr::const_iterator endChildren = pNode->getMFChildren()->end  ();
00429 
00430         for(; itChildren != endChildren; ++itChildren)
00431         {
00432             if((  *itChildren                                  != NullFC) &&
00433                (((*itChildren)->getTravMask() & getTravMask()) != 0     )   )
00434             {
00435                 // gained refs: child
00436                 incRefCount(_itActiveState);
00437 
00438                 pqPush(
00439                     NodeQueueEntry(*itChildren,
00440                                    PriorityTypeTraits::getZeroElement(),
00441                                    1, _itActiveState                    ));
00442             }
00443         }
00444     }
00445 
00446     for(UInt32 i = 0, size = ecl.getSize(); i < size; ++i)
00447     {
00448         if(( ecl.getActive(i)                                 == true  ) &&
00449            ( ecl.getChild (i)                                 != NullFC) &&
00450            ((ecl.getChild (i)->getTravMask() & getTravMask()) != 0     )   )
00451         {
00452             // gained refs: extra child
00453             incRefCount(_itActiveState);
00454 
00455             pqPush(NodeQueueEntry(ecl.getChild(i), ecl.getPriority(i),
00456                                   1,               _itActiveState     ));
00457         }
00458     }
00459 
00460     setChildrenListEnabled(false);
00461     ecl.clear             (     );
00462     setNumPasses          (1    );
00463 
00464     // lost refs: current node
00465     decRefCount(_itActiveState);
00466 }
00467 
00468 /*------------------------------------------------------------------------*/
00469 /*                              cvs id's                                  */
00470 
00471 #ifdef OSG_SGI_CC
00472 #pragma set woff 1174
00473 #endif
00474 
00475 #ifdef OSG_LINUX_ICC
00476 #pragma warning(disable : 177)
00477 #endif
00478 
00479 namespace
00480 {
00481     static Char8 cvsid_cpp       [] = "@(#)$Id: OSGPriorityAction.cpp,v 1.3 2004/09/17 14:09:43 neumannc Exp $";
00482     static Char8 cvsid_hpp       [] = OSGPRIORITYACTION_HEADER_CVSID;
00483     static Char8 cvsid_inl       [] = OSGPRIORITYACTION_INLINE_CVSID;
00484 }
00485 
00486 #ifdef OSG_LINUX_ICC
00487 #pragma warning(enable : 177)
00488 #endif
00489 
00490 #ifdef OSG_SGI_CC
00491 #pragma reset woff 1174
00492 #endif

Generated on Thu Aug 25 04:08:45 2005 for OpenSG by  doxygen 1.4.3