Skip to content

Commit

Permalink
Additional XML verification for ReactiveSequence nodes (BehaviorTree#885
Browse files Browse the repository at this point in the history
)

* 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 <[email protected]>
  • Loading branch information
AndyZe and AndyZe authored Dec 13, 2024
1 parent 40d535d commit d4d8ae1
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 0 deletions.
23 changes: 23 additions & 0 deletions src/xml_parsing.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
28 changes: 28 additions & 0 deletions tests/gtest_reactive.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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"(
<root BTCPP_format="4" >
<BehaviorTree ID="MainTree">
<ReactiveSequence>
<AsyncSequence name="first">
<TestA/>
<TestB/>
<TestC/>
</AsyncSequence>
<AsyncSequence name="second">
<TestD/>
<TestE/>
<TestF/>
</AsyncSequence>
</ReactiveSequence>
</BehaviorTree>
</root>
)";

BT::BehaviorTreeFactory factory;
std::array<int, 6> counters;
RegisterTestTick(factory, "Test", counters);

EXPECT_ANY_THROW(auto tree = factory.createTreeFromText(reactive_xml_text));
}

0 comments on commit d4d8ae1

Please sign in to comment.