00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
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
00049
00050
00058
00059
00060
00061
00062
00063
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
00075
00076
00077
00078
00079
00080
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
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
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
00196
00197
00198
00199
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
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
00241 if ( ( res = callStart() ) != Continue )
00242 return res;
00243
00244
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
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
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 )
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
00352 Action::ResultE Action::callNewList(void)
00353 {
00354 Action::ResultE result = Continue;
00355
00356
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
00378
00379 Action::ResultE Action::callStart( void )
00380 {
00381 Action::ResultE res = Continue;
00382
00383
00384
00385 _newList.clear();
00386
00387 if ( ( res = start() ) != Continue )
00388 return res;
00389
00390
00391
00392 if ( ! _newList.empty() )
00393 res = callNewList();
00394
00395
00396
00397 return res;
00398 }
00399
00400
00401
00402 Action::ResultE Action::callStop( ResultE res )
00403 {
00404
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
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
00431
00435 Action& Action::operator = (const Action &source)
00436 {
00437 if (this == &source)
00438 return *this;
00439
00440
00441
00442
00443
00444
00445
00446
00447 return *this;
00448 }
00449
00450
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
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
00494
00495
00496
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
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 }