diff --git a/src/xml_parsing.cpp b/src/xml_parsing.cpp
index e37836d0f..cbe1e99b9 100644
--- a/src/xml_parsing.cpp
+++ b/src/xml_parsing.cpp
@@ -666,10 +666,11 @@ void VerifyXML(const std::string& xml_text,
std::string("Unknown node type: ") + child_name);
}
const auto child_type = child_search->second;
+ // Only the asynchronous CONTROL nodes can be detected here: the
+ // manifest does not record whether an ACTION is asynchronous, so
+ // async leaf actions are not caught.
if(child_type == NodeType::CONTROL &&
- ((child_name == "ThreadedAction") ||
- (child_name == "StatefulActionNode") ||
- (child_name == "CoroActionNode") || (child_name == "AsyncSequence")))
+ ((child_name == "AsyncSequence") || (child_name == "AsyncFallback")))
{
++async_count;
if(async_count > 1)
diff --git a/tests/gtest_reactive.cpp b/tests/gtest_reactive.cpp
index 55c9176de..cc33b8953 100644
--- a/tests/gtest_reactive.cpp
+++ b/tests/gtest_reactive.cpp
@@ -187,6 +187,102 @@ TEST(Reactive, TwoAsyncNodesInReactiveSequence)
EXPECT_ANY_THROW(auto tree = factory.createTreeFromText(reactive_xml_text));
}
+TEST(Reactive, TwoAsyncFallbacksInReactiveSequence)
+{
+ 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));
+}
+
+TEST(Reactive, AsyncSequenceAndAsyncFallbackInReactiveSequence)
+{
+ 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));
+}
+
+// DISABLED: fails, not yet fixed.
+TEST(Reactive, DISABLED_TwoAsyncActionsInReactiveSequence)
+{
+ static const char* reactive_xml_text = R"(
+
+
+
+
+
+
+
+
+)";
+
+ BT::BehaviorTreeFactory factory;
+
+ EXPECT_ANY_THROW(auto tree = factory.createTreeFromText(reactive_xml_text));
+}
+
+TEST(Reactive, SingleAsyncChildInReactiveSequenceIsAllowed)
+{
+ static const char* reactive_xml_text = R"(
+
+
+
+
+
+
+
+
+
+
+
+)";
+
+ BT::BehaviorTreeFactory factory;
+ std::array counters{};
+ RegisterTestTick(factory, "Test", counters);
+
+ EXPECT_NO_THROW(auto tree = factory.createTreeFromText(reactive_xml_text));
+}
+
// ============ Phase 4: Additional Reactive Tests ============
TEST(Reactive, ReactiveSequence_FirstChildFails)