@vworlds/vecs 1.0.10 → 1.0.11
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/README.md +218 -229
- package/dist/command.d.ts +1 -46
- package/dist/component.d.ts +51 -59
- package/dist/component.js +31 -25
- package/dist/component.js.map +1 -1
- package/dist/dsl.d.ts +34 -26
- package/dist/dsl.js +46 -20
- package/dist/dsl.js.map +1 -1
- package/dist/entity.d.ts +96 -106
- package/dist/entity.js +261 -190
- package/dist/entity.js.map +1 -1
- package/dist/filter.d.ts +31 -23
- package/dist/filter.js +24 -17
- package/dist/filter.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/package.json +3 -1
- package/dist/phase.d.ts +5 -28
- package/dist/phase.js +11 -10
- package/dist/phase.js.map +1 -1
- package/dist/query.d.ts +107 -144
- package/dist/query.js +200 -169
- package/dist/query.js.map +1 -1
- package/dist/system.d.ts +59 -87
- package/dist/system.js +114 -114
- package/dist/system.js.map +1 -1
- package/dist/util/array_map.d.ts +4 -55
- package/dist/util/array_map.js +35 -37
- package/dist/util/array_map.js.map +1 -1
- package/dist/util/bitset.d.ts +40 -50
- package/dist/util/bitset.js +76 -62
- package/dist/util/bitset.js.map +1 -1
- package/dist/util/events.d.ts +14 -18
- package/dist/util/events.js +24 -3
- package/dist/util/events.js.map +1 -1
- package/dist/util/ordered_set.d.ts +1 -17
- package/dist/util/ordered_set.js +74 -25
- package/dist/util/ordered_set.js.map +1 -1
- package/dist/world.d.ts +212 -224
- package/dist/world.js +368 -330
- package/dist/world.js.map +1 -1
- package/eslint-rules/internal-underscore.js +60 -0
- package/eslint.config.js +5 -0
- package/package.json +3 -1
package/dist/util/array_map.d.ts
CHANGED
|
@@ -1,58 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* Read-only view of an {@link ArrayMap}: the mutating methods `set`, `delete`,
|
|
3
|
+
* and `clear` are omitted.
|
|
3
4
|
*
|
|
4
|
-
*
|
|
5
|
-
* `Map` because array index access avoids the hash-table overhead. Used
|
|
6
|
-
* internally to store per-entity component instances and per-type component
|
|
7
|
-
* metadata.
|
|
8
|
-
*
|
|
9
|
-
* Keys must be non-negative integers. Gaps in the key space are represented
|
|
10
|
-
* as `undefined` slots and do not count toward `size`.
|
|
11
|
-
*
|
|
12
|
-
* @typeParam T - The value type stored in the map.
|
|
5
|
+
* @typeParam T - Value type stored in the map.
|
|
13
6
|
*/
|
|
14
|
-
export
|
|
15
|
-
private backend;
|
|
16
|
-
private _size;
|
|
17
|
-
constructor();
|
|
18
|
-
/**
|
|
19
|
-
* Store `value` at `key`, replacing any existing value.
|
|
20
|
-
*
|
|
21
|
-
* @param key - Non-negative integer key.
|
|
22
|
-
* @param value - Value to store.
|
|
23
|
-
*/
|
|
24
|
-
set(key: number, value: T): void;
|
|
25
|
-
/**
|
|
26
|
-
* Return the value stored at `key`, or `undefined` if not present.
|
|
27
|
-
*
|
|
28
|
-
* @param key - Non-negative integer key.
|
|
29
|
-
*/
|
|
30
|
-
get(key: number): T | undefined;
|
|
31
|
-
/**
|
|
32
|
-
* Remove the entry at `key`. Does nothing if `key` is not present.
|
|
33
|
-
*
|
|
34
|
-
* @param key - Non-negative integer key.
|
|
35
|
-
*/
|
|
36
|
-
delete(key: number): void;
|
|
37
|
-
/**
|
|
38
|
-
* Return `true` if an entry exists at `key`.
|
|
39
|
-
*
|
|
40
|
-
* @param key - Non-negative integer key.
|
|
41
|
-
*/
|
|
42
|
-
has(key: number): boolean;
|
|
43
|
-
/**
|
|
44
|
-
* Iterate over all present entries.
|
|
45
|
-
*
|
|
46
|
-
* Undefined slots are skipped; the callback is only called for keys that
|
|
47
|
-
* have an associated value.
|
|
48
|
-
*
|
|
49
|
-
* @param callback - Called with `(value, key, map)` for each entry.
|
|
50
|
-
*/
|
|
51
|
-
forEach(callback: (value: T, key: number, map: ArrayMap<T>) => void): void;
|
|
52
|
-
/**
|
|
53
|
-
* Remove all entries and reset the size to zero.
|
|
54
|
-
*/
|
|
55
|
-
clear(): void;
|
|
56
|
-
/** The number of entries currently in the map. */
|
|
57
|
-
get size(): number;
|
|
58
|
-
}
|
|
7
|
+
export type ReadonlyArrayMap<T> = Omit<ArrayMap<T>, "set" | "delete" | "clear">;
|
package/dist/util/array_map.js
CHANGED
|
@@ -1,84 +1,82 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* A `Map<number, T>` backed by a sparse JavaScript array.
|
|
2
|
+
* A `Map<number, T>` substitute backed by a sparse JavaScript array.
|
|
3
3
|
*
|
|
4
|
-
* For small, dense integer key spaces
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
* metadata.
|
|
4
|
+
* For small, dense, non-negative integer key spaces, indexing into a regular
|
|
5
|
+
* array is faster than the hash-table lookups performed by the built-in
|
|
6
|
+
* `Map`. `ArrayMap` is used inside the ECS to store per-entity component
|
|
7
|
+
* instances and per-type metadata.
|
|
8
8
|
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
9
|
+
* Empty slots are represented as `undefined` and do not count toward
|
|
10
|
+
* {@link size}.
|
|
11
11
|
*
|
|
12
|
-
* @
|
|
12
|
+
* @internal Used only inside the package.
|
|
13
|
+
*
|
|
14
|
+
* @typeParam T - Value type stored in the map.
|
|
13
15
|
*/
|
|
14
16
|
export class ArrayMap {
|
|
15
17
|
constructor() {
|
|
16
|
-
this.
|
|
18
|
+
this._backend = [];
|
|
17
19
|
this._size = 0;
|
|
18
20
|
}
|
|
21
|
+
/** The number of entries currently in the map. */
|
|
22
|
+
get size() {
|
|
23
|
+
return this._size;
|
|
24
|
+
}
|
|
19
25
|
/**
|
|
20
|
-
*
|
|
26
|
+
* Insert or replace the value at `key`.
|
|
21
27
|
*
|
|
22
28
|
* @param key - Non-negative integer key.
|
|
23
29
|
* @param value - Value to store.
|
|
24
30
|
*/
|
|
25
31
|
set(key, value) {
|
|
26
|
-
if (this.
|
|
32
|
+
if (this._backend[key] === undefined) {
|
|
27
33
|
this._size++;
|
|
28
34
|
}
|
|
29
|
-
this.
|
|
35
|
+
this._backend[key] = value;
|
|
30
36
|
}
|
|
31
37
|
/**
|
|
32
|
-
*
|
|
38
|
+
* Retrieve the value stored at `key`, or `undefined` if no entry exists.
|
|
33
39
|
*
|
|
34
40
|
* @param key - Non-negative integer key.
|
|
35
41
|
*/
|
|
36
42
|
get(key) {
|
|
37
|
-
return this.
|
|
43
|
+
return this._backend[key];
|
|
38
44
|
}
|
|
39
45
|
/**
|
|
40
|
-
*
|
|
46
|
+
* Return `true` when an entry exists at `key`.
|
|
41
47
|
*
|
|
42
48
|
* @param key - Non-negative integer key.
|
|
43
49
|
*/
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
this.backend[key] = undefined;
|
|
47
|
-
this._size--;
|
|
48
|
-
}
|
|
50
|
+
has(key) {
|
|
51
|
+
return this._backend[key] !== undefined;
|
|
49
52
|
}
|
|
50
53
|
/**
|
|
51
|
-
*
|
|
54
|
+
* Remove the entry at `key`. Does nothing if no entry exists there.
|
|
52
55
|
*
|
|
53
56
|
* @param key - Non-negative integer key.
|
|
54
57
|
*/
|
|
55
|
-
|
|
56
|
-
|
|
58
|
+
delete(key) {
|
|
59
|
+
if (this._backend[key] !== undefined) {
|
|
60
|
+
this._backend[key] = undefined;
|
|
61
|
+
this._size--;
|
|
62
|
+
}
|
|
57
63
|
}
|
|
58
64
|
/**
|
|
59
|
-
*
|
|
60
|
-
*
|
|
61
|
-
* Undefined slots are skipped; the callback is only called for keys that
|
|
62
|
-
* have an associated value.
|
|
65
|
+
* Visit every present entry in ascending key order. Empty slots are skipped.
|
|
63
66
|
*
|
|
64
|
-
* @param callback -
|
|
67
|
+
* @param callback - Invoked with `(value, key, map)` for each entry.
|
|
65
68
|
*/
|
|
66
69
|
forEach(callback) {
|
|
67
|
-
this.
|
|
70
|
+
this._backend.forEach((value, index) => {
|
|
68
71
|
if (value !== undefined) {
|
|
69
72
|
callback(value, index, this);
|
|
70
73
|
}
|
|
71
74
|
});
|
|
72
75
|
}
|
|
73
|
-
/**
|
|
74
|
-
* Remove all entries and reset the size to zero.
|
|
75
|
-
*/
|
|
76
|
+
/** Remove all entries and reset {@link size} to zero. */
|
|
76
77
|
clear() {
|
|
77
|
-
this.
|
|
78
|
-
|
|
79
|
-
/** The number of entries currently in the map. */
|
|
80
|
-
get size() {
|
|
81
|
-
return this._size;
|
|
78
|
+
this._backend.length = 0;
|
|
79
|
+
this._size = 0;
|
|
82
80
|
}
|
|
83
81
|
}
|
|
84
82
|
//# sourceMappingURL=array_map.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"array_map.js","sourceRoot":"","sources":["../../src/util/array_map.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"array_map.js","sourceRoot":"","sources":["../../src/util/array_map.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AACH,MAAM,OAAO,QAAQ;IAArB;QACU,aAAQ,GAAsB,EAAE,CAAC;QACjC,UAAK,GAAW,CAAC,CAAC;IAoE5B,CAAC;IAlEC,kDAAkD;IAClD,IAAW,IAAI;QACb,OAAO,IAAI,CAAC,KAAK,CAAC;IACpB,CAAC;IAED;;;;;OAKG;IACI,GAAG,CAAC,GAAW,EAAE,KAAQ;QAC9B,IAAI,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,KAAK,SAAS,EAAE;YACpC,IAAI,CAAC,KAAK,EAAE,CAAC;SACd;QACD,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;IAC7B,CAAC;IAED;;;;OAIG;IACI,GAAG,CAAC,GAAW;QACpB,OAAO,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;IAC5B,CAAC;IAED;;;;OAIG;IACI,GAAG,CAAC,GAAW;QACpB,OAAO,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,KAAK,SAAS,CAAC;IAC1C,CAAC;IAED;;;;OAIG;IACI,MAAM,CAAC,GAAW;QACvB,IAAI,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,KAAK,SAAS,EAAE;YACpC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,GAAG,SAAS,CAAC;YAC/B,IAAI,CAAC,KAAK,EAAE,CAAC;SACd;IACH,CAAC;IAED;;;;OAIG;IACI,OAAO,CAAC,QAA2D;QACxE,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE;YACrC,IAAI,KAAK,KAAK,SAAS,EAAE;gBACvB,QAAQ,CAAC,KAAK,EAAE,KAAK,EAAE,IAAI,CAAC,CAAC;aAC9B;QACH,CAAC,CAAC,CAAC;IACL,CAAC;IAED,yDAAyD;IAClD,KAAK;QACV,IAAI,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC;QACzB,IAAI,CAAC,KAAK,GAAG,CAAC,CAAC;IACjB,CAAC;CACF"}
|
package/dist/util/bitset.d.ts
CHANGED
|
@@ -2,93 +2,79 @@
|
|
|
2
2
|
* A compact, growable set of non-negative integers backed by an array of
|
|
3
3
|
* 32-bit words.
|
|
4
4
|
*
|
|
5
|
-
*
|
|
6
|
-
* ids attached to an entity) and
|
|
7
|
-
*
|
|
5
|
+
* `Bitset` is the data structure the ECS uses to represent entity archetypes
|
|
6
|
+
* (the set of component type ids attached to an entity) and watchlists
|
|
7
|
+
* (the set of component types a query reacts to).
|
|
8
|
+
*
|
|
9
|
+
* It is exported in the public API so component data can use it for
|
|
10
|
+
* compact bit-flag fields:
|
|
8
11
|
*
|
|
9
12
|
* ```ts
|
|
10
13
|
* class Tags extends Component {
|
|
11
|
-
* tags
|
|
12
|
-
* oldTags = new Bitset();
|
|
14
|
+
* tags = new Bitset();
|
|
13
15
|
* }
|
|
14
16
|
*
|
|
15
|
-
*
|
|
17
|
+
* tags.tags.add(TAG_VISIBLE);
|
|
16
18
|
* if (tags.tags.has(TAG_VISIBLE)) { ... }
|
|
17
19
|
* ```
|
|
18
20
|
*/
|
|
19
21
|
export declare class Bitset {
|
|
20
|
-
/** @internal */
|
|
21
|
-
_bits: number[];
|
|
22
|
-
constructor();
|
|
23
|
-
/**
|
|
24
|
-
* Return `true` if this bitset and `other` have exactly the same bits set.
|
|
25
|
-
*/
|
|
26
|
-
equal(other: Bitset): boolean;
|
|
27
22
|
/**
|
|
28
|
-
*
|
|
29
|
-
*
|
|
30
|
-
* @internal Low-level bulk operation; prefer {@link add} for single bits.
|
|
31
|
-
*/
|
|
32
|
-
addIndexBitmask(arrayIndex: number, bitmask: number): void;
|
|
33
|
-
/**
|
|
34
|
-
* Replace the word at position `arrayIndex` with `bitmask`.
|
|
23
|
+
* Set bit `n`.
|
|
35
24
|
*
|
|
36
|
-
* @
|
|
25
|
+
* @param n - Non-negative integer bit index.
|
|
37
26
|
*/
|
|
38
|
-
|
|
27
|
+
add(n: number): void;
|
|
39
28
|
/**
|
|
40
29
|
* Set the bit described by `bptr` (fast path using a pre-computed
|
|
41
30
|
* {@link BitPtr}).
|
|
31
|
+
*
|
|
32
|
+
* @param bptr - Pre-computed pointer to a bit position.
|
|
42
33
|
*/
|
|
43
34
|
addBit(bptr: BitPtr): void;
|
|
44
35
|
/**
|
|
45
|
-
*
|
|
36
|
+
* Clear bit `n`. Trailing zero words are trimmed so the internal storage
|
|
37
|
+
* stays compact.
|
|
46
38
|
*
|
|
47
39
|
* @param n - Non-negative integer bit index.
|
|
48
40
|
*/
|
|
49
|
-
|
|
41
|
+
delete(n: number): void;
|
|
50
42
|
/**
|
|
51
|
-
*
|
|
52
|
-
*
|
|
53
|
-
* Trailing zero words are trimmed so that the internal array stays compact.
|
|
43
|
+
* Return `true` when bit `n` is set.
|
|
54
44
|
*
|
|
55
45
|
* @param n - Non-negative integer bit index.
|
|
56
46
|
*/
|
|
57
|
-
|
|
58
|
-
/**
|
|
59
|
-
* Return `true` if the bit described by `bptr` is set (fast path).
|
|
60
|
-
*/
|
|
61
|
-
hasBit(bptr: BitPtr): boolean;
|
|
47
|
+
has(n: number): boolean;
|
|
62
48
|
/**
|
|
63
|
-
* Return `true`
|
|
49
|
+
* Return `true` when the bit described by `bptr` is set (fast path).
|
|
64
50
|
*
|
|
65
|
-
* @param
|
|
51
|
+
* @param bptr - Pre-computed pointer to a bit position.
|
|
66
52
|
*/
|
|
67
|
-
|
|
53
|
+
hasBit(bptr: BitPtr): boolean;
|
|
68
54
|
/**
|
|
69
|
-
* Return `true`
|
|
55
|
+
* Return `true` when this bitset and `other` have exactly the same bits set.
|
|
70
56
|
*
|
|
71
|
-
* @
|
|
57
|
+
* @param other - Bitset to compare against.
|
|
72
58
|
*/
|
|
73
|
-
|
|
59
|
+
equal(other: Bitset): boolean;
|
|
74
60
|
/**
|
|
75
|
-
* Return `true`
|
|
76
|
-
* `other` is a subset of `this`).
|
|
61
|
+
* Return `true` when every bit set in `other` is also set in this bitset
|
|
62
|
+
* (i.e. `other` is a subset of `this`).
|
|
77
63
|
*
|
|
78
64
|
* Used by the world to test whether an entity's archetype satisfies a
|
|
79
|
-
*
|
|
65
|
+
* `HAS` query.
|
|
66
|
+
*
|
|
67
|
+
* @param other - Bitset whose set bits must all appear in this bitset.
|
|
80
68
|
*/
|
|
81
69
|
hasBitset(other: Bitset): boolean;
|
|
82
70
|
/**
|
|
83
|
-
*
|
|
71
|
+
* Visit each set bit index in ascending order.
|
|
84
72
|
*
|
|
85
|
-
* @param callback -
|
|
73
|
+
* @param callback - Invoked once per set bit.
|
|
86
74
|
*/
|
|
87
75
|
forEach(callback: (n: number) => void): void;
|
|
88
76
|
/**
|
|
89
|
-
* Return an array of
|
|
90
|
-
*
|
|
91
|
-
* @returns `number[]` of set bit positions.
|
|
77
|
+
* Return an array of every set bit index in ascending order.
|
|
92
78
|
*/
|
|
93
79
|
indices(): number[];
|
|
94
80
|
}
|
|
@@ -96,12 +82,12 @@ export declare class Bitset {
|
|
|
96
82
|
* A pre-computed pointer into a {@link Bitset}'s internal word array.
|
|
97
83
|
*
|
|
98
84
|
* Computing `arrayIndex` and `bitmask` from a raw bit index requires a floor
|
|
99
|
-
* division and a
|
|
85
|
+
* division and a bit shift. `BitPtr` caches both values so that hot-path
|
|
100
86
|
* archetype checks ({@link Bitset.hasBit}, {@link Bitset.addBit}) avoid
|
|
101
87
|
* repeating the arithmetic on every entity update.
|
|
102
88
|
*
|
|
103
|
-
*
|
|
104
|
-
*
|
|
89
|
+
* One `BitPtr` is created per registered component type and stored on
|
|
90
|
+
* `ComponentMeta.bitPtr`.
|
|
105
91
|
*/
|
|
106
92
|
export declare class BitPtr {
|
|
107
93
|
/** The raw bit index this pointer refers to. */
|
|
@@ -113,6 +99,10 @@ export declare class BitPtr {
|
|
|
113
99
|
constructor(
|
|
114
100
|
/** The raw bit index this pointer refers to. */
|
|
115
101
|
value: number);
|
|
116
|
-
/**
|
|
102
|
+
/**
|
|
103
|
+
* Return `true` when both pointers refer to the same bit position.
|
|
104
|
+
*
|
|
105
|
+
* @param other - Pointer to compare against.
|
|
106
|
+
*/
|
|
117
107
|
equals(other: BitPtr): boolean;
|
|
118
108
|
}
|
package/dist/util/bitset.js
CHANGED
|
@@ -2,53 +2,27 @@
|
|
|
2
2
|
* A compact, growable set of non-negative integers backed by an array of
|
|
3
3
|
* 32-bit words.
|
|
4
4
|
*
|
|
5
|
-
*
|
|
6
|
-
* ids attached to an entity) and
|
|
7
|
-
*
|
|
5
|
+
* `Bitset` is the data structure the ECS uses to represent entity archetypes
|
|
6
|
+
* (the set of component type ids attached to an entity) and watchlists
|
|
7
|
+
* (the set of component types a query reacts to).
|
|
8
|
+
*
|
|
9
|
+
* It is exported in the public API so component data can use it for
|
|
10
|
+
* compact bit-flag fields:
|
|
8
11
|
*
|
|
9
12
|
* ```ts
|
|
10
13
|
* class Tags extends Component {
|
|
11
|
-
* tags
|
|
12
|
-
* oldTags = new Bitset();
|
|
14
|
+
* tags = new Bitset();
|
|
13
15
|
* }
|
|
14
16
|
*
|
|
15
|
-
*
|
|
17
|
+
* tags.tags.add(TAG_VISIBLE);
|
|
16
18
|
* if (tags.tags.has(TAG_VISIBLE)) { ... }
|
|
17
19
|
* ```
|
|
18
20
|
*/
|
|
19
21
|
export class Bitset {
|
|
20
22
|
constructor() {
|
|
23
|
+
/** @internal Underlying word storage; exposed for tests. */
|
|
21
24
|
this._bits = [];
|
|
22
25
|
}
|
|
23
|
-
/**
|
|
24
|
-
* Return `true` if this bitset and `other` have exactly the same bits set.
|
|
25
|
-
*/
|
|
26
|
-
equal(other) {
|
|
27
|
-
return (this._bits.length === other._bits.length && this._bits.every((v, i) => other._bits[i] === v));
|
|
28
|
-
}
|
|
29
|
-
/**
|
|
30
|
-
* OR the given `bitmask` word into the word at position `arrayIndex`.
|
|
31
|
-
*
|
|
32
|
-
* @internal Low-level bulk operation; prefer {@link add} for single bits.
|
|
33
|
-
*/
|
|
34
|
-
addIndexBitmask(arrayIndex, bitmask) {
|
|
35
|
-
this._bits[arrayIndex] |= bitmask;
|
|
36
|
-
}
|
|
37
|
-
/**
|
|
38
|
-
* Replace the word at position `arrayIndex` with `bitmask`.
|
|
39
|
-
*
|
|
40
|
-
* @internal Used by network deserialization to set a whole word at once.
|
|
41
|
-
*/
|
|
42
|
-
setIndexBitmask(arrayIndex, bitmask) {
|
|
43
|
-
this._bits[arrayIndex] = bitmask;
|
|
44
|
-
}
|
|
45
|
-
/**
|
|
46
|
-
* Set the bit described by `bptr` (fast path using a pre-computed
|
|
47
|
-
* {@link BitPtr}).
|
|
48
|
-
*/
|
|
49
|
-
addBit(bptr) {
|
|
50
|
-
this.addIndexBitmask(bptr.arrayIndex, bptr.bitmask);
|
|
51
|
-
}
|
|
52
26
|
/**
|
|
53
27
|
* Set bit `n`.
|
|
54
28
|
*
|
|
@@ -57,12 +31,20 @@ export class Bitset {
|
|
|
57
31
|
add(n) {
|
|
58
32
|
const arrayIndex = Math.floor(n / 32);
|
|
59
33
|
const bitmask = 1 << (n % 32);
|
|
60
|
-
this.
|
|
34
|
+
this._addIndexBitmask(arrayIndex, bitmask);
|
|
61
35
|
}
|
|
62
36
|
/**
|
|
63
|
-
*
|
|
37
|
+
* Set the bit described by `bptr` (fast path using a pre-computed
|
|
38
|
+
* {@link BitPtr}).
|
|
64
39
|
*
|
|
65
|
-
*
|
|
40
|
+
* @param bptr - Pre-computed pointer to a bit position.
|
|
41
|
+
*/
|
|
42
|
+
addBit(bptr) {
|
|
43
|
+
this._addIndexBitmask(bptr.arrayIndex, bptr.bitmask);
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Clear bit `n`. Trailing zero words are trimmed so the internal storage
|
|
47
|
+
* stays compact.
|
|
66
48
|
*
|
|
67
49
|
* @param n - Non-negative integer bit index.
|
|
68
50
|
*/
|
|
@@ -80,13 +62,7 @@ export class Bitset {
|
|
|
80
62
|
}
|
|
81
63
|
}
|
|
82
64
|
/**
|
|
83
|
-
* Return `true`
|
|
84
|
-
*/
|
|
85
|
-
hasBit(bptr) {
|
|
86
|
-
return this.hasIndexBitmask(bptr.arrayIndex, bptr.bitmask);
|
|
87
|
-
}
|
|
88
|
-
/**
|
|
89
|
-
* Return `true` if bit `n` is set.
|
|
65
|
+
* Return `true` when bit `n` is set.
|
|
90
66
|
*
|
|
91
67
|
* @param n - Non-negative integer bit index.
|
|
92
68
|
*/
|
|
@@ -97,22 +73,32 @@ export class Bitset {
|
|
|
97
73
|
}
|
|
98
74
|
const bitIndex = n % 32;
|
|
99
75
|
const bitmask = 1 << bitIndex;
|
|
100
|
-
return this.
|
|
76
|
+
return this._hasIndexBitmask(arrayIndex, bitmask);
|
|
101
77
|
}
|
|
102
78
|
/**
|
|
103
|
-
* Return `true`
|
|
79
|
+
* Return `true` when the bit described by `bptr` is set (fast path).
|
|
104
80
|
*
|
|
105
|
-
* @
|
|
81
|
+
* @param bptr - Pre-computed pointer to a bit position.
|
|
106
82
|
*/
|
|
107
|
-
|
|
108
|
-
return
|
|
83
|
+
hasBit(bptr) {
|
|
84
|
+
return this._hasIndexBitmask(bptr.arrayIndex, bptr.bitmask);
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Return `true` when this bitset and `other` have exactly the same bits set.
|
|
88
|
+
*
|
|
89
|
+
* @param other - Bitset to compare against.
|
|
90
|
+
*/
|
|
91
|
+
equal(other) {
|
|
92
|
+
return (this._bits.length === other._bits.length && this._bits.every((v, i) => other._bits[i] === v));
|
|
109
93
|
}
|
|
110
94
|
/**
|
|
111
|
-
* Return `true`
|
|
112
|
-
* `other` is a subset of `this`).
|
|
95
|
+
* Return `true` when every bit set in `other` is also set in this bitset
|
|
96
|
+
* (i.e. `other` is a subset of `this`).
|
|
113
97
|
*
|
|
114
98
|
* Used by the world to test whether an entity's archetype satisfies a
|
|
115
|
-
*
|
|
99
|
+
* `HAS` query.
|
|
100
|
+
*
|
|
101
|
+
* @param other - Bitset whose set bits must all appear in this bitset.
|
|
116
102
|
*/
|
|
117
103
|
hasBitset(other) {
|
|
118
104
|
if (this._bits.length < other._bits.length) {
|
|
@@ -126,9 +112,9 @@ export class Bitset {
|
|
|
126
112
|
return true;
|
|
127
113
|
}
|
|
128
114
|
/**
|
|
129
|
-
*
|
|
115
|
+
* Visit each set bit index in ascending order.
|
|
130
116
|
*
|
|
131
|
-
* @param callback -
|
|
117
|
+
* @param callback - Invoked once per set bit.
|
|
132
118
|
*/
|
|
133
119
|
forEach(callback) {
|
|
134
120
|
this._bits.forEach((b, j) => {
|
|
@@ -141,26 +127,50 @@ export class Bitset {
|
|
|
141
127
|
});
|
|
142
128
|
}
|
|
143
129
|
/**
|
|
144
|
-
* Return an array of
|
|
145
|
-
*
|
|
146
|
-
* @returns `number[]` of set bit positions.
|
|
130
|
+
* Return an array of every set bit index in ascending order.
|
|
147
131
|
*/
|
|
148
132
|
indices() {
|
|
149
133
|
const idx = [];
|
|
150
134
|
this.forEach((i) => idx.push(i));
|
|
151
135
|
return idx;
|
|
152
136
|
}
|
|
137
|
+
/**
|
|
138
|
+
* OR `bitmask` into the word at position `arrayIndex`.
|
|
139
|
+
*
|
|
140
|
+
* @internal Low-level bulk operation; prefer {@link add} or {@link addBit}
|
|
141
|
+
* for single bits.
|
|
142
|
+
*/
|
|
143
|
+
_addIndexBitmask(arrayIndex, bitmask) {
|
|
144
|
+
this._bits[arrayIndex] |= bitmask;
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* Replace the word at position `arrayIndex` with `bitmask`.
|
|
148
|
+
*
|
|
149
|
+
* @internal Used by network deserialization to write a whole word at once.
|
|
150
|
+
*/
|
|
151
|
+
_setIndexBitmask(arrayIndex, bitmask) {
|
|
152
|
+
this._bits[arrayIndex] = bitmask;
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* Return `true` when every bit in `bitmask` is set in the word at
|
|
156
|
+
* `arrayIndex`.
|
|
157
|
+
*
|
|
158
|
+
* @internal
|
|
159
|
+
*/
|
|
160
|
+
_hasIndexBitmask(arrayIndex, bitmask) {
|
|
161
|
+
return (this._bits[arrayIndex] & bitmask) !== 0;
|
|
162
|
+
}
|
|
153
163
|
}
|
|
154
164
|
/**
|
|
155
165
|
* A pre-computed pointer into a {@link Bitset}'s internal word array.
|
|
156
166
|
*
|
|
157
167
|
* Computing `arrayIndex` and `bitmask` from a raw bit index requires a floor
|
|
158
|
-
* division and a
|
|
168
|
+
* division and a bit shift. `BitPtr` caches both values so that hot-path
|
|
159
169
|
* archetype checks ({@link Bitset.hasBit}, {@link Bitset.addBit}) avoid
|
|
160
170
|
* repeating the arithmetic on every entity update.
|
|
161
171
|
*
|
|
162
|
-
*
|
|
163
|
-
*
|
|
172
|
+
* One `BitPtr` is created per registered component type and stored on
|
|
173
|
+
* `ComponentMeta.bitPtr`.
|
|
164
174
|
*/
|
|
165
175
|
export class BitPtr {
|
|
166
176
|
constructor(
|
|
@@ -170,7 +180,11 @@ export class BitPtr {
|
|
|
170
180
|
this.arrayIndex = Math.floor(value / 32);
|
|
171
181
|
this.bitmask = 1 << (value % 32);
|
|
172
182
|
}
|
|
173
|
-
/**
|
|
183
|
+
/**
|
|
184
|
+
* Return `true` when both pointers refer to the same bit position.
|
|
185
|
+
*
|
|
186
|
+
* @param other - Pointer to compare against.
|
|
187
|
+
*/
|
|
174
188
|
equals(other) {
|
|
175
189
|
return this.arrayIndex == other.arrayIndex && this.bitmask == other.bitmask;
|
|
176
190
|
}
|
package/dist/util/bitset.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bitset.js","sourceRoot":"","sources":["../../src/util/bitset.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"bitset.js","sourceRoot":"","sources":["../../src/util/bitset.ts"],"names":[],"mappings":"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"}
|
package/dist/util/events.d.ts
CHANGED
|
@@ -1,27 +1,23 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
4
|
-
*
|
|
2
|
+
* Strongly-typed wrapper around `eventemitter3`.
|
|
3
|
+
*
|
|
4
|
+
* The class declared in this file is purely a typings shim — at module load
|
|
5
|
+
* its prototype is swapped out for `EventEmitter` from `eventemitter3` so the
|
|
6
|
+
* concrete behavior is provided by that library, while consumers see typed
|
|
7
|
+
* `on` / `emit` / `off` signatures driven by an `EventMap`.
|
|
8
|
+
*
|
|
9
|
+
* Inspired by the typings in `@yandeu/events`
|
|
10
|
+
* (https://github.com/yandeu/events). The original typings turned out to be
|
|
11
|
+
* usable directly on top of `eventemitter3`.
|
|
12
|
+
*
|
|
13
|
+
* @internal Used only inside the package, to expose typed entity-level events.
|
|
5
14
|
*/
|
|
6
15
|
declare type ValidEventMap<T = any> = T extends {
|
|
7
16
|
[P in keyof T]: (...args: any[]) => void;
|
|
8
17
|
} ? T : never;
|
|
9
18
|
declare type Handler<T extends any | ((...args: any[]) => R), R = any> = T;
|
|
19
|
+
/** Listener signature inferred from an `EventMap` entry. */
|
|
10
20
|
export declare type EventListener<T extends ValidEventMap, K extends EventNames<T>> = T extends string | symbol ? (...args: any[]) => void : K extends keyof T ? Handler<T[K], void> : never;
|
|
11
|
-
|
|
21
|
+
/** Names of the events declared on an `EventMap`. */
|
|
12
22
|
export declare type EventNames<T extends ValidEventMap> = T extends string | symbol ? T : keyof T;
|
|
13
|
-
declare class events<EventMap extends ValidEventMap = any> {
|
|
14
|
-
on<T extends EventNames<EventMap>>(event: T, fn: EventListener<EventMap, T>, context?: any): events<EventMap>;
|
|
15
|
-
emit<T extends EventNames<EventMap>>(event: T, ...args: EventArgs<EventMap, T>): boolean;
|
|
16
|
-
once<T extends EventNames<EventMap>>(event: T, fn: EventListener<EventMap, T>, context?: any): events<EventMap>;
|
|
17
|
-
eventNames(): EventNames<EventMap>[];
|
|
18
|
-
listeners(event: EventNames<EventMap>): any[];
|
|
19
|
-
listenerCount(event: EventNames<EventMap>): any;
|
|
20
|
-
removeListener<T extends EventNames<EventMap>>(event: T, fn?: EventListener<EventMap, T>, context?: any, once?: boolean): this;
|
|
21
|
-
removeAllListeners(event?: EventNames<EventMap>): this;
|
|
22
|
-
off<T extends EventNames<EventMap>>(event: T, fn?: EventListener<EventMap, T> | undefined, context?: any, once?: boolean | undefined): events<EventMap>;
|
|
23
|
-
addListener<T extends EventNames<EventMap>>(event: T, fn: EventListener<EventMap, T>, context?: any): events<EventMap>;
|
|
24
|
-
}
|
|
25
|
-
export declare class Events<EventMap extends ValidEventMap = any> extends events<EventMap> {
|
|
26
|
-
}
|
|
27
23
|
export {};
|