源码解析之Sequence"/>
BT7:ControlNodes源码解析之Sequence
大家好,欢迎大家关注我的知乎专栏慢慢悠悠小马车
SequenceNode
最常见的control node,按从左到右的顺序依次执行子节点。
如果某个子节点返回RUNNING,返回RUNNING,且下次tick()时之前的子节点不会再执行。类内维护当前执行节点的标号current_child_idx_。
如果某个子节点返回SUCCESS,立即执行下一个子节点(不会等下一次tick())。如果所有子节点返回SUCCESS,返回SUCCESS。
如果某个子节点返回FAILURE,返回FAILURE,并且复位所有成员变量(尤其注意current_child_idx_)。当再次tick()时,从头开始。
NodeStatus SequenceNode::tick() {const size_t children_count = children_nodes_.size();setStatus(NodeStatus::RUNNING);while (current_child_idx_ < children_count) {TreeNode* current_child_node = children_nodes_[current_child_idx_];const NodeStatus child_status = current_child_node->executeTick();switch (child_status) {case NodeStatus::RUNNING: {return child_status;}case NodeStatus::FAILURE: {// Reset on failurehaltChildren();current_child_idx_ = 0;return child_status;}case NodeStatus::SUCCESS: {current_child_idx_++;} break;case NodeStatus::IDLE: {throw LogicError("A child node must never return IDLE");}} // end switch} // end while loop// The entire while loop completed. This means that all the children returned SUCCESS.if (current_child_idx_ == children_count) {haltChildren();current_child_idx_ = 0;}return NodeStatus::SUCCESS;
}
SequenceStarNode
同上,不同之处在于如果某个子节点返回FAILURE,返回FAILURE,终止所有节点的执行,但不复位current_child_idx_。所以当再次tick()时,从FAILURE的子节点开始。
NodeStatus SequenceStarNode::tick() {...while (current_child_idx_ < children_count) {TreeNode* current_child_node = children_nodes_[current_child_idx_];const NodeStatus child_status = current_child_node->executeTick();switch (child_status) { case NodeStatus::FAILURE: {// DO NOT reset current_child_idx_ on failurefor (size_t i = current_child_idx_; i < childrenCount(); i++) {haltChild(i);}return child_status;}...} // end switch} // end while loop...
}
ReactiveSequence
是SequneceNode的reactive版本,和ParallelNode类似,常用来周期检查某个外部条件是否成立。类内不保存当前执行节点的标号。
如果某个子节点返回RUNNING,返回RUNNING,终止其他节点,下次tick()时从头开始执行。reactive所在。
如果某个子节点返回SUCCESS,立即执行下一个子节点(不会等下一次tick())。如果所有子节点返回SUCCESS,返回SUCCESS。
如果某个子节点返回FAILURE,返回FAILURE,终止所有节点,下次tick()时从头开始执行。
NodeStatus ReactiveSequence::tick() {for (size_t index = 0; index < childrenCount(); index++) {TreeNode* current_child_node = children_nodes_[index];const NodeStatus child_status = current_child_node->executeTick();switch (child_status) {case NodeStatus::RUNNING: {for (size_t i = index + 1; i < childrenCount(); i++) {haltChild(i);}return NodeStatus::RUNNING;}case NodeStatus::FAILURE: {haltChildren();return NodeStatus::FAILURE;}...} // end switch} // end for...
}
3种node的差异可以总结如下:
更多推荐
BT7:ControlNodes源码解析之Sequence
发布评论