@woosh/meep-engine 2.43.21 → 2.43.23
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/collection/HashMap.d.ts +2 -2
- package/core/collection/HashMap.js +22 -2
- package/core/geom/3d/morton/mortonEncode_magicbits.js +18 -0
- package/core/geom/3d/tetrahedra/delaunay/compute_delaunay_tetrahedral_mesh.js +2 -2
- package/core/geom/3d/topology/struct/TopoEdge.js +4 -0
- package/core/geom/3d/topology/struct/TopoMesh.js +25 -0
- package/core/geom/3d/topology/struct/TopoTriangle.js +4 -0
- package/core/geom/3d/topology/struct/TopoVertex.js +8 -0
- package/core/geom/3d/topology/struct/binary/BinaryElementPool.js +288 -0
- package/core/geom/3d/topology/struct/binary/BinaryElementPool.spec.js +36 -0
- package/core/geom/3d/topology/struct/binary/BinaryTopology.js +617 -0
- package/core/geom/3d/topology/struct/binary/BinaryTopology.spec.js +16 -0
- package/core/geom/3d/topology/struct/binary/io/OrderedEdge.js +66 -0
- package/core/geom/3d/topology/struct/binary/io/bt_index_geometry_to_topology.js +188 -0
- package/core/geom/3d/topology/struct/binary/io/bt_index_geometry_to_topology.spec.js +84 -0
- package/core/geom/3d/topology/struct/binary/io/bt_mesh_calc_edges.js +51 -0
- package/core/geom/3d/topology/struct/binary/io/create_edge.js +106 -0
- package/core/geom/3d/topology/struct/binary/io/get_or_create_edge_map.js +26 -0
- package/core/geom/3d/topology/struct/binary/query/bt_mesh_edge_has_vertex.js +16 -0
- package/core/geom/3d/topology/struct/binary/query/bt_mesh_edge_has_vertex.spec.js +15 -0
- package/core/geom/3d/topology/struct/binary/query/bt_mesh_edge_other_vertex.js +21 -0
- package/core/geom/3d/topology/struct/binary/query/bt_mesh_edge_other_vertex.spec.js +16 -0
- package/core/geom/3d/topology/struct/prototypeBinaryTopology.js +55 -0
- package/core/path/PATH_SEPARATOR.js +1 -0
- package/core/path/computeFileExtension.js +24 -0
- package/core/path/computeFileExtension.spec.js +13 -0
- package/core/path/computePathBase.js +21 -0
- package/core/path/computePathBase.spec.js +13 -0
- package/core/path/computePathDirectory.js +25 -0
- package/editor/view/library/MeshLibraryView.js +1 -1
- package/engine/asset/guessAssetType.js +1 -1
- package/engine/asset/loaders/image/ImageRGBADataLoader.js +1 -1
- package/engine/asset/loaders/texture/TextureAssetLoader.js +1 -1
- package/engine/ecs/storage/BinaryBufferSerializer.js +7 -0
- package/engine/graphics/material/composeCompile.js +3 -5
- package/engine/graphics/micron/plugin/GLTFAssetTransformer.js +90 -65
- package/engine/graphics/sh3/README.md +2 -0
- package/engine/graphics/sh3/path_tracer/PathTracer.js +2 -15
- package/engine/graphics/sh3/path_tracer/getBiasedNormalSample.js +1 -1
- package/engine/graphics/sh3/path_tracer/prototypePathTracer.js +14 -9
- package/engine/graphics/texture/cubemap/load_environment_map.js +1 -1
- package/engine/graphics/util/makeMeshPreviewScene.js +38 -26
- package/engine/network/RemoteController.js +98 -0
- package/engine/network/remoteEditor.js +33 -0
- package/engine/save/storage/IndexedDBStorage.js +1 -0
- package/package.json +1 -1
- package/view/elements/MeshPreview.js +5 -1
- package/core/FilePath.js +0 -73
- package/core/FilePath.spec.js +0 -25
- package/core/geom/3d/topology/struct/BinaryTopology.js +0 -112
|
@@ -5,8 +5,8 @@ export class HashMap<K, V> implements Iterable<[V, K]> {
|
|
|
5
5
|
capacity,
|
|
6
6
|
loadFactor
|
|
7
7
|
}: {
|
|
8
|
-
keyHashFunction
|
|
9
|
-
keyEqualityFunction
|
|
8
|
+
keyHashFunction?: (k: K) => number,
|
|
9
|
+
keyEqualityFunction?: (a: K, b: K) => boolean,
|
|
10
10
|
capacity?: number,
|
|
11
11
|
loadFactor?: number
|
|
12
12
|
})
|
|
@@ -60,6 +60,8 @@ export class HashMap {
|
|
|
60
60
|
|
|
61
61
|
assert.isFunction(keyHashFunction, 'keyHashFunction');
|
|
62
62
|
assert.isFunction(keyEqualityFunction, 'keyEqualityFunction');
|
|
63
|
+
assert.isNonNegativeInteger(capacity, 'capacity');
|
|
64
|
+
assert.isNumber(loadFactor, 'loadFactor');
|
|
63
65
|
|
|
64
66
|
/**
|
|
65
67
|
*
|
|
@@ -275,8 +277,8 @@ export class HashMap {
|
|
|
275
277
|
|
|
276
278
|
/**
|
|
277
279
|
*
|
|
278
|
-
* @param {
|
|
279
|
-
* @param {function(
|
|
280
|
+
* @param {K} key
|
|
281
|
+
* @param {function(K):V} compute
|
|
280
282
|
* @param {*} [compute_context]
|
|
281
283
|
* @return {V}
|
|
282
284
|
*/
|
|
@@ -294,6 +296,24 @@ export class HashMap {
|
|
|
294
296
|
return value;
|
|
295
297
|
}
|
|
296
298
|
|
|
299
|
+
/**
|
|
300
|
+
* Returns existing value if key exists, if it doesn't - sets it and returns what was passed in
|
|
301
|
+
* @param {K} key
|
|
302
|
+
* @param {V} value this value will be written at the key location if the key wasn't found in the Map
|
|
303
|
+
* @return {V}
|
|
304
|
+
*/
|
|
305
|
+
getOrSet(key, value) {
|
|
306
|
+
const existing = this.get(key);
|
|
307
|
+
|
|
308
|
+
if (existing !== undefined) {
|
|
309
|
+
return existing;
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
this.set(key, value);
|
|
313
|
+
|
|
314
|
+
return value;
|
|
315
|
+
}
|
|
316
|
+
|
|
297
317
|
|
|
298
318
|
/**
|
|
299
319
|
*
|
|
@@ -15,6 +15,24 @@ function split_by_3(a) {
|
|
|
15
15
|
return x;
|
|
16
16
|
}
|
|
17
17
|
|
|
18
|
+
/**
|
|
19
|
+
* method to separate bits from a given integer 2 positions apart
|
|
20
|
+
*
|
|
21
|
+
* @example when input is ABC, output bits are A00B00C
|
|
22
|
+
* @see https://github.com/Forceflow/libmorton/blob/234a443ca8e2c64f6385f1a9d6ee10a70d08a3fa/include/libmorton/morton2D.h#L99
|
|
23
|
+
* @param {number} a
|
|
24
|
+
* @returns {number}
|
|
25
|
+
*/
|
|
26
|
+
export function split_by_2(a) {
|
|
27
|
+
let x = a;
|
|
28
|
+
x = (x | x << 16) & 0x0000FFFF;
|
|
29
|
+
x = (x | x << 8) & 0x00FF00FF;
|
|
30
|
+
x = (x | x << 4) & 0x0F0F0F0F;
|
|
31
|
+
x = (x | x << 2) & 0x33333333;
|
|
32
|
+
x = (x | x << 1) & 0x55555555;
|
|
33
|
+
return x;
|
|
34
|
+
}
|
|
35
|
+
|
|
18
36
|
/**
|
|
19
37
|
* Based on article and C++ source code:
|
|
20
38
|
* https://www.forceflow.be/2013/10/07/morton-encodingdecoding-through-bit-interleaving-implementations/
|
|
@@ -17,10 +17,10 @@ import { assert } from "../../../../assert.js";
|
|
|
17
17
|
* @see [1] "One machine, one minute, three billion tetrahedra" by Célestin Marot et al
|
|
18
18
|
* @param {TetrahedralMesh} mesh
|
|
19
19
|
* @param {number[]} input serialized set of 3d points (x,y,z)
|
|
20
|
-
* @param {number} n number of points in the input
|
|
20
|
+
* @param {number} [n] number of points in the input
|
|
21
21
|
* @returns {boolean}
|
|
22
22
|
*/
|
|
23
|
-
export function compute_delaunay_tetrahedral_mesh(mesh, input, n) {
|
|
23
|
+
export function compute_delaunay_tetrahedral_mesh(mesh, input, n = input.length / 3) {
|
|
24
24
|
assert.notNull(mesh, 'mesh');
|
|
25
25
|
assert.defined(mesh, 'mesh');
|
|
26
26
|
|
|
@@ -35,6 +35,31 @@ export class TopoMesh {
|
|
|
35
35
|
this.__faces = new Set();
|
|
36
36
|
}
|
|
37
37
|
|
|
38
|
+
/**
|
|
39
|
+
* Approximation of memory footprint of this object
|
|
40
|
+
* NOTE: this is highly speculative and will differ from reality depending on VM running the code as well as many other factors
|
|
41
|
+
* @return {number}
|
|
42
|
+
*/
|
|
43
|
+
get byteSize() {
|
|
44
|
+
let r = 0;
|
|
45
|
+
|
|
46
|
+
for (let i = 0; i < this.vertices.length; i++) {
|
|
47
|
+
const v = this.vertices[i];
|
|
48
|
+
|
|
49
|
+
r += v.byteSize;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
for (const edge of this.__edges) {
|
|
53
|
+
r += edge.byteSize;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
for (const face of this.__faces) {
|
|
57
|
+
r += face.byteSize;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
return r;
|
|
61
|
+
}
|
|
62
|
+
|
|
38
63
|
/**
|
|
39
64
|
*
|
|
40
65
|
* @returns {Set<TopoEdge>}
|
|
@@ -52,6 +52,14 @@ export class TopoVertex {
|
|
|
52
52
|
return this.z;
|
|
53
53
|
}
|
|
54
54
|
|
|
55
|
+
/**
|
|
56
|
+
* Estimate of this object's size in RAM, in bytes
|
|
57
|
+
* @return {number}
|
|
58
|
+
*/
|
|
59
|
+
get byteSize() {
|
|
60
|
+
return 80 + 6 * 4 + 8 + this.edges.length * 8 + 10 + this.faces.length * 8 + 10;
|
|
61
|
+
}
|
|
62
|
+
|
|
55
63
|
/**
|
|
56
64
|
*
|
|
57
65
|
* @param {TopoVertex} other
|
|
@@ -0,0 +1,288 @@
|
|
|
1
|
+
import { max3 } from "../../../../../math/max3.js";
|
|
2
|
+
import { assert } from "../../../../../assert.js";
|
|
3
|
+
import { typed_array_copy } from "../../../../../collection/array/typed/typed_array_copy.js";
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* How many items to reserve by default
|
|
7
|
+
* @readonly
|
|
8
|
+
* @type {number}
|
|
9
|
+
*/
|
|
10
|
+
const INITIAL_CAPACITY = 128;
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* @readonly
|
|
14
|
+
* @type {number}
|
|
15
|
+
*/
|
|
16
|
+
const CAPACITY_GROW_MULTIPLIER = 1.2;
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* @readonly
|
|
20
|
+
* @type {number}
|
|
21
|
+
*/
|
|
22
|
+
const CAPACITY_GROW_MIN_STEP = 32;
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Align on 4 byte boundary
|
|
26
|
+
* @param {number} n
|
|
27
|
+
* @return {number}
|
|
28
|
+
*/
|
|
29
|
+
function align_4(n) {
|
|
30
|
+
const result = ((n + 0x3) >> 2) << 2;
|
|
31
|
+
|
|
32
|
+
assert.greaterThanOrEqual(result, n, 'aligned result must be >= input');
|
|
33
|
+
|
|
34
|
+
return result;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* @see https://github.com/blender/blender/blob/master/source/blender/blenlib/intern/BLI_mempool.c
|
|
39
|
+
*/
|
|
40
|
+
export class BinaryElementPool {
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
*
|
|
44
|
+
* @param {number} item_size in bytes
|
|
45
|
+
* @param {number} initial_capacity how many items to reverse in the newly created pool
|
|
46
|
+
*/
|
|
47
|
+
constructor(item_size, initial_capacity = INITIAL_CAPACITY) {
|
|
48
|
+
assert.isNonNegativeInteger(item_size, 'item_size');
|
|
49
|
+
assert.greaterThan(item_size, 0, 'item_size must be greater than 0');
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Size of a single pool item in bytes
|
|
53
|
+
* @type {number}
|
|
54
|
+
* @private
|
|
55
|
+
*/
|
|
56
|
+
this.__item_size = item_size;
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Unused slots
|
|
60
|
+
* @type {number[]}
|
|
61
|
+
* @private
|
|
62
|
+
*/
|
|
63
|
+
this.__free = [];
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Tracks last unallocated item in the list,
|
|
67
|
+
* this separate cursor is necessary to prevent re-allocation of the 'free' array
|
|
68
|
+
* @type {number}
|
|
69
|
+
* @private
|
|
70
|
+
*/
|
|
71
|
+
this.__free_pointer = 0;
|
|
72
|
+
|
|
73
|
+
this.__data_buffer = new ArrayBuffer(align_4(initial_capacity * item_size));
|
|
74
|
+
this.__data_uint8 = new Uint8Array(this.__data_buffer);
|
|
75
|
+
this.__data_uint32 = new Uint32Array(this.__data_buffer);
|
|
76
|
+
this.__data_float32 = new Float32Array(this.__data_buffer);
|
|
77
|
+
this.data_view = new DataView(this.__data_buffer);
|
|
78
|
+
|
|
79
|
+
this.__capacity = initial_capacity;
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
*
|
|
83
|
+
* @type {number}
|
|
84
|
+
* @private
|
|
85
|
+
*/
|
|
86
|
+
this.__size = 0;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* Returns size of used region, this includes both elements that are allocated and those that aren't
|
|
91
|
+
* Please note that this value does not represent number of currently active elements, if you need that - you'll need to use something else
|
|
92
|
+
* @return {number}
|
|
93
|
+
*/
|
|
94
|
+
get size() {
|
|
95
|
+
return this.__size;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
*
|
|
100
|
+
* @return {number}
|
|
101
|
+
*/
|
|
102
|
+
get byteSize() {
|
|
103
|
+
return this.__capacity * this.__item_size;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
*
|
|
108
|
+
* @return {Uint32Array}
|
|
109
|
+
*/
|
|
110
|
+
get data_uint32() {
|
|
111
|
+
return this.__data_uint32;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
*
|
|
116
|
+
* @return {Float32Array}
|
|
117
|
+
*/
|
|
118
|
+
get data_float32() {
|
|
119
|
+
return this.__data_float32;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
/**
|
|
123
|
+
* Get rid of excess capacity
|
|
124
|
+
*/
|
|
125
|
+
trim() {
|
|
126
|
+
this.__set_capacity(this.__size);
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
/**
|
|
130
|
+
*
|
|
131
|
+
* @param {number} id
|
|
132
|
+
* @return {number}
|
|
133
|
+
*/
|
|
134
|
+
element_address(id) {
|
|
135
|
+
assert.isNonNegativeInteger(id, 'id');
|
|
136
|
+
|
|
137
|
+
return this.__item_size * id;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
/**
|
|
141
|
+
* Used alongside iterators to check if element is actually allocated or not
|
|
142
|
+
* @param {number} id
|
|
143
|
+
* @return {boolean}
|
|
144
|
+
*/
|
|
145
|
+
is_allocated(id) {
|
|
146
|
+
if (id >= this.__size) {
|
|
147
|
+
// ID is past allocated region
|
|
148
|
+
return false;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
const pointer = this.__free_pointer;
|
|
152
|
+
|
|
153
|
+
for (let i = 0; i < pointer; i++) {
|
|
154
|
+
const _id = this.__free[i];
|
|
155
|
+
|
|
156
|
+
if (id === _id) {
|
|
157
|
+
// found in unallocated set
|
|
158
|
+
return false;
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
return true;
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
/**
|
|
166
|
+
*
|
|
167
|
+
* @param {number} new_capacity
|
|
168
|
+
* @private
|
|
169
|
+
*/
|
|
170
|
+
__set_capacity(new_capacity) {
|
|
171
|
+
if (this.__capacity === new_capacity) {
|
|
172
|
+
// no point
|
|
173
|
+
return;
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
const old_data_uint8 = this.__data_uint8;
|
|
177
|
+
|
|
178
|
+
const aligned_byte_size = align_4(new_capacity * this.__item_size);
|
|
179
|
+
|
|
180
|
+
const new_data_buffer = new ArrayBuffer(aligned_byte_size);
|
|
181
|
+
|
|
182
|
+
this.__data_buffer = new_data_buffer;
|
|
183
|
+
this.__data_uint8 = new Uint8Array(new_data_buffer);
|
|
184
|
+
this.__data_uint32 = new Uint32Array(this.__data_buffer);
|
|
185
|
+
this.__data_float32 = new Float32Array(this.__data_buffer);
|
|
186
|
+
this.data_view = new DataView(new_data_buffer);
|
|
187
|
+
|
|
188
|
+
// copy old data
|
|
189
|
+
typed_array_copy(old_data_uint8, this.__data_uint8);
|
|
190
|
+
|
|
191
|
+
this.__capacity = new_capacity;
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
/**
|
|
195
|
+
*
|
|
196
|
+
* @param {number} min_capacity
|
|
197
|
+
* @private
|
|
198
|
+
*/
|
|
199
|
+
__grow_capacity(min_capacity) {
|
|
200
|
+
const new_capacity = Math.ceil(max3(
|
|
201
|
+
min_capacity,
|
|
202
|
+
this.__capacity * CAPACITY_GROW_MULTIPLIER,
|
|
203
|
+
this.__capacity + CAPACITY_GROW_MIN_STEP
|
|
204
|
+
));
|
|
205
|
+
|
|
206
|
+
this.__set_capacity(new_capacity);
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
/**
|
|
210
|
+
*
|
|
211
|
+
* @param {number} capacity
|
|
212
|
+
*/
|
|
213
|
+
ensure_capacity(capacity) {
|
|
214
|
+
if (this.__capacity < capacity) {
|
|
215
|
+
this.__grow_capacity(capacity);
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
|
|
220
|
+
/**
|
|
221
|
+
*
|
|
222
|
+
* @return {number} ID of the allocated element
|
|
223
|
+
*/
|
|
224
|
+
allocate() {
|
|
225
|
+
if (this.__free_pointer > 0) {
|
|
226
|
+
// get unused slot
|
|
227
|
+
this.__free_pointer--;
|
|
228
|
+
return this.__free[this.__free_pointer];
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
// allocate new
|
|
232
|
+
let result = this.__size;
|
|
233
|
+
this.__size++;
|
|
234
|
+
|
|
235
|
+
if (this.__size >= this.__capacity) {
|
|
236
|
+
// grow if necessary
|
|
237
|
+
this.__grow_capacity(this.__size);
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
// assert.greaterThan(this.__data_buffer.byteLength, result * this.__item_size, 'memory underflow');
|
|
241
|
+
|
|
242
|
+
return result;
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
/**
|
|
246
|
+
* Allocate a continuous range of IDs in bulk
|
|
247
|
+
* @param {number} count
|
|
248
|
+
* @return {number} offset where the range starts, this is your first ID basically
|
|
249
|
+
*/
|
|
250
|
+
allocate_continuous(count) {
|
|
251
|
+
const offset = this.__size;
|
|
252
|
+
|
|
253
|
+
this.__size += count;
|
|
254
|
+
|
|
255
|
+
if (this.__size >= this.__capacity) {
|
|
256
|
+
this.__grow_capacity(this.__size);
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
// assert.greaterThanOrEqual(this.__data_buffer.byteLength, (offset + count) * this.__item_size, 'memory underflow');
|
|
260
|
+
|
|
261
|
+
return offset;
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
/**
|
|
265
|
+
* Please note that this method does not perform any checks at all.
|
|
266
|
+
* You have to make sure that the item is actually unneeded and no duplicate calls are made
|
|
267
|
+
* @param {number} id
|
|
268
|
+
*/
|
|
269
|
+
release(id) {
|
|
270
|
+
if (id === this.__size - 1) {
|
|
271
|
+
// releasing item at the end of the reserved region, don't have to push it into free set
|
|
272
|
+
this.__size--;
|
|
273
|
+
} else if (id >= this.__size) {
|
|
274
|
+
// do nothing, just throw it away
|
|
275
|
+
// this should never happen
|
|
276
|
+
} else {
|
|
277
|
+
this.__free[this.__free_pointer++] = id;
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
/**
|
|
282
|
+
* Removed all data from the pool
|
|
283
|
+
*/
|
|
284
|
+
clear() {
|
|
285
|
+
this.__size = 0;
|
|
286
|
+
this.__free_pointer = 0;
|
|
287
|
+
}
|
|
288
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { BinaryElementPool } from "./BinaryElementPool.js";
|
|
2
|
+
|
|
3
|
+
test('Constructor does not throw', () => {
|
|
4
|
+
new BinaryElementPool(1);
|
|
5
|
+
});
|
|
6
|
+
|
|
7
|
+
test('Allocation returns a valid non-negative ID', () => {
|
|
8
|
+
const pool = new BinaryElementPool(1);
|
|
9
|
+
|
|
10
|
+
const id = pool.allocate();
|
|
11
|
+
|
|
12
|
+
expect(id).toBeGreaterThanOrEqual(0);
|
|
13
|
+
expect(Number.isInteger(id)).toBe(true);
|
|
14
|
+
expect(Number.isFinite(id)).toBe(true);
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
test('Consecutive allocations return different IDs', () => {
|
|
18
|
+
const pool = new BinaryElementPool(1);
|
|
19
|
+
|
|
20
|
+
const a = pool.allocate();
|
|
21
|
+
const b = pool.allocate();
|
|
22
|
+
|
|
23
|
+
expect(a).not.toEqual(b);
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
test('Allocate, release, allocate produces the same ID',()=>{
|
|
27
|
+
const pool = new BinaryElementPool(1);
|
|
28
|
+
|
|
29
|
+
const a = pool.allocate();
|
|
30
|
+
|
|
31
|
+
pool.release(a);
|
|
32
|
+
|
|
33
|
+
const b = pool.allocate();
|
|
34
|
+
|
|
35
|
+
expect(a).toEqual(b);
|
|
36
|
+
});
|