OSGAction.cpp
Go to the documentation of this file.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 <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
00043 #include <boost/bind.hpp>
00044
00045 OSG_USING_NAMESPACE
00046
00047
00048
00049
00050
00051
00059
00060
00061
00062
00063
00064
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
00075
00076
00077
00078
00079
00080
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
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
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
00207
00208
00209
00210
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
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
00258
00259 if((res = callStart()) != Continue)
00260 return res;
00261
00262
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
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
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)
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
00384 ActionBase::ResultE Action::callNewList(void)
00385 {
00386 ResultE result = Continue;
00387
00388
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
00411
00412 ActionBase::ResultE Action::callStart(void)
00413 {
00414 ResultE res = Continue;
00415
00416
00417
00418 _newList.clear();
00419
00420 if((res = start()) != Continue)
00421 return res;
00422
00423
00424
00425 if(! _newList.empty())
00426 res = callNewList();
00427
00428
00429
00430 return res;
00431 }
00432
00433
00434
00435 ActionBase::ResultE Action::callStop(ResultE res)
00436 {
00437
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
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
00463
00467 Action& Action::operator = (const Action &source)
00468 {
00469 if (this == &source)
00470 return *this;
00471
00472 return *this;
00473 }
00474
00475
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
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
00519
00520
00521
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
00536
00537 OSG_BEGIN_NAMESPACE
00538
00539
00540
00541
00542
00543
00544
00545
00546
00547
00548
00549
00550
00551
00552
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