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 if(node->getOcclusionMask() & 1)
00297 return Continue;
00298
00299 NodeCorePtr core = node->getCore();
00300
00301 if ( core == NullFC )
00302 {
00303 SWARNING << "recurse: core is Null, don't know what to do!"
00304 << std::endl;
00305 return Quit;
00306 }
00307
00308 Action::ResultE result;
00309
00310 _actList = NULL;
00311 _actNode = node;
00312 _newList.clear();
00313 _useNewList = false;
00314
00315 result = callEnter( node );
00316
00317 if ( result != Continue )
00318 {
00319 if ( result == Skip )
00320 return Continue;
00321
00322 return result;
00323 }
00324
00325 if ( ! _newList.empty() )
00326 {
00327 result = callNewList();
00328 }
00329 else if ( ! _useNewList )
00330 {
00331 std::vector<NodePtr>::iterator it;
00332
00333 for ( it = node->getMFChildren()->begin(); it != node->getMFChildren()->end(); it ++ )
00334 {
00335 result = recurse( *it );
00336
00337 if ( result != Continue )
00338 break;
00339 }
00340 }
00341
00342 _actNode = node;
00343 if ( result == Continue )
00344 result = callLeave( node );
00345 else
00346 callLeave( node );
00347
00348 if ( result == Skip )
00349 return Continue;
00350
00351 return result;
00352 }
00353
00354
00355 Action::ResultE Action::callNewList(void)
00356 {
00357 Action::ResultE result = Continue;
00358
00359
00360
00361 std::vector<NodePtr> nodeList;
00362 nodeList.swap(_newList);
00363
00364 std::vector<NodePtr>::iterator it;
00365
00366 _actList = &nodeList;
00367
00368 for(it = nodeList.begin(); it != nodeList.end(); ++it)
00369 {
00370 result = recurse(*it);
00371
00372 if(result != Continue)
00373 break;
00374 }
00375
00376 return result;
00377 }
00378
00379
00380
00381
00382 Action::ResultE Action::callStart( void )
00383 {
00384 Action::ResultE res = Continue;
00385
00386
00387
00388 _newList.clear();
00389
00390 if ( ( res = start() ) != Continue )
00391 return res;
00392
00393
00394
00395 if ( ! _newList.empty() )
00396 res = callNewList();
00397
00398
00399
00400 return res;
00401 }
00402
00403
00404
00405 Action::ResultE Action::callStop( ResultE res )
00406 {
00407
00408
00409 _newList.clear();
00410
00411 if ( ( res = stop( res ) ) != Continue )
00412 return res;
00413
00414 if ( ! _newList.empty() )
00415 res = callNewList();
00416
00417 return res;
00418 }
00419
00420
00421
00422
00423 Action::ResultE Action::start( void )
00424 {
00425 return Continue;
00426 }
00427
00428 Action::ResultE Action::stop( ResultE res )
00429 {
00430 return res;
00431 }
00432
00433
00434
00438 Action& Action::operator = (const Action &source)
00439 {
00440 if (this == &source)
00441 return *this;
00442
00443
00444
00445
00446
00447
00448
00449
00450 return *this;
00451 }
00452
00453
00454
00458 bool Action::operator < (const Action &other)
00459 {
00460 return this < &other;
00461 }
00462
00466 bool Action::operator == (const Action &OSG_CHECK_ARG(other))
00467 {
00468 return false;
00469 }
00470
00474 bool Action::operator != (const Action &other)
00475 {
00476 return ! (*this == other);
00477 }
00478
00479
00480
00481
00482
00483
00484 std::vector<Action::Functor>* Action::getDefaultEnterFunctors( void )
00485 {
00486 return _defaultEnterFunctors;
00487 }
00488
00489 std::vector<Action::Functor>* Action::getDefaultLeaveFunctors( void )
00490 {
00491 return _defaultLeaveFunctors;
00492 }
00493
00494
00495
00496
00497
00498
00499
00500
00501 Action::ResultE Action::_defaultEnterFunction(CNodePtr &OSG_CHECK_ARG(node ),
00502 Action *OSG_CHECK_ARG(action))
00503 {
00504 return Continue;
00505 }
00506
00507 Action::ResultE Action::_defaultLeaveFunction(CNodePtr &OSG_CHECK_ARG(node ),
00508 Action *OSG_CHECK_ARG(action))
00509 {
00510 return Continue;
00511 }
00512
00513
00514
00515 OSG_BEGIN_NAMESPACE
00516
00517 inline
00518 Action::ResultE doCallEnter(NodePtr node,
00519 TraverseEnterFunctor &func)
00520 {
00521 return func.call(node);
00522 }
00523
00524 inline
00525 Action::ResultE doCallLeave(NodePtr node,
00526 Action::ResultE res,
00527 TraverseLeaveFunctor &func)
00528 {
00529 return func.call(node, res);
00530 }
00531
00532 OSG_END_NAMESPACE
00533
00536 OSG_SYSTEMLIB_DLLMAPPING
00537 Action::ResultE OSG::traverse(std::vector<NodePtr> &nodeList,
00538 TraverseEnterFunctor func )
00539 {
00540 Action::ResultE res = Action::Continue;
00541
00542 std::vector<NodePtr>::iterator it = nodeList.begin();
00543 std::vector<NodePtr>::iterator en = nodeList.end ();
00544
00545 for ( ; it != en; ++it )
00546 {
00547 res = traverse((*it), func);
00548
00549 if(res == Action::Quit)
00550 break;
00551 }
00552
00553 return res;
00554 }
00555
00558 OSG_SYSTEMLIB_DLLMAPPING
00559 Action::ResultE OSG::traverse( NodePtr node,
00560 TraverseEnterFunctor func )
00561 {
00562 Action::ResultE res = Action::Continue;
00563
00564 res = doCallEnter(node, func);
00565
00566 switch(res)
00567 {
00568 case Action::Skip: return Action::Continue;
00569 case Action::Continue: return traverse( node->getMFChildren()->getValues(),
00570 func );
00571 default: break;
00572 }
00573
00574 return res;
00575 }
00576
00580 OSG_SYSTEMLIB_DLLMAPPING
00581 Action::ResultE OSG::traverse(std::vector<NodePtr> &nodeList,
00582 TraverseEnterFunctor enter,
00583 TraverseLeaveFunctor leave )
00584 {
00585 Action::ResultE res = Action::Continue;
00586
00587 std::vector<NodePtr>::iterator it = nodeList.begin();
00588 std::vector<NodePtr>::iterator en = nodeList.end ();
00589
00590 for ( ; it != en; ++it )
00591 {
00592 res = traverse((*it), enter, leave);
00593
00594 if(res == Action::Quit)
00595 break;
00596 }
00597
00598 return res;
00599 }
00600
00601
00605 OSG_SYSTEMLIB_DLLMAPPING
00606 Action::ResultE OSG::traverse( NodePtr node,
00607 TraverseEnterFunctor enter,
00608 TraverseLeaveFunctor leave )
00609 {
00610 Action::ResultE res = Action::Continue;
00611
00612 res = doCallEnter(node, enter);
00613
00614 switch(res)
00615 {
00616 case Action::Skip: res = Action::Continue;
00617 break;
00618 case Action::Continue: res = traverse( node->getMFChildren()->getValues(),
00619 enter, leave );
00620 default: break;
00621 }
00622
00623 res = doCallLeave(node, res, leave);
00624
00625 return res;
00626 }