diff --git a/include/behaviortree_cpp_v3/bt_factory.h b/include/behaviortree_cpp_v3/bt_factory.h index e369bb4f5..4191d6329 100644 --- a/include/behaviortree_cpp_v3/bt_factory.h +++ b/include/behaviortree_cpp_v3/bt_factory.h @@ -316,6 +316,11 @@ class BehaviorTreeFactory /// registerBehaviorTreeFromFile or registerBehaviorTreeFromText. std::vector registeredBehaviorTrees() const; + /** + * @brief Clear previously-registered behavior trees. + */ + void clearRegisteredBehaviorTrees(); + /** * @brief instantiateTreeNode creates an instance of a previously registered TreeNode. * diff --git a/include/behaviortree_cpp_v3/bt_parser.h b/include/behaviortree_cpp_v3/bt_parser.h index b09a1d878..64cc310c3 100644 --- a/include/behaviortree_cpp_v3/bt_parser.h +++ b/include/behaviortree_cpp_v3/bt_parser.h @@ -40,6 +40,8 @@ class Parser virtual Tree instantiateTree(const Blackboard::Ptr& root_blackboard, std::string tree_name = {}) = 0; + + virtual void clearInternalState() {}; }; } // namespace BT diff --git a/include/behaviortree_cpp_v3/xml_parsing.h b/include/behaviortree_cpp_v3/xml_parsing.h index 1b5bc0899..2b136bc28 100644 --- a/include/behaviortree_cpp_v3/xml_parsing.h +++ b/include/behaviortree_cpp_v3/xml_parsing.h @@ -31,6 +31,8 @@ class XMLParser : public Parser Tree instantiateTree(const Blackboard::Ptr& root_blackboard, std::string main_tree_to_execute = {}) override; + void clearInternalState() override; + private: struct Pimpl; Pimpl* _p; diff --git a/src/bt_factory.cpp b/src/bt_factory.cpp index 050987368..62fd6f32b 100644 --- a/src/bt_factory.cpp +++ b/src/bt_factory.cpp @@ -227,7 +227,7 @@ void BehaviorTreeFactory::registerBehaviorTreeFromFile(const std::string& filena void BehaviorTreeFactory::registerBehaviorTreeFromText(const std::string& xml_text) { - parser_->loadFromText(xml_text); + parser_->loadFromText(xml_text, true /* add_includes */); } std::vector BehaviorTreeFactory::registeredBehaviorTrees() const @@ -235,6 +235,11 @@ std::vector BehaviorTreeFactory::registeredBehaviorTrees() const return parser_->registeredBehaviorTrees(); } +void BehaviorTreeFactory::clearRegisteredBehaviorTrees() +{ + parser_->clearInternalState(); +} + std::unique_ptr BehaviorTreeFactory::instantiateTreeNode( const std::string& name, const std::string& ID, const NodeConfiguration& config) const { diff --git a/src/xml_parsing.cpp b/src/xml_parsing.cpp index c54354f4f..67f91deec 100644 --- a/src/xml_parsing.cpp +++ b/src/xml_parsing.cpp @@ -484,6 +484,11 @@ Tree XMLParser::instantiateTree(const Blackboard::Ptr& root_blackboard, return output_tree; } +void XMLParser::clearInternalState() +{ + _p->clear(); +} + TreeNode::Ptr XMLParser::Pimpl::createNodeFromXML(const XMLElement* element, const Blackboard::Ptr& blackboard, const TreeNode::Ptr& node_parent) diff --git a/tests/gtest_factory.cpp b/tests/gtest_factory.cpp index c39952477..27096dfc1 100644 --- a/tests/gtest_factory.cpp +++ b/tests/gtest_factory.cpp @@ -407,3 +407,49 @@ TEST(BehaviorTreeFactory, DecoratorWithTwoChildrenThrows) ASSERT_THROW(factory.createTreeFromText(xml_text), BehaviorTreeException); } + +TEST(BehaviorTreeFactory, ParserClearRegisteredBehaviorTrees) +{ + const std::string tree_xml = R"( + + + + + +)"; + + BehaviorTreeFactory factory; + XMLParser parser(factory); + + ASSERT_NO_THROW(parser.loadFromText(tree_xml)); + + const auto trees = parser.registeredBehaviorTrees(); + ASSERT_FALSE(trees.empty()); + + parser.clearInternalState(); + + const auto trees_after_clear = parser.registeredBehaviorTrees(); + EXPECT_TRUE(trees_after_clear.empty()); +} + +TEST(BehaviorTreeFactory, FactoryClearRegisteredBehaviorTrees) +{ + BehaviorTreeFactory factory; + const std::string tree_xml = R"( + + + + + +)"; + + ASSERT_NO_THROW(factory.registerBehaviorTreeFromText(tree_xml)); + + const auto trees = factory.registeredBehaviorTrees(); + ASSERT_FALSE(trees.empty()); + + factory.clearRegisteredBehaviorTrees(); + + const auto trees_after_clear = factory.registeredBehaviorTrees(); + EXPECT_TRUE(trees_after_clear.empty()); +}