@woosh/meep-engine 2.48.1 → 2.48.5
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/package.json +1 -1
- package/src/core/binary/32BitEncoder.js +11 -3
- package/src/core/binary/BinaryBuffer.js +80 -59
- package/src/core/binary/int32_to_binary_string.js +32 -7
- package/src/core/binary/to_half_float_uint16.js +6 -4
- package/src/core/bvh2/visual/convert_bvh_to_dot_format_string.js +1 -1
- package/src/core/collection/list/List.js +3 -0
- package/src/core/geom/3d/CircleMath.js +13 -2
- package/src/core/geom/3d/matrix/m4_make_translation.js +15 -0
- package/src/core/geom/3d/triangle/computeTrianglePlaneSide.js +4 -13
- package/src/core/geom/Vector3.spec.js +10 -0
- package/src/core/graph/convertGraphToDotString.js +13 -3
- package/src/core/graph/v2/Graph.js +17 -1
- package/src/core/graph/v2/NodeContainer.js +58 -0
- package/src/core/model/ModuleRegistry.js +44 -10
- package/src/core/model/ResourceAccessKind.js +11 -0
- package/src/core/model/ResourceAccessSpecification.js +41 -0
- package/src/engine/Engine.js +1 -1
- package/src/engine/ecs/EntityEventBinding.js +74 -0
- package/src/engine/ecs/EntityManager.js +143 -0
- package/src/engine/ecs/System.js +53 -5
- package/src/engine/ecs/animation/InverseKinematicsSystem.js +6 -0
- package/src/engine/ecs/attachment/AttachmentSystem.js +8 -0
- package/src/engine/ecs/dynamic_actions/DynamicActorSystem.js +5 -0
- package/src/engine/ecs/fow/FogOfWarRevealerSystem.js +7 -3
- package/src/engine/ecs/fow/FogOfWarSystem.js +6 -0
- package/src/engine/ecs/gui/GUIElementSystem.js +1 -1
- package/src/engine/ecs/gui/hud/HeadsUpDisplaySystem.js +8 -0
- package/src/engine/ecs/gui/position/ViewportPositionSystem.js +6 -0
- package/src/engine/ecs/speaker/VoiceSystem.js +13 -0
- package/src/engine/ecs/storage/binary/object/BinaryObjectSerializationAdapter2.js +451 -12
- package/src/engine/ecs/storage/binary/object/BinaryObjectSerializationAdapter2.spec.js +123 -0
- package/src/engine/ecs/system/computeSystemComponentDependencyGraph.js +71 -0
- package/src/engine/ecs/systems/RenderSystem.js +6 -0
- package/src/engine/ecs/terrain/ecs/Terrain.js +26 -44
- package/src/engine/ecs/terrain/ecs/cling/ClingToTerrainSystem.js +9 -0
- package/src/engine/ecs/terrain/tiles/TerrainTile.js +5 -0
- package/src/engine/ecs/terrain/tiles/TerrainTileManager.js +26 -6
- package/src/engine/ecs/tooltip/TooltipComponentSystem.js +7 -0
- package/src/engine/graphics/ecs/animation/animator/AnimationGraphSystem.js +6 -0
- package/src/engine/graphics/ecs/camera/CameraSystem.js +6 -0
- package/src/engine/graphics/ecs/camera/pp/PerfectPanner.js +4 -0
- package/src/engine/graphics/ecs/camera/topdown/TopDownCameraControllerSystem.js +5 -0
- package/src/engine/graphics/ecs/camera/topdown/TopDownCameraLanderSystem.js +6 -0
- package/src/engine/graphics/ecs/light/LightSystem.js +8 -0
- package/src/engine/graphics/ecs/mesh/MeshSystem.js +8 -1
- package/src/engine/graphics/ecs/path/PathDisplaySystem.js +7 -1
- package/src/engine/graphics/ecs/trail2d/Trail2DSystem.js +7 -0
- package/src/engine/graphics/geometry/instancing/InstancedMeshGroup.js +34 -7
- package/src/engine/graphics/particles/ecs/ParticleEmitterSystem.js +6 -0
- package/src/engine/grid/systems/GridPosition2TransformSystem.js +6 -0
- package/src/engine/grid/transform2grid/Transform2GridPositionSystem.js +6 -0
- package/src/engine/intelligence/behavior/Behavior.js +11 -0
- package/src/engine/intelligence/behavior/composite/CompositeBehavior.js +10 -4
- package/src/engine/intelligence/behavior/decorator/AbstractDecoratorBehavior.js +1 -0
- package/src/engine/intelligence/behavior/util/behavior_traverse_tree.js +8 -0
- package/src/engine/navigation/ecs/path_following/PathFollowingSystem.js +8 -0
- package/src/engine/network/RemoteController.js +60 -84
- package/src/engine/network/remoteEditor.js +108 -2
- package/src/engine/sound/SoundEngine.js +81 -79
- package/src/engine/sound/ecs/SoundControllerSystem.js +8 -0
- package/src/engine/sound/ecs/SoundListenerSystem.js +7 -0
- package/src/engine/sound/ecs/emitter/SoundEmitterComponentContext.js +42 -46
- package/src/engine/sound/ecs/emitter/SoundEmitterSystem.js +15 -2
- package/src/engine/sound/ecs/emitter/SoundTrack.js +137 -35
- package/src/engine/sound/ecs/emitter/SoundTrackFlags.js +17 -1
- package/src/engine/sound/ecs/emitter/SoundTrackNodes.js +2 -4
- package/src/engine/sound/ecs/emitter/loadSoundTrackAsset.js +1 -2
- package/src/generation/theme/ThemeEngine.js +20 -3
- package/src/view/{elements/image → common}/HTMLElementCacheKey.js +5 -5
- package/src/view/elements/button/ButtonView.js +10 -2
- package/src/view/elements/image/ImageView.js +1 -1
- package/src/view/elements/video/VideoView.js +1 -1
- package/src/view/interaction/CommandButtonView.js +16 -153
- package/src/view/interaction/createInterfaceCommandButton.js +124 -0
package/package.json
CHANGED
|
@@ -1,11 +1,15 @@
|
|
|
1
|
+
import { FunctionCompiler } from "../function/FunctionCompiler.js";
|
|
2
|
+
import { assert } from "../assert.js";
|
|
3
|
+
|
|
1
4
|
/**
|
|
2
5
|
*
|
|
3
6
|
* @param {number[]} bitCounts
|
|
4
7
|
* @returns {{encode: function(...number):number, decode: function(value:number, result:number[]):void}}
|
|
5
8
|
*/
|
|
6
|
-
import { FunctionCompiler } from "../function/FunctionCompiler.js";
|
|
7
|
-
|
|
8
9
|
export function create32BitCodec(bitCounts) {
|
|
10
|
+
assert.isArray(bitCounts, 'bitCounts');
|
|
11
|
+
assert.lessThanOrEqual(bitCounts.length, 32, `at most 32 groups are supported (1 bit each), instead ${bitCounts} was requested`);
|
|
12
|
+
|
|
9
13
|
const layout = [];
|
|
10
14
|
|
|
11
15
|
const encoderFunctionBody = [];
|
|
@@ -15,10 +19,14 @@ export function create32BitCodec(bitCounts) {
|
|
|
15
19
|
|
|
16
20
|
let offsetCursor = 0;
|
|
17
21
|
|
|
22
|
+
const group_count = bitCounts.length;
|
|
18
23
|
|
|
19
|
-
for (let i = 0, numVariables =
|
|
24
|
+
for (let i = 0, numVariables = group_count; i < numVariables; i++) {
|
|
20
25
|
const size = bitCounts[i];
|
|
21
26
|
|
|
27
|
+
assert.isNonNegativeInteger(size, `size[${i}]`);
|
|
28
|
+
assert.greaterThan(size, 0, `size[${i}] bust be greater than 0, instead was ${size}`);
|
|
29
|
+
|
|
22
30
|
const offset = offsetCursor;
|
|
23
31
|
|
|
24
32
|
layout.push({ offset, size });
|
|
@@ -26,64 +26,70 @@ const MIN_GROWTH_STEP = 1024;
|
|
|
26
26
|
*/
|
|
27
27
|
const MAX_SAFE_UINT_VAR = 2147483647;
|
|
28
28
|
|
|
29
|
+
/**
|
|
30
|
+
* @readonly
|
|
31
|
+
* @type {number}
|
|
32
|
+
*/
|
|
33
|
+
const DEFAULT_INITIAL_SIZE = 1024;
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Utility for reading/writing binary data
|
|
38
|
+
* Mostly useful for serialization/deserialization tasks
|
|
39
|
+
*/
|
|
29
40
|
export class BinaryBuffer {
|
|
41
|
+
|
|
30
42
|
/**
|
|
31
43
|
*
|
|
32
|
-
* @
|
|
33
|
-
*/
|
|
34
|
-
|
|
35
|
-
/**
|
|
36
|
-
*
|
|
37
|
-
* @type {EndianType|boolean}
|
|
38
|
-
*/
|
|
39
|
-
this.endianness = EndianType.BigEndian;
|
|
40
|
-
|
|
41
|
-
/**
|
|
42
|
-
*
|
|
43
|
-
* @type {number}
|
|
44
|
-
*/
|
|
45
|
-
this.position = 0;
|
|
44
|
+
* @type {EndianType|boolean}
|
|
45
|
+
*/
|
|
46
|
+
endianness = EndianType.BigEndian;
|
|
46
47
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
/**
|
|
54
|
-
*
|
|
55
|
-
* @type {number}
|
|
56
|
-
*/
|
|
57
|
-
this.capacity = 0;
|
|
58
|
-
|
|
59
|
-
/**
|
|
60
|
-
*
|
|
61
|
-
* @type {ArrayBuffer}
|
|
62
|
-
* @private
|
|
63
|
-
*/
|
|
64
|
-
this.data = new ArrayBuffer(0);
|
|
65
|
-
|
|
66
|
-
/**
|
|
67
|
-
*
|
|
68
|
-
* @type {DataView}
|
|
69
|
-
* @private
|
|
70
|
-
*/
|
|
71
|
-
this.dataView = new DataView(this.data);
|
|
48
|
+
/**
|
|
49
|
+
*
|
|
50
|
+
* @type {number}
|
|
51
|
+
*/
|
|
52
|
+
position = 0;
|
|
72
53
|
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
this.__data_uint8 = new Uint8Array(0);
|
|
54
|
+
/**
|
|
55
|
+
* @deprecated
|
|
56
|
+
* @type {number}
|
|
57
|
+
*/
|
|
58
|
+
length = 0;
|
|
79
59
|
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
60
|
+
/**
|
|
61
|
+
*
|
|
62
|
+
* @type {number}
|
|
63
|
+
*/
|
|
64
|
+
capacity = DEFAULT_INITIAL_SIZE;
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
*
|
|
68
|
+
* @type {ArrayBuffer}
|
|
69
|
+
* @private
|
|
70
|
+
*/
|
|
71
|
+
data = new ArrayBuffer(DEFAULT_INITIAL_SIZE);
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
*
|
|
75
|
+
* @type {DataView}
|
|
76
|
+
* @private
|
|
77
|
+
*/
|
|
78
|
+
dataView = new DataView(this.data);
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
*
|
|
82
|
+
* @type {Uint8Array}
|
|
83
|
+
* @private
|
|
84
|
+
*/
|
|
85
|
+
__data_uint8 = new Uint8Array(this.data);
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
*
|
|
89
|
+
* @type {number}
|
|
90
|
+
* @private
|
|
91
|
+
*/
|
|
92
|
+
__growFactor = 1.1;
|
|
87
93
|
|
|
88
94
|
/**
|
|
89
95
|
* Access raw underlying bytes attached to the buffer
|
|
@@ -94,21 +100,24 @@ export class BinaryBuffer {
|
|
|
94
100
|
}
|
|
95
101
|
|
|
96
102
|
/**
|
|
97
|
-
* @param {ArrayBuffer}
|
|
103
|
+
* @param {ArrayBuffer} data
|
|
98
104
|
*/
|
|
99
|
-
fromArrayBuffer(
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
this.__data_uint8 = new Uint8Array(arrayBuffer);
|
|
105
|
+
fromArrayBuffer(data) {
|
|
106
|
+
assert.defined(data, 'data');
|
|
107
|
+
assert.notNull(data, 'data');
|
|
103
108
|
|
|
104
|
-
this.
|
|
109
|
+
this.data = data;
|
|
110
|
+
this.dataView = new DataView(data);
|
|
111
|
+
this.__data_uint8 = new Uint8Array(data);
|
|
112
|
+
|
|
113
|
+
this.capacity = data.byteLength;
|
|
105
114
|
//assume that all the data is useful
|
|
106
115
|
this.length = this.capacity;
|
|
107
116
|
this.position = 0;
|
|
108
117
|
}
|
|
109
118
|
|
|
110
119
|
/**
|
|
111
|
-
*
|
|
120
|
+
* Set capacity to contain data only up to current position
|
|
112
121
|
* @returns {BinaryBuffer}
|
|
113
122
|
*/
|
|
114
123
|
trim() {
|
|
@@ -122,6 +131,12 @@ export class BinaryBuffer {
|
|
|
122
131
|
* @param {number} capacity
|
|
123
132
|
*/
|
|
124
133
|
setCapacity(capacity) {
|
|
134
|
+
assert.isNonNegativeInteger(capacity, 'capacity');
|
|
135
|
+
|
|
136
|
+
if (capacity < this.position) {
|
|
137
|
+
throw new Error(`Attempting to set capacity(=${capacity}) below current position(=${this.position})`);
|
|
138
|
+
}
|
|
139
|
+
|
|
125
140
|
const oldData = this.__data_uint8;
|
|
126
141
|
const newData = new Uint8Array(capacity);
|
|
127
142
|
|
|
@@ -1117,3 +1132,9 @@ export class BinaryBuffer {
|
|
|
1117
1132
|
return temp;
|
|
1118
1133
|
}
|
|
1119
1134
|
}
|
|
1135
|
+
|
|
1136
|
+
/**
|
|
1137
|
+
* @readonly
|
|
1138
|
+
* @type {boolean}
|
|
1139
|
+
*/
|
|
1140
|
+
BinaryBuffer.prototype.isBinaryBuffer = true;
|
|
@@ -1,3 +1,19 @@
|
|
|
1
|
+
|
|
2
|
+
|
|
3
|
+
const RX = /\B(?=(.{8})+(?!.))/g;
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* 2147483647
|
|
7
|
+
* @type {number}
|
|
8
|
+
*/
|
|
9
|
+
const MAX_VALUE = 2 ** 31 - 1;
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* -2147483648
|
|
13
|
+
* @type {number}
|
|
14
|
+
*/
|
|
15
|
+
const MIN_VALUE = -1 * (2 ** 31);
|
|
16
|
+
|
|
1
17
|
/**
|
|
2
18
|
* @see https://stackoverflow.com/questions/9939760/how-do-i-convert-an-integer-to-binary-in-javascript
|
|
3
19
|
* @example 1024 -> "00000000 00000000 00000100 00000000"
|
|
@@ -7,12 +23,21 @@
|
|
|
7
23
|
*/
|
|
8
24
|
export function int32_to_binary_string(nMask) {
|
|
9
25
|
// nMask must be between -2147483648 and 2147483647
|
|
10
|
-
if (nMask >
|
|
11
|
-
throw "number too large. number shouldn't be > 2**31-1"
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
26
|
+
if (nMask > MAX_VALUE) {
|
|
27
|
+
throw "number too large. number shouldn't be > 2**31-1";//added
|
|
28
|
+
}
|
|
29
|
+
if (nMask < MIN_VALUE) {
|
|
30
|
+
throw "number too far negative, number shouldn't be < 2**31"//added
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
let nFlag = 0, nShifted = nMask, sMask = '';
|
|
34
|
+
|
|
35
|
+
for (; nFlag < 32;
|
|
36
|
+
nFlag++, sMask += String(nShifted >>> 31), nShifted <<= 1
|
|
37
|
+
) {
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
sMask = sMask.replace(RX, " ") // added
|
|
41
|
+
|
|
17
42
|
return sMask;
|
|
18
43
|
}
|
|
@@ -8,11 +8,13 @@ const _int32View = new Int32Array(_floatView.buffer);
|
|
|
8
8
|
* @returns {number}
|
|
9
9
|
*/
|
|
10
10
|
export function to_half_float_uint16(val) {
|
|
11
|
-
|
|
11
|
+
let _val = val;
|
|
12
12
|
|
|
13
|
-
|
|
13
|
+
if (_val > 65504) {
|
|
14
14
|
|
|
15
|
-
|
|
15
|
+
console.warn('to_half_float_uint16(): value exceeds 65504.');
|
|
16
|
+
|
|
17
|
+
_val = 65504; // maximum representable value in float16
|
|
16
18
|
|
|
17
19
|
}
|
|
18
20
|
|
|
@@ -22,7 +24,7 @@ export function to_half_float_uint16(val) {
|
|
|
22
24
|
* used, eg. in Ogre), with the additional benefit of rounding, inspired
|
|
23
25
|
* by James Tursa?s half-precision code. */
|
|
24
26
|
|
|
25
|
-
_floatView[0] =
|
|
27
|
+
_floatView[0] = _val;
|
|
26
28
|
const x = _int32View[0];
|
|
27
29
|
|
|
28
30
|
let bits = (x >> 16) & 0x8000; /* Get the sign */
|
|
@@ -753,6 +753,9 @@ List.prototype.toJSON = function () {
|
|
|
753
753
|
*/
|
|
754
754
|
List.prototype.fromJSON = function (json, constructor) {
|
|
755
755
|
this.reset();
|
|
756
|
+
|
|
757
|
+
assert.isArray(json,'json');
|
|
758
|
+
|
|
756
759
|
if (typeof constructor === "function") {
|
|
757
760
|
this.addAll(json.map(function (elJSON) {
|
|
758
761
|
const el = new constructor();
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { v3_angle_between } from "../v3_angle_between.js";
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
|
+
* Compute 3d bounds of a circle in 3d space
|
|
4
5
|
* NOTE: based on https://stackoverflow.com/questions/2592011/bounding-boxes-for-circle-and-arcs-in-3d
|
|
5
6
|
* @param {AABB3} result
|
|
6
7
|
* @param {number} centerX
|
|
@@ -11,7 +12,13 @@ import { v3_angle_between } from "../v3_angle_between.js";
|
|
|
11
12
|
* @param {number} normalZ orientation of the circle
|
|
12
13
|
* @param {number} radius
|
|
13
14
|
*/
|
|
14
|
-
export function computeCircleBoundingBox(
|
|
15
|
+
export function computeCircleBoundingBox(
|
|
16
|
+
result,
|
|
17
|
+
centerX, centerY, centerZ,
|
|
18
|
+
normalX, normalY, normalZ,
|
|
19
|
+
radius
|
|
20
|
+
) {
|
|
21
|
+
|
|
15
22
|
const ax = v3_angle_between(normalX, normalY, normalZ, 1, 0, 0);
|
|
16
23
|
const ay = v3_angle_between(normalX, normalY, normalZ, 0, 1, 0);
|
|
17
24
|
const az = v3_angle_between(normalX, normalY, normalZ, 0, 0, 1);
|
|
@@ -20,5 +27,9 @@ export function computeCircleBoundingBox(result, centerX, centerY, centerZ, norm
|
|
|
20
27
|
const rY = Math.sin(ay) * radius;
|
|
21
28
|
const rZ = Math.sin(az) * radius;
|
|
22
29
|
|
|
23
|
-
result.setBounds(
|
|
30
|
+
result.setBounds(
|
|
31
|
+
centerX - rX, centerY - rY, centerZ - rZ,
|
|
32
|
+
centerX + rX, centerY + rY, centerZ + rZ
|
|
33
|
+
);
|
|
34
|
+
|
|
24
35
|
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { array_copy } from "../../../collection/array/copyArray.js";
|
|
2
|
+
import { MATRIX_4_IDENTITY } from "./MATRIX_4_IDENTITY.js";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Create a 4x4 matrix that corresponds to translation transform
|
|
6
|
+
* @param {ArrayLike<number>} output
|
|
7
|
+
* @param {ArrayLike<number>} translation 3d vector
|
|
8
|
+
*/
|
|
9
|
+
export function m4_make_translation(output, translation) {
|
|
10
|
+
array_copy(MATRIX_4_IDENTITY, 0, output, 0, 16);
|
|
11
|
+
|
|
12
|
+
output[12] = translation[0];
|
|
13
|
+
output[13] = translation[1];
|
|
14
|
+
output[14] = translation[2];
|
|
15
|
+
}
|
|
@@ -19,19 +19,10 @@ import { v3_dot } from "../../v3_dot.js";
|
|
|
19
19
|
* @returns {number}
|
|
20
20
|
*/
|
|
21
21
|
export function computeTrianglePlaneSide(
|
|
22
|
-
plane_normal_x,
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
ax,
|
|
27
|
-
ay,
|
|
28
|
-
az,
|
|
29
|
-
bx,
|
|
30
|
-
by,
|
|
31
|
-
bz,
|
|
32
|
-
cx,
|
|
33
|
-
cy,
|
|
34
|
-
cz
|
|
22
|
+
plane_normal_x, plane_normal_y, plane_normal_z, plane_constant,
|
|
23
|
+
ax, ay, az,
|
|
24
|
+
bx, by, bz,
|
|
25
|
+
cx, cy, cz
|
|
35
26
|
) {
|
|
36
27
|
let result = 0;
|
|
37
28
|
|
|
@@ -35,3 +35,13 @@ test('slerp', () => {
|
|
|
35
35
|
expect(v.y).toBeCloseTo(0.7071067811865475);
|
|
36
36
|
expect(v.z).toBeCloseTo(0);
|
|
37
37
|
});
|
|
38
|
+
|
|
39
|
+
test('addVectors', () => {
|
|
40
|
+
const ut = new Vector3();
|
|
41
|
+
|
|
42
|
+
ut.addVectors(new Vector3(1, 3, 5), new Vector3(-7, 11, 13));
|
|
43
|
+
|
|
44
|
+
expect(ut.x).toBe(-6);
|
|
45
|
+
expect(ut.y).toBe(14);
|
|
46
|
+
expect(ut.z).toBe(18);
|
|
47
|
+
});
|
|
@@ -1,12 +1,22 @@
|
|
|
1
1
|
import LineBuilder from "../codegen/LineBuilder.js";
|
|
2
2
|
import { EdgeDirectionType } from "./Edge.js";
|
|
3
3
|
|
|
4
|
+
|
|
5
|
+
function defaultNodeToDot(node){
|
|
6
|
+
return `[label="${node.toString()}"]`;
|
|
7
|
+
}
|
|
8
|
+
|
|
4
9
|
/**
|
|
10
|
+
* @template Node
|
|
5
11
|
* Build a Graphviz DOT representation of the graph
|
|
6
|
-
* @param {Graph} graph
|
|
12
|
+
* @param {Graph<Node>} graph
|
|
13
|
+
* @param {function(Node):string} nodeToDot
|
|
7
14
|
* @returns {string}
|
|
8
15
|
*/
|
|
9
|
-
export function convertGraphToDotString(
|
|
16
|
+
export function convertGraphToDotString({
|
|
17
|
+
graph,
|
|
18
|
+
nodeToDot=defaultNodeToDot
|
|
19
|
+
}) {
|
|
10
20
|
const lb = new LineBuilder();
|
|
11
21
|
|
|
12
22
|
lb.add('strict digraph Graph {');
|
|
@@ -24,7 +34,7 @@ export function convertGraphToDotString(graph) {
|
|
|
24
34
|
|
|
25
35
|
const node = nodes[i];
|
|
26
36
|
|
|
27
|
-
lb.add(`${nodeId(i)}
|
|
37
|
+
lb.add(`${nodeId(i)} ${nodeToDot(node)};`);
|
|
28
38
|
|
|
29
39
|
}
|
|
30
40
|
|
|
@@ -62,7 +62,7 @@ export class Graph {
|
|
|
62
62
|
/**
|
|
63
63
|
*
|
|
64
64
|
* @param {N} node
|
|
65
|
-
* @returns {boolean}
|
|
65
|
+
* @returns {boolean} true if node was added, false if node already exists
|
|
66
66
|
*/
|
|
67
67
|
addNode(node) {
|
|
68
68
|
if (this.hasNode(node)) {
|
|
@@ -328,6 +328,22 @@ export class Graph {
|
|
|
328
328
|
return context_a.getAnyEdgeWith(b);
|
|
329
329
|
}
|
|
330
330
|
|
|
331
|
+
/**
|
|
332
|
+
*
|
|
333
|
+
* @param {N} from
|
|
334
|
+
* @param {N} to
|
|
335
|
+
* @returns {Edge<N>|undefined}
|
|
336
|
+
*/
|
|
337
|
+
getAnyDirectedEdge(from, to){
|
|
338
|
+
const ctx_a = this.__nodes.get(from);
|
|
339
|
+
|
|
340
|
+
if(ctx_a === undefined){
|
|
341
|
+
return undefined;
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
return ctx_a.getAnyDirectionEdgeTo(to);
|
|
345
|
+
}
|
|
346
|
+
|
|
331
347
|
/**
|
|
332
348
|
*
|
|
333
349
|
* @param {Edge<N>[]} result
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { EdgeDirectionType } from "../Edge.js";
|
|
2
|
+
|
|
1
3
|
export class NodeContainer {
|
|
2
4
|
/**
|
|
3
5
|
* @template N
|
|
@@ -40,6 +42,31 @@ export class NodeContainer {
|
|
|
40
42
|
return this.__edges;
|
|
41
43
|
}
|
|
42
44
|
|
|
45
|
+
/**
|
|
46
|
+
*
|
|
47
|
+
* @return {number}
|
|
48
|
+
*/
|
|
49
|
+
getIncomingEdgeCount() {
|
|
50
|
+
let r = 0;
|
|
51
|
+
|
|
52
|
+
const edges = this.__edges;
|
|
53
|
+
const edge_count = edges.length;
|
|
54
|
+
|
|
55
|
+
for (let i = 0; i < edge_count; i++) {
|
|
56
|
+
const edge = edges[i];
|
|
57
|
+
|
|
58
|
+
if (
|
|
59
|
+
(edge.first === this.node && edge.direction === EdgeDirectionType.Forward)
|
|
60
|
+
|| (edge.second === this.node && edge.direction === EdgeDirectionType.Backward)
|
|
61
|
+
|
|
62
|
+
) {
|
|
63
|
+
r++;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
return r;
|
|
68
|
+
}
|
|
69
|
+
|
|
43
70
|
|
|
44
71
|
/**
|
|
45
72
|
*
|
|
@@ -101,6 +128,37 @@ export class NodeContainer {
|
|
|
101
128
|
return undefined;
|
|
102
129
|
}
|
|
103
130
|
|
|
131
|
+
/**
|
|
132
|
+
* Undirected edges don't count
|
|
133
|
+
* @param {N} other
|
|
134
|
+
* @returns {Edge<N>|undefined}
|
|
135
|
+
*/
|
|
136
|
+
getAnyDirectionEdgeTo(other) {
|
|
137
|
+
|
|
138
|
+
/**
|
|
139
|
+
*
|
|
140
|
+
* @type {Edge[]}
|
|
141
|
+
*/
|
|
142
|
+
const edges = this.__edges;
|
|
143
|
+
|
|
144
|
+
const n = edges.length;
|
|
145
|
+
|
|
146
|
+
for (let i = 0; i < n; i++) {
|
|
147
|
+
const edge = edges[i];
|
|
148
|
+
|
|
149
|
+
if (
|
|
150
|
+
(edge.second === other && edge.direction === EdgeDirectionType.Forward)
|
|
151
|
+
|| (edge.first === other && edge.direction === EdgeDirectionType.Backward)
|
|
152
|
+
|
|
153
|
+
) {
|
|
154
|
+
return edge;
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
// not found
|
|
159
|
+
return undefined;
|
|
160
|
+
}
|
|
161
|
+
|
|
104
162
|
/**
|
|
105
163
|
*
|
|
106
164
|
* @param {Edge} e
|
|
@@ -1,12 +1,19 @@
|
|
|
1
1
|
import { assert } from "../assert.js";
|
|
2
2
|
|
|
3
3
|
export class ModuleRegistry {
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
*
|
|
7
|
+
* @type {Map<string, *>}
|
|
8
|
+
*/
|
|
9
|
+
#modules = new Map();
|
|
10
|
+
/**
|
|
11
|
+
*
|
|
12
|
+
* @type {Map<*,string[]>}
|
|
13
|
+
*/
|
|
14
|
+
#reverse_lookup = new Map();
|
|
15
|
+
|
|
4
16
|
constructor() {
|
|
5
|
-
/**
|
|
6
|
-
*
|
|
7
|
-
* @type {Map<string, *>}
|
|
8
|
-
*/
|
|
9
|
-
this.__elements = new Map();
|
|
10
17
|
|
|
11
18
|
const self = this;
|
|
12
19
|
|
|
@@ -19,7 +26,7 @@ export class ModuleRegistry {
|
|
|
19
26
|
* @returns {Class}
|
|
20
27
|
*/
|
|
21
28
|
get(target, p, receiver) {
|
|
22
|
-
const module = self.
|
|
29
|
+
const module = self.get(p);
|
|
23
30
|
|
|
24
31
|
if (module === undefined) {
|
|
25
32
|
throw new Error(`Module '${p}' not found in the registry`);
|
|
@@ -35,7 +42,7 @@ export class ModuleRegistry {
|
|
|
35
42
|
* @param {(name:string, module:*)=>void} visitor
|
|
36
43
|
*/
|
|
37
44
|
traverse(visitor) {
|
|
38
|
-
this.
|
|
45
|
+
this.#modules.forEach((klass, name) => visitor(name, klass));
|
|
39
46
|
}
|
|
40
47
|
|
|
41
48
|
|
|
@@ -45,7 +52,7 @@ export class ModuleRegistry {
|
|
|
45
52
|
* @returns {T}
|
|
46
53
|
*/
|
|
47
54
|
get(name) {
|
|
48
|
-
return this.
|
|
55
|
+
return this.#modules.get(name);
|
|
49
56
|
}
|
|
50
57
|
|
|
51
58
|
/**
|
|
@@ -54,7 +61,7 @@ export class ModuleRegistry {
|
|
|
54
61
|
* @returns {boolean}
|
|
55
62
|
*/
|
|
56
63
|
has(name) {
|
|
57
|
-
return this.
|
|
64
|
+
return this.#modules.has(name);
|
|
58
65
|
}
|
|
59
66
|
|
|
60
67
|
/**
|
|
@@ -75,11 +82,38 @@ export class ModuleRegistry {
|
|
|
75
82
|
return false;
|
|
76
83
|
}
|
|
77
84
|
|
|
78
|
-
this.
|
|
85
|
+
this.#modules.set(name, module);
|
|
86
|
+
|
|
87
|
+
let names = this.#reverse_lookup.get(module);
|
|
88
|
+
|
|
89
|
+
if (names === undefined) {
|
|
90
|
+
names = [];
|
|
91
|
+
this.#reverse_lookup.set(module, names);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
names.push(name);
|
|
79
95
|
|
|
80
96
|
return true;
|
|
81
97
|
}
|
|
82
98
|
|
|
99
|
+
/**
|
|
100
|
+
* Find all names associated with the given module
|
|
101
|
+
* @template T
|
|
102
|
+
* @param {T} module
|
|
103
|
+
* @returns {string[]}
|
|
104
|
+
* @throws if module is not registered
|
|
105
|
+
*/
|
|
106
|
+
findNamesByModule(module) {
|
|
107
|
+
|
|
108
|
+
const names = this.#reverse_lookup.get(module);
|
|
109
|
+
|
|
110
|
+
if (names === undefined) {
|
|
111
|
+
throw new Error('Module not found');
|
|
112
|
+
} else {
|
|
113
|
+
return names;
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
|
|
83
117
|
initialize() {
|
|
84
118
|
|
|
85
119
|
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Note that values correspond to shifted specific 1 bit mask,
|
|
3
|
+
* this is intentional, to allow you to encode complex access pattern into a single integer value
|
|
4
|
+
* @readonly
|
|
5
|
+
* @enum {number}
|
|
6
|
+
*/
|
|
7
|
+
export const ResourceAccessKind = {
|
|
8
|
+
Read: 1,
|
|
9
|
+
Write: 2,
|
|
10
|
+
Create: 4
|
|
11
|
+
};
|