diff --git a/src/xml_parsing.cpp b/src/xml_parsing.cpp index 4c9a57b1c..02ee7fb3f 100644 --- a/src/xml_parsing.cpp +++ b/src/xml_parsing.cpp @@ -679,10 +679,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..c38ef11c7 100644 --- a/tests/gtest_reactive.cpp +++ b/tests/gtest_reactive.cpp @@ -187,6 +187,83 @@ 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)); +} + +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)