Skip to content

Commit 4008f92

Browse files
committed
Selectors are now evaluated differently for aborts
1 parent 14f5955 commit 4008f92

File tree

8 files changed

+154
-6
lines changed

8 files changed

+154
-6
lines changed

Assets/FluidBehaviorTree/Editor/Testing/Builders/TaskStubBuilder.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ public ITask Build () {
3030
var task = Substitute.For<ITask>();
3131
task.Enabled.Returns(_enabled);
3232
task.Update().Returns(_status);
33+
task.GetAbortStatus().Returns(i => task.Update());
3334

3435
if (_abortConditionSelf) {
3536
task.GetAbortCondition().Returns(task);

Assets/FluidBehaviorTree/Editor/Testing/ParentTasks/TaskSequenceTest.cs

Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -226,6 +226,120 @@ public void Triggers_on_lower_priority_3rd_sibling () {
226226

227227
Assert.AreEqual(TaskStatus.Failure, _sequence.Update());
228228
}
229+
230+
public class WithSelector : UpdateMethod {
231+
[Test]
232+
public void Triggers_failure_on_revaluation () {
233+
var childContinue = A.TaskStub()
234+
.WithUpdateStatus(TaskStatus.Continue)
235+
.Build();
236+
237+
var childCondition = A.TaskStub()
238+
.WithAbortConditionSelf(true)
239+
.WithUpdateStatus(TaskStatus.Success)
240+
.Build();
241+
242+
var selector = new Selector {AbortType = AbortType.LowerPriority}
243+
.AddChild(childCondition);
244+
245+
_sequence.AddChild(selector)
246+
.AddChild(childContinue);
247+
248+
Assert.AreEqual(TaskStatus.Continue, _sequence.Update());
249+
250+
childCondition.Update().Returns(TaskStatus.Failure);
251+
252+
Assert.AreEqual(TaskStatus.Failure, _sequence.Update());
253+
}
254+
255+
[Test]
256+
public void Triggers_failure_on_revaluation_of_2nd_child () {
257+
var childContinue = A.TaskStub()
258+
.WithUpdateStatus(TaskStatus.Continue)
259+
.Build();
260+
261+
var childCondition = A.TaskStub()
262+
.WithAbortConditionSelf(true)
263+
.WithUpdateStatus(TaskStatus.Success)
264+
.Build();
265+
266+
var selector = new Selector {AbortType = AbortType.LowerPriority}
267+
.AddChild(childCondition);
268+
269+
_sequence
270+
.AddChild(A.TaskStub().Build())
271+
.AddChild(selector)
272+
.AddChild(childContinue);
273+
274+
Assert.AreEqual(TaskStatus.Continue, _sequence.Update());
275+
276+
childCondition.Update().Returns(TaskStatus.Failure);
277+
278+
Assert.AreEqual(TaskStatus.Failure, _sequence.Update());
279+
}
280+
281+
[Test]
282+
public void Triggers_continue_on_revaluation_with_2nd_selector_condition_as_success () {
283+
var childContinue = A.TaskStub()
284+
.WithUpdateStatus(TaskStatus.Continue)
285+
.Build();
286+
287+
var childConditionA = A.TaskStub()
288+
.WithAbortConditionSelf(true)
289+
.WithUpdateStatus(TaskStatus.Success)
290+
.Build();
291+
292+
var childConditionB = A.TaskStub()
293+
.WithAbortConditionSelf(true)
294+
.WithUpdateStatus(TaskStatus.Success)
295+
.Build();
296+
297+
var selector = new Selector {AbortType = AbortType.LowerPriority}
298+
.AddChild(childConditionA)
299+
.AddChild(childConditionB);
300+
301+
_sequence
302+
.AddChild(selector)
303+
.AddChild(childContinue);
304+
305+
Assert.AreEqual(TaskStatus.Continue, _sequence.Update());
306+
307+
childConditionA.Update().Returns(TaskStatus.Failure);
308+
309+
Assert.AreEqual(TaskStatus.Continue, _sequence.Update());
310+
}
311+
312+
[Test]
313+
public void Triggers_failure_on_revaluation_with_2nd_condition () {
314+
var childContinue = A.TaskStub()
315+
.WithUpdateStatus(TaskStatus.Continue)
316+
.Build();
317+
318+
var childConditionA = A.TaskStub()
319+
.WithAbortConditionSelf(true)
320+
.WithUpdateStatus(TaskStatus.Failure)
321+
.Build();
322+
323+
var childConditionB = A.TaskStub()
324+
.WithAbortConditionSelf(true)
325+
.WithUpdateStatus(TaskStatus.Success)
326+
.Build();
327+
328+
var selector = new Selector {AbortType = AbortType.LowerPriority}
329+
.AddChild(childConditionA)
330+
.AddChild(childConditionB);
331+
332+
_sequence
333+
.AddChild(selector)
334+
.AddChild(childContinue);
335+
336+
Assert.AreEqual(TaskStatus.Continue, _sequence.Update());
337+
338+
childConditionB.Update().Returns(TaskStatus.Failure);
339+
340+
Assert.AreEqual(TaskStatus.Failure, _sequence.Update());
341+
}
342+
}
229343
}
230344

231345
public class WhenAbortSelf : UpdateMethod {

Assets/FluidBehaviorTree/Scripts/TaskParents/Composites/CompositeBase.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ protected bool AbortSelf (TaskStatus requiredStatus) {
3333
if (!AbortType.HasFlag(AbortType.Self)
3434
|| ChildIndex <= 0
3535
|| SelfAbortTask == null
36-
|| SelfAbortTask.Update() != requiredStatus) {
36+
|| SelfAbortTask.GetAbortStatus() != requiredStatus) {
3737
return false;
3838
}
3939

Assets/FluidBehaviorTree/Scripts/TaskParents/Composites/Selector.cs

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,10 @@ protected override TaskStatus OnUpdate () {
88
}
99

1010
foreach (var abort in AbortLowerPriorities) {
11-
if (abort.Update() != TaskStatus.Success) continue;
11+
if (abort.GetAbortStatus() != TaskStatus.Success) continue;
1212
children[ChildIndex].End();
1313
Reset();
14-
// @TODO Should use the abort's index to figure out what to revaluate
14+
// @TODO Should use the abort's index to figure out what to revaluate (should not run entire branch)
1515
return Update();
1616
}
1717

@@ -38,5 +38,23 @@ protected override TaskStatus OnUpdate () {
3838

3939
return TaskStatus.Failure;
4040
}
41+
42+
public override ITask GetAbortCondition () {
43+
return this;
44+
}
45+
46+
// @TODO Cache the abort children on first run since they will never change
47+
public override TaskStatus GetAbortStatus () {
48+
foreach (var child in children) {
49+
var abort = child.GetAbortCondition();
50+
if (abort == null) continue;
51+
52+
if (abort.GetAbortStatus() == TaskStatus.Success) {
53+
return TaskStatus.Success;
54+
}
55+
}
56+
57+
return TaskStatus.Failure;
58+
}
4159
}
4260
}

Assets/FluidBehaviorTree/Scripts/TaskParents/Composites/Sequence.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ protected override TaskStatus OnUpdate () {
88
}
99

1010
foreach (var abort in AbortLowerPriorities) {
11-
if (abort.Update() != TaskStatus.Failure) continue;
11+
if (abort.GetAbortStatus() != TaskStatus.Failure) continue;
1212
children[ChildIndex].End();
1313
Reset();
1414
return TaskStatus.Failure;

Assets/FluidBehaviorTree/Scripts/TaskParents/TaskParentBase.cs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,7 @@ public TaskStatus Update () {
2323
return OnUpdate();
2424
}
2525

26-
// @TODO Should allow returning multiple conditions (for selectors)
27-
public ITask GetAbortCondition () {
26+
public virtual ITask GetAbortCondition () {
2827
if (children.Count > 0) {
2928
return children[0].GetAbortCondition();
3029
}
@@ -58,5 +57,9 @@ public virtual ITaskParent AddChild (ITask child) {
5857

5958
return this;
6059
}
60+
61+
public virtual TaskStatus GetAbortStatus () {
62+
throw new System.NotImplementedException();
63+
}
6164
}
6265
}

Assets/FluidBehaviorTree/Scripts/Tasks/ITask.cs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,5 +33,13 @@ public interface ITask {
3333
/// </summary>
3434
/// <param name="hardReset"></param>
3535
void Reset (bool hardReset = false);
36+
37+
/// <summary>
38+
/// Query this parent task to get the correct corresponding abort type
39+
/// Example selector tries all valid conditions until success (or returns failure), while
40+
/// sequence returns first item
41+
/// </summary>
42+
/// <returns></returns>
43+
TaskStatus GetAbortStatus ();
3644
}
3745
}

Assets/FluidBehaviorTree/Scripts/Tasks/TaskBase.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,10 @@ public void Reset (bool hardReset = false) {
4444
}
4545
}
4646

47+
public TaskStatus GetAbortStatus () {
48+
return Update();
49+
}
50+
4751
public void End () {
4852
Exit();
4953
}

0 commit comments

Comments
 (0)