@@ -52,9 +52,6 @@ NodeStatus ParallelNode::tick()
5252 }
5353 }
5454
55- size_t success_children_num = 0 ;
56- size_t failure_children_num = 0 ;
57-
5855 const size_t children_count = children_nodes_.size ();
5956
6057 if (children_count < successThreshold ())
@@ -67,79 +64,81 @@ NodeStatus ParallelNode::tick()
6764 throw LogicError (" Number of children is less than threshold. Can never fail." );
6865 }
6966
70- if (status () == NodeStatus::IDLE)
71- {
72- all_skipped_ = true ;
73- }
7467 setStatus (NodeStatus::RUNNING);
7568
69+ size_t skipped_count = 0 ;
70+
7671 // Routing the tree according to the sequence node's logic:
7772 for (size_t i = 0 ; i < children_count; i++)
7873 {
79- TreeNode* child_node = children_nodes_[i];
80-
81- bool const in_skip_list = (skip_list_.count (i) != 0 );
82-
83- NodeStatus const prev_status = child_node->status ();
84- NodeStatus const child_status =
85- in_skip_list ? prev_status : child_node->executeTick ();
74+ if (completed_list_.count (i) == 0 )
75+ {
76+ TreeNode* child_node = children_nodes_[i];
77+ NodeStatus const child_status = child_node->executeTick ();
78+
79+ switch (child_status)
80+ {
81+ case NodeStatus::SKIPPED: {
82+ skipped_count++;
83+ } break ;
84+
85+ case NodeStatus::SUCCESS: {
86+ completed_list_.insert (i);
87+ success_count_++;
88+ }
89+ break ;
8690
87- // switch to RUNNING state as soon as you find an active child
88- all_skipped_ &= (child_status == NodeStatus::SKIPPED);
91+ case NodeStatus::FAILURE: {
92+ completed_list_.insert (i);
93+ failure_count_++;
94+ }
95+ break ;
8996
90- switch (child_status)
91- {
92- case NodeStatus::SUCCESS: {
93- skip_list_.insert (i);
94- success_children_num++;
95-
96- if (success_children_num == successThreshold ())
97- {
98- skip_list_.clear ();
99- resetChildren ();
100- return NodeStatus::SUCCESS;
97+ case NodeStatus::RUNNING: {
98+ // Still working. Check the next
10199 }
102- }
103- break ;
104-
105- case NodeStatus::FAILURE: {
106- skip_list_.insert (i);
107- failure_children_num++;
108-
109- // It fails if it is not possible to succeed anymore or if
110- // number of failures are equal to failure_threshold_
111- if ((failure_children_num > children_count - successThreshold ()) ||
112- (failure_children_num == failureThreshold ()))
113- {
114- skip_list_.clear ();
115- resetChildren ();
116- return NodeStatus::FAILURE;
100+ break ;
101+
102+ case NodeStatus::IDLE: {
103+ throw LogicError (" [" , name (), " ]: A children should not return IDLE" );
117104 }
118105 }
119- break ;
106+ }
120107
121- case NodeStatus::RUNNING: {
122- // Still working. Check the next
123- }
124- break ;
108+ const size_t required_success_count = successThreshold ();
125109
126- case NodeStatus::SKIPPED: {
127- // Node requested to be skipped or halted. Check the next
128- }
129- break ;
110+ if (success_count_ >= required_success_count ||
111+ (success_threshold_ < 0 && (success_count_ + skipped_count) >= required_success_count))
112+ {
113+ clear ();
114+ resetChildren ();
115+ return NodeStatus::SUCCESS;
116+ }
130117
131- case NodeStatus::IDLE: {
132- throw LogicError (" [" , name (), " ]: A children should not return IDLE" );
133- }
118+ // It fails if it is not possible to succeed anymore or if
119+ // number of failures are equal to failure_threshold_
120+ if (((children_count - failure_count_) < required_success_count) ||
121+ (failure_count_ == failureThreshold ()))
122+ {
123+ clear ();
124+ resetChildren ();
125+ return NodeStatus::FAILURE;
134126 }
135127 }
136128 // Skip if ALL the nodes have been skipped
137- return all_skipped_ ? NodeStatus::SKIPPED : NodeStatus::RUNNING;
129+ return (skipped_count == children_count) ? NodeStatus::SKIPPED : NodeStatus::RUNNING;
130+ }
131+
132+ void ParallelNode::clear ()
133+ {
134+ completed_list_.clear ();
135+ success_count_ = 0 ;
136+ failure_count_ = 0 ;
138137}
139138
140139void ParallelNode::halt ()
141140{
142- skip_list_. clear ();
141+ clear ();
143142 ControlNode::halt ();
144143}
145144
0 commit comments