Skip to content

Commit fe1e1a1

Browse files
committed
Consistently terminate composites
1 parent 1496ec3 commit fe1e1a1

File tree

1 file changed

+21
-7
lines changed

1 file changed

+21
-7
lines changed

py_trees/composites.py

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,7 @@ def update(self) -> common.Status:
120120
behaviours do the real work.
121121
122122
Such flows are a consequence of how the composite
123-
interacts with it's children. The success of
123+
interacts with its children. The success of
124124
behaviour trees depends on this logic being simple,
125125
well defined and limited to a few well established
126126
patterns - this is what ensures that visualising
@@ -391,7 +391,7 @@ def tick(self) -> typing.Iterator[behaviour.Behaviour]:
391391
Customise the tick behaviour for a selector.
392392
393393
This implements priority-interrupt style handling amongst the selector's children.
394-
The selector's status is always a reflection of it's children's status.
394+
The selector's status is always a reflection of its children's status.
395395
396396
Yields:
397397
:class:`~py_trees.behaviour.Behaviour`: a reference to itself or one of its children
@@ -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:
@@ -560,13 +568,19 @@ def tick(self) -> typing.Iterator[behaviour.Behaviour]:
560568
for node in child.tick():
561569
yield node
562570
if node is child and node.status != common.Status.SUCCESS:
563-
self.status = node.status
564571
if not self.memory:
565572
# invalidate the remainder of the sequence
566573
# i.e. kill dangling runners
567574
for child in itertools.islice(self.children, index + 1, None):
568575
if child.status != common.Status.INVALID:
569576
child.stop(common.Status.INVALID)
577+
578+
# stop the sequence if a terminal (non-success) state was reached
579+
if node.status != common.Status.RUNNING:
580+
self.stop(node.status)
581+
else:
582+
self.status = node.status
583+
570584
yield self
571585
return
572586
try:
@@ -666,7 +680,7 @@ def setup(self, **kwargs: typing.Any) -> None:
666680
667681
Args:
668682
**kwargs (:obj:`dict`): distribute arguments to this
669-
behaviour and in turn, all of it's children
683+
behaviour and in turn, all of its children
670684
671685
Raises:
672686
RuntimeError: if the parallel's policy configuration is invalid

0 commit comments

Comments
 (0)