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 <cstdlib>
00033 #include <cstdio>
00034 
00035 #include "OSGConfig.h"
00036 
00037 #include <OSGLog.h>
00038 #include <OSGFieldContainer.h>
00039 #include <OSGNodeCore.h>
00040 #include "OSGAction.h"
00041 
00042 //#define BOOST_MEM_FN_ENABLE_CDECL
00043 #include <boost/bind.hpp>
00044 
00045 OSG_USING_NAMESPACE
00046 
00047 
00048 /***************************************************************************\
00049  *                            Description                                  *
00050 \***************************************************************************/
00051 
00059 /***************************************************************************\
00060  *                               Types                                     *
00061 \***************************************************************************/
00062 
00063 /***************************************************************************\
00064  *                           Class variables                               *
00065 \***************************************************************************/
00066 
00067 
00068 Action *Action::_prototype = NULL;
00069 
00070 std::vector<Action::Functor> *Action::_defaultEnterFunctors = NULL;
00071 std::vector<Action::Functor> *Action::_defaultLeaveFunctors = NULL;
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 == NULL)
00087         _defaultEnterFunctors = new std::vector<Action::Functor>;
00088 
00089 #ifndef OSG_WINCE
00090     while(type.getId() >= _defaultEnterFunctors->size())
00091     {
00092         _defaultEnterFunctors->push_back(&Action::_defaultEnterFunction);
00093     }
00094 #else
00095     while(type.getId() >= _defaultEnterFunctors->size())
00096     {
00097         _defaultEnterFunctors->push_back(&NodeCore::defaultEnter);
00098     }
00099 #endif
00100     
00101     (*_defaultEnterFunctors)[type.getId()] = func;
00102 }
00103 
00104 void Action::registerLeaveDefault(const FieldContainerType &type, 
00105                                   const Action::Functor    &func)
00106 {
00107     if(_defaultLeaveFunctors == NULL)
00108         _defaultLeaveFunctors = new std::vector<Action::Functor>;
00109 
00110 #ifndef OSG_WINCE
00111     while(type.getId() >= _defaultLeaveFunctors->size())
00112     {
00113         _defaultLeaveFunctors->push_back(&Action::_defaultLeaveFunction);
00114     }
00115 #else
00116     while(type.getId() >= _defaultLeaveFunctors->size())
00117     {
00118         _defaultLeaveFunctors->push_back(&NodeCore::defaultLeave);
00119     }
00120 #endif
00121     
00122     (*_defaultLeaveFunctors)[type.getId()] = func;
00123 }
00124 
00125 void Action::setPrototype(Action *proto)
00126 {
00127     _prototype = proto;
00128 }
00129 
00130 Action *Action::getPrototype(void)
00131 {
00132     return _prototype;
00133 }
00134 
00135 /*-------------------------------------------------------------------------*\
00136  -  protected                                                              -
00137 \*-------------------------------------------------------------------------*/
00138 
00139 
00140 /*-------------------------------------------------------------------------*\
00141  -  private                                                                -
00142 \*-------------------------------------------------------------------------*/
00143 
00144 
00145 
00146 /***************************************************************************\
00147  *                           Instance methods                              *
00148 \***************************************************************************/
00149 
00150 /*-------------------------------------------------------------------------*\
00151  -  public                                                                 -
00152 \*-------------------------------------------------------------------------*/
00153 
00154 /*------------- constructors & destructors --------------------------------*/
00155 
00159 Action::Action(void) : 
00160     _travMask(TypeTraits<UInt32>::getMax())
00161 {
00162     if(_defaultEnterFunctors)
00163         _enterFunctors = *_defaultEnterFunctors;
00164 
00165     if(_defaultLeaveFunctors)
00166         _leaveFunctors = *_defaultLeaveFunctors;
00167 }
00168 
00172 Action::Action(const Action & source) :
00173     _enterFunctors(source._enterFunctors),
00174     _leaveFunctors(source._leaveFunctors),
00175     _travMask     (source._travMask     )
00176 {
00177 }
00178 
00179 
00183 Action *Action::create(void)
00184 {
00185     Action *act;
00186     
00187     if(_prototype)
00188     {
00189         act = new Action(*_prototype);
00190     }
00191     else
00192     {
00193         act = new Action();
00194     }
00195 
00196     return act;
00197 }
00198 
00202 Action::~Action(void)
00203 {
00204 }
00205 
00206 /*------------------------------ access -----------------------------------*/
00207 
00208 /*---------------------------- properties ---------------------------------*/
00209 
00210 /*-------------------------- your_category---------------------------------*/
00211 
00212 void Action::registerEnterFunction(const FieldContainerType &type, 
00213                                    const Action::Functor    &func)
00214 {
00215 #ifndef OSG_WINCE
00216     while(type.getId() >= _enterFunctors.size())
00217     {
00218         _enterFunctors.push_back(&Action::_defaultEnterFunction);
00219     }
00220 #else
00221     while(type.getId() >= _enterFunctors.size())
00222     {
00223         _enterFunctors.push_back(&NodeCore::defaultEnter);
00224     }
00225 #endif
00226     
00227     _enterFunctors[type.getId()] = func;
00228 }
00229 
00230 void Action::registerLeaveFunction(const FieldContainerType &type, 
00231                                    const Action::Functor    &func)
00232 {
00233 #ifndef OSG_WINCE
00234     while(type.getId() >= _leaveFunctors.size())
00235     {
00236         _leaveFunctors.push_back(&Action::_defaultLeaveFunction);
00237     }
00238 #else
00239     while(type.getId() >= _leaveFunctors.size())
00240     {
00241         _leaveFunctors.push_back(&NodeCore::defaultLeave);
00242     }
00243 #endif
00244     
00245     _leaveFunctors[type.getId()] = func;
00246 }
00247 
00248 
00249 
00250 // application entry points
00251 
00252 ActionBase::ResultE Action::apply(std::vector<NodePtr>::iterator begin,
00253                                   std::vector<NodePtr>::iterator end)
00254 {
00255     Action::ResultE res = Continue;
00256     
00257     // call the start function and its' returns
00258 
00259     if((res = callStart()) != Continue)
00260         return res;     
00261     
00262     // call the given nodes
00263     
00264     for(; begin != end; ++begin)
00265     {
00266         if(*begin == NullFC)
00267         {
00268             SWARNING << "apply: encountered NullNode!" << std::endl;
00269             return Quit;            
00270         }
00271         else
00272         {
00273             res = recurse(*begin);
00274             
00275             if(res != Continue)
00276                 break;
00277         }
00278     }
00279         
00280     // call the stop function and its' returns
00281     res = callStop(res);  
00282     
00283     return res;
00284 }
00285 
00286 ActionBase::ResultE Action::apply(NodePtrConstArg node)
00287 {
00288     if(node == NullFC)
00289     {
00290         SWARNING << "apply: node is Null!" << std::endl;
00291         return Quit;            
00292     }
00293 
00294     std::vector<NodePtr> nodeList;
00295 
00296     nodeList.push_back(node);
00297 
00298     return apply(nodeList.begin(), nodeList.end());
00299 }
00300 
00301 
00302 
00303 
00304 // recursion calling
00305 
00306 ActionBase::ResultE Action::recurse(NodePtrConstArg node)
00307 {
00308     if(node == NullFC)
00309         return Continue;
00310 
00311     if((node->getTravMask() & getTravMask()) == 0)
00312         return Continue;
00313 
00314 #if OSG_1_COMPAT
00315     if(node->getOcclusionMask() & 1)
00316         return Continue;
00317 #endif
00318 
00319     NodeCorePtr core = node->getCore();
00320     
00321     if(core == NullFC)
00322     {
00323         SWARNING << "recurse: core is Null,  don't know what to do!" 
00324                  << std::endl;
00325         return Quit;                    
00326     }
00327     
00328     Action::ResultE result;
00329     
00330     _actList = NULL;
00331     _actNode = node;
00332 
00333     _newList.clear();
00334 
00335     _useNewList = false;
00336     
00337     result = callEnter(node->getCore());
00338 
00339     if(result != Continue)
00340     {
00341         if(result == Skip)
00342             return Continue;
00343     
00344         return result;
00345     }
00346     
00347     if(! _newList.empty())
00348     {
00349         result = callNewList();
00350     }
00351     else if(! _useNewList) // new list is empty, but not used?
00352     {
00353         std::vector<NodePtr>::const_iterator it;
00354 
00355         for(  it  = node->getMFChildren()->begin(); 
00356               it != node->getMFChildren()->end(); 
00357             ++it)
00358         {
00359             result = recurse(*it);
00360             
00361             if(result != Continue)
00362                 break;
00363         }
00364     }   
00365     
00366     _actNode = node;
00367 
00368     if(result == Continue)
00369     {
00370         result = callLeave(node->getCore());
00371     }
00372     else
00373     {
00374         callLeave(node->getCore());
00375     }
00376 
00377     if(result == Skip)
00378         return Continue;
00379         
00380     return result;
00381 }
00382 
00383 // call the _newList objects
00384 ActionBase::ResultE Action::callNewList(void)
00385 {
00386     ResultE result = Continue;
00387 
00388     // need to make a copy, because the one in the action is cleared
00389 
00390     std::vector<NodePtr> nodeList;
00391 
00392     nodeList.swap(_newList);
00393 
00394     std::vector<NodePtr>::iterator it;
00395 
00396     _actList = &nodeList;
00397 
00398     for(it = nodeList.begin(); it != nodeList.end(); ++it)
00399     {
00400         result = recurse(*it);
00401 
00402         if(result != Continue)
00403             break;
00404     }
00405     
00406     return result;
00407 }
00408 
00409 
00410 // call the start function and its results
00411 
00412 ActionBase::ResultE Action::callStart(void)
00413 {
00414     ResultE res = Continue;
00415     
00416     // call the start and see if it returns some nodes
00417     
00418     _newList.clear();
00419 
00420     if((res = start()) != Continue)
00421         return res;     
00422     
00423     // got some nodes? call them
00424     
00425     if(! _newList.empty())
00426         res = callNewList();
00427     
00428     // return the result
00429 
00430     return res;
00431 }
00432 
00433 // call the stop function and its results
00434 
00435 ActionBase::ResultE Action::callStop(ResultE res)
00436 {
00437     // call the start and see if it returns some nodes
00438     
00439     _newList.clear();
00440 
00441     if((res = stop(res)) != Continue)
00442         return res;     
00443             
00444     if(! _newList.empty())
00445         res = callNewList();
00446 
00447     return res;
00448 }
00449 
00450 // default start/stop, does nothing
00451 
00452 ActionBase::ResultE Action::start(void)
00453 {
00454     return Continue;
00455 }
00456 
00457 ActionBase::ResultE Action::stop(ResultE res)
00458 {
00459     return res;
00460 }
00461 
00462 /*-------------------------- assignment -----------------------------------*/
00463 
00467 Action& Action::operator = (const Action &source)
00468 {
00469     if (this == &source)
00470         return *this;
00471 
00472     return *this;
00473 }
00474 
00475 /*-------------------------- comparison -----------------------------------*/
00476 
00480 bool Action::operator < (const Action &other)
00481 {
00482     return this < &other;
00483 }
00484 
00488 bool Action::operator == (const Action &OSG_CHECK_ARG(other))
00489 {
00490     return false;
00491 }
00492 
00496 bool Action::operator != (const Action &other)
00497 {
00498     return ! (*this == other);
00499 }
00500 
00501 
00502 /*-------------------------------------------------------------------------*\
00503  -  protected                                                              -
00504 \*-------------------------------------------------------------------------*/
00505 
00506 std::vector<Action::Functor>* Action::getDefaultEnterFunctors(void)
00507 {
00508     return _defaultEnterFunctors;
00509 }
00510 
00511 std::vector<Action::Functor>* Action::getDefaultLeaveFunctors(void)
00512 {
00513     return _defaultLeaveFunctors;
00514 }
00515 
00516 
00517 /*-------------------------------------------------------------------------*\
00518  -  private                                                                -
00519 \*-------------------------------------------------------------------------*/
00520 
00521 // default Action function: just call all kids
00522 
00523 ActionBase::ResultE Action::_defaultEnterFunction(NodeCorePtrConstArg  , 
00524                                                   Action          *)
00525 {
00526     return Continue;
00527 }
00528 
00529 ActionBase::ResultE Action::_defaultLeaveFunction(NodeCorePtrConstArg  , 
00530                                                   Action          *)
00531 {
00532     return Continue;
00533 }
00534 
00535 /*************** Functions ******************/
00536 
00537 OSG_BEGIN_NAMESPACE
00538 
00539 /*
00540 inline
00541 ActionBase::ResultE doCallEnter(NodePtrConstArg       node, 
00542                                 TraverseEnterFunctor &func)
00543 {
00544     return func.call(node);
00545 }
00546 
00547 inline
00548 ActionBase::ResultE doCallLeave(NodePtrConstArg       node, 
00549                                 ActionBase::ResultE   res,
00550                                 TraverseLeaveFunctor &func)
00551 {
00552     return func.call(node, res);
00553 }
00554 */
00555 
00559 ActionBase::ResultE traverse(const std::vector<NodePtr> &nodeList, 
00560                                    TraverseEnterFunctor  func    )
00561 {
00562     ActionBase::ResultE res = ActionBase::Continue;
00563 
00564     std::vector<NodePtr>::const_iterator it = nodeList.begin();
00565     std::vector<NodePtr>::const_iterator en = nodeList.end  ();
00566     
00567     for(; it != en; ++it)
00568     {
00569         res = traverse((*it), func);
00570         
00571         if(res == ActionBase::Quit)
00572             break;
00573     }
00574         
00575     return res;
00576 }
00577 
00581 ActionBase::ResultE traverse(NodePtrConstArg      node, 
00582                              TraverseEnterFunctor func )
00583 {
00584     ActionBase::ResultE res = ActionBase::Continue;
00585     
00586     res = func(node);
00587     
00588     switch(res)
00589     {
00590         case ActionBase::Skip:      
00591             return Action::Continue;
00592 
00593         case ActionBase::Continue:  
00594             return traverse(node->getMFChildren()->getValues(), 
00595                             func                              );
00596 
00597         default:                
00598             break;
00599     }
00600                  
00601     return res;
00602 }
00603                             
00608 ActionBase::ResultE traverse(const std::vector<NodePtr> &nodeList, 
00609                                    TraverseEnterFunctor  enter, 
00610                                    TraverseLeaveFunctor  leave )
00611 {
00612     ActionBase::ResultE res = ActionBase::Continue;
00613 
00614     std::vector<NodePtr>::const_iterator it = nodeList.begin();
00615     std::vector<NodePtr>::const_iterator en = nodeList.end  ();
00616     
00617     for(; it != en; ++it)
00618     {
00619         res = traverse((*it), enter, leave);
00620         
00621         if(res == Action::Quit)
00622             break;
00623     }
00624         
00625     return res;
00626 }
00627 
00628                             
00633 ActionBase::ResultE traverse(NodePtrConstArg      node, 
00634                              TraverseEnterFunctor enter, 
00635                              TraverseLeaveFunctor leave )
00636 {
00637     ActionBase::ResultE res = ActionBase::Continue;
00638     
00639     res = enter(node);
00640     
00641     switch(res)
00642     {
00643         case ActionBase::Skip:      
00644             res = Action::Continue;
00645             break;
00646 
00647         case ActionBase::Continue:  
00648             res = traverse(node->getMFChildren()->getValues(), 
00649                            enter, 
00650                            leave                             );
00651 
00652         default:                
00653             break;
00654     }
00655      
00656     res = leave(node, res);
00657                 
00658     return res;
00659 }
00660 
00661 OSG_END_NAMESPACE