@woosh/meep-engine 2.43.42 → 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/parser/simple/computeDataTypeFromValue.js +25 -0
- 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/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 +6 -40
- package/engine/intelligence/blackboard/make_blackboard_proxy.js +47 -0
- package/engine/intelligence/blackboard/make_blackboard_proxy.spec.js +23 -0
- package/package.json +1 -1
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { DataType } from "./DataType.js";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @template T
|
|
5
|
+
* @param {T} value
|
|
6
|
+
* @return {DataType}
|
|
7
|
+
*/
|
|
8
|
+
export function computeDataTypeFromValue(value) {
|
|
9
|
+
const t = typeof value;
|
|
10
|
+
|
|
11
|
+
switch (t) {
|
|
12
|
+
case "number":
|
|
13
|
+
return DataType.Number;
|
|
14
|
+
case "string":
|
|
15
|
+
return DataType.String;
|
|
16
|
+
case "boolean":
|
|
17
|
+
return DataType.Boolean;
|
|
18
|
+
default:
|
|
19
|
+
if (Array.isArray(value)) {
|
|
20
|
+
return DataType.Array;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
throw new Error(`Unsupported value type for value '${value}'`);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export class GizmoShapeRenderingInterface {
|
|
2
|
+
color: number[]
|
|
3
|
+
|
|
4
|
+
draw_solid_cube(center: number[], size: number[]): void
|
|
5
|
+
|
|
6
|
+
draw_wire_cube(center: number[], size: number[]): void
|
|
7
|
+
|
|
8
|
+
draw_solid_sphere(center: number[], radius: number): void
|
|
9
|
+
|
|
10
|
+
draw_wire_sphere(center: number[], radius: number): void
|
|
11
|
+
|
|
12
|
+
static INSTANCE: GizmoShapeRenderingInterface
|
|
13
|
+
}
|
|
@@ -37,6 +37,9 @@ function add_instance(group, matrix, color) {
|
|
|
37
37
|
);
|
|
38
38
|
}
|
|
39
39
|
|
|
40
|
+
/**
|
|
41
|
+
* Inspired by IMGUI and Unity's debug renderer
|
|
42
|
+
*/
|
|
40
43
|
export class GizmoShapeRenderingInterface {
|
|
41
44
|
constructor() {
|
|
42
45
|
|
|
@@ -99,6 +102,7 @@ export class GizmoShapeRenderingInterface {
|
|
|
99
102
|
}
|
|
100
103
|
|
|
101
104
|
/**
|
|
105
|
+
* Color used for drawing shapes, draw_x will take on the currently set color when called
|
|
102
106
|
* RGBA
|
|
103
107
|
* @param {number[]} color
|
|
104
108
|
*/
|
|
@@ -110,6 +114,14 @@ export class GizmoShapeRenderingInterface {
|
|
|
110
114
|
array_copy(color, 0, this.__color, 0, 4);
|
|
111
115
|
}
|
|
112
116
|
|
|
117
|
+
/**
|
|
118
|
+
* RGBA
|
|
119
|
+
* @return {number[]}
|
|
120
|
+
*/
|
|
121
|
+
get color() {
|
|
122
|
+
return this.__color;
|
|
123
|
+
}
|
|
124
|
+
|
|
113
125
|
/**
|
|
114
126
|
*
|
|
115
127
|
* @param {number[]} center
|
|
@@ -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;
|
|
@@ -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
|
/**
|
|
@@ -3,6 +3,8 @@ import { assert } from "../../../core/assert.js";
|
|
|
3
3
|
import Signal from "../../../core/events/signal/Signal.js";
|
|
4
4
|
import { BlackboardValue } from "./BlackboardValue.js";
|
|
5
5
|
import { AbstractBlackboard } from "./AbstractBlackboard.js";
|
|
6
|
+
import { make_blackboard_proxy } from "./make_blackboard_proxy.js";
|
|
7
|
+
|
|
6
8
|
|
|
7
9
|
export class Blackboard extends AbstractBlackboard {
|
|
8
10
|
constructor() {
|
|
@@ -25,47 +27,11 @@ export class Blackboard extends AbstractBlackboard {
|
|
|
25
27
|
/**
|
|
26
28
|
* @private
|
|
27
29
|
*/
|
|
28
|
-
this.proxy =
|
|
29
|
-
|
|
30
|
-
*
|
|
31
|
-
* @param target
|
|
32
|
-
* @param {string} p
|
|
33
|
-
* @param receiver
|
|
34
|
-
* @returns {*}
|
|
35
|
-
*/
|
|
36
|
-
get(target, p, receiver) {
|
|
37
|
-
const data = target.data;
|
|
38
|
-
|
|
39
|
-
if (!data.hasOwnProperty(p)) {
|
|
40
|
-
// property not found
|
|
41
|
-
return undefined;
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
const blackboardValue = data[p];
|
|
45
|
-
|
|
46
|
-
const resolved_value = blackboardValue.value.getValue();
|
|
47
|
-
|
|
48
|
-
return resolved_value;
|
|
49
|
-
},
|
|
50
|
-
set(target, p, value, receiver) {
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
const blackboardValue = target.data[p];
|
|
54
|
-
|
|
55
|
-
if (blackboardValue === undefined) {
|
|
56
|
-
// blackboard property not found
|
|
57
|
-
return undefined;
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
blackboardValue.value.set(value);
|
|
61
|
-
|
|
62
|
-
},
|
|
63
|
-
ownKeys(target) {
|
|
64
|
-
|
|
65
|
-
return Reflect.ownKeys(target.data);
|
|
30
|
+
this.proxy = make_blackboard_proxy(this);
|
|
31
|
+
}
|
|
66
32
|
|
|
67
|
-
|
|
68
|
-
|
|
33
|
+
getKeys() {
|
|
34
|
+
return Reflect.ownKeys(this.data);
|
|
69
35
|
}
|
|
70
36
|
|
|
71
37
|
/**
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import DataType from "../../../core/parser/simple/DataType.js";
|
|
2
|
+
import { computeDataTypeFromValue } from "../../../core/parser/simple/computeDataTypeFromValue.js";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Given a blackboard, returns a Proxy instance, exposing blackboard attributes as plain JSON
|
|
6
|
+
* Useful for connecting blackboard to systems that are not explicitly designed to work with a blackboard
|
|
7
|
+
* @param {AbstractBlackboard} blackboard
|
|
8
|
+
* @returns {Proxy}
|
|
9
|
+
*/
|
|
10
|
+
export function make_blackboard_proxy(blackboard) {
|
|
11
|
+
return new Proxy(blackboard, {
|
|
12
|
+
/**
|
|
13
|
+
*
|
|
14
|
+
* @param target
|
|
15
|
+
* @param {string} p
|
|
16
|
+
* @param receiver
|
|
17
|
+
* @returns {*}
|
|
18
|
+
*/
|
|
19
|
+
get(target, p, receiver) {
|
|
20
|
+
|
|
21
|
+
if (!target.contains(p, DataType.Any)) {
|
|
22
|
+
// property not found
|
|
23
|
+
return undefined;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
const value_container = target.acquire(p, DataType.Any);
|
|
27
|
+
|
|
28
|
+
return value_container.getValue();
|
|
29
|
+
},
|
|
30
|
+
set(target, p, value, receiver) {
|
|
31
|
+
|
|
32
|
+
const dataType = computeDataTypeFromValue(value);
|
|
33
|
+
|
|
34
|
+
const value_container = target.acquire(p, dataType, value);
|
|
35
|
+
|
|
36
|
+
value_container.set(value);
|
|
37
|
+
|
|
38
|
+
// succeeded
|
|
39
|
+
return true;
|
|
40
|
+
},
|
|
41
|
+
ownKeys(target) {
|
|
42
|
+
|
|
43
|
+
return target.getKeys();
|
|
44
|
+
|
|
45
|
+
}
|
|
46
|
+
})
|
|
47
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { Blackboard } from "./Blackboard.js";
|
|
2
|
+
import { make_blackboard_proxy } from "./make_blackboard_proxy.js";
|
|
3
|
+
|
|
4
|
+
test("setters propagate", () => {
|
|
5
|
+
const bb = new Blackboard();
|
|
6
|
+
|
|
7
|
+
const proxy = make_blackboard_proxy(bb);
|
|
8
|
+
|
|
9
|
+
proxy.hello = 7;
|
|
10
|
+
|
|
11
|
+
expect(bb.acquireNumber('hello').getValue()).toBe(7);
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
test("getters propagate", () => {
|
|
16
|
+
const bb = new Blackboard();
|
|
17
|
+
|
|
18
|
+
bb.acquireNumber('hello').set(7);
|
|
19
|
+
|
|
20
|
+
const proxy = make_blackboard_proxy(bb);
|
|
21
|
+
|
|
22
|
+
expect(proxy.hello).toBe(7);
|
|
23
|
+
});
|
package/package.json
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
"productName": "Meep",
|
|
6
6
|
"description": "production-ready JavaScript game engine based on Entity Component System Architecture",
|
|
7
7
|
"author": "Alexander Goldring",
|
|
8
|
-
"version": "2.43.
|
|
8
|
+
"version": "2.43.43",
|
|
9
9
|
"dependencies": {
|
|
10
10
|
"gl-matrix": "3.4.3",
|
|
11
11
|
"fast-levenshtein": "2.0.6",
|