From d4d8ae13fabe82c88de7c1885ce226272015325a Mon Sep 17 00:00:00 2001 From: AndyZe Date: Fri, 13 Dec 2024 04:25:02 -0600 Subject: [PATCH] Additional XML verification for ReactiveSequence nodes (#885) * Additional XML verification for Control nodes * Parse for async nodes based on node name * Add a unit test * Improve the check by counting num async children * Minor update (const) --------- Co-authored-by: AndyZe --- src/xml_parsing.cpp | 23 +++++++++++++++++++++++ tests/gtest_reactive.cpp | 28 ++++++++++++++++++++++++++++ 2 files changed, 51 insertions(+) diff --git a/src/xml_parsing.cpp b/src/xml_parsing.cpp index 32a1e42ab..31e2f28f7 100644 --- a/src/xml_parsing.cpp +++ b/src/xml_parsing.cpp @@ -541,6 +541,29 @@ void VerifyXML(const std::string& xml_text, ThrowError(line_number, std::string("The node <") + name + "> must have 1 or more children"); } + if(name == "ReactiveSequence") + { + size_t async_count = 0; + for(auto child = node->FirstChildElement(); child != nullptr; + child = child->NextSiblingElement()) + { + const std::string child_name = node->FirstChildElement()->Name(); + const auto child_search = registered_nodes.find(child_name); + const auto child_type = child_search->second; + if(child_type == NodeType::CONTROL && + ((child_name == "ThreadedAction") || + (child_name == "StatefulActionNode") || + (child_name == "CoroActionNode") || (child_name == "AsyncSequence"))) + { + ++async_count; + if(async_count > 1) + { + ThrowError(line_number, std::string("A ReactiveSequence cannot have more " + "than one async child.")); + } + } + } + } } } //recursion diff --git a/tests/gtest_reactive.cpp b/tests/gtest_reactive.cpp index b393c03e8..47e4435ae 100644 --- a/tests/gtest_reactive.cpp +++ b/tests/gtest_reactive.cpp @@ -156,3 +156,31 @@ TEST(Reactive, TestLogging) ASSERT_EQ(observer.getStatistics("testA").success_count, num_ticks); ASSERT_EQ(observer.getStatistics("success").success_count, num_ticks); } + +TEST(Reactive, TwoAsyncNodesInReactiveSequence) +{ + static const char* reactive_xml_text = R"( + + + + + + + + + + + + + + + + +)"; + + BT::BehaviorTreeFactory factory; + std::array counters; + RegisterTestTick(factory, "Test", counters); + + EXPECT_ANY_THROW(auto tree = factory.createTreeFromText(reactive_xml_text)); +}