| 23 | } |
| 24 | |
| 25 | NodeStatus ReactiveFallback::tick() |
| 26 | { |
| 27 | bool all_skipped = true; |
| 28 | if(status() == NodeStatus::IDLE) |
| 29 | { |
| 30 | running_child_ = -1; |
| 31 | } |
| 32 | setStatus(NodeStatus::RUNNING); |
| 33 | |
| 34 | for(size_t index = 0; index < childrenCount(); index++) |
| 35 | { |
| 36 | TreeNode* current_child_node = children_nodes_[index]; |
| 37 | const NodeStatus child_status = current_child_node->executeTick(); |
| 38 | |
| 39 | // switch to RUNNING state as soon as you find an active child |
| 40 | all_skipped &= (child_status == NodeStatus::SKIPPED); |
| 41 | |
| 42 | switch(child_status) |
| 43 | { |
| 44 | case NodeStatus::RUNNING: { |
| 45 | // reset the previous children, to make sure that they are |
| 46 | // in IDLE state the next time we tick them |
| 47 | for(size_t i = 0; i < childrenCount(); i++) |
| 48 | { |
| 49 | if(i != index) |
| 50 | { |
| 51 | haltChild(i); |
| 52 | } |
| 53 | } |
| 54 | if(running_child_ == -1) |
| 55 | { |
| 56 | running_child_ = static_cast<int>(index); |
| 57 | } |
| 58 | else if(throw_if_multiple_running && running_child_ != static_cast<int>(index)) |
| 59 | { |
| 60 | throw LogicError("[ReactiveFallback]: only a single child can return RUNNING.\n" |
| 61 | "This throw can be disabled with " |
| 62 | "ReactiveFallback::EnableException(false)"); |
| 63 | } |
| 64 | return NodeStatus::RUNNING; |
| 65 | } |
| 66 | |
| 67 | case NodeStatus::FAILURE: |
| 68 | break; |
| 69 | |
| 70 | case NodeStatus::SUCCESS: { |
| 71 | resetChildren(); |
| 72 | return NodeStatus::SUCCESS; |
| 73 | } |
| 74 | |
| 75 | case NodeStatus::SKIPPED: { |
| 76 | // to allow it to be skipped again, we must reset the node |
| 77 | haltChild(index); |
| 78 | } |
| 79 | break; |
| 80 | |
| 81 | case NodeStatus::IDLE: { |
| 82 | throw LogicError("[", name(), "]: A children should not return IDLE"); |
nothing calls this directly
no test coverage detected