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)