Skip to content

Commit 5961531

Browse files
authored
[composites] Consistently terminate composites (#481)
1 parent 858809a commit 5961531

File tree

1 file changed

+20
-7
lines changed

1 file changed

+20
-7
lines changed

py_trees/composites.py

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -427,7 +427,8 @@ def tick(self) -> typing.Iterator[behaviour.Behaviour]:
427427
# clear out preceding status' - not actually necessary but helps
428428
# visualise the case of memory vs no memory
429429
for child in itertools.islice(self.children, None, index):
430-
child.stop(common.Status.INVALID)
430+
if child.status != common.Status.INVALID:
431+
child.stop(common.Status.INVALID)
431432
else:
432433
index = 0
433434

@@ -442,7 +443,6 @@ def tick(self) -> typing.Iterator[behaviour.Behaviour]:
442443
or node.status == common.Status.SUCCESS
443444
):
444445
self.current_child = child
445-
self.status = node.status
446446
if previous is None or previous != self.current_child:
447447
# we interrupted, invalidate everything at a lower priority
448448
passed = False
@@ -451,10 +451,18 @@ def tick(self) -> typing.Iterator[behaviour.Behaviour]:
451451
if child.status != common.Status.INVALID:
452452
child.stop(common.Status.INVALID)
453453
passed = True if child == self.current_child else passed
454+
455+
# terminate the selector if a terminal state was reached
456+
if node.status == common.Status.SUCCESS:
457+
self.stop(node.status)
458+
else:
459+
self.status = node.status
460+
454461
yield self
455462
return
463+
456464
# all children failed, set failure ourselves and current child to the last bugger who failed us
457-
self.status = common.Status.FAILURE
465+
self.stop(common.Status.FAILURE)
458466
try:
459467
self.current_child = self.children[-1]
460468
except IndexError:
@@ -539,10 +547,9 @@ def tick(self) -> typing.Iterator[behaviour.Behaviour]:
539547
if child.status != common.Status.INVALID:
540548
child.stop(common.Status.INVALID)
541549
self.initialise() # user specific initialisation
542-
elif self.memory and common.Status.RUNNING:
543-
assert self.current_child is not None # should never be true, help mypy out
550+
elif self.memory and self.current_child is not None:
544551
index = self.children.index(self.current_child)
545-
elif not self.memory and common.Status.RUNNING:
552+
elif not self.memory:
546553
self.current_child = self.children[0] if self.children else None
547554
else:
548555
# previous conditional checks should cover all variations
@@ -560,13 +567,19 @@ def tick(self) -> typing.Iterator[behaviour.Behaviour]:
560567
for node in child.tick():
561568
yield node
562569
if node is child and node.status != common.Status.SUCCESS:
563-
self.status = node.status
564570
if not self.memory:
565571
# invalidate the remainder of the sequence
566572
# i.e. kill dangling runners
567573
for child in itertools.islice(self.children, index + 1, None):
568574
if child.status != common.Status.INVALID:
569575
child.stop(common.Status.INVALID)
576+
577+
# stop the sequence if a terminal (non-success) state was reached
578+
if node.status != common.Status.RUNNING:
579+
self.stop(node.status)
580+
else:
581+
self.status = node.status
582+
570583
yield self
571584
return
572585
try:

0 commit comments

Comments
 (0)