@@ -524,3 +524,69 @@ TEST(Parallel, Issue593)
524524
525525 ASSERT_EQ (0 , counters[0 ]);
526526}
527+
528+ TEST (Parallel, PauseWithRetry)
529+ {
530+ static const char * xml_text = R"(
531+ <root BTCPP_format="4">
532+ <BehaviorTree ID="TestTree">
533+ <Parallel>
534+ <Sequence>
535+ <Sleep msec="100"/>
536+ <Script code="paused := false"/>
537+ <Sleep msec="100"/>
538+ </Sequence>
539+
540+ <Sequence>
541+ <Script code="paused := true; done := false"/>
542+ <RetryUntilSuccessful _while="paused" num_attempts="-1" _onHalted="done = true">
543+ <AlwaysFailure/>
544+ </RetryUntilSuccessful>
545+ </Sequence>
546+ </Parallel>
547+ </BehaviorTree>
548+ </root>
549+ )" ;
550+ using namespace BT ;
551+
552+ BehaviorTreeFactory factory;
553+
554+ auto tree = factory.createTreeFromText (xml_text);
555+ auto t1 = std::chrono::system_clock::now ();
556+ std::chrono::system_clock::time_point done_time;
557+ bool done_detected = false ;
558+
559+ auto status = tree.tickExactlyOnce ();
560+
561+ while (!isStatusCompleted (status))
562+ {
563+ tree.sleep (std::chrono::milliseconds (1 ));
564+ if (!done_detected)
565+ {
566+ if (tree.subtrees .front ()->blackboard ->get <bool >(" done" ))
567+ {
568+ done_detected = true ;
569+ done_time = std::chrono::system_clock::now ();
570+ }
571+ }
572+ status = tree.tickExactlyOnce ();
573+ }
574+ auto t2 = std::chrono::system_clock::now ();
575+
576+ auto toMsec = [](const auto & t)
577+ {
578+ return std::chrono::duration_cast<std::chrono::milliseconds>(t).count ();
579+ };
580+
581+ ASSERT_EQ (NodeStatus::SUCCESS, status);
582+
583+ // tolerate an error in time measurement within this margin
584+ const int margin_msec = 5 ;
585+
586+ // the whole process should take about 200 milliseconds
587+ ASSERT_LE ( std::abs (toMsec (t2-t1) - 200 ), margin_msec );
588+ // the second branch with the RetryUntilSuccessful should take about 100 ms
589+ ASSERT_LE ( std::abs (toMsec (done_time-t1) - 100 ), margin_msec );
590+ }
591+
592+
0 commit comments