@woosh/meep-engine 2.47.14 → 2.47.16
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/build/meep.cjs +66 -54
- package/build/meep.min.js +1 -1
- package/build/meep.module.js +66 -54
- package/package.json +1 -1
- package/src/core/IdPool.js +66 -54
- package/src/core/json/abstractJSONSerializer.js +24 -24
- package/src/core/model/node-graph/NodeGraph.js +23 -6
- package/src/core/model/node-graph/node/NodeInstance.d.ts +4 -0
package/build/meep.module.js
CHANGED
|
@@ -117641,78 +117641,90 @@ class MaxRectanglesPacker {
|
|
|
117641
117641
|
*/
|
|
117642
117642
|
|
|
117643
117643
|
/**
|
|
117644
|
-
*
|
|
117645
|
-
*
|
|
117644
|
+
* Pool of unsigned integer IDs, useful when you don't want to just keep incrementing ID counter and want to re-use IDs after they are no longer needed
|
|
117645
|
+
* Main use case is when your IDs are array indices, having compact IDs lets you use fixed size array even as objects are added and removed as you're able to reuse slots in an efficient manner
|
|
117646
117646
|
*/
|
|
117647
|
-
|
|
117647
|
+
class IdPool {
|
|
117648
117648
|
/**
|
|
117649
117649
|
* @private
|
|
117650
117650
|
* @type {BitSet}
|
|
117651
117651
|
*/
|
|
117652
|
-
|
|
117653
|
-
}
|
|
117652
|
+
#set = new BitSet();
|
|
117654
117653
|
|
|
117655
|
-
/**
|
|
117656
|
-
|
|
117657
|
-
|
|
117658
|
-
|
|
117659
|
-
|
|
117660
|
-
|
|
117654
|
+
/**
|
|
117655
|
+
* Looks up next available ID without reserving it
|
|
117656
|
+
* If you want to also reserve the ID - use {@link get} instead
|
|
117657
|
+
* @returns {number}
|
|
117658
|
+
*/
|
|
117659
|
+
peek() {
|
|
117660
|
+
return this.#set.nextClearBit(0);
|
|
117661
|
+
}
|
|
117661
117662
|
|
|
117662
|
-
|
|
117663
|
+
/**
|
|
117664
|
+
*
|
|
117665
|
+
* @returns {number}
|
|
117666
|
+
*/
|
|
117667
|
+
get() {
|
|
117668
|
+
const id = this.peek();
|
|
117663
117669
|
|
|
117664
|
-
|
|
117665
|
-
};
|
|
117670
|
+
this.#set.set(id, true);
|
|
117666
117671
|
|
|
117667
|
-
|
|
117668
|
-
* Attempt to request a specific ID from the pool.
|
|
117669
|
-
* @param {number} id
|
|
117670
|
-
* @return {boolean} true if request succeeds, false otherwise
|
|
117671
|
-
*/
|
|
117672
|
-
IdPool.prototype.getSpecific = function (id) {
|
|
117673
|
-
if (this.isUsed(id)) {
|
|
117674
|
-
return false;
|
|
117672
|
+
return id;
|
|
117675
117673
|
}
|
|
117676
117674
|
|
|
117677
|
-
|
|
117678
|
-
|
|
117679
|
-
}
|
|
117675
|
+
/**
|
|
117676
|
+
* Attempt to request a specific ID from the pool.
|
|
117677
|
+
* @param {number} id
|
|
117678
|
+
* @return {boolean} true if request succeeds, false otherwise
|
|
117679
|
+
*/
|
|
117680
|
+
getSpecific(id) {
|
|
117681
|
+
if (this.isUsed(id)) {
|
|
117682
|
+
return false;
|
|
117683
|
+
}
|
|
117680
117684
|
|
|
117681
|
-
|
|
117682
|
-
|
|
117683
|
-
|
|
117684
|
-
* @returns {boolean}
|
|
117685
|
-
*/
|
|
117686
|
-
IdPool.prototype.isUsed = function (id) {
|
|
117687
|
-
return this.bitSet.get(id);
|
|
117688
|
-
};
|
|
117685
|
+
this.#set.set(id, true);
|
|
117686
|
+
return true;
|
|
117687
|
+
}
|
|
117689
117688
|
|
|
117690
|
-
/**
|
|
117691
|
-
|
|
117692
|
-
|
|
117693
|
-
|
|
117694
|
-
|
|
117695
|
-
|
|
117689
|
+
/**
|
|
117690
|
+
*
|
|
117691
|
+
* @param {number} id
|
|
117692
|
+
* @returns {boolean}
|
|
117693
|
+
*/
|
|
117694
|
+
isUsed(id) {
|
|
117695
|
+
return this.#set.get(id);
|
|
117696
|
+
}
|
|
117696
117697
|
|
|
117697
|
-
|
|
117698
|
+
/**
|
|
117699
|
+
* Traverse all IDs currently in use
|
|
117700
|
+
* @param {function(id:number)} visitor
|
|
117701
|
+
*/
|
|
117702
|
+
traverseUsed(visitor) {
|
|
117703
|
+
assert.isFunction(visitor, "visitor");
|
|
117698
117704
|
|
|
117699
|
-
|
|
117700
|
-
visitor(i);
|
|
117701
|
-
}
|
|
117705
|
+
const set = this.#set;
|
|
117702
117706
|
|
|
117703
|
-
|
|
117707
|
+
for (let i = set.nextSetBit(0); i !== -1; i = set.nextSetBit(i + 1)) {
|
|
117708
|
+
visitor(i);
|
|
117709
|
+
}
|
|
117704
117710
|
|
|
117705
|
-
|
|
117706
|
-
*
|
|
117707
|
-
* @param {number} id
|
|
117708
|
-
*/
|
|
117709
|
-
IdPool.prototype.release = function (id) {
|
|
117710
|
-
this.bitSet.clear(id);
|
|
117711
|
-
};
|
|
117711
|
+
}
|
|
117712
117712
|
|
|
117713
|
-
|
|
117714
|
-
|
|
117715
|
-
}
|
|
117713
|
+
/**
|
|
117714
|
+
*
|
|
117715
|
+
* @param {number} id
|
|
117716
|
+
*/
|
|
117717
|
+
release(id) {
|
|
117718
|
+
this.#set.clear(id);
|
|
117719
|
+
}
|
|
117720
|
+
|
|
117721
|
+
/**
|
|
117722
|
+
* Release all used IDs
|
|
117723
|
+
*/
|
|
117724
|
+
reset() {
|
|
117725
|
+
this.#set.reset();
|
|
117726
|
+
}
|
|
117727
|
+
}
|
|
117716
117728
|
|
|
117717
117729
|
class AtlasPatch {
|
|
117718
117730
|
constructor() {
|
package/package.json
CHANGED
package/src/core/IdPool.js
CHANGED
|
@@ -7,77 +7,89 @@ import { assert } from "./assert.js";
|
|
|
7
7
|
import { BitSet } from "./binary/BitSet.js";
|
|
8
8
|
|
|
9
9
|
/**
|
|
10
|
-
*
|
|
11
|
-
*
|
|
10
|
+
* Pool of unsigned integer IDs, useful when you don't want to just keep incrementing ID counter and want to re-use IDs after they are no longer needed
|
|
11
|
+
* Main use case is when your IDs are array indices, having compact IDs lets you use fixed size array even as objects are added and removed as you're able to reuse slots in an efficient manner
|
|
12
12
|
*/
|
|
13
|
-
|
|
13
|
+
class IdPool {
|
|
14
14
|
/**
|
|
15
15
|
* @private
|
|
16
16
|
* @type {BitSet}
|
|
17
17
|
*/
|
|
18
|
-
|
|
19
|
-
}
|
|
18
|
+
#set = new BitSet();
|
|
20
19
|
|
|
21
|
-
/**
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
20
|
+
/**
|
|
21
|
+
* Looks up next available ID without reserving it
|
|
22
|
+
* If you want to also reserve the ID - use {@link get} instead
|
|
23
|
+
* @returns {number}
|
|
24
|
+
*/
|
|
25
|
+
peek() {
|
|
26
|
+
return this.#set.nextClearBit(0);
|
|
27
|
+
}
|
|
27
28
|
|
|
28
|
-
|
|
29
|
+
/**
|
|
30
|
+
*
|
|
31
|
+
* @returns {number}
|
|
32
|
+
*/
|
|
33
|
+
get() {
|
|
34
|
+
const id = this.peek();
|
|
29
35
|
|
|
30
|
-
|
|
31
|
-
};
|
|
36
|
+
this.#set.set(id, true);
|
|
32
37
|
|
|
33
|
-
|
|
34
|
-
* Attempt to request a specific ID from the pool.
|
|
35
|
-
* @param {number} id
|
|
36
|
-
* @return {boolean} true if request succeeds, false otherwise
|
|
37
|
-
*/
|
|
38
|
-
IdPool.prototype.getSpecific = function (id) {
|
|
39
|
-
if (this.isUsed(id)) {
|
|
40
|
-
return false;
|
|
38
|
+
return id;
|
|
41
39
|
}
|
|
42
40
|
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
}
|
|
41
|
+
/**
|
|
42
|
+
* Attempt to request a specific ID from the pool.
|
|
43
|
+
* @param {number} id
|
|
44
|
+
* @return {boolean} true if request succeeds, false otherwise
|
|
45
|
+
*/
|
|
46
|
+
getSpecific(id) {
|
|
47
|
+
if (this.isUsed(id)) {
|
|
48
|
+
return false;
|
|
49
|
+
}
|
|
46
50
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
* @returns {boolean}
|
|
51
|
-
*/
|
|
52
|
-
IdPool.prototype.isUsed = function (id) {
|
|
53
|
-
return this.bitSet.get(id);
|
|
54
|
-
};
|
|
51
|
+
this.#set.set(id, true);
|
|
52
|
+
return true;
|
|
53
|
+
}
|
|
55
54
|
|
|
56
|
-
/**
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
55
|
+
/**
|
|
56
|
+
*
|
|
57
|
+
* @param {number} id
|
|
58
|
+
* @returns {boolean}
|
|
59
|
+
*/
|
|
60
|
+
isUsed(id) {
|
|
61
|
+
return this.#set.get(id);
|
|
62
|
+
}
|
|
62
63
|
|
|
63
|
-
|
|
64
|
+
/**
|
|
65
|
+
* Traverse all IDs currently in use
|
|
66
|
+
* @param {function(id:number)} visitor
|
|
67
|
+
*/
|
|
68
|
+
traverseUsed(visitor) {
|
|
69
|
+
assert.isFunction(visitor, "visitor");
|
|
64
70
|
|
|
65
|
-
|
|
66
|
-
visitor(i);
|
|
67
|
-
}
|
|
71
|
+
const set = this.#set;
|
|
68
72
|
|
|
69
|
-
|
|
73
|
+
for (let i = set.nextSetBit(0); i !== -1; i = set.nextSetBit(i + 1)) {
|
|
74
|
+
visitor(i);
|
|
75
|
+
}
|
|
70
76
|
|
|
71
|
-
|
|
72
|
-
*
|
|
73
|
-
* @param {number} id
|
|
74
|
-
*/
|
|
75
|
-
IdPool.prototype.release = function (id) {
|
|
76
|
-
this.bitSet.clear(id);
|
|
77
|
-
};
|
|
77
|
+
}
|
|
78
78
|
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
}
|
|
79
|
+
/**
|
|
80
|
+
*
|
|
81
|
+
* @param {number} id
|
|
82
|
+
*/
|
|
83
|
+
release(id) {
|
|
84
|
+
this.#set.clear(id);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* Release all used IDs
|
|
89
|
+
*/
|
|
90
|
+
reset() {
|
|
91
|
+
this.#set.reset();
|
|
92
|
+
}
|
|
93
|
+
}
|
|
82
94
|
|
|
83
95
|
export default IdPool;
|
|
@@ -12,37 +12,37 @@ export function abstractJSONSerializer(source, serializers, classNames) {
|
|
|
12
12
|
return source;
|
|
13
13
|
}
|
|
14
14
|
|
|
15
|
-
|
|
15
|
+
// parameter is an object
|
|
16
16
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
17
|
+
// extract type name
|
|
18
|
+
const Klass = source.constructor;
|
|
19
|
+
let typeName = classNames.get(Klass);
|
|
20
20
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
21
|
+
if (typeName === undefined) {
|
|
22
|
+
// try fallback to "typeName" field on constructor
|
|
23
|
+
typeName = Klass.typeName;
|
|
24
|
+
}
|
|
25
25
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
26
|
+
if (typeName === undefined) {
|
|
27
|
+
throw new Error(`Failed to resolve type name. No name found in classNames registry and no .typeName field on the constructor {name: '${Klass.name}}'`);
|
|
28
|
+
}
|
|
29
29
|
|
|
30
|
-
|
|
31
|
-
|
|
30
|
+
let serializer = serializers.get(typeName);
|
|
31
|
+
let serializerContext = undefined;
|
|
32
32
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
33
|
+
if (serializer === undefined) {
|
|
34
|
+
serializer = source.toJSON;
|
|
35
|
+
serializerContext = source;
|
|
36
|
+
}
|
|
37
37
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
38
|
+
if (serializer === undefined) {
|
|
39
|
+
throw new Error(`Failed to resolve serializer for object type '${typeName}'. No serializer found in serializers registry and no .toJSON method on object itself`);
|
|
40
|
+
}
|
|
41
41
|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
42
|
+
return {
|
|
43
|
+
type: typeName,
|
|
44
|
+
data: serializer.call(serializerContext, source)
|
|
45
|
+
};
|
|
46
46
|
|
|
47
47
|
|
|
48
48
|
}
|
|
@@ -127,6 +127,7 @@ export class NodeGraph {
|
|
|
127
127
|
* Merge foreign nodes and associated connections into this graph
|
|
128
128
|
* New node instances and connections will be created to reflect these inside this graph
|
|
129
129
|
* NOTE: parameters on merged nodes are shallow copies
|
|
130
|
+
* NOTE: if IDs are available - copied nodes will have the same IDs as the originals
|
|
130
131
|
* @param {NodeInstance[]} nodes
|
|
131
132
|
* @param {Connection[]} [connections]
|
|
132
133
|
* @returns {{connections:Connection[], nodes:NodeInstance[]}} local created instances
|
|
@@ -147,12 +148,28 @@ export class NodeGraph {
|
|
|
147
148
|
for (let i = 0; i < additional_node_count; i++) {
|
|
148
149
|
const other_node = nodes[i];
|
|
149
150
|
|
|
150
|
-
const
|
|
151
|
-
this_nodes[other_node.id] = this_node_id;
|
|
151
|
+
const other_node_id = other_node.id;
|
|
152
152
|
|
|
153
|
-
|
|
154
|
-
|
|
153
|
+
const this_node = new NodeInstance();
|
|
154
|
+
this_node.setDescription(other_node.description);
|
|
155
|
+
|
|
156
|
+
|
|
157
|
+
// attempt to gain the same ID
|
|
158
|
+
const can_use_same_id = this.__idpNodes.isUsed(other_node_id);
|
|
159
|
+
|
|
160
|
+
let this_node_id;
|
|
161
|
+
if (can_use_same_id) {
|
|
162
|
+
this_node_id = other_node_id;
|
|
163
|
+
} else {
|
|
164
|
+
this_node_id = this.__idpNodes.peek();
|
|
165
|
+
}
|
|
155
166
|
|
|
167
|
+
this.addNode(this_node);
|
|
168
|
+
|
|
169
|
+
|
|
170
|
+
this_nodes[other_node_id] = this_node_id;
|
|
171
|
+
|
|
172
|
+
// copy parameters
|
|
156
173
|
this_node.setParameters(other_node.parameters);
|
|
157
174
|
|
|
158
175
|
}
|
|
@@ -376,13 +393,13 @@ export class NodeGraph {
|
|
|
376
393
|
createNode(node) {
|
|
377
394
|
const nodeInstance = new NodeInstance();
|
|
378
395
|
|
|
379
|
-
const id = this.__idpNodes.
|
|
396
|
+
const id = this.__idpNodes.peek();
|
|
380
397
|
|
|
381
398
|
nodeInstance.id = id;
|
|
382
399
|
nodeInstance.setDescription(node);
|
|
383
400
|
|
|
384
401
|
//record the node
|
|
385
|
-
this.
|
|
402
|
+
this.addNode(nodeInstance);
|
|
386
403
|
|
|
387
404
|
return id;
|
|
388
405
|
}
|