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

OSGAction.cpp

Go to the documentation of this file.
00001 /*---------------------------------------------------------------------------*\
00002  *                                OpenSG                                     *
00003  *                                                                           *
00004  *                                                                           *
00005  *                         Copyright 2000 by OpenSG Forum                    *
00006  *                                                                           *
00007  *          contact: {reiners|vossg}@igd.fhg.de, jbehr@zgdv.de               *
00008  *                                                                           *
00009 \*---------------------------------------------------------------------------*/
00010 /*---------------------------------------------------------------------------*\
00011  *                                License                                    *
00012  *                                                                           *
00013  *                                                                           *
00014  *                                                                           *
00015  *                                                                           *
00016  *                                                                           *
00017 \*---------------------------------------------------------------------------*/
00018 /*---------------------------------------------------------------------------*\
00019  *                                Changes                                    *
00020  *                                                                           *
00021  *                                                                           *
00022  *                                                                           *
00023  *                                                                           *
00024  *                                                                           *
00025  *                                                                           *
00026 \*---------------------------------------------------------------------------*/
00027 
00028 //---------------------------------------------------------------------------
00029 //  Includes
00030 //---------------------------------------------------------------------------
00031 
00032 #include <stdlib.h>
00033 #include <stdio.h>
00034 
00035 #include "OSGConfig.h"
00036 
00037 #include <OSGLog.h>
00038 #include <OSGFieldContainer.h>
00039 #include <OSGFieldContainerPtr.h>
00040 #include <OSGNode.h>
00041 #include <OSGNodeCore.h>
00042 #include "OSGAction.h"
00043 
00044 OSG_USING_NAMESPACE
00045 
00046 
00047 /***************************************************************************\
00048  *                            Description                                  *
00049 \***************************************************************************/
00050 
00058 /***************************************************************************\
00059  *                               Types                                     *
00060 \***************************************************************************/
00061 
00062 /***************************************************************************\
00063  *                           Class variables                               *
00064 \***************************************************************************/
00065 
00066 char Action::cvsid[] = "@(#)$Id: $";
00067 
00068 Action * Action::_prototype = NULL;
00069 
00070 std::vector<Action::Functor> *Action::_defaultEnterFunctors;
00071 std::vector<Action::Functor> *Action::_defaultLeaveFunctors;
00072 
00073 /***************************************************************************\
00074  *                           Class methods                                 *
00075 \***************************************************************************/
00076 
00077 
00078 
00079 /*-------------------------------------------------------------------------*\
00080  -  public                                                                 -
00081 \*-------------------------------------------------------------------------*/
00082 
00083 void Action::registerEnterDefault(  const FieldContainerType &type, 
00084                                         const Action::Functor &func )
00085 {
00086     if ( ! _defaultEnterFunctors )
00087         _defaultEnterFunctors = new std::vector<Action::Functor>;
00088 
00089     while(type.getId() >= _defaultEnterFunctors->size())
00090     {
00091         _defaultEnterFunctors->push_back( 
00092             osgTypedFunctionFunctor2CPtrRef<
00093                 ResultE, 
00094                 CNodePtr,
00095                 Action *                   >(&Action::_defaultEnterFunction));
00096     }
00097     
00098     (*_defaultEnterFunctors)[ type.getId() ] = func;
00099 }
00100 
00101 void Action::registerLeaveDefault(  const FieldContainerType &type, 
00102                                         const Action::Functor &func )
00103 {
00104     if ( ! _defaultLeaveFunctors )
00105         _defaultLeaveFunctors = new std::vector<Action::Functor>;
00106 
00107     while(type.getId() >= _defaultLeaveFunctors->size())
00108     {
00109         _defaultLeaveFunctors->push_back( 
00110             osgTypedFunctionFunctor2CPtrRef<
00111                 ResultE, 
00112                 CNodePtr,
00113                 Action *                   >(&Action::_defaultLeaveFunction));
00114     }
00115     
00116     (*_defaultLeaveFunctors)[ type.getId() ] = func;
00117 }
00118 
00119 void Action::setPrototype( Action * proto )
00120 {
00121     _prototype = proto;
00122 }
00123 
00124 Action *Action::getPrototype( void )
00125 {
00126     return _prototype;
00127 }
00128 
00129 /*-------------------------------------------------------------------------*\
00130  -  protected                                                              -
00131 \*-------------------------------------------------------------------------*/
00132 
00133 
00134 /*-------------------------------------------------------------------------*\
00135  -  private                                                                -
00136 \*-------------------------------------------------------------------------*/
00137 
00138 
00139 
00140 /***************************************************************************\
00141  *                           Instance methods                              *
00142 \***************************************************************************/
00143 
00144 /*-------------------------------------------------------------------------*\
00145  -  public                                                                 -
00146 \*-------------------------------------------------------------------------*/
00147 
00148 /*------------- constructors & destructors --------------------------------*/
00149 
00153 Action::Action(void) : _travMask(TypeTraits<UInt32>::getMax())
00154 {
00155     if ( _defaultEnterFunctors )
00156         _enterFunctors = *_defaultEnterFunctors;
00157 
00158     if ( _defaultLeaveFunctors )
00159         _leaveFunctors = *_defaultLeaveFunctors;
00160 }
00161 
00165 Action::Action( const Action & source ) :
00166     _enterFunctors( source._enterFunctors ),
00167     _leaveFunctors( source._leaveFunctors ),
00168     _travMask     ( source._travMask      )
00169 {
00170 }
00171 
00172 
00176 Action * Action::create( void )
00177 {
00178     Action * act;
00179     
00180     if ( _prototype )
00181         act = new Action( *_prototype );
00182     else
00183         act = new Action();
00184     
00185     return act;
00186 }
00187 
00191 Action::~Action(void)
00192 {
00193 }
00194 
00195 /*------------------------------ access -----------------------------------*/
00196 
00197 /*---------------------------- properties ---------------------------------*/
00198 
00199 /*-------------------------- your_category---------------------------------*/
00200 
00201 void Action::registerEnterFunction( const FieldContainerType &type, 
00202         const Action::Functor& func )
00203 {
00204     while ( type.getId() >= _enterFunctors.size() )
00205     {
00206         _enterFunctors.push_back(
00207             osgTypedFunctionFunctor2CPtrRef<
00208                 ResultE, 
00209                 CNodePtr,
00210                 Action *                   >(&Action::_defaultEnterFunction));
00211     }
00212     
00213     _enterFunctors[ type.getId() ] = func;
00214 }
00215 
00216 void Action::registerLeaveFunction( const FieldContainerType &type, 
00217         const Action::Functor& func )
00218 {
00219     while ( type.getId() >= _leaveFunctors.size() )
00220     {
00221         _leaveFunctors.push_back(
00222             osgTypedFunctionFunctor2CPtrRef<
00223                 ResultE, 
00224                 CNodePtr,
00225                 Action *                   >(&Action::_defaultLeaveFunction));
00226     }
00227     
00228     _leaveFunctors[ type.getId() ] = func;
00229 }
00230 
00231 
00232 
00233 // application entry points
00234 
00235 Action::ResultE Action::apply(std::vector<NodePtr>::iterator begin,
00236                               std::vector<NodePtr>::iterator end)
00237 {
00238     Action::ResultE res = Continue;
00239     
00240     // call the start function and its' returns
00241     if ( ( res = callStart() ) != Continue )
00242         return res;     
00243     
00244     // call the given nodes
00245     
00246     for ( ; begin != end; begin ++ )
00247     {
00248         if ( *begin == NullFC )
00249         {
00250             SWARNING << "apply: encountered NullNode!" << std::endl;
00251             return Quit;            
00252         }
00253         else
00254         {
00255             res = recurse( *begin );
00256             
00257             if ( res != Continue )
00258                 break;
00259         }
00260     }
00261         
00262     // call the stop function and its' returns
00263     res = callStop( res );  
00264     
00265     return res;
00266 }
00267 
00268 Action::ResultE Action::apply(NodePtr node)
00269 {
00270     if(node == NullFC)
00271     {
00272         SWARNING << "apply: node is Null!" << std::endl;
00273         return Quit;            
00274     }
00275 
00276     std::vector<NodePtr> nodeList;
00277 
00278     nodeList.push_back(node);
00279 
00280     return apply(nodeList.begin(), nodeList.end());
00281 }
00282 
00283 
00284 
00285 
00286 // recursion calling
00287 
00288 Action::ResultE Action::recurse( NodePtr node  )
00289 {
00290     if ( node == NullFC )
00291         return Continue;
00292 
00293     if((node->getTravMask() & getTravMask()) == 0)
00294         return Continue;
00295 
00296     NodeCorePtr core = node->getCore();
00297     
00298     if ( core == NullFC )
00299     {
00300         SWARNING << "recurse: core is Null,  don't know what to do!" 
00301                  << std::endl;
00302         return Quit;                    
00303     }
00304     
00305     Action::ResultE result;
00306     
00307     _actList = NULL;
00308     _actNode = node;
00309     _newList.clear();
00310     _useNewList = false;
00311     
00312     result = callEnter( node );
00313 
00314     if ( result != Continue )
00315     {
00316         if ( result == Skip )
00317             return Continue;
00318     
00319         return result;
00320     }
00321     
00322     if ( ! _newList.empty() )
00323     {
00324         result = callNewList();
00325     }
00326     else if ( ! _useNewList ) // new list is empty, but not used?
00327     {
00328         std::vector<NodePtr>::iterator it;
00329 
00330         for ( it = node->getMFChildren()->begin(); it != node->getMFChildren()->end(); it ++ )
00331         {
00332             result = recurse( *it );
00333             
00334             if ( result != Continue )
00335                 break;
00336         }
00337     }   
00338 
00339     _actNode = node;
00340     if ( result == Continue )
00341         result = callLeave( node );
00342     else
00343         callLeave( node );
00344 
00345     if ( result == Skip )
00346         return Continue;
00347         
00348     return result;
00349 }
00350 
00351 // call the _newList objects
00352 Action::ResultE Action::callNewList(void)
00353 {
00354     Action::ResultE result = Continue;
00355 
00356     // need to make a copy, because the one in the action is cleared
00357 
00358     std::vector<NodePtr> nodeList;
00359     nodeList.swap(_newList);
00360 
00361     std::vector<NodePtr>::iterator it;
00362 
00363     _actList = &nodeList;
00364 
00365     for(it = nodeList.begin(); it != nodeList.end(); ++it)
00366     {
00367         result = recurse(*it);
00368 
00369         if(result != Continue)
00370             break;
00371     }
00372     
00373     return result;
00374 }
00375 
00376 
00377 // call the start function and its results
00378 
00379 Action::ResultE Action::callStart( void )
00380 {
00381     Action::ResultE res = Continue;
00382     
00383     // call the start and see if it returns some nodes
00384     
00385     _newList.clear();
00386 
00387     if ( ( res = start() ) != Continue )
00388         return res;     
00389     
00390     // got some nodes? call them
00391     
00392     if ( ! _newList.empty() )
00393         res = callNewList();
00394     
00395     // return the result
00396 
00397     return res;
00398 }
00399 
00400 // call the stop function and its results
00401 
00402 Action::ResultE Action::callStop( ResultE res )
00403 {
00404     // call the start and see if it returns some nodes
00405     
00406     _newList.clear();
00407 
00408     if ( ( res = stop( res ) ) != Continue )
00409         return res;     
00410             
00411     if ( ! _newList.empty() )
00412         res = callNewList();
00413 
00414     return res;
00415 }
00416 
00417 // default start/stop, does nothing
00418 
00419 
00420 Action::ResultE Action::start( void )
00421 {
00422     return Continue;
00423 }
00424 
00425 Action::ResultE Action::stop( ResultE res )
00426 {
00427     return res;
00428 }
00429 
00430 /*-------------------------- assignment -----------------------------------*/
00431 
00435 Action& Action::operator = (const Action &source)
00436 {
00437     if (this == &source)
00438         return *this;
00439 
00440     // free mem alloced by members of 'this'
00441 
00442     
00443     // alloc new mem for members
00444 
00445     // copy 
00446 
00447     return *this;
00448 }
00449 
00450 /*-------------------------- comparison -----------------------------------*/
00451 
00455 bool Action::operator < (const Action &other)
00456 {
00457     return this < &other;
00458 }
00459 
00463 bool Action::operator == (const Action &OSG_CHECK_ARG(other))
00464 {
00465     return false;
00466 }
00467 
00471 bool Action::operator != (const Action &other)
00472 {
00473     return ! (*this == other);
00474 }
00475 
00476 
00477 /*-------------------------------------------------------------------------*\
00478  -  protected                                                              -
00479 \*-------------------------------------------------------------------------*/
00480 
00481 std::vector<Action::Functor>* Action::getDefaultEnterFunctors( void )
00482 {
00483     return _defaultEnterFunctors;
00484 }
00485 
00486 std::vector<Action::Functor>* Action::getDefaultLeaveFunctors( void )
00487 {
00488     return _defaultLeaveFunctors;
00489 }
00490 
00491 
00492 /*-------------------------------------------------------------------------*\
00493  -  private                                                                -
00494 \*-------------------------------------------------------------------------*/
00495 
00496 // default Action function: just call all kids
00497 
00498 Action::ResultE Action::_defaultEnterFunction(CNodePtr &OSG_CHECK_ARG(node  ), 
00499                                               Action   *OSG_CHECK_ARG(action))
00500 {
00501     return Continue;
00502 }
00503 
00504 Action::ResultE Action::_defaultLeaveFunction(CNodePtr &OSG_CHECK_ARG(node  ), 
00505                                               Action   *OSG_CHECK_ARG(action))
00506 {
00507     return Continue;
00508 }
00509 
00510 /*************** Functions ******************/
00511 
00512 OSG_BEGIN_NAMESPACE
00513 
00514 inline
00515 Action::ResultE doCallEnter(NodePtr               node, 
00516                             TraverseEnterFunctor &func)
00517 {
00518     return func.call(node);
00519 }
00520 
00521 inline
00522 Action::ResultE doCallLeave(NodePtr               node, 
00523                             Action::ResultE       res,
00524                             TraverseLeaveFunctor &func)
00525 {
00526     return func.call(node, res);
00527 }
00528 
00529 OSG_END_NAMESPACE
00530 
00533 OSG_SYSTEMLIB_DLLMAPPING
00534 Action::ResultE OSG::traverse(std::vector<NodePtr> &nodeList, 
00535                               TraverseEnterFunctor  func    )
00536 {
00537     Action::ResultE res = Action::Continue;
00538 
00539     std::vector<NodePtr>::iterator it = nodeList.begin();
00540     std::vector<NodePtr>::iterator en = nodeList.end  ();
00541     
00542     for ( ; it != en; ++it )
00543     {
00544         res = traverse((*it), func);
00545         
00546         if(res == Action::Quit)
00547             break;
00548     }
00549         
00550     return res;
00551 }
00552 
00555 OSG_SYSTEMLIB_DLLMAPPING
00556 Action::ResultE OSG::traverse( NodePtr              node, 
00557                                TraverseEnterFunctor func )
00558 {
00559     Action::ResultE res = Action::Continue;
00560     
00561     res = doCallEnter(node, func);
00562     
00563     switch(res)
00564     {
00565     case Action::Skip:      return Action::Continue;
00566     case Action::Continue:  return traverse( node->getMFChildren()->getValues(), 
00567                                              func );
00568     default:                break;
00569     }
00570                  
00571     return res;
00572 }
00573                             
00577 OSG_SYSTEMLIB_DLLMAPPING
00578 Action::ResultE OSG::traverse(std::vector<NodePtr> &nodeList, 
00579                               TraverseEnterFunctor  enter, 
00580                               TraverseLeaveFunctor  leave )
00581 {
00582     Action::ResultE res = Action::Continue;
00583 
00584     std::vector<NodePtr>::iterator it = nodeList.begin();
00585     std::vector<NodePtr>::iterator en = nodeList.end  ();
00586     
00587     for ( ; it != en; ++it )
00588     {
00589         res = traverse((*it), enter, leave);
00590         
00591         if(res == Action::Quit)
00592             break;
00593     }
00594         
00595     return res;
00596 }
00597 
00598                             
00602 OSG_SYSTEMLIB_DLLMAPPING
00603 Action::ResultE OSG::traverse(   NodePtr node, 
00604                                  TraverseEnterFunctor enter, 
00605                                  TraverseLeaveFunctor leave )
00606 {
00607     Action::ResultE res = Action::Continue;
00608     
00609     res = doCallEnter(node, enter);
00610     
00611     switch(res)
00612     {
00613     case Action::Skip:      res = Action::Continue;
00614                             break;
00615     case Action::Continue:  res = traverse( node->getMFChildren()->getValues(), 
00616                                              enter, leave );
00617     default:                break;
00618     }
00619      
00620     res = doCallLeave(node, res, leave);
00621                 
00622     return res;
00623 }

Generated on Thu Aug 25 04:00:59 2005 for OpenSG by  doxygen 1.4.3