MCPcopy Create free account
hub / github.com/BehaviorTree/BehaviorTree.CPP / recursivelyCreateSubtree

Method recursivelyCreateSubtree

src/xml_parsing.cpp:1042–1262  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

1040}
1041
1042void BT::XMLParser::PImpl::recursivelyCreateSubtree(
1043 const std::string& tree_ID, const std::string& tree_path,
1044 const std::string& prefix_path, Tree& output_tree, Blackboard::Ptr blackboard,
1045 const TreeNode::Ptr& root_node, std::unordered_set<std::string>& ancestors)
1046{
1047 if(!ancestors.insert(tree_ID).second)
1048 {
1049 throw RuntimeError("Recursive behavior tree cycle detected: tree '", tree_ID,
1050 "' references itself (directly or indirectly)");
1051 }
1052 constexpr int kMaxNestingDepth = 256;
1053 std::function<void(const TreeNode::Ptr&, Tree::Subtree::Ptr, std::string,
1054 const XMLElement*, int)>
1055 recursiveStep;
1056
1057 recursiveStep = [&](TreeNode::Ptr parent_node, Tree::Subtree::Ptr subtree,
1058 std::string prefix, const XMLElement* element, int depth) {
1059 if(depth > kMaxNestingDepth)
1060 {
1061 throw RuntimeError("Maximum XML nesting depth exceeded during tree "
1062 "instantiation (limit: ",
1063 std::to_string(kMaxNestingDepth),
1064 "). The XML is too deeply nested.");
1065 }
1066 // create the node
1067 auto node = createNodeFromXML(element, blackboard, parent_node, prefix, output_tree);
1068 subtree->nodes.push_back(node);
1069
1070 // common case: iterate through all children
1071 if(node->type() != NodeType::SUBTREE)
1072 {
1073 for(auto child_element = element->FirstChildElement(); child_element != nullptr;
1074 child_element = child_element->NextSiblingElement())
1075 {
1076 recursiveStep(node, subtree, prefix, child_element, depth + 1);
1077 }
1078 }
1079 else // special case: SubTreeNode
1080 {
1081 auto new_bb = Blackboard::create(blackboard);
1082 // Inherit polymorphic cast registry from factory (Issue #943)
1083 new_bb->setPolymorphicCastRegistry(factory->polymorphicCastRegistryPtr());
1084 const std::string subtree_ID = element->Attribute("ID");
1085 std::unordered_map<std::string, std::string> subtree_remapping;
1086 bool do_autoremap = false;
1087
1088 for(auto attr = element->FirstAttribute(); attr != nullptr; attr = attr->Next())
1089 {
1090 const std::string attr_name = attr->Name();
1091 std::string attr_value = attr->Value();
1092 if(attr_value == "{=}")
1093 {
1094 attr_value = StrCat("{", attr_name, "}");
1095 }
1096
1097 if(attr_name == "_autoremap")
1098 {
1099 do_autoremap = convertFromString<bool>(attr_value);

Callers 1

instantiateTreeMethod · 0.80

Calls 15

RuntimeErrorClass · 0.85
createFunction · 0.85
StrCatFunction · 0.85
IsAllowedPortNameFunction · 0.85
stringFunction · 0.85
push_backMethod · 0.80
FirstChildElementMethod · 0.80
NextSiblingElementMethod · 0.80
AttributeMethod · 0.80
NameMethod · 0.80

Tested by

no test coverage detected