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 Action::FunctorStore *Action::_defaultEnterFunctors = NULL;
00071 Action::FunctorStore *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_EMBEDDED
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_EMBEDDED
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     _enterFunctors(                            ),
00161     _leaveFunctors(                            ),
00162     _actNode      (NULL                        ),
00163     _actParent    (NULL                        ),
00164     _actList      (NULL                        ),
00165     _useNewList   (false                       ),
00166     _travMask     (TypeTraits<UInt32>::getMax()),
00167     _sTravMask    (                            ),
00168     _nodeEnterCB  (                            ),
00169     _nodeLeaveCB  (                            )
00170 {
00171     if(_defaultEnterFunctors)
00172         _enterFunctors = *_defaultEnterFunctors;
00173
00174     if(_defaultLeaveFunctors)
00175         _leaveFunctors = *_defaultLeaveFunctors;
00176 }
00177
00181 Action::Action(const Action & source) :
00182     _enterFunctors(source._enterFunctors       ),
00183     _leaveFunctors(source._leaveFunctors       ),
00184     _actNode      (NULL                        ),
00185     _actParent    (NULL                        ),
00186     _actList      (NULL                        ),
00187     _useNewList   (false                       ),
00188     _travMask     (source._travMask            ),
00189     _sTravMask    (                            ),
00190     _nodeEnterCB  (source._nodeEnterCB         ),
00191     _nodeLeaveCB  (source._nodeLeaveCB         )
00192 {
00193 }
00194
00195
00199 Action *Action::create(void)
00200 {
00201     Action *act;
00202
00203     if(_prototype)
00204     {
00205         act = new Action(*_prototype);
00206     }
00207     else
00208     {
00209         act = new Action();
00210     }
00211
00212     return act;
00213 }
00214
00218 Action::~Action(void)
00219 {
00220 }
00221
00222 /*------------------------------ access -----------------------------------*/
00223
00224 /*---------------------------- properties ---------------------------------*/
00225
00226 /*-------------------------- your_category---------------------------------*/
00227
00228 void Action::registerEnterFunction(const FieldContainerType &type,
00229                                    const Action::Functor    &func)
00230 {
00231 #ifndef OSG_EMBEDDED
00232     while(type.getId() >= _enterFunctors.size())
00233     {
00234         _enterFunctors.push_back(&Action::_defaultEnterFunction);
00235     }
00236 #else
00237     while(type.getId() >= _enterFunctors.size())
00238     {
00239         _enterFunctors.push_back(&NodeCore::defaultEnter);
00240     }
00241 #endif
00242 
00243     _enterFunctors[type.getId()] = func;
00244 }
00245
00246 void Action::registerLeaveFunction(const FieldContainerType &type,
00247                                    const Action::Functor    &func)
00248 {
00249 #ifndef OSG_EMBEDDED
00250     while(type.getId() >= _leaveFunctors.size())
00251     {
00252         _leaveFunctors.push_back(&Action::_defaultLeaveFunction);
00253     }
00254 #else
00255     while(type.getId() >= _leaveFunctors.size())
00256     {
00257         _leaveFunctors.push_back(&NodeCore::defaultLeave);
00258     }
00259 #endif
00260 
00261     _leaveFunctors[type.getId()] = func;
00262 }
00263
00264
00265
00266 // application entry points
00267
00268 ActionBase::ResultE Action::apply(std::vector<Node *>::iterator begin,
00269                                   std::vector<Node *>::iterator end)
00270 {
00271     Action::ResultE res = Continue;
00272
00273     // call the start function and its' returns
00274
00275     if((res = callStart()) != Continue)
00276         return res;
00277
00278     // call the given nodes
00279
00280     for(; begin != end; ++begin)
00281     {
00282         if(*begin == NULL)
00283         {
00284             SWARNING << "apply: encountered NullNode!" << std::endl;
00285             return Quit;
00286         }
00287         else
00288         {
00289             res = recurse(*begin);
00290
00291             if(res != Continue)
00292                 break;
00293         }
00294     }
00295
00296     // call the stop function and its' returns
00297     res = callStop(res);
00298
00299     return res;
00300 }
00301
00302 ActionBase::ResultE Action::apply(Node * const node)
00303 {
00304     if(node == NULL)
00305     {
00306         SWARNING << "apply: node is Null!" << std::endl;
00307         return Quit;
00308     }
00309
00310     std::vector<Node *> nodeList;
00311
00312     nodeList.push_back(node);
00313
00314     return apply(nodeList.begin(), nodeList.end());
00315 }
00316
00317
00318
00319
00320 // recursion calling
00321
00322 ActionBase::ResultE Action::recurse(Node * const node)
00323 {
00324     if(node == NULL)
00325         return Continue;
00326
00327     if((node->getTravMask() & getTravMask()) == 0)
00328         return Continue;
00329
00330 #if OSG_1_COMPAT
00331     if(node->getOcclusionMask() & 1)
00332         return Continue;
00333 #endif
00334 
00335     NodeCore *core = node->getCore();
00336
00337     if(core == NULL)
00338     {
00339         SWARNING << "recurse: core is Null,  don't know what to do!"
00340                  << std::endl;
00341         return Quit;
00342     }
00343
00344     Action::ResultE result = Continue;
00345
00346     _actList   = NULL;
00347     _actNode   = node;
00348     _actParent = node;
00349
00350     _newList.clear();
00351
00352     _useNewList = false;
00353
00354     if(_nodeEnterCB != NULL)
00355         result = _nodeEnterCB(node, this);
00356
00357     if(result != Continue)
00358     {
00359         if(result == Skip)
00360             return Continue;
00361
00362         return result;
00363     }
00364
00365     result = callEnter(node->getCore());
00366
00367     _actNode   = node;
00368     _actParent = node;
00369
00370     if(result != Continue)
00371     {
00372         if(result == Skip)
00373             return Continue;
00374
00375         return result;
00376     }
00377
00378     if(! _newList.empty())
00379     {
00380         result = callNewList();
00381     }
00382     else if(! _useNewList) // new list is empty, but not used?
00383     {
00384         MFUnrecChildNodePtr::const_iterator it = node->getMFChildren()->begin();
00385         MFUnrecChildNodePtr::const_iterator en = node->getMFChildren()->end  ();
00386
00387         for(; it != en; ++it)
00388         {
00389             result = recurse(*it);
00390
00391             if(result != Continue)
00392                 break;
00393         }
00394     }
00395
00396     _actNode   = node;
00397     _actParent = node;
00398
00399     if(result == Continue)
00400     {
00401         result = callLeave(node->getCore());
00402     }
00403     else
00404     {
00405         callLeave(node->getCore());
00406     }
00407
00408     _actNode   = node;
00409     _actParent = node;
00410
00411     if(_nodeLeaveCB != NULL)
00412         _nodeLeaveCB(node, this);
00413
00414     if(result == Skip)
00415         return Continue;
00416
00417     return result;
00418 }
00419
00420 // call the _newList objects
00421 ActionBase::ResultE Action::callNewList(void)
00422 {
00423     ResultE result = Continue;
00424
00425     // need to make a copy, because the one in the action is cleared
00426
00427     std::vector<Node *> nodeList;
00428
00429     nodeList.swap(_newList);
00430
00431     std::vector<Node *>::iterator it = nodeList.begin();
00432     std::vector<Node *>::iterator en = nodeList.end();
00433
00434     _actList = &nodeList;
00435
00436     for(; it != en; ++it)
00437     {
00438         result = recurse(*it);
00439
00440         if(result != Continue)
00441             break;
00442     }
00443
00444     _actList = NULL;
00445
00446     return result;
00447 }
00448
00449
00450 // call the start function and its results
00451
00452 ActionBase::ResultE Action::callStart(void)
00453 {
00454     ResultE       res          = Continue;
00455     FunctorStore *defaultEnter = getDefaultEnterFunctors();
00456     FunctorStore *defaultLeave = getDefaultLeaveFunctors();
00457
00458     // new default enter functor registered since this action was created
00459     if(defaultEnter          != NULL &&
00460        _enterFunctors.size() <  defaultEnter->size())
00461     {
00462         _enterFunctors.reserve(defaultEnter->size());
00463
00464         FunctorStoreConstIt fIt  = defaultEnter->begin() + _enterFunctors.size();
00465         FunctorStoreConstIt fEnd = defaultEnter->end  ();
00466
00467         for(; fIt != fEnd; ++fIt)
00468         {
00469             _enterFunctors.push_back(*fIt);
00470         }
00471     }
00472
00473     // new default leave functor registered since this action was created
00474     if(defaultLeave          != NULL &&
00475        _leaveFunctors.size() <  defaultLeave->size())
00476     {
00477         _leaveFunctors.reserve(defaultLeave->size());
00478
00479         FunctorStoreConstIt fIt  = defaultLeave->begin() + _leaveFunctors.size();
00480         FunctorStoreConstIt fEnd = defaultLeave->end  ();
00481
00482         for(; fIt != fEnd; ++fIt)
00483         {
00484             _leaveFunctors.push_back(*fIt);
00485         }
00486     }
00487
00488     // call the start and see if it returns some nodes
00489
00490     _newList.clear();
00491
00492     if((res = start()) != Continue)
00493         return res;
00494
00495     // got some nodes? call them
00496
00497     if(! _newList.empty())
00498         res = callNewList();
00499
00500     // return the result
00501
00502     return res;
00503 }
00504
00505 // call the stop function and its results
00506
00507 ActionBase::ResultE Action::callStop(ResultE res)
00508 {
00509     // call the start and see if it returns some nodes
00510
00511     _newList.clear();
00512
00513     if((res = stop(res)) != Continue)
00514         return res;
00515
00516     if(! _newList.empty())
00517         res = callNewList();
00518
00519     return res;
00520 }
00521
00522 // default start/stop, does nothing
00523
00524 ActionBase::ResultE Action::start(void)
00525 {
00526     while(_sTravMask.empty() == false)
00527         _sTravMask.pop();
00528
00529     return Continue;
00530 }
00531
00532 ActionBase::ResultE Action::stop(ResultE res)
00533 {
00534     return res;
00535 }
00536
00537 /*-------------------------- assignment -----------------------------------*/
00538
00542 Action& Action::operator = (const Action &source)
00543 {
00544     if (this == &source)
00545         return *this;
00546
00547     return *this;
00548 }
00549
00550 /*-------------------------- comparison -----------------------------------*/
00551
00555 bool Action::operator < (const Action &other)
00556 {
00557     return this < &other;
00558 }
00559
00563 bool Action::operator == (const Action &OSG_CHECK_ARG(other))
00564 {
00565     return false;
00566 }
00567
00571 bool Action::operator != (const Action &other)
00572 {
00573     return ! (*this == other);
00574 }
00575
00576
00577 /*-------------------------------------------------------------------------*\
00578  -  protected                                                              -
00579 \*-------------------------------------------------------------------------*/
00580
00581 Action::FunctorStore* Action::getDefaultEnterFunctors(void)
00582 {
00583     return _defaultEnterFunctors;
00584 }
00585
00586 Action::FunctorStore* Action::getDefaultLeaveFunctors(void)
00587 {
00588     return _defaultLeaveFunctors;
00589 }
00590
00591
00592 /*-------------------------------------------------------------------------*\
00593  -  private                                                                -
00594 \*-------------------------------------------------------------------------*/
00595
00596 // default Action function: just call all kids
00597
00598 ActionBase::ResultE Action::_defaultEnterFunction(NodeCore * const,
00599                                                   Action   *      )
00600 {
00601     return Continue;
00602 }
00603
00604 ActionBase::ResultE Action::_defaultLeaveFunction(NodeCore * const,
00605                                                   Action   *      )
00606 {
00607     return Continue;
00608 }
00609
00610 /*************** Functions ******************/
00611
00612 OSG_BEGIN_NAMESPACE
00613
00614 /*
00615 inline
00616 ActionBase::ResultE doCallEnter(NodePtrConstArg       node, 
00617                                 TraverseEnterFunctor &func)
00618 {
00619     return func.call(node);
00620 }
00621 
00622 inline
00623 ActionBase::ResultE doCallLeave(NodePtrConstArg       node, 
00624                                 ActionBase::ResultE   res,
00625                                 TraverseLeaveFunctor &func)
00626 {
00627     return func.call(node, res);
00628 }
00629 */
00630
00634 ActionBase::ResultE traverse(const std::vector<Node *>  &nodeList,
00635                                    TraverseEnterFunctor  func    )
00636 {
00637     ActionBase::ResultE res = ActionBase::Continue;
00638
00639     std::vector<Node *>::const_iterator it = nodeList.begin();
00640     std::vector<Node *>::const_iterator en = nodeList.end  ();
00641
00642     for(; it != en; ++it)
00643     {
00644         res = traverse((*it), func);
00645
00646         if(res == ActionBase::Quit)
00647             break;
00648     }
00649
00650     return res;
00651 }
00652
00653 ActionBase::ResultE traverse(const MFUnrecChildNodePtr  &nodeList,
00654                                    TraverseEnterFunctor  func    )
00655 {
00656     ActionBase::ResultE res = ActionBase::Continue;
00657
00658     MFUnrecChildNodePtr::const_iterator it = nodeList.begin();
00659     MFUnrecChildNodePtr::const_iterator en = nodeList.end  ();
00660
00661     for(; it != en; ++it)
00662     {
00663         res = traverse((*it), func);
00664
00665         if(res == ActionBase::Quit)
00666             break;
00667     }
00668
00669     return res;
00670 }
00671
00675 ActionBase::ResultE traverse(Node                 * const node,
00676                              TraverseEnterFunctor         func )
00677 {
00678     ActionBase::ResultE res = ActionBase::Continue;
00679
00680     res = func(node);
00681
00682     if(node == NULL)
00683         return Action::Continue;
00684
00685     switch(res)
00686     {
00687         case ActionBase::Skip:
00688             return Action::Continue;
00689
00690         case ActionBase::Continue:
00691             return traverse(*(node->getMFChildren()),
00692                             func                    );
00693
00694         default:
00695             break;
00696     }
00697
00698     return res;
00699 }
00700
00705 ActionBase::ResultE traverse(const std::vector<Node *> &nodeList,
00706                                    TraverseEnterFunctor  enter,
00707                                    TraverseLeaveFunctor  leave )
00708 {
00709     ActionBase::ResultE res = ActionBase::Continue;
00710
00711     std::vector<Node *>::const_iterator it = nodeList.begin();
00712     std::vector<Node *>::const_iterator en = nodeList.end  ();
00713
00714     for(; it != en; ++it)
00715     {
00716         res = traverse((*it), enter, leave);
00717
00718         if(res == Action::Quit)
00719             break;
00720     }
00721
00722     return res;
00723 }
00724
00725 ActionBase::ResultE traverse(const MFUnrecChildNodePtr  &nodeList,
00726                                    TraverseEnterFunctor  enter,
00727                                    TraverseLeaveFunctor  leave )
00728 {
00729     ActionBase::ResultE res = ActionBase::Continue;
00730
00731     MFUnrecChildNodePtr::const_iterator it = nodeList.begin();
00732     MFUnrecChildNodePtr::const_iterator en = nodeList.end  ();
00733
00734     for(; it != en; ++it)
00735     {
00736         res = traverse((*it), enter, leave);
00737
00738         if(res == Action::Quit)
00739             break;
00740     }
00741
00742     return res;
00743 }
00744
00745
00750 ActionBase::ResultE traverse(Node                 * const node,
00751                              TraverseEnterFunctor         enter,
00752                              TraverseLeaveFunctor         leave)
00753 {
00754     ActionBase::ResultE res = ActionBase::Continue;
00755
00756     res = enter(node);
00757
00758     switch(res)
00759     {
00760         case ActionBase::Skip:
00761             res = Action::Continue;
00762             break;
00763
00764         case ActionBase::Continue:
00765             res = traverse(*(node->getMFChildren()),
00766                            enter,
00767                            leave                   );
00768
00769         default:
00770             break;
00771     }
00772
00773     res = leave(node, res);
00774
00775     return res;
00776 }
00777
00778 OSG_END_NAMESPACE