@woosh/meep-engine 2.48.17 → 2.48.19
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/dec2hex.spec.js +13 -0
- package/src/core/bvh2/bvh3/ExplicitBinaryBoundingVolumeHierarchy.d.ts +18 -0
- package/src/core/bvh2/bvh3/ExplicitBinaryBoundingVolumeHierarchy.js +18 -0
- package/src/core/bvh2/bvh3/ExplicitBinaryBoundingVolumeHierarchy.spec.js +56 -0
- package/src/core/cache/Cache.d.ts +5 -0
- package/src/core/cache/Cache.js +8 -1
- package/src/core/cache/Cache.spec.js +47 -3
- package/src/core/codegen/LineBuilder.js +117 -106
- package/src/core/collection/HashMap.spec.js +32 -0
- package/src/core/collection/list/List.js +6 -4
- package/src/core/geom/Matrix4.js +4 -1
- package/src/core/geom/Quaternion.js +4 -0
- package/src/core/geom/Vector3.js +9 -31
- package/src/core/graph/Edge.js +11 -2
- package/src/core/graph/v2/Graph.js +36 -31
- package/src/core/graph/v2/Graph.spec.js +309 -1
- package/src/core/math/fract.spec.js +11 -0
- package/src/core/math/isPowerOfTwo.spec.js +9 -0
- package/src/core/math/isPowerOrTwo.js +5 -0
- package/src/core/math/newton_solver_1d.js +1 -1
- package/src/core/math/newton_solver_1d.spec.js +9 -0
- package/src/core/math/pingpong.spec.js +11 -0
- package/src/core/math/random/randomBytes.js +16 -0
- package/src/core/math/random/randomFloatBetween.spec.js +8 -0
- package/src/core/math/random/randomFromArray.js +3 -3
- package/src/core/math/random/randomIntegerBetween.js +5 -0
- package/src/core/math/random/randomIntegerBetween.spec.js +7 -0
- package/src/core/math/statistics/halton_sequence.spec.js +17 -0
- package/src/engine/asset/AssetManager.d.ts +11 -1
- package/src/engine/asset/AssetManager.spec.js +2 -2
- package/src/engine/control/ControlContext.js +2 -1
- package/src/engine/ecs/EntityBuilder.d.ts +6 -0
- package/src/engine/ecs/EntityBuilder.js +2 -22
- package/src/engine/ecs/EntityBuilder.spec.js +71 -1
- package/src/engine/ecs/EntityBuilderFlags.js +20 -0
- package/src/engine/ecs/EntityComponentDataset.js +3 -6
- package/src/engine/ecs/dynamic_actions/DynamicActorSystem.js +2 -1
- package/src/engine/ecs/gui/menu/radial/RadialContextMenu.js +2 -1
- package/src/engine/ecs/guid/GUID.js +48 -26
- package/src/engine/ecs/guid/GUID.spec.js +56 -10
- package/src/engine/ecs/speaker/VoiceSystem.js +2 -1
- package/src/engine/ecs/transform/Transform.d.ts +11 -1
- package/src/engine/ecs/transform/Transform.js +6 -3
- package/src/engine/ecs/transform/Transform.spec.js +67 -1
- package/src/engine/graphics/ecs/decal/v2/prototypeDecalSystem.js +2 -1
- package/src/engine/physics/fluid/Fluid.js +3 -0
- /package/src/core/geom/{Matrix3.js → m3_determinant.js} +0 -0
package/package.json
CHANGED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { dec2hex } from "./dec2hex.js";
|
|
2
|
+
|
|
3
|
+
test("zero padding", () => {
|
|
4
|
+
expect(dec2hex(0)).toBe("00");
|
|
5
|
+
expect(dec2hex(10)).toBe("0a");
|
|
6
|
+
});
|
|
7
|
+
|
|
8
|
+
test("two digits", () => {
|
|
9
|
+
|
|
10
|
+
expect(dec2hex(16)).toBe("10");
|
|
11
|
+
expect(dec2hex(255)).toBe("ff");
|
|
12
|
+
|
|
13
|
+
});
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
export class ExplicitBinaryBoundingVolumeHierarchy {
|
|
2
2
|
readonly root: number
|
|
3
3
|
|
|
4
|
+
node_capacity: number
|
|
5
|
+
|
|
4
6
|
allocate_node(): number
|
|
5
7
|
|
|
6
8
|
release_node(node: number): void
|
|
@@ -19,6 +21,22 @@ export class ExplicitBinaryBoundingVolumeHierarchy {
|
|
|
19
21
|
|
|
20
22
|
node_get_user_data(node: number): number
|
|
21
23
|
|
|
24
|
+
node_set_child1(node: number, child1: number): void
|
|
25
|
+
|
|
26
|
+
node_get_child1(node: number): number
|
|
27
|
+
|
|
28
|
+
node_set_child2(node: number, child1: number): void
|
|
29
|
+
|
|
30
|
+
node_get_child2(node: number): number
|
|
31
|
+
|
|
32
|
+
node_set_parent(node: number, parent: number): void
|
|
33
|
+
|
|
34
|
+
node_get_parent(node: number): number
|
|
35
|
+
|
|
36
|
+
node_set_height(node: number, height: number): void
|
|
37
|
+
|
|
38
|
+
node_get_height(node: number): number
|
|
39
|
+
|
|
22
40
|
release_all(): void
|
|
23
41
|
|
|
24
42
|
trim(): void
|
|
@@ -130,6 +130,18 @@ export class ExplicitBinaryBoundingVolumeHierarchy {
|
|
|
130
130
|
return this.__capacity;
|
|
131
131
|
}
|
|
132
132
|
|
|
133
|
+
/**
|
|
134
|
+
*
|
|
135
|
+
* @param {number} v
|
|
136
|
+
*/
|
|
137
|
+
set node_capacity(v) {
|
|
138
|
+
if (this.__size > v) {
|
|
139
|
+
throw new Error(`Can't shrink capacity to ${v}, because it's below occupancy(${this.__size}).`);
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
this.__set_capacity(v);
|
|
143
|
+
}
|
|
144
|
+
|
|
133
145
|
__grow_capacity() {
|
|
134
146
|
const new_capacity = Math.ceil(max2(
|
|
135
147
|
this.__capacity * CAPACITY_GROW_MULTIPLIER,
|
|
@@ -145,6 +157,12 @@ export class ExplicitBinaryBoundingVolumeHierarchy {
|
|
|
145
157
|
* @private
|
|
146
158
|
*/
|
|
147
159
|
__set_capacity(new_capacity) {
|
|
160
|
+
assert.isNonNegativeInteger(new_capacity, 'new_capacity');
|
|
161
|
+
|
|
162
|
+
if (this.__capacity === new_capacity) {
|
|
163
|
+
// already at the exact desired capacity
|
|
164
|
+
return;
|
|
165
|
+
}
|
|
148
166
|
|
|
149
167
|
const old_data_uint32 = this.__data_uint32;
|
|
150
168
|
|
|
@@ -162,3 +162,59 @@ test("release_all with 1 leaf", () => {
|
|
|
162
162
|
|
|
163
163
|
expect(bvh.root).toBe(NULL_NODE);
|
|
164
164
|
});
|
|
165
|
+
|
|
166
|
+
test("capacity grows as necessary when allocating", () => {
|
|
167
|
+
const bvh = new ExplicitBinaryBoundingVolumeHierarchy();
|
|
168
|
+
|
|
169
|
+
bvh.node_capacity = 1;
|
|
170
|
+
|
|
171
|
+
bvh.allocate_node();
|
|
172
|
+
|
|
173
|
+
bvh.allocate_node();
|
|
174
|
+
|
|
175
|
+
expect(bvh.node_capacity).toBeGreaterThanOrEqual(2);
|
|
176
|
+
});
|
|
177
|
+
|
|
178
|
+
test("trim sets capacity to exact allocated size", () => {
|
|
179
|
+
const bvh = new ExplicitBinaryBoundingVolumeHierarchy();
|
|
180
|
+
|
|
181
|
+
bvh.node_capacity = 1;
|
|
182
|
+
|
|
183
|
+
bvh.allocate_node();
|
|
184
|
+
|
|
185
|
+
bvh.allocate_node();
|
|
186
|
+
|
|
187
|
+
bvh.trim();
|
|
188
|
+
|
|
189
|
+
expect(bvh.node_capacity).toBe(2);
|
|
190
|
+
});
|
|
191
|
+
|
|
192
|
+
|
|
193
|
+
test("node property setters/getters", () => {
|
|
194
|
+
|
|
195
|
+
const bvh = new ExplicitBinaryBoundingVolumeHierarchy();
|
|
196
|
+
|
|
197
|
+
const node = bvh.allocate_node();
|
|
198
|
+
|
|
199
|
+
bvh.node_set_user_data(node, 3);
|
|
200
|
+
|
|
201
|
+
expect(bvh.node_get_user_data(node)).toBe(3);
|
|
202
|
+
|
|
203
|
+
bvh.node_set_child1(node, 7);
|
|
204
|
+
bvh.node_set_child2(node, 11);
|
|
205
|
+
bvh.node_set_parent(node, 13);
|
|
206
|
+
bvh.node_set_height(node, 17);
|
|
207
|
+
|
|
208
|
+
const expected_aabb = new Float32Array([1.1, 3.2, 7.3, 11.4, 13.5, 17.6]);
|
|
209
|
+
bvh.node_set_aabb(node, expected_aabb);
|
|
210
|
+
|
|
211
|
+
expect(bvh.node_get_child1(node)).toBe(7);
|
|
212
|
+
expect(bvh.node_get_child2(node)).toBe(11);
|
|
213
|
+
expect(bvh.node_get_parent(node)).toBe(13);
|
|
214
|
+
expect(bvh.node_get_height(node)).toBe(17);
|
|
215
|
+
|
|
216
|
+
const actual_aabb = [];
|
|
217
|
+
bvh.node_get_aabb(node, actual_aabb)
|
|
218
|
+
|
|
219
|
+
expect(actual_aabb).toEqual(Array.from(expected_aabb));
|
|
220
|
+
});
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import Signal from "../events/signal/Signal";
|
|
2
|
+
|
|
1
3
|
export class Cache<K, V> {
|
|
2
4
|
constructor({
|
|
3
5
|
maxWeight,
|
|
@@ -15,6 +17,9 @@ export class Cache<K, V> {
|
|
|
15
17
|
capacity?: number
|
|
16
18
|
})
|
|
17
19
|
|
|
20
|
+
readonly onEvicted: Signal<K, V>
|
|
21
|
+
readonly onRemoved: Signal<K, V>
|
|
22
|
+
|
|
18
23
|
readonly weight: number
|
|
19
24
|
readonly maxWeight: number
|
|
20
25
|
|
package/src/core/cache/Cache.js
CHANGED
|
@@ -3,6 +3,7 @@ import { HashMap } from "../collection/HashMap.js";
|
|
|
3
3
|
import Signal from "../events/signal/Signal.js";
|
|
4
4
|
import { returnOne, returnZero, strictEquals } from "../function/Functions.js";
|
|
5
5
|
import { CacheElement } from "./CacheElement.js";
|
|
6
|
+
import { collectIteratorValueToArray } from "../collection/IteratorUtils.js";
|
|
6
7
|
|
|
7
8
|
/**
|
|
8
9
|
* TODO validate hashes of held elements to keep them up to date. Keys are assumed to be immutable, but this assumption may be broken by users
|
|
@@ -419,7 +420,13 @@ export class Cache {
|
|
|
419
420
|
* Remove all elements from the cache
|
|
420
421
|
*/
|
|
421
422
|
clear() {
|
|
422
|
-
|
|
423
|
+
/**
|
|
424
|
+
*
|
|
425
|
+
* @type {Key[]}
|
|
426
|
+
*/
|
|
427
|
+
const keys = [];
|
|
428
|
+
|
|
429
|
+
collectIteratorValueToArray(keys,this.data.keys());
|
|
423
430
|
|
|
424
431
|
const n = keys.length;
|
|
425
432
|
for (let i = 0; i < n; i++) {
|
|
@@ -88,11 +88,55 @@ test("remove method", () => {
|
|
|
88
88
|
expect(cache.get("a")).toBe(null);
|
|
89
89
|
});
|
|
90
90
|
|
|
91
|
-
test("replacing element with the same key",()=>{
|
|
91
|
+
test("replacing element with the same key", () => {
|
|
92
92
|
const cache = new Cache();
|
|
93
93
|
|
|
94
|
-
cache.put("a","b");
|
|
95
|
-
cache.put("a","c");
|
|
94
|
+
cache.put("a", "b");
|
|
95
|
+
cache.put("a", "c");
|
|
96
96
|
|
|
97
97
|
expect(cache.get("a")).toBe("c");
|
|
98
98
|
});
|
|
99
|
+
|
|
100
|
+
test("getOrCompute", () => {
|
|
101
|
+
|
|
102
|
+
const cache = new Cache();
|
|
103
|
+
|
|
104
|
+
const tokens = [1, 3, 5];
|
|
105
|
+
|
|
106
|
+
const compute = () => tokens.shift();
|
|
107
|
+
|
|
108
|
+
expect(cache.getOrCompute("x", compute)).toBe(1);
|
|
109
|
+
|
|
110
|
+
expect(cache.get("x")).toBe(1);
|
|
111
|
+
|
|
112
|
+
expect(cache.getOrCompute("x", compute)).toBe(1);
|
|
113
|
+
|
|
114
|
+
expect(cache.getOrCompute("y", compute)).toBe(3);
|
|
115
|
+
|
|
116
|
+
expect(cache.get("y")).toBe(3);
|
|
117
|
+
|
|
118
|
+
expect(cache.getOrCompute("y", compute)).toBe(3);
|
|
119
|
+
|
|
120
|
+
})
|
|
121
|
+
|
|
122
|
+
test("clear on empty does not throw", () => {
|
|
123
|
+
|
|
124
|
+
const cache = new Cache();
|
|
125
|
+
|
|
126
|
+
cache.clear();
|
|
127
|
+
|
|
128
|
+
});
|
|
129
|
+
|
|
130
|
+
test("clear with a single entry", () => {
|
|
131
|
+
|
|
132
|
+
const cache = new Cache();
|
|
133
|
+
|
|
134
|
+
cache.set("x", 1);
|
|
135
|
+
|
|
136
|
+
expect(cache.contains("x")).toBe(true);
|
|
137
|
+
|
|
138
|
+
cache.clear();
|
|
139
|
+
|
|
140
|
+
expect(cache.contains("x")).toBe(false);
|
|
141
|
+
|
|
142
|
+
});
|
|
@@ -3,146 +3,157 @@
|
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
5
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
6
|
+
class Line {
|
|
7
|
+
/**
|
|
8
|
+
*
|
|
9
|
+
* @param {string} text
|
|
10
|
+
* @param {number} indent
|
|
11
|
+
* @constructor
|
|
12
|
+
*/
|
|
13
|
+
constructor(text, indent) {
|
|
14
|
+
this.text = text;
|
|
15
|
+
this.indentation = indent;
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
class LineBuilder {
|
|
16
20
|
|
|
17
|
-
const LineBuilder = function () {
|
|
18
21
|
/**
|
|
19
22
|
*
|
|
20
|
-
* @type {
|
|
23
|
+
* @type {Line[]}
|
|
21
24
|
*/
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
}
|
|
25
|
+
lines = [];
|
|
26
|
+
/**
|
|
27
|
+
*
|
|
28
|
+
* @type {number}
|
|
29
|
+
*/
|
|
30
|
+
indentation = 0;
|
|
31
|
+
/**
|
|
32
|
+
*
|
|
33
|
+
* @type {number}
|
|
34
|
+
*/
|
|
35
|
+
indentSpaces = 4;
|
|
26
36
|
|
|
27
|
-
/**
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
37
|
+
/**
|
|
38
|
+
*
|
|
39
|
+
* @return {boolean}
|
|
40
|
+
* @param {string} term
|
|
41
|
+
*/
|
|
42
|
+
containsSubstring(term) {
|
|
43
|
+
const lines = this.lines;
|
|
44
|
+
const n = lines.length;
|
|
45
|
+
for (let i = 0; i < n; i++) {
|
|
46
|
+
const line = lines[i];
|
|
34
47
|
|
|
35
|
-
|
|
48
|
+
const termIndex = line.text.indexOf(term);
|
|
36
49
|
|
|
37
|
-
|
|
50
|
+
if (termIndex !== -1) {
|
|
51
|
+
return true;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
38
54
|
|
|
39
|
-
|
|
55
|
+
return false;
|
|
56
|
+
}
|
|
40
57
|
|
|
41
|
-
|
|
58
|
+
/**
|
|
59
|
+
*
|
|
60
|
+
* @returns {LineBuilder}
|
|
61
|
+
*/
|
|
62
|
+
indent() {
|
|
63
|
+
this.indentation++;
|
|
64
|
+
return this;
|
|
65
|
+
}
|
|
42
66
|
|
|
67
|
+
/**
|
|
68
|
+
*
|
|
69
|
+
* @returns {LineBuilder}
|
|
70
|
+
*/
|
|
71
|
+
dedent() {
|
|
72
|
+
this.indentation--;
|
|
73
|
+
return this;
|
|
43
74
|
}
|
|
44
75
|
|
|
45
|
-
|
|
46
|
-
|
|
76
|
+
/**
|
|
77
|
+
*
|
|
78
|
+
* @param {string} line_text
|
|
79
|
+
* @returns {LineBuilder}
|
|
80
|
+
*/
|
|
81
|
+
add(line_text) {
|
|
82
|
+
const line = new Line(line_text, this.indentation);
|
|
83
|
+
this.lines.push(line);
|
|
84
|
+
return this;
|
|
85
|
+
}
|
|
47
86
|
|
|
48
|
-
/**
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
LineBuilder.prototype.containsSubstring = function (term) {
|
|
54
|
-
const lines = this.lines;
|
|
55
|
-
const n = lines.length;
|
|
56
|
-
for (let i = 0; i < n; i++) {
|
|
57
|
-
const line = lines[i];
|
|
87
|
+
/**
|
|
88
|
+
*
|
|
89
|
+
* @param {LineBuilder} lines
|
|
90
|
+
*/
|
|
91
|
+
addLines(lines) {
|
|
58
92
|
|
|
59
|
-
const
|
|
93
|
+
const other_lines = lines.lines;
|
|
60
94
|
|
|
61
|
-
|
|
62
|
-
return true;
|
|
63
|
-
}
|
|
64
|
-
}
|
|
95
|
+
const other_line_count = other_lines.length;
|
|
65
96
|
|
|
66
|
-
|
|
67
|
-
|
|
97
|
+
for (let i = 0; i < other_line_count; i++) {
|
|
98
|
+
const otherLine = other_lines[i];
|
|
68
99
|
|
|
69
|
-
|
|
70
|
-
*
|
|
71
|
-
* @returns {LineBuilder}
|
|
72
|
-
*/
|
|
73
|
-
LineBuilder.prototype.indent = function () {
|
|
74
|
-
this.indentation++;
|
|
75
|
-
return this;
|
|
76
|
-
};
|
|
100
|
+
const line = new Line(otherLine.text, otherLine.indentation + this.indentation);
|
|
77
101
|
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
* @returns {LineBuilder}
|
|
81
|
-
*/
|
|
82
|
-
LineBuilder.prototype.dedent = function () {
|
|
83
|
-
this.indentation--;
|
|
84
|
-
return this;
|
|
85
|
-
};
|
|
102
|
+
this.lines.push(line);
|
|
103
|
+
}
|
|
86
104
|
|
|
87
|
-
|
|
88
|
-
*
|
|
89
|
-
* @param {string} l
|
|
90
|
-
* @returns {LineBuilder}
|
|
91
|
-
*/
|
|
92
|
-
LineBuilder.prototype.add = function (l) {
|
|
93
|
-
const line = new Line(l, this.indentation);
|
|
94
|
-
this.lines.push(line);
|
|
95
|
-
return this;
|
|
96
|
-
};
|
|
105
|
+
}
|
|
97
106
|
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
107
|
+
clear() {
|
|
108
|
+
this.lines = [];
|
|
109
|
+
this.indentation = 0;
|
|
110
|
+
this.indentSpaces = 4;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
*
|
|
115
|
+
* @returns {string}
|
|
116
|
+
*/
|
|
117
|
+
build() {
|
|
118
|
+
const result = [];
|
|
119
|
+
let i, j, l;
|
|
103
120
|
|
|
104
|
-
const other_lines = lines.lines;
|
|
105
121
|
|
|
106
|
-
|
|
122
|
+
const lines = this.lines;
|
|
123
|
+
for (i = 0, l = lines.length; i < l; i++) {
|
|
124
|
+
const line = lines[i];
|
|
107
125
|
|
|
108
|
-
|
|
109
|
-
|
|
126
|
+
let indentString = '';
|
|
127
|
+
for (j = 0; j < line.indentation * this.indentSpaces; j++) {
|
|
128
|
+
indentString += ' ';
|
|
129
|
+
}
|
|
110
130
|
|
|
111
|
-
|
|
131
|
+
result.push(indentString + line.text);
|
|
132
|
+
}
|
|
112
133
|
|
|
113
|
-
|
|
134
|
+
return result.join('\n');
|
|
114
135
|
}
|
|
115
136
|
|
|
116
|
-
|
|
137
|
+
/**
|
|
138
|
+
*
|
|
139
|
+
* @param {string} text
|
|
140
|
+
* @returns {LineBuilder}
|
|
141
|
+
*/
|
|
142
|
+
static fromText(text) {
|
|
143
|
+
const r = new LineBuilder();
|
|
117
144
|
|
|
118
|
-
|
|
119
|
-
this.lines = [];
|
|
120
|
-
this.indentation = 0;
|
|
121
|
-
this.indentSpaces = 4;
|
|
122
|
-
};
|
|
145
|
+
const lines = text.split('\n');
|
|
123
146
|
|
|
124
|
-
|
|
125
|
-
*
|
|
126
|
-
* @returns {string}
|
|
127
|
-
*/
|
|
128
|
-
LineBuilder.prototype.build = function () {
|
|
129
|
-
const result = [];
|
|
130
|
-
let i, j, l;
|
|
147
|
+
const n = lines.length;
|
|
131
148
|
|
|
149
|
+
for (let i = 0; i < n; i++) {
|
|
132
150
|
|
|
133
|
-
|
|
134
|
-
for (i = 0, l = lines.length; i < l; i++) {
|
|
135
|
-
const line = lines[i];
|
|
151
|
+
r.add(lines[i]);
|
|
136
152
|
|
|
137
|
-
let indentString = '';
|
|
138
|
-
for (j = 0; j < line.indentation * this.indentSpaces; j++) {
|
|
139
|
-
indentString += ' ';
|
|
140
153
|
}
|
|
141
154
|
|
|
142
|
-
|
|
155
|
+
return r;
|
|
143
156
|
}
|
|
144
|
-
|
|
145
|
-
return result.join('\n');
|
|
146
|
-
};
|
|
157
|
+
}
|
|
147
158
|
|
|
148
159
|
export default LineBuilder;
|
|
@@ -50,6 +50,38 @@ test("put 2 values with same hash", () => {
|
|
|
50
50
|
expect(m.get("b")).toBe(42);
|
|
51
51
|
});
|
|
52
52
|
|
|
53
|
+
test("overwrite a value with the same key", () => {
|
|
54
|
+
|
|
55
|
+
const map = new HashMap({
|
|
56
|
+
keyHashFunction: returnOne,
|
|
57
|
+
keyEqualityFunction: strictEquals
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
map.set("x", 3);
|
|
61
|
+
map.set("x", 7);
|
|
62
|
+
|
|
63
|
+
expect(map.get("x")).toBe(7);
|
|
64
|
+
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
test("getOrCompute", () => {
|
|
68
|
+
|
|
69
|
+
const values = [1, 3, 5];
|
|
70
|
+
|
|
71
|
+
const compute = () => values.shift();
|
|
72
|
+
|
|
73
|
+
const map = new HashMap({
|
|
74
|
+
keyHashFunction: returnOne,
|
|
75
|
+
keyEqualityFunction: strictEquals
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
expect(map.getOrCompute("x", compute)).toBe(1);
|
|
79
|
+
expect(map.getOrCompute("x", compute)).toBe(1);
|
|
80
|
+
|
|
81
|
+
expect(map.getOrCompute("y", compute)).toBe(3);
|
|
82
|
+
expect(map.getOrCompute("y", compute)).toBe(3);
|
|
83
|
+
});
|
|
84
|
+
|
|
53
85
|
test("retrieval works as intended after hash map grows", () => {
|
|
54
86
|
const m = new HashMap({
|
|
55
87
|
keyHashFunction: passThrough,
|
|
@@ -171,7 +171,9 @@ List.prototype.crop = function (startIndex, endIndex) {
|
|
|
171
171
|
};
|
|
172
172
|
|
|
173
173
|
/**
|
|
174
|
-
*
|
|
174
|
+
* Replace the data, replacements is performed surgically, meaning that diff is computed and add/remove operations are performed on the set
|
|
175
|
+
* This method is tailored to work well with visualisation as only elements that's missing from the new set is removed, and only elements that are new to are added
|
|
176
|
+
* Conversely, relevant events are dispatched that a visualisation can observe. This results in fewer changes required to the visualisation
|
|
175
177
|
* @param {T[]} newOutput
|
|
176
178
|
*/
|
|
177
179
|
List.prototype.patch = function (newOutput) {
|
|
@@ -754,7 +756,7 @@ List.prototype.toJSON = function () {
|
|
|
754
756
|
List.prototype.fromJSON = function (json, constructor) {
|
|
755
757
|
this.reset();
|
|
756
758
|
|
|
757
|
-
assert.isArray(json,'json');
|
|
759
|
+
assert.isArray(json, 'json');
|
|
758
760
|
|
|
759
761
|
if (typeof constructor === "function") {
|
|
760
762
|
this.addAll(json.map(function (elJSON) {
|
|
@@ -780,7 +782,7 @@ List.prototype.toBinaryBuffer = function (buffer) {
|
|
|
780
782
|
for (let i = 0; i < n; i++) {
|
|
781
783
|
const item = this.data[i];
|
|
782
784
|
|
|
783
|
-
if(typeof item.toBinaryBuffer !== "function"){
|
|
785
|
+
if (typeof item.toBinaryBuffer !== "function") {
|
|
784
786
|
throw new Error('item.toBinaryBuffer is not a function');
|
|
785
787
|
}
|
|
786
788
|
|
|
@@ -798,7 +800,7 @@ List.prototype.fromBinaryBuffer = function (buffer, constructor) {
|
|
|
798
800
|
|
|
799
801
|
const el = new constructor();
|
|
800
802
|
|
|
801
|
-
if(typeof el.fromBinaryBuffer !== "function"){
|
|
803
|
+
if (typeof el.fromBinaryBuffer !== "function") {
|
|
802
804
|
throw new Error('item.fromBinaryBuffer is not a function');
|
|
803
805
|
}
|
|
804
806
|
|
package/src/core/geom/Matrix4.js
CHANGED
|
@@ -4,6 +4,9 @@ const _z = new Vector3();
|
|
|
4
4
|
const _x = new Vector3();
|
|
5
5
|
const _y = new Vector3();
|
|
6
6
|
|
|
7
|
+
/**
|
|
8
|
+
* @deprecated use arrays instead or mat4 from gl-matrix
|
|
9
|
+
*/
|
|
7
10
|
export class Matrix4 {
|
|
8
11
|
/**
|
|
9
12
|
*
|
|
@@ -197,7 +200,7 @@ export class Matrix4 {
|
|
|
197
200
|
const sz = Math.hypot(this.c0, this.c1, this.c2);
|
|
198
201
|
|
|
199
202
|
// if determine is negative, we need to invert one scale
|
|
200
|
-
const
|
|
203
|
+
const det = this.determinant();
|
|
201
204
|
if (det < 0) sx = -sx;
|
|
202
205
|
|
|
203
206
|
position.set(
|