00001 /* Copyright (C) 2015-2017 Michele Colledanchise - All Rights Reserved 00002 * 00003 * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), 00004 * to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, 00005 * and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 00006 * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 00007 * 00008 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 00009 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 00010 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 00011 */ 00012 00013 #include <decorator_node.h> 00014 #include <string> 00015 00016 BT::DecoratorNode::DecoratorNode(std::string name) : ControlNode::ControlNode(name) {} 00017 00018 BT::DecoratorNode::~DecoratorNode() {} 00019 00020 void BT::DecoratorNode::AddChild(TreeNode* child) 00021 { 00022 // Verify if the decoretor doesn't already has a child 00023 if (children_nodes_.size() > 0) 00024 { 00025 throw BehaviorTreeException("'" + get_name() + " has a child already. A decorator is not capable of handling more than one child node."); 00026 return; 00027 } 00028 00029 child->set_has_parent(true); 00030 children_nodes_.push_back(child); 00031 children_states_.push_back(BT::IDLE); 00032 } 00033 00034 BT::ReturnStatus BT::DecoratorNode::Tick() 00035 { 00036 { 00037 // gets the number of children. The number could change if, at runtime, one edits the tree. 00038 N_of_children_ = children_nodes_.size(); 00039 00040 if (N_of_children_ > 0) 00041 { 00042 if (children_nodes_[0]->get_type() == BT::ACTION_NODE) 00043 { 00044 child_i_status_ = children_nodes_[0]->get_status(); 00045 00046 if (child_i_status_ == BT::IDLE || child_i_status_ == BT::HALTED) 00047 { 00048 DEBUG_STDOUT(get_name() << "NEEDS TO TICK " << children_nodes_[0]->get_name()); 00049 children_nodes_[0]->tick_engine.Tick(); 00050 00051 // waits for the tick to arrive to the child 00052 do 00053 { 00054 child_i_status_ = children_nodes_[0]->get_status(); 00055 std::this_thread::sleep_for(std::chrono::milliseconds(10)); 00056 } 00057 while (child_i_status_ != BT::RUNNING && child_i_status_ != BT::SUCCESS && child_i_status_ != BT::FAILURE); 00058 } 00059 } 00060 else 00061 { 00062 child_i_status_ = children_nodes_[0]->Tick(); 00063 } 00064 00065 if (child_i_status_ == BT::SUCCESS || child_i_status_ == BT::FAILURE) 00066 { 00067 children_nodes_[0]->set_status(BT::IDLE); 00068 } 00069 00070 if (child_i_status_ != BT::FAILURE) 00071 { 00072 HaltChildren(1); 00073 } 00074 00075 set_status(child_i_status_); 00076 return child_i_status_; 00077 } 00078 } 00079 return BT::EXIT; 00080 } 00081 00082 int BT::DecoratorNode::DrawType() 00083 { 00084 // Lock acquistion 00085 00086 return BT::DECORATOR; 00087 }