-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathBehaviourBuilder.cs
More file actions
148 lines (137 loc) · 4.34 KB
/
BehaviourBuilder.cs
File metadata and controls
148 lines (137 loc) · 4.34 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
using System;
using System.Collections.Generic;
using FluentBehaviour.Nodes;
namespace FluentBehaviour
{
public class BehaviourBuilder
{
/// <summary>
/// Represents the last node added to the tree (after End() was called)
/// </summary>
private IBranchNode? lastPoppedNode;
private readonly Stack<IBranchNode> branchNodeStack = new Stack<IBranchNode>();
//Task node builders
public BehaviourBuilder Task(string name, Func<TimeData, NodeStatus> task)
{
if(branchNodeStack.Count > 0)
{
branchNodeStack.Peek().AddChild(new TaskNode(name, task));
}
else
{
throw new Exception("TaskNode must be a child of a control node or decorator");
}
return this;
}
public BehaviourBuilder Condition(string name, Func<TimeData, bool> fn)
{
return Task(name, t => fn(t) ? NodeStatus.Success : NodeStatus.Failure);
}
public BehaviourBuilder Wait(string name, float seconds)
{
if (branchNodeStack.Count > 0)
{
branchNodeStack.Peek().AddChild(new WaitNode(name, seconds));
}
else
{
throw new Exception("WaitNode must be a child of a control node or decorator");
}
return this;
}
//Control node builders
public BehaviourBuilder Parallel(string name)
{
AddControlNodeToStack(new ParallelNode(name));
return this;
}
public BehaviourBuilder RandomSelect(string name)
{
AddControlNodeToStack(new RandomSelectNode(name));
return this;
}
public BehaviourBuilder Sequence(string name)
{
AddControlNodeToStack(new SequnceNode(name));
return this;
}
public BehaviourBuilder Selector(string name)
{
AddControlNodeToStack(new SelectorNode(name));
return this;
}
//Decorater node builders
public BehaviourBuilder Always(string name)
{
AddControlNodeToStack(new AlwaysDecorator(name));
return this;
}
public BehaviourBuilder Fail(string name)
{
AddControlNodeToStack(new FailDecorator(name));
return this;
}
public BehaviourBuilder Succeed(string name)
{
AddControlNodeToStack(new SucceedDecorator(name));
return this;
}
public BehaviourBuilder Invert(string name)
{
AddControlNodeToStack(new InvertDecorator(name));
return this;
}
public BehaviourBuilder Once(string name, bool returnChildStatus = false)
{
AddControlNodeToStack(new OnceDecorator(name, returnChildStatus));
return this;
}
public BehaviourBuilder Probability(string name, float probability)
{
AddControlNodeToStack(new ProbabilityDecorator(name, probability));
return this;
}
public BehaviourBuilder Retry(string name, int retries)
{
AddControlNodeToStack(new RetryDecorator(name, retries));
return this;
}
//Builder functions
public BehaviourBuilder Merge(IBranchNode subTree)
{
AddControlNodeToStack(subTree);
return this;
}
/// <summary>
/// Ends a chain of child nodes
/// </summary>
public BehaviourBuilder End()
{
lastPoppedNode = branchNodeStack.Pop();
return this;
}
/// <summary>
/// Build the behaviour
/// </summary>
public Behaviour Build(string name)
{
if(lastPoppedNode == null || branchNodeStack.Count > 0)
{
throw new Exception("Call End() before Build()");
}
else
{
return new Behaviour(name, lastPoppedNode);
}
}
//Helpers
private void AddControlNodeToStack(IBranchNode node)
{
if (branchNodeStack.Count > 0)
{
branchNodeStack.Peek().AddChild(node);
}
branchNodeStack.Push(node);
}
}
}