-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathBehaviorTreeBuilder.cs
More file actions
273 lines (230 loc) · 7.46 KB
/
Copy pathBehaviorTreeBuilder.cs
File metadata and controls
273 lines (230 loc) · 7.46 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
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace BehaviorTree
{
/// <summary>
/// Builder for building a behaviour tree.
/// </summary>
public class BehaviorTreeBuilder
{
public BehaviorTreeBuilder()
{
m_ParentNodeStack = new Stack<ParentNode>();
m_CurrentParentNode = null;
m_BehaviorTree = null;
m_CurrentChildNode = null;
}
public BehaviorTreeBuilder Tree(string name)
{
m_BehaviorTree = new Tree(name);
return this;
}
/// <summary>
/// Create an action node.
/// </summary>
public BehaviorTreeBuilder Do(string name, Func<BehaviorTreeStatus> fn)
{
var node = new ActionNode(name, fn);
AddChildNode(node);
return this;
}
/// <summary>
/// Create an condition node.
/// </summary>
public BehaviorTreeBuilder Condition(string name, Func<bool> fn)
{
var node = new ConditionNode(name, fn);
AddChildNode(node);
return this;
}
/// <summary>
/// Create an Inverter node that inverts the success/failure of its children.
/// </summary>
public BehaviorTreeBuilder Inverter(string name)
{
AddParentNode(new InverterNode(name));
return this;
}
/// <summary>
/// Create a Repeater node that.
/// </summary>
public BehaviorTreeBuilder Repeater(string name, int repeatTimes = RepeaterNode.RepeatForever, bool endOnFailure = false)
{
AddParentNode(new RepeaterNode(name, repeatTimes, endOnFailure));
return this;
}
/// <summary>
/// Create an UntilFailure node.
/// </summary>
public BehaviorTreeBuilder UntilFailure(string name)
{
AddParentNode(new UntilFailureNode(name));
return this;
}
/// <summary>
/// Create an UntilSuccess node.
/// </summary>
public BehaviorTreeBuilder UntilSuccess(string name)
{
AddParentNode(new UntilSuccessNode(name));
return this;
}
/// <summary>
/// Create an UntilFailure node.
/// </summary>
public BehaviorTreeBuilder ReturnFailure(string name)
{
AddParentNode(new ReturnFailureNode(name));
return this;
}
/// <summary>
/// Create an UntilSuccess node.
/// </summary>
public BehaviorTreeBuilder ReturnSuccess(string name)
{
AddParentNode(new ReturnSuccessNode(name));
return this;
}
/// <summary>
/// Create a sequence node.
/// </summary>
public BehaviorTreeBuilder Sequence(string name)
{
AddParentNode(new SequenceNode(name));
return this;
}
/// <summary>
/// Create a parallel node.
/// </summary>
public BehaviorTreeBuilder Parallel(string name)
{
AddParentNode(new ParallelNode(name));
return this;
}
/// <summary>
/// Create a selector node.
/// </summary>
public BehaviorTreeBuilder Selector(string name)
{
AddParentNode(new SelectorNode(name));
return this;
}
/// <summary>
/// Splice a sub tree into the parent tree.
/// </summary>
public BehaviorTreeBuilder Splice(Node subTree)
{
if (subTree == null)
{
throw new ArgumentNullException("Argument subTree is null");
}
AddChildNode(subTree);
return this;
}
public BehaviorTreeBuilder ParentNode(ParentNode node)
{
if (node == null)
{
throw new ArgumentNullException("Argument node is null");
}
AddParentNode(node);
return this;
}
/// <summary>
/// The end of a parent node.
/// </summary>
public BehaviorTreeBuilder End()
{
m_CurrentParentNode = m_ParentNodeStack.Pop();
return this;
}
/// <summary>
/// Return the behavior tree just built.
/// </summary>
public Tree Build()
{
if (m_BehaviorTree == null)
{
throw new InvalidOperationException("Must call Tree() before call Build()!!!");
}
Tree ret = null;
if (m_CurrentChildNode != null)
{
m_BehaviorTree.SetRootNode(m_CurrentChildNode);
m_CurrentChildNode = null;
}
else
{
if (m_CurrentParentNode == null || m_ParentNodeStack.Count > 0)
{
throw new InvalidOperationException("End() operation dose not match parent node creation");
}
m_BehaviorTree.SetRootNode(m_CurrentParentNode);
m_CurrentParentNode = null;
}
ret = m_BehaviorTree;
m_BehaviorTree = null;
return ret;
}
/// <summary>
/// Return the behavior tree just built.
/// </summary>
public Node BuildSubTree()
{
if (m_BehaviorTree != null)
{
throw new InvalidOperationException("Should not call Tree() before call BuildSubTree()!!!");
}
Node ret = null;
if (m_CurrentChildNode != null)
{
ret = m_CurrentChildNode;
m_CurrentChildNode = null;
}
else
{
if (m_CurrentParentNode == null || m_ParentNodeStack.Count > 0)
{
throw new InvalidOperationException("End() operation dose not match parent node creation");
}
ret = m_CurrentParentNode;
m_CurrentParentNode = null;
}
return ret;
}
private void AddParentNode(ParentNode node)
{
if (m_CurrentChildNode != null)
{
throw new InvalidOperationException("Cannot add parent node " + node.Name + " to child node " + m_CurrentChildNode.Name);
}
if (m_ParentNodeStack.Count > 0)
{
m_ParentNodeStack.Peek().AddChild(node);
}
m_ParentNodeStack.Push(node);
}
private void AddChildNode(Node node)
{
if (m_CurrentChildNode != null)
{
throw new InvalidOperationException("Cannot add child node " + node.Name + " to child node " + m_CurrentChildNode.Name);
}
if (m_ParentNodeStack.Count > 0)
{
m_ParentNodeStack.Peek().AddChild(node);
}
else
{
m_CurrentChildNode = node;
}
}
private Tree m_BehaviorTree;
private Stack<ParentNode> m_ParentNodeStack;
private Node m_CurrentParentNode;
private Node m_CurrentChildNode;
}
}