@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/entity.js
CHANGED
|
@@ -2,73 +2,127 @@ import { ArrayMap } from "./util/array_map.js";
|
|
|
2
2
|
import { Events } from "./util/events.js";
|
|
3
3
|
import { Bitset } from "./util/bitset.js";
|
|
4
4
|
/**
|
|
5
|
-
* A game object
|
|
6
|
-
* {@link Component | components} attached
|
|
5
|
+
* A game object: a unique numeric id with an arbitrary set of
|
|
6
|
+
* {@link Component | components} attached.
|
|
7
7
|
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
* external authority
|
|
8
|
+
* Never instantiate `Entity` directly. Use {@link World.entity} for an
|
|
9
|
+
* auto-assigned id, or {@link World.getOrCreateEntity} when the id comes from
|
|
10
|
+
* an external authority such as a game server:
|
|
11
11
|
*
|
|
12
12
|
* ```ts
|
|
13
13
|
* const e = world.entity();
|
|
14
14
|
* e.set(Position, { x: 100 });
|
|
15
15
|
* ```
|
|
16
16
|
*
|
|
17
|
-
* Entities support a parent–child hierarchy.
|
|
18
|
-
*
|
|
17
|
+
* Entities support a parent–child hierarchy. `parent` and `children` form a
|
|
18
|
+
* bidirectional link maintained by {@link setParent}; the children set is
|
|
19
|
+
* created lazily. Destroying a parent recursively destroys its children.
|
|
19
20
|
*
|
|
20
21
|
* ## Deferred semantics
|
|
21
22
|
*
|
|
22
23
|
* Inside a system body or `forEach` iteration the world is in **deferred
|
|
23
|
-
* mode**: `add` / `set` / `remove` / `destroy`
|
|
24
|
-
* data layer (
|
|
25
|
-
*
|
|
24
|
+
* mode**: `add` / `set` / `modified` / `remove` / `destroy` / `setParent` only
|
|
25
|
+
* enqueue commands. The data layer (the components map and `componentBitmask`)
|
|
26
|
+
* is mutated when the world drains its queue. Concretely, while deferred:
|
|
26
27
|
*
|
|
27
28
|
* - `entity.get(C)` returns `undefined` after `entity.add(C)` (no instance yet).
|
|
28
29
|
* - `entity.get(C)` returns the previous value after `entity.set(C, props)`.
|
|
29
30
|
* - `entity.get(C)` still returns the component after `entity.remove(C)`.
|
|
30
31
|
*
|
|
31
|
-
* Outside deferred mode
|
|
32
|
-
*
|
|
32
|
+
* Outside deferred mode the same calls execute inline and mutations are
|
|
33
|
+
* visible immediately.
|
|
33
34
|
*/
|
|
34
35
|
export class Entity {
|
|
35
36
|
constructor(
|
|
36
|
-
/**
|
|
37
|
+
/** World that owns this entity. */
|
|
37
38
|
world,
|
|
38
|
-
/** Unique numeric entity id assigned at creation
|
|
39
|
+
/** Unique numeric entity id assigned at creation. */
|
|
39
40
|
eid) {
|
|
40
41
|
this.world = world;
|
|
41
42
|
this.eid = eid;
|
|
42
|
-
|
|
43
|
+
/** @internal Maps numeric component type id to component instance. */
|
|
44
|
+
this._components = new ArrayMap();
|
|
45
|
+
/** @internal Set of queries this entity currently belongs to. */
|
|
46
|
+
this._queries = new Set();
|
|
43
47
|
/**
|
|
44
|
-
* Bitmask
|
|
45
|
-
*
|
|
46
|
-
* predicates.
|
|
48
|
+
* Bitmask of component type ids currently attached to this entity. Used by
|
|
49
|
+
* the world for fast archetype matching against query predicates.
|
|
47
50
|
*/
|
|
48
51
|
this.componentBitmask = new Bitset();
|
|
49
|
-
this.queries = new Set();
|
|
50
52
|
/**
|
|
51
|
-
*
|
|
52
|
-
*
|
|
53
|
+
* Free-form property bag. Modules can use it to associate arbitrary data with
|
|
54
|
+
* an entity without registering a dedicated component.
|
|
53
55
|
*/
|
|
54
56
|
this.properties = new Map();
|
|
55
|
-
/** @internal
|
|
57
|
+
/** @internal Set to `true` after the world has fully torn down this entity. */
|
|
56
58
|
this._destroyed = false;
|
|
57
59
|
}
|
|
58
|
-
/**
|
|
59
|
-
|
|
60
|
-
|
|
60
|
+
/**
|
|
61
|
+
* Re-evaluate every world query for this entity, firing `_enter` / `_exit`
|
|
62
|
+
* routing whenever membership flipped.
|
|
63
|
+
*/
|
|
64
|
+
_updateQueries() {
|
|
65
|
+
this.world.queries.forEach((q) => {
|
|
66
|
+
const belongs = q.belongs(this);
|
|
67
|
+
const isIn = this._isInQuery(q);
|
|
68
|
+
if (belongs !== isIn) {
|
|
69
|
+
belongs ? q._enter(this) : q._exit(this);
|
|
70
|
+
}
|
|
71
|
+
});
|
|
61
72
|
}
|
|
62
|
-
/**
|
|
63
|
-
|
|
64
|
-
|
|
73
|
+
/**
|
|
74
|
+
* Construct a fresh component of `type`, apply `props`, store it on this
|
|
75
|
+
* entity, fire the `onAdd` hook, and route query updates.
|
|
76
|
+
*
|
|
77
|
+
* If the component type belongs to an exclusivity group, any conflicting
|
|
78
|
+
* component already on this entity is removed first.
|
|
79
|
+
*/
|
|
80
|
+
_new(type, props) {
|
|
81
|
+
const meta = this.world.getComponentMeta(type);
|
|
82
|
+
if (meta.exclusive) {
|
|
83
|
+
for (const exclusiveType of meta.exclusive) {
|
|
84
|
+
if (this._components.has(exclusiveType)) {
|
|
85
|
+
this._remove(exclusiveType);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
const c = new meta.Class(this, meta);
|
|
90
|
+
if (props !== undefined) {
|
|
91
|
+
Object.assign(c, props);
|
|
92
|
+
}
|
|
93
|
+
this._components.set(type, c);
|
|
94
|
+
this.componentBitmask.add(type);
|
|
95
|
+
if (meta._onAddHandlers) {
|
|
96
|
+
meta._onAddHandlers.forEach((handler) => handler(c));
|
|
97
|
+
}
|
|
98
|
+
this._updateQueries();
|
|
99
|
+
return c;
|
|
65
100
|
}
|
|
66
101
|
/**
|
|
67
|
-
*
|
|
68
|
-
|
|
69
|
-
|
|
102
|
+
* @internal Return `true` when this entity is currently tracked by `q`.
|
|
103
|
+
*/
|
|
104
|
+
_isInQuery(q) {
|
|
105
|
+
return this._queries.has(q);
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* @internal Look up a component instance by numeric type id.
|
|
109
|
+
*
|
|
110
|
+
* Faster than {@link get} because no class → type id resolution is needed.
|
|
111
|
+
*/
|
|
112
|
+
_get(type) {
|
|
113
|
+
return this._components.get(type);
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* @internal Reparent this entity in place, maintaining the bidirectional
|
|
117
|
+
* link. Throws if `newParent` is a descendant of this entity.
|
|
118
|
+
*
|
|
119
|
+
* Called by the world either inline (outside deferred mode) or while
|
|
120
|
+
* routing a queued `SetParent` command.
|
|
70
121
|
*/
|
|
71
122
|
_setParent(newParent) {
|
|
123
|
+
if (this._destroyed) {
|
|
124
|
+
return;
|
|
125
|
+
}
|
|
72
126
|
if (newParent !== undefined) {
|
|
73
127
|
let ancestor = newParent;
|
|
74
128
|
while (ancestor !== undefined) {
|
|
@@ -86,9 +140,171 @@ export class Entity {
|
|
|
86
140
|
(newParent._children ?? (newParent._children = new Set())).add(this);
|
|
87
141
|
}
|
|
88
142
|
}
|
|
143
|
+
/**
|
|
144
|
+
* @internal Apply a `Set` command: create the component if missing, assign
|
|
145
|
+
* `props` if provided, fire `onSet`, and route modified events to every
|
|
146
|
+
* query that watches the component type.
|
|
147
|
+
*/
|
|
148
|
+
_set(type, props) {
|
|
149
|
+
if (this._destroyed) {
|
|
150
|
+
return;
|
|
151
|
+
}
|
|
152
|
+
const existing = this._components.get(type);
|
|
153
|
+
const c = existing ?? this._new(type, props);
|
|
154
|
+
if (props !== undefined) {
|
|
155
|
+
if (existing) {
|
|
156
|
+
Object.assign(c, props);
|
|
157
|
+
}
|
|
158
|
+
const setHandlers = c.meta._onSetHandlers;
|
|
159
|
+
if (setHandlers) {
|
|
160
|
+
setHandlers.forEach((handler) => handler(c));
|
|
161
|
+
}
|
|
162
|
+
c._dirty = false;
|
|
163
|
+
if (existing) {
|
|
164
|
+
this._queries.forEach((q) => q._notifyModified(c));
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
/**
|
|
169
|
+
* @internal Apply a `Modified` command: fire `onSet` and route modified
|
|
170
|
+
* events to every query that watches the component type.
|
|
171
|
+
*/
|
|
172
|
+
_modified(type) {
|
|
173
|
+
if (this._destroyed) {
|
|
174
|
+
return;
|
|
175
|
+
}
|
|
176
|
+
const c = this._components.get(type);
|
|
177
|
+
if (!c) {
|
|
178
|
+
return;
|
|
179
|
+
}
|
|
180
|
+
const setHandlers = c.meta._onSetHandlers;
|
|
181
|
+
if (setHandlers) {
|
|
182
|
+
setHandlers.forEach((handler) => handler(c));
|
|
183
|
+
}
|
|
184
|
+
c._dirty = false;
|
|
185
|
+
this._queries.forEach((q) => q._notifyModified(c));
|
|
186
|
+
}
|
|
187
|
+
/**
|
|
188
|
+
* @internal Apply a `Remove` command: clear the type bit, route exits,
|
|
189
|
+
* detach the component, and fire `onRemove`.
|
|
190
|
+
*/
|
|
191
|
+
_remove(type) {
|
|
192
|
+
if (this._destroyed) {
|
|
193
|
+
return;
|
|
194
|
+
}
|
|
195
|
+
const c = this._components.get(type);
|
|
196
|
+
if (!c) {
|
|
197
|
+
return;
|
|
198
|
+
}
|
|
199
|
+
this.componentBitmask.delete(type);
|
|
200
|
+
this._updateQueries();
|
|
201
|
+
this._components.delete(type);
|
|
202
|
+
const removeHandlers = c.meta._onRemoveHandlers;
|
|
203
|
+
if (removeHandlers) {
|
|
204
|
+
removeHandlers.forEach((handler) => handler(c));
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
/**
|
|
208
|
+
* @internal Apply a `Destroy` command: fire `_exit` on every query, then
|
|
209
|
+
* `onRemove` on every component, emit the `destroy` event, and unlink from
|
|
210
|
+
* the world and any parent.
|
|
211
|
+
*/
|
|
212
|
+
_destroy() {
|
|
213
|
+
if (this._destroyed) {
|
|
214
|
+
return;
|
|
215
|
+
}
|
|
216
|
+
this._destroyed = true;
|
|
217
|
+
const toExit = [];
|
|
218
|
+
this._queries.forEach((q) => {
|
|
219
|
+
if (q.world) {
|
|
220
|
+
toExit.push(q);
|
|
221
|
+
}
|
|
222
|
+
});
|
|
223
|
+
toExit.forEach((q) => q._exit(this));
|
|
224
|
+
this._components.forEach((c) => {
|
|
225
|
+
const removeHandlers = c.meta._onRemoveHandlers;
|
|
226
|
+
if (removeHandlers) {
|
|
227
|
+
removeHandlers.forEach((handler) => handler(c));
|
|
228
|
+
}
|
|
229
|
+
});
|
|
230
|
+
if (this._events) {
|
|
231
|
+
this._events.emit("destroy");
|
|
232
|
+
this._events.removeAllListeners("destroy");
|
|
233
|
+
}
|
|
234
|
+
this.world._unregisterEntity(this);
|
|
235
|
+
if (this._parent) {
|
|
236
|
+
this._parent._children?.delete(this);
|
|
237
|
+
this._parent = undefined;
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
/**
|
|
241
|
+
* @internal Forget query `q` without firing exit callbacks. Called by
|
|
242
|
+
* {@link World} when a {@link Query.destroy} sweeps every entity.
|
|
243
|
+
*/
|
|
244
|
+
_purgeQuery(q) {
|
|
245
|
+
this._queries.delete(q);
|
|
246
|
+
}
|
|
247
|
+
/**
|
|
248
|
+
* @internal Record that this entity is now tracked by `q`. Called by
|
|
249
|
+
* `Query._enter`.
|
|
250
|
+
*/
|
|
251
|
+
_addQueryMembership(q) {
|
|
252
|
+
this._queries.add(q);
|
|
253
|
+
}
|
|
254
|
+
/**
|
|
255
|
+
* @internal Record that this entity is no longer tracked by `q`. Called by
|
|
256
|
+
* `Query._exit`.
|
|
257
|
+
*/
|
|
258
|
+
_removeQueryMembership(q) {
|
|
259
|
+
this._queries.delete(q);
|
|
260
|
+
}
|
|
261
|
+
/** Parent entity in the scene hierarchy, or `undefined` for a root entity. */
|
|
262
|
+
get parent() {
|
|
263
|
+
return this._parent;
|
|
264
|
+
}
|
|
265
|
+
/**
|
|
266
|
+
* Read-only view of direct child entities. The backing set is created lazily
|
|
267
|
+
* on the first child link; before that this getter returns a shared empty set.
|
|
268
|
+
*/
|
|
269
|
+
get children() {
|
|
270
|
+
return this._children ?? Entity._emptyChildren;
|
|
271
|
+
}
|
|
272
|
+
/**
|
|
273
|
+
* Typed event emitter for entity-level lifecycle events. Currently only the
|
|
274
|
+
* `"destroy"` event is emitted, just before the entity is fully torn down.
|
|
275
|
+
*
|
|
276
|
+
* The emitter is created lazily on first access.
|
|
277
|
+
*/
|
|
278
|
+
get events() {
|
|
279
|
+
if (!this._events) {
|
|
280
|
+
this._events = new Events();
|
|
281
|
+
}
|
|
282
|
+
return this._events;
|
|
283
|
+
}
|
|
284
|
+
/** `true` when no components are currently attached to this entity. */
|
|
285
|
+
get empty() {
|
|
286
|
+
return this._components.size == 0;
|
|
287
|
+
}
|
|
288
|
+
/**
|
|
289
|
+
* Read-only view of all components currently attached to this entity, keyed
|
|
290
|
+
* by numeric component type id.
|
|
291
|
+
*
|
|
292
|
+
* The mutating methods (`set`, `delete`, `clear`) are not exposed. Use
|
|
293
|
+
* `entity.add`, `entity.set`, and `entity.remove` to change the component
|
|
294
|
+
* set.
|
|
295
|
+
*
|
|
296
|
+
* ```ts
|
|
297
|
+
* entity.components.forEach((c) => console.log(c.constructor.name));
|
|
298
|
+
* ```
|
|
299
|
+
*/
|
|
300
|
+
get components() {
|
|
301
|
+
return this._components;
|
|
302
|
+
}
|
|
89
303
|
/**
|
|
90
304
|
* Reparent this entity. In deferred mode the change is queued; outside
|
|
91
|
-
* deferred mode it executes
|
|
305
|
+
* deferred mode it executes inline.
|
|
306
|
+
*
|
|
307
|
+
* @param newParent - New parent, or `undefined` to make this a root entity.
|
|
92
308
|
*/
|
|
93
309
|
setParent(newParent) {
|
|
94
310
|
if (this.world.deferred) {
|
|
@@ -99,13 +315,14 @@ export class Entity {
|
|
|
99
315
|
}
|
|
100
316
|
}
|
|
101
317
|
/**
|
|
102
|
-
*
|
|
103
|
-
*
|
|
318
|
+
* Mark `c` as having changed, queueing the corresponding `onSet` / `update`
|
|
319
|
+
* notifications.
|
|
104
320
|
*
|
|
105
|
-
* Equivalent to `
|
|
106
|
-
*
|
|
321
|
+
* Equivalent to `c.modified()` but returns the entity for chaining. Repeated
|
|
322
|
+
* calls before the world routes the modified command are coalesced via the
|
|
323
|
+
* component's dirty flag.
|
|
107
324
|
*
|
|
108
|
-
* @param c -
|
|
325
|
+
* @param c - Component instance whose data changed.
|
|
109
326
|
* @returns This entity, for chaining.
|
|
110
327
|
*/
|
|
111
328
|
modified(c) {
|
|
@@ -150,160 +367,22 @@ export class Entity {
|
|
|
150
367
|
this._remove(type);
|
|
151
368
|
}
|
|
152
369
|
}
|
|
153
|
-
/** @internal Look up a component instance by type id. */
|
|
154
|
-
_get(type) {
|
|
155
|
-
return this.components.get(type);
|
|
156
|
-
}
|
|
157
370
|
/**
|
|
158
|
-
*
|
|
371
|
+
* Look up a component on this entity.
|
|
159
372
|
*
|
|
160
373
|
* @param typeOrClass - Component class or numeric type id.
|
|
161
|
-
* @returns The component instance or `undefined
|
|
374
|
+
* @returns The component instance, or `undefined` when it is not attached.
|
|
162
375
|
*/
|
|
163
376
|
get(typeOrClass) {
|
|
164
377
|
const type = this.world.getComponentType(typeOrClass);
|
|
165
378
|
return this._get(type);
|
|
166
379
|
}
|
|
167
380
|
/**
|
|
168
|
-
*
|
|
169
|
-
*
|
|
170
|
-
* Currently emits one event:
|
|
171
|
-
* - `"destroy"` — fired just before the entity is fully torn down.
|
|
172
|
-
*
|
|
173
|
-
* The emitter is created lazily on first access.
|
|
174
|
-
*/
|
|
175
|
-
get events() {
|
|
176
|
-
if (!this._events) {
|
|
177
|
-
this._events = new Events();
|
|
178
|
-
}
|
|
179
|
-
return this._events;
|
|
180
|
-
}
|
|
181
|
-
isInQuery(q) {
|
|
182
|
-
return this.queries.has(q);
|
|
183
|
-
}
|
|
184
|
-
/** @internal Removes a query from this entity's tracking sets without firing any callbacks. */
|
|
185
|
-
_purgeQuery(q) {
|
|
186
|
-
this.queries.delete(q);
|
|
187
|
-
}
|
|
188
|
-
/** @internal Add a query to the entity's tracked-query set. Called by Query._enter. */
|
|
189
|
-
_addQueryMembership(q) {
|
|
190
|
-
this.queries.add(q);
|
|
191
|
-
}
|
|
192
|
-
/** @internal Remove a query from the entity's tracked-query set. Called by Query._exit. */
|
|
193
|
-
_removeQueryMembership(q) {
|
|
194
|
-
this.queries.delete(q);
|
|
195
|
-
}
|
|
196
|
-
_updateQueries() {
|
|
197
|
-
this.world.queries.forEach((q) => {
|
|
198
|
-
const belongs = q.belongs(this);
|
|
199
|
-
const isIn = this.isInQuery(q);
|
|
200
|
-
if (belongs !== isIn) {
|
|
201
|
-
belongs ? q._enter(this) : q._exit(this);
|
|
202
|
-
}
|
|
203
|
-
});
|
|
204
|
-
}
|
|
205
|
-
_new(type, props) {
|
|
206
|
-
const meta = this.world.getComponentMeta(type);
|
|
207
|
-
if (meta.exclusive) {
|
|
208
|
-
for (const exclusiveType of meta.exclusive) {
|
|
209
|
-
if (this.components.has(exclusiveType)) {
|
|
210
|
-
this._remove(exclusiveType);
|
|
211
|
-
}
|
|
212
|
-
}
|
|
213
|
-
}
|
|
214
|
-
const c = new meta.Class(this, meta);
|
|
215
|
-
if (props !== undefined) {
|
|
216
|
-
Object.assign(c, props);
|
|
217
|
-
}
|
|
218
|
-
this.components.set(type, c);
|
|
219
|
-
this.componentBitmask.add(type);
|
|
220
|
-
meta._onAddHandler?.(c);
|
|
221
|
-
this._updateQueries();
|
|
222
|
-
return c;
|
|
223
|
-
}
|
|
224
|
-
/** @internal Execute a Set command — create if absent, apply props, fire hooks, route events. */
|
|
225
|
-
_set(type, props) {
|
|
226
|
-
if (this._destroyed) {
|
|
227
|
-
return;
|
|
228
|
-
}
|
|
229
|
-
const existing = this.components.get(type);
|
|
230
|
-
const c = existing ?? this._new(type, props);
|
|
231
|
-
if (props !== undefined) {
|
|
232
|
-
if (existing) {
|
|
233
|
-
Object.assign(c, props);
|
|
234
|
-
}
|
|
235
|
-
c.meta._onSetHandler?.(c);
|
|
236
|
-
c._dirty = false;
|
|
237
|
-
if (existing) {
|
|
238
|
-
this.queries.forEach((q) => q.notifyModified(c));
|
|
239
|
-
}
|
|
240
|
-
}
|
|
241
|
-
}
|
|
242
|
-
/** @internal Execute a Modified command — fire onSet and route update events. */
|
|
243
|
-
_modified(type) {
|
|
244
|
-
if (this._destroyed) {
|
|
245
|
-
return;
|
|
246
|
-
}
|
|
247
|
-
const c = this.components.get(type);
|
|
248
|
-
if (!c) {
|
|
249
|
-
return;
|
|
250
|
-
}
|
|
251
|
-
c.meta._onSetHandler?.(c);
|
|
252
|
-
c._dirty = false;
|
|
253
|
-
this.queries.forEach((q) => q.notifyModified(c));
|
|
254
|
-
}
|
|
255
|
-
/** @internal Execute a Remove command — clear bitmask, route exits, remove component, fire onRemove. */
|
|
256
|
-
_remove(type) {
|
|
257
|
-
if (this._destroyed) {
|
|
258
|
-
return;
|
|
259
|
-
}
|
|
260
|
-
const c = this.components.get(type);
|
|
261
|
-
if (!c) {
|
|
262
|
-
return;
|
|
263
|
-
}
|
|
264
|
-
this.componentBitmask.delete(type);
|
|
265
|
-
this._updateQueries();
|
|
266
|
-
this.components.delete(type);
|
|
267
|
-
c.meta._onRemoveHandler?.(c);
|
|
268
|
-
}
|
|
269
|
-
/** @internal Execute a Destroy command — exit queries, fire onRemove, emit event, unregister. */
|
|
270
|
-
_destroy() {
|
|
271
|
-
if (this._destroyed) {
|
|
272
|
-
return;
|
|
273
|
-
}
|
|
274
|
-
// 1. Fire exit on every query the entity belongs to.
|
|
275
|
-
const toExit = [];
|
|
276
|
-
this.queries.forEach((q) => {
|
|
277
|
-
if (q.world) {
|
|
278
|
-
toExit.push(q);
|
|
279
|
-
}
|
|
280
|
-
});
|
|
281
|
-
toExit.forEach((q) => q._exit(this));
|
|
282
|
-
// 2. Fire onRemove on every still-attached component.
|
|
283
|
-
this.components.forEach((c) => c.meta._onRemoveHandler?.(c));
|
|
284
|
-
// 3. Emit the destroy event.
|
|
285
|
-
if (this._events) {
|
|
286
|
-
this._events.emit("destroy");
|
|
287
|
-
this._events.removeAllListeners("destroy");
|
|
288
|
-
}
|
|
289
|
-
// 4. Mark destroyed and unhook from world / parent.
|
|
290
|
-
this._destroyed = true;
|
|
291
|
-
this.world._unregisterEntity(this);
|
|
292
|
-
if (this._parent) {
|
|
293
|
-
this._parent._children?.delete(this);
|
|
294
|
-
this._parent = undefined;
|
|
295
|
-
}
|
|
296
|
-
}
|
|
297
|
-
/** `true` when the entity has no components attached. */
|
|
298
|
-
get empty() {
|
|
299
|
-
return this.components.size == 0;
|
|
300
|
-
}
|
|
301
|
-
/**
|
|
302
|
-
* Destroy this entity and recursively destroy all of its children.
|
|
381
|
+
* Destroy this entity and recursively destroy its children.
|
|
303
382
|
*
|
|
304
|
-
*
|
|
305
|
-
*
|
|
306
|
-
* entity must not be used
|
|
383
|
+
* Each component fires its `onRemove` hook, the `"destroy"` event is emitted
|
|
384
|
+
* just before teardown, and the entity is unregistered from the world.
|
|
385
|
+
* After destruction the entity must not be used.
|
|
307
386
|
*/
|
|
308
387
|
destroy() {
|
|
309
388
|
if (this.world.deferred) {
|
|
@@ -319,19 +398,11 @@ export class Entity {
|
|
|
319
398
|
this._children.clear();
|
|
320
399
|
}
|
|
321
400
|
}
|
|
322
|
-
/**
|
|
323
|
-
* Iterate over every component currently attached to this entity.
|
|
324
|
-
*
|
|
325
|
-
* @param callback - Called with each component instance. Iteration order is
|
|
326
|
-
* not guaranteed.
|
|
327
|
-
*/
|
|
328
|
-
forEachComponent(callback) {
|
|
329
|
-
this.components.forEach(callback);
|
|
330
|
-
}
|
|
331
401
|
/** Returns `"EntityN"` where N is the entity id. */
|
|
332
402
|
toString() {
|
|
333
403
|
return `Entity${this.eid}`;
|
|
334
404
|
}
|
|
335
405
|
}
|
|
406
|
+
/** @internal Empty children set used as the default `children` value. */
|
|
336
407
|
Entity._emptyChildren = new Set();
|
|
337
408
|
//# sourceMappingURL=entity.js.map
|
package/dist/entity.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"entity.js","sourceRoot":"","sources":["../src/entity.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,QAAQ,
|
|
1
|
+
{"version":3,"file":"entity.js","sourceRoot":"","sources":["../src/entity.ts"],"names":[],"mappings":"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"}
|