@woosh/meep-engine 2.43.40 → 2.43.43
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/core/binary/BitSet.js +4 -18
- package/core/model/node-graph/Connection.js +41 -0
- package/core/model/node-graph/Connection.spec.js +21 -0
- package/core/model/node-graph/DataType.js +23 -1
- package/core/model/node-graph/DataType.spec.js +28 -0
- package/core/model/node-graph/NodeGraph.js +16 -7
- package/core/model/node-graph/node/NodeDescription.js +12 -5
- package/core/model/node-graph/node/NodeInstance.js +9 -3
- package/core/model/node-graph/node/NodeInstancePortReference.js +18 -0
- package/core/model/node-graph/node/NodeRegistry.js +36 -10
- package/core/model/node-graph/node/NodeRegistry.spec.js +25 -0
- package/core/model/node-graph/node/Port.js +12 -1
- package/core/model/node-graph/node/PortDirection.js +1 -1
- package/core/parser/simple/computeDataTypeFromValue.js +25 -0
- package/engine/graphics/render/frame_graph/RenderGraph.js +5 -1
- package/engine/graphics/render/gizmo/Gizmo.d.ts +3 -0
- package/engine/graphics/render/gizmo/GizmoRenderingPlugin.d.ts +5 -0
- package/engine/graphics/render/gizmo/GizmoShapeRenderingInterface.d.ts +13 -0
- package/engine/graphics/render/gizmo/GizmoShapeRenderingInterface.js +12 -0
- package/engine/intelligence/behavior/Behavior.d.ts +11 -0
- package/engine/intelligence/behavior/Behavior.js +4 -3
- package/engine/intelligence/behavior/BehaviorStatus.d.ts +8 -0
- package/engine/intelligence/behavior/SelectorBehavior.js +3 -1
- package/engine/intelligence/behavior/behavior_to_dot.js +251 -0
- package/engine/intelligence/behavior/behavior_to_dot.prototype.js +55 -0
- package/engine/intelligence/behavior/composite/CompositeBehavior.js +6 -0
- package/engine/intelligence/behavior/composite/ParallelBehavior.js +10 -0
- package/engine/intelligence/behavior/composite/SequenceBehavior.js +6 -50
- package/engine/intelligence/behavior/composite/SequenceBehaviorSerializationAdapter.js +52 -0
- package/engine/intelligence/behavior/ecs/BehaviorComponent.js +3 -8
- package/engine/intelligence/behavior/ecs/BehaviorComponentFlag.js +7 -0
- package/engine/intelligence/behavior/ecs/BehaviorSystem.js +2 -1
- package/engine/intelligence/behavior/ecs/ClockChannelType.js +7 -0
- package/engine/intelligence/behavior/primitive/SucceedingBehavior.js +1 -28
- package/engine/intelligence/behavior/primitive/SucceedingBehaviorSerializationAdapter.js +29 -0
- package/engine/intelligence/blackboard/AbstractBlackboard.js +9 -1
- package/engine/intelligence/blackboard/Blackboard.js +32 -54
- package/engine/intelligence/blackboard/Blackboard.spec.js +62 -0
- package/engine/intelligence/blackboard/{Blacboard.spec.js → BlackboardSerializationAdapter.spec.js} +1 -1
- package/engine/intelligence/blackboard/make_blackboard_proxy.js +47 -0
- package/engine/intelligence/blackboard/make_blackboard_proxy.spec.js +23 -0
- package/engine/intelligence/mcts/README.md +7 -0
- package/engine/intelligence/optimization/RandomOptimizer.js +2 -1
- package/engine/intelligence/resource/ResourceAllocationBid.js +3 -3
- package/engine/intelligence/resource/ResourceAllocationSolver.js +1 -1
- package/engine/intelligence/resource/StrategicResourceAllocator.js +6 -4
- package/engine/intelligence/resource/TacticalModule.js +7 -0
- package/engine/knowledge/database/StaticKnowledgeDataTableDescriptor.js +5 -5
- package/engine/navigation/grid/GridField.js +1 -0
- package/engine/notify/NotificationLog.js +2 -2
- package/package.json +1 -1
|
@@ -2,6 +2,7 @@ import { BehaviorStatus } from "./BehaviorStatus.js";
|
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* Base class of behavior tree implementation
|
|
5
|
+
* @see "The Behavior Tree Starter Kit" by Alex J. Champandard and Philip Dunstan
|
|
5
6
|
* @template CTX
|
|
6
7
|
*/
|
|
7
8
|
export class Behavior {
|
|
@@ -14,9 +15,9 @@ export class Behavior {
|
|
|
14
15
|
}
|
|
15
16
|
|
|
16
17
|
/**
|
|
17
|
-
* Main update function
|
|
18
|
+
* Main update function. Every behavior executes some logic, some behaviors are long-running and some are instantaneous
|
|
18
19
|
* @param {number} timeDelta time step in seconds
|
|
19
|
-
* @returns {BehaviorStatus}
|
|
20
|
+
* @returns {BehaviorStatus} signals status of the behavior, "success" or "failure" are used to signal completion of the behavior
|
|
20
21
|
*/
|
|
21
22
|
tick(timeDelta) {
|
|
22
23
|
throw new Error('Abstract method, needs to be overridden');
|
|
@@ -25,7 +26,7 @@ export class Behavior {
|
|
|
25
26
|
/**
|
|
26
27
|
* Called before behavior gets executed via {@link #tick} for the first time
|
|
27
28
|
* Used to prepare the behavior for execution
|
|
28
|
-
* @param {
|
|
29
|
+
* @param {CTX} [context]
|
|
29
30
|
*/
|
|
30
31
|
initialize(context) {
|
|
31
32
|
this.context = context;
|
|
@@ -0,0 +1,251 @@
|
|
|
1
|
+
import LineBuilder from "../../../core/codegen/LineBuilder.js";
|
|
2
|
+
import { Behavior } from "./Behavior.js";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
*
|
|
6
|
+
* @param {Behavior} behavior
|
|
7
|
+
* @return {string}
|
|
8
|
+
*/
|
|
9
|
+
function compute_behavior_name(behavior) {
|
|
10
|
+
|
|
11
|
+
// try to get name from the constructor field
|
|
12
|
+
const typeName = behavior.constructor.typeName;
|
|
13
|
+
if (typeof typeName === "string") {
|
|
14
|
+
return typeName;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
const constructor_name = behavior.constructor.name;
|
|
18
|
+
if (typeof constructor_name === "string") {
|
|
19
|
+
return constructor_name;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
return '$Behavior';
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
*
|
|
28
|
+
* @param {Behavior|SequenceBehavior|ParallelBehavior} behavior
|
|
29
|
+
* @return {Object}
|
|
30
|
+
*/
|
|
31
|
+
function behavior_node_attributes(behavior) {
|
|
32
|
+
const result = {};
|
|
33
|
+
|
|
34
|
+
if (behavior.isCompositeBehavior === true) {
|
|
35
|
+
|
|
36
|
+
result.fillcolor = "orange";
|
|
37
|
+
|
|
38
|
+
if (behavior.isSequenceBehavior === true) {
|
|
39
|
+
result.fillcolor = "paleturquoise";
|
|
40
|
+
} else if (behavior.isParallelBehavior === true) {
|
|
41
|
+
result.fillcolor = "plum";
|
|
42
|
+
}
|
|
43
|
+
} else {
|
|
44
|
+
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
return result;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
*
|
|
52
|
+
* @param {Object} attributes
|
|
53
|
+
* @return {string}
|
|
54
|
+
*/
|
|
55
|
+
function attributes_to_dot(attributes) {
|
|
56
|
+
const key_names = Object.keys(attributes);
|
|
57
|
+
|
|
58
|
+
return key_names.map(key => {
|
|
59
|
+
|
|
60
|
+
return `${key}=${attributes[key]}`;
|
|
61
|
+
|
|
62
|
+
}).join(', ');
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
*
|
|
67
|
+
* @param {string} prop
|
|
68
|
+
* @param {Object} object
|
|
69
|
+
*/
|
|
70
|
+
function should_property_be_included(prop, object) {
|
|
71
|
+
if (prop.startsWith('_')) {
|
|
72
|
+
// private field
|
|
73
|
+
return false;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
const value = object[prop];
|
|
77
|
+
|
|
78
|
+
if (object.constructor.prototype[prop] === value) {
|
|
79
|
+
return false;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
const typeof_value = typeof value;
|
|
83
|
+
|
|
84
|
+
if (value === null || typeof_value === "undefined" || typeof_value === "symbol") {
|
|
85
|
+
return false;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
if (typeof_value === "object" && String(value) === '[object Object]') {
|
|
89
|
+
return false;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
return true;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
function property_to_string(value, max_length = 200) {
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
let string_value;
|
|
99
|
+
|
|
100
|
+
if (typeof value !== "string") {
|
|
101
|
+
string_value = String(value);
|
|
102
|
+
} else {
|
|
103
|
+
string_value = `\"${value}\"`;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
const sanitized = string_value.replace(/\n/, "\n");
|
|
107
|
+
|
|
108
|
+
if (sanitized.length > max_length) {
|
|
109
|
+
return '[...]';
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
return sanitized;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
/**
|
|
116
|
+
*
|
|
117
|
+
* @param {Behavior} behavior
|
|
118
|
+
* @param {number} max_props
|
|
119
|
+
*/
|
|
120
|
+
function build_node_properties_string(behavior, max_props = 10) {
|
|
121
|
+
|
|
122
|
+
const properties = {};
|
|
123
|
+
|
|
124
|
+
let qualified_property_count = 0;
|
|
125
|
+
|
|
126
|
+
for (const behaviorKey in behavior) {
|
|
127
|
+
|
|
128
|
+
if (should_property_be_included(behaviorKey, behavior)) {
|
|
129
|
+
if (qualified_property_count < max_props) {
|
|
130
|
+
properties[behaviorKey] = property_to_string(behavior[behaviorKey]);
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
qualified_property_count++;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
// stringify and concatenate
|
|
139
|
+
return Object.keys(properties).map(key => `${key} = ${properties[key]}`).join('<BR/>');
|
|
140
|
+
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
/**
|
|
144
|
+
*
|
|
145
|
+
* @param {Behavior} behavior
|
|
146
|
+
* @return {boolean}
|
|
147
|
+
*/
|
|
148
|
+
function should_behavior_have_properties_string(behavior) {
|
|
149
|
+
if (behavior.isCompositeBehavior === true) {
|
|
150
|
+
return false;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
return true;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
function build_node_label(behavior) {
|
|
157
|
+
const node_name = compute_behavior_name(behavior);
|
|
158
|
+
|
|
159
|
+
const label_pieces = [];
|
|
160
|
+
|
|
161
|
+
label_pieces.push(`<B>${node_name}</B>`);
|
|
162
|
+
|
|
163
|
+
if (should_behavior_have_properties_string(behavior)) {
|
|
164
|
+
const properties = build_node_properties_string(behavior);
|
|
165
|
+
|
|
166
|
+
if (properties.trim().length > 0) {
|
|
167
|
+
|
|
168
|
+
label_pieces.push(properties);
|
|
169
|
+
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
return `<{ {${label_pieces.join('<BR/>')} } }>`;
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
/**
|
|
177
|
+
*
|
|
178
|
+
* @param {LineBuilder} out
|
|
179
|
+
* @param {Behavior|CompositeBehavior} behavior
|
|
180
|
+
* @param {{id_counter:number, node_ids:Map<Behavior,string>}} context
|
|
181
|
+
* @returns {string}
|
|
182
|
+
*/
|
|
183
|
+
function parse_behavior(out, behavior, context) {
|
|
184
|
+
const id = context.id_counter++;
|
|
185
|
+
const node_id = `Node_${id}`;
|
|
186
|
+
|
|
187
|
+
context.node_ids.set(behavior, node_id);
|
|
188
|
+
|
|
189
|
+
const attributes = {
|
|
190
|
+
label: build_node_label(behavior),
|
|
191
|
+
style: "\"rounded,filled\""
|
|
192
|
+
};
|
|
193
|
+
|
|
194
|
+
Object.assign(attributes, behavior_node_attributes(behavior));
|
|
195
|
+
|
|
196
|
+
out.add(`${node_id} [${attributes_to_dot(attributes)}]`);
|
|
197
|
+
|
|
198
|
+
if (behavior.isCompositeBehavior === true) {
|
|
199
|
+
// is a composite behavior, which means it includes other behaviors
|
|
200
|
+
|
|
201
|
+
const children = behavior.getChildren();
|
|
202
|
+
|
|
203
|
+
const child_count = children.length;
|
|
204
|
+
|
|
205
|
+
for (let i = 0; i < child_count; i++) {
|
|
206
|
+
const child = children[i];
|
|
207
|
+
|
|
208
|
+
const child_id = parse_behavior(out, child, context);
|
|
209
|
+
|
|
210
|
+
// create edge
|
|
211
|
+
out.add(`${node_id} -> ${child_id} [label="№${i + 1}"];`);
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
return node_id;
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
/**
|
|
220
|
+
* Produces a diagram of behavior tree in DOT format, useful for debugging and exploration of complex trees
|
|
221
|
+
*
|
|
222
|
+
* @see https://en.wikipedia.org/wiki/DOT_(graph_description_language)
|
|
223
|
+
* @param {Behavior} behavior
|
|
224
|
+
* @returns {string}
|
|
225
|
+
*/
|
|
226
|
+
export function behavior_to_dot(behavior) {
|
|
227
|
+
const out = new LineBuilder();
|
|
228
|
+
|
|
229
|
+
const context = {
|
|
230
|
+
id_counter: 0,
|
|
231
|
+
node_ids: new Map()
|
|
232
|
+
};
|
|
233
|
+
|
|
234
|
+
const font = {
|
|
235
|
+
name: "helvetica",
|
|
236
|
+
size: 10
|
|
237
|
+
};
|
|
238
|
+
|
|
239
|
+
out.add("digraph BehaviorTree {");
|
|
240
|
+
out.indent();
|
|
241
|
+
out.add("graph [style=invis, rankdir=\"TB\" ordering=out, splines=spline]");
|
|
242
|
+
out.add(`node [shape=record, fontname=\"${font.name}\", fontsize=${font.size}, margin=\"0.2,0.03\", fillcolor=ivory]`);
|
|
243
|
+
out.add(`edge [labelfontname=\"${font.name}\", labelfontsize=${font.size}, fontname=\"${font.name}\", fontsize=${font.size}, fontcolor=grey]`);
|
|
244
|
+
|
|
245
|
+
parse_behavior(out, behavior, context);
|
|
246
|
+
|
|
247
|
+
out.dedent();
|
|
248
|
+
out.add("}");
|
|
249
|
+
|
|
250
|
+
return out.build();
|
|
251
|
+
}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { SequenceBehavior } from "./composite/SequenceBehavior.js";
|
|
2
|
+
import { SucceedingBehavior } from "./primitive/SucceedingBehavior.js";
|
|
3
|
+
import { Behavior } from "./Behavior.js";
|
|
4
|
+
import { ParallelBehavior } from "./composite/ParallelBehavior.js";
|
|
5
|
+
import { behavior_to_dot } from "./behavior_to_dot.js";
|
|
6
|
+
import { DelayBehavior } from "./util/DelayBehavior.js";
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class CenterCameraOnObject extends Behavior{
|
|
10
|
+
object = "whiteboard"
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
class UserControlsDisable extends Behavior{
|
|
14
|
+
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
class PlayVideoInPopup extends Behavior{
|
|
18
|
+
url = "url/how_to_use_whiteboard.mp4"
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
class DrawCurvesOnWhiteBoard extends Behavior{
|
|
22
|
+
curve = "hello"
|
|
23
|
+
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
class UserControlsEnable extends Behavior{
|
|
27
|
+
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
const complex = SequenceBehavior.from([
|
|
31
|
+
new SucceedingBehavior(),
|
|
32
|
+
SequenceBehavior.from([
|
|
33
|
+
new Behavior()
|
|
34
|
+
]),
|
|
35
|
+
ParallelBehavior.from([
|
|
36
|
+
new SucceedingBehavior(),
|
|
37
|
+
DelayBehavior.from(17)
|
|
38
|
+
])
|
|
39
|
+
]);
|
|
40
|
+
|
|
41
|
+
const tutorial = SequenceBehavior.from([ // will execute all members one after another
|
|
42
|
+
|
|
43
|
+
ParallelBehavior.from([ // will execute all members at the same time, completes when last member completes
|
|
44
|
+
|
|
45
|
+
new CenterCameraOnObject( ), // center camera on whiteboard
|
|
46
|
+
new UserControlsDisable(),
|
|
47
|
+
new PlayVideoInPopup() // plays a video in a popup, behavior finishes when video does
|
|
48
|
+
|
|
49
|
+
]),
|
|
50
|
+
new DrawCurvesOnWhiteBoard(),
|
|
51
|
+
new UserControlsEnable()
|
|
52
|
+
|
|
53
|
+
])
|
|
54
|
+
|
|
55
|
+
console.log(behavior_to_dot(tutorial));
|
|
@@ -226,5 +226,15 @@ export class ParallelBehavior extends CompositeBehavior {
|
|
|
226
226
|
}
|
|
227
227
|
}
|
|
228
228
|
|
|
229
|
+
/**
|
|
230
|
+
* @readonly
|
|
231
|
+
* @type {boolean}
|
|
232
|
+
*/
|
|
233
|
+
ParallelBehavior.prototype.isParallelBehavior = true;
|
|
234
|
+
|
|
235
|
+
/**
|
|
236
|
+
* @readonly
|
|
237
|
+
* @type {string}
|
|
238
|
+
*/
|
|
229
239
|
ParallelBehavior.typeName = "ParallelBehavior";
|
|
230
240
|
|
|
@@ -1,9 +1,6 @@
|
|
|
1
1
|
import { Behavior } from "../Behavior.js";
|
|
2
2
|
import { CompositeBehavior } from "./CompositeBehavior.js";
|
|
3
3
|
import { BehaviorStatus } from "../BehaviorStatus.js";
|
|
4
|
-
import {
|
|
5
|
-
ObjectBasedClassSerializationAdapter
|
|
6
|
-
} from "../../../ecs/storage/binary/object/ObjectBasedClassSerializationAdapter.js";
|
|
7
4
|
import { assert } from "../../../../core/assert.js";
|
|
8
5
|
|
|
9
6
|
export class SequenceBehavior extends CompositeBehavior {
|
|
@@ -115,52 +112,11 @@ export class SequenceBehavior extends CompositeBehavior {
|
|
|
115
112
|
}
|
|
116
113
|
}
|
|
117
114
|
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
this.klass = SequenceBehavior;
|
|
125
|
-
this.version = 0;
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
/**
|
|
129
|
-
*
|
|
130
|
-
* @param {BinaryBuffer} buffer
|
|
131
|
-
* @param {SequenceBehavior} value
|
|
132
|
-
*/
|
|
133
|
-
serialize(buffer, value) {
|
|
134
|
-
const children = value.getChildren();
|
|
135
|
-
|
|
136
|
-
const n = children.length;
|
|
137
|
-
buffer.writeUintVar(n);
|
|
138
|
-
|
|
139
|
-
for (let i = 0; i < n; i++) {
|
|
140
|
-
const behavior = children[i];
|
|
115
|
+
/**
|
|
116
|
+
* @readonly
|
|
117
|
+
* @type {boolean}
|
|
118
|
+
*/
|
|
119
|
+
SequenceBehavior.prototype.isSequenceBehavior = true;
|
|
141
120
|
|
|
142
|
-
|
|
143
|
-
}
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
/**
|
|
147
|
-
*
|
|
148
|
-
* @param {BinaryBuffer} buffer
|
|
149
|
-
* @param {SequenceBehavior} value
|
|
150
|
-
*/
|
|
151
|
-
deserialize(buffer, value) {
|
|
152
|
-
const n = buffer.readUintVar();
|
|
153
|
-
|
|
154
|
-
value.clearChildren();
|
|
155
|
-
|
|
156
|
-
for (let i = 0; i < n; i++) {
|
|
157
|
-
/**
|
|
158
|
-
*
|
|
159
|
-
* @type {Behavior}
|
|
160
|
-
*/
|
|
161
|
-
const behavior = this.objectAdapter.deserialize(buffer);
|
|
121
|
+
SequenceBehavior.typeName = "SequenceBehavior";
|
|
162
122
|
|
|
163
|
-
value.addChild(behavior);
|
|
164
|
-
}
|
|
165
|
-
}
|
|
166
|
-
}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import {
|
|
2
|
+
ObjectBasedClassSerializationAdapter
|
|
3
|
+
} from "../../../ecs/storage/binary/object/ObjectBasedClassSerializationAdapter.js";
|
|
4
|
+
import { SequenceBehavior } from "./SequenceBehavior.js";
|
|
5
|
+
|
|
6
|
+
export class SequenceBehaviorSerializationAdapter extends ObjectBasedClassSerializationAdapter {
|
|
7
|
+
constructor() {
|
|
8
|
+
super();
|
|
9
|
+
|
|
10
|
+
this.klass = SequenceBehavior;
|
|
11
|
+
this.version = 0;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
*
|
|
16
|
+
* @param {BinaryBuffer} buffer
|
|
17
|
+
* @param {SequenceBehavior} value
|
|
18
|
+
*/
|
|
19
|
+
serialize(buffer, value) {
|
|
20
|
+
const children = value.getChildren();
|
|
21
|
+
|
|
22
|
+
const n = children.length;
|
|
23
|
+
buffer.writeUintVar(n);
|
|
24
|
+
|
|
25
|
+
for (let i = 0; i < n; i++) {
|
|
26
|
+
const behavior = children[i];
|
|
27
|
+
|
|
28
|
+
this.objectAdapter.serialize(buffer, behavior);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
*
|
|
34
|
+
* @param {BinaryBuffer} buffer
|
|
35
|
+
* @param {SequenceBehavior} value
|
|
36
|
+
*/
|
|
37
|
+
deserialize(buffer, value) {
|
|
38
|
+
const n = buffer.readUintVar();
|
|
39
|
+
|
|
40
|
+
value.clearChildren();
|
|
41
|
+
|
|
42
|
+
for (let i = 0; i < n; i++) {
|
|
43
|
+
/**
|
|
44
|
+
*
|
|
45
|
+
* @type {Behavior}
|
|
46
|
+
*/
|
|
47
|
+
const behavior = this.objectAdapter.deserialize(buffer);
|
|
48
|
+
|
|
49
|
+
value.addChild(behavior);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
}
|
|
@@ -4,16 +4,11 @@ import { RepeatBehavior } from "../decorator/RepeatBehavior.js";
|
|
|
4
4
|
import { ActionBehavior } from "../primitive/ActionBehavior.js";
|
|
5
5
|
import { SequenceBehavior } from "../composite/SequenceBehavior.js";
|
|
6
6
|
|
|
7
|
-
export const BehaviorComponentFlag = {
|
|
8
|
-
AllowSleep: 1,
|
|
9
|
-
Resolved: 2
|
|
10
|
-
};
|
|
11
|
-
|
|
12
7
|
export class BehaviorComponent {
|
|
13
8
|
constructor() {
|
|
14
9
|
|
|
15
10
|
/**
|
|
16
|
-
*
|
|
11
|
+
* What clock should be used for ticking associated behavior
|
|
17
12
|
* @type {ClockChannelType|number}
|
|
18
13
|
*/
|
|
19
14
|
this.clock = ClockChannelType.Simulation;
|
|
@@ -135,8 +130,8 @@ export class BehaviorComponent {
|
|
|
135
130
|
* @returns {BehaviorComponent}
|
|
136
131
|
*/
|
|
137
132
|
static fromOne(b) {
|
|
138
|
-
assert.
|
|
139
|
-
assert.
|
|
133
|
+
assert.defined(b, 'behavior');
|
|
134
|
+
assert.notNull(b, 'behavior');
|
|
140
135
|
assert.equal(b.isBehavior, true, 'b.isBehavior !== true');
|
|
141
136
|
|
|
142
137
|
const result = new BehaviorComponent();
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { System } from "../../../ecs/System.js";
|
|
2
|
-
import { BehaviorComponent
|
|
2
|
+
import { BehaviorComponent } from "./BehaviorComponent.js";
|
|
3
3
|
import { BehaviorStatus } from "../BehaviorStatus.js";
|
|
4
4
|
import Clock from "../../../Clock.js";
|
|
5
5
|
import { ClockChannelType } from "./ClockChannelType.js";
|
|
6
|
+
import { BehaviorComponentFlag } from "./BehaviorComponentFlag.js";
|
|
6
7
|
|
|
7
8
|
/**
|
|
8
9
|
*
|
|
@@ -3,6 +3,13 @@
|
|
|
3
3
|
* @enum {number}
|
|
4
4
|
*/
|
|
5
5
|
export const ClockChannelType = {
|
|
6
|
+
/**
|
|
7
|
+
* Simulation clock is the one that the entire world is running on
|
|
8
|
+
*/
|
|
6
9
|
Simulation: 0,
|
|
10
|
+
/**
|
|
11
|
+
* System clock is essentially real-time
|
|
12
|
+
* Useful for things that need to run even when the world simulation is paused
|
|
13
|
+
*/
|
|
7
14
|
System: 1
|
|
8
15
|
};
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { Behavior } from "../Behavior.js";
|
|
2
2
|
import { BehaviorStatus } from "../BehaviorStatus.js";
|
|
3
|
-
import { BinaryClassSerializationAdapter } from "../../../ecs/storage/binary/BinaryClassSerializationAdapter.js";
|
|
4
3
|
|
|
5
4
|
/**
|
|
6
5
|
* Behavior that always succeeds
|
|
@@ -25,7 +24,7 @@ export class SucceedingBehavior extends Behavior {
|
|
|
25
24
|
return r;
|
|
26
25
|
}
|
|
27
26
|
|
|
28
|
-
tick() {
|
|
27
|
+
tick(timeDelta) {
|
|
29
28
|
if (this.delayTicks === 0) {
|
|
30
29
|
return BehaviorStatus.Succeeded;
|
|
31
30
|
} else {
|
|
@@ -37,29 +36,3 @@ export class SucceedingBehavior extends Behavior {
|
|
|
37
36
|
|
|
38
37
|
SucceedingBehavior.typeName = "SucceedingBehavior";
|
|
39
38
|
|
|
40
|
-
export class SucceedingBehaviorSerializationAdapter extends BinaryClassSerializationAdapter {
|
|
41
|
-
constructor() {
|
|
42
|
-
super();
|
|
43
|
-
|
|
44
|
-
this.klass = SucceedingBehavior;
|
|
45
|
-
this.version = 0;
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
/**
|
|
49
|
-
*
|
|
50
|
-
* @param {BinaryBuffer} buffer
|
|
51
|
-
* @param {SucceedingBehavior} value
|
|
52
|
-
*/
|
|
53
|
-
serialize(buffer, value) {
|
|
54
|
-
buffer.writeUintVar(value.delayTicks);
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
/**
|
|
58
|
-
*
|
|
59
|
-
* @param {BinaryBuffer} buffer
|
|
60
|
-
* @param {SucceedingBehavior} value
|
|
61
|
-
*/
|
|
62
|
-
deserialize(buffer, value) {
|
|
63
|
-
value.delayTicks = buffer.readUintVar();
|
|
64
|
-
}
|
|
65
|
-
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { BinaryClassSerializationAdapter } from "../../../ecs/storage/binary/BinaryClassSerializationAdapter.js";
|
|
2
|
+
import { SucceedingBehavior } from "./SucceedingBehavior.js";
|
|
3
|
+
|
|
4
|
+
export class SucceedingBehaviorSerializationAdapter extends BinaryClassSerializationAdapter {
|
|
5
|
+
constructor() {
|
|
6
|
+
super();
|
|
7
|
+
|
|
8
|
+
this.klass = SucceedingBehavior;
|
|
9
|
+
this.version = 0;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
*
|
|
14
|
+
* @param {BinaryBuffer} buffer
|
|
15
|
+
* @param {SucceedingBehavior} value
|
|
16
|
+
*/
|
|
17
|
+
serialize(buffer, value) {
|
|
18
|
+
buffer.writeUintVar(value.delayTicks);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
*
|
|
23
|
+
* @param {BinaryBuffer} buffer
|
|
24
|
+
* @param {SucceedingBehavior} value
|
|
25
|
+
*/
|
|
26
|
+
deserialize(buffer, value) {
|
|
27
|
+
value.delayTicks = buffer.readUintVar();
|
|
28
|
+
}
|
|
29
|
+
}
|
|
@@ -13,6 +13,14 @@ export class AbstractBlackboard {
|
|
|
13
13
|
throw new Error('Not implemented');
|
|
14
14
|
}
|
|
15
15
|
|
|
16
|
+
/**
|
|
17
|
+
* Produces a list of all held keys
|
|
18
|
+
* @returns {string[]}
|
|
19
|
+
*/
|
|
20
|
+
getKeys() {
|
|
21
|
+
throw new Error('Not implemented');
|
|
22
|
+
}
|
|
23
|
+
|
|
16
24
|
/**
|
|
17
25
|
* @template T
|
|
18
26
|
* @param {string} name
|
|
@@ -30,7 +38,7 @@ export class AbstractBlackboard {
|
|
|
30
38
|
* @returns {void}
|
|
31
39
|
*/
|
|
32
40
|
release(name) {
|
|
33
|
-
|
|
41
|
+
throw new Error('Not implemented');
|
|
34
42
|
}
|
|
35
43
|
|
|
36
44
|
/**
|