@codehz/ecs 0.10.0 → 0.10.2
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/dist/builder.d.mts +122 -79
- package/dist/world.mjs +20 -6
- package/dist/world.mjs.map +1 -1
- package/package.json +1 -1
- package/src/__tests__/component/singleton.test.ts +50 -5
- package/src/world/operations.ts +15 -3
- package/src/world/singleton.ts +3 -2
- package/src/world/world.ts +129 -78
package/package.json
CHANGED
|
@@ -3,6 +3,8 @@ import { ComponentEntityStore } from "../../component/entity-store";
|
|
|
3
3
|
import { component, createEntityId, relation, type EntityId } from "../../entity";
|
|
4
4
|
import { World } from "../../world/world";
|
|
5
5
|
|
|
6
|
+
function expectType<T>(_value: T): void {}
|
|
7
|
+
|
|
6
8
|
describe("World - Singleton Component", () => {
|
|
7
9
|
type GlobalConfig = { debug: boolean; version: string };
|
|
8
10
|
type GameState = { score: number; level: number };
|
|
@@ -26,21 +28,64 @@ describe("World - Singleton Component", () => {
|
|
|
26
28
|
const world = new World();
|
|
27
29
|
const singleton = world.singleton(GlobalConfigId);
|
|
28
30
|
const Marker = component<void>();
|
|
31
|
+
const originalWarn = console.warn;
|
|
32
|
+
const warnings: string[] = [];
|
|
33
|
+
|
|
34
|
+
console.warn = (...args: unknown[]) => {
|
|
35
|
+
warnings.push(args.join(" "));
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
try {
|
|
39
|
+
world.set(GlobalConfigId, Marker);
|
|
40
|
+
} finally {
|
|
41
|
+
console.warn = originalWarn;
|
|
42
|
+
}
|
|
29
43
|
|
|
30
|
-
world.set(GlobalConfigId, Marker);
|
|
31
44
|
world.sync();
|
|
32
45
|
|
|
33
46
|
expect(world.has(GlobalConfigId, Marker)).toBe(true);
|
|
34
47
|
expect(singleton.has()).toBe(false);
|
|
48
|
+
expect(warnings).toHaveLength(0);
|
|
35
49
|
});
|
|
36
50
|
|
|
37
|
-
it("should
|
|
51
|
+
it("should support the deprecated singleton data shorthand for non-number values", () => {
|
|
38
52
|
const world = new World();
|
|
39
53
|
const config: GlobalConfig = { debug: true, version: "1.0.0" };
|
|
54
|
+
const originalWarn = console.warn;
|
|
55
|
+
const warnings: string[] = [];
|
|
40
56
|
|
|
41
|
-
|
|
42
|
-
world.set(GlobalConfigId
|
|
43
|
-
}
|
|
57
|
+
if (false) {
|
|
58
|
+
expectType<void>(world.set(GlobalConfigId, config));
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
console.warn = (...args: unknown[]) => {
|
|
62
|
+
warnings.push(args.join(" "));
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
try {
|
|
66
|
+
world.set(GlobalConfigId, config);
|
|
67
|
+
} finally {
|
|
68
|
+
console.warn = originalWarn;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
world.sync();
|
|
72
|
+
|
|
73
|
+
expect(world.get(GlobalConfigId)).toEqual(config);
|
|
74
|
+
expect(warnings).toHaveLength(1);
|
|
75
|
+
expect(warnings[0]).toContain("deprecated");
|
|
76
|
+
expect(warnings[0]).toContain("world.singleton(componentId).set(value)");
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
it("should not expose the deprecated shorthand for numeric singleton types at the type level", () => {
|
|
80
|
+
const world = new World();
|
|
81
|
+
const Score = component<number>();
|
|
82
|
+
|
|
83
|
+
if (false) {
|
|
84
|
+
// @ts-expect-error Numeric singleton shorthand is intentionally unsupported.
|
|
85
|
+
expectType<void>(world.set(Score, 123));
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
expect(true).toBe(true);
|
|
44
89
|
});
|
|
45
90
|
|
|
46
91
|
it("should manage singleton data through an explicit handle", () => {
|
package/src/world/operations.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { ComponentId, EntityId } from "../entity";
|
|
2
|
-
import { getDetailedIdType } from "../entity";
|
|
2
|
+
import { getDetailedIdType, isComponentId } from "../entity";
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* Validation and overload-resolution helpers extracted from World.
|
|
@@ -51,14 +51,26 @@ export function resolveSetOperation(
|
|
|
51
51
|
entityId: EntityId | ComponentId,
|
|
52
52
|
componentTypeOrComponent?: EntityId | any,
|
|
53
53
|
maybeComponent?: any,
|
|
54
|
+
argCount = 3,
|
|
54
55
|
exists: (id: EntityId) => boolean = () => true, // default permissive for tests / internal
|
|
55
|
-
): { entityId: EntityId; componentType: EntityId; component: any } {
|
|
56
|
+
): { entityId: EntityId; componentType: EntityId; component: any; deprecatedSingletonShorthand: boolean } {
|
|
56
57
|
const targetEntityId = entityId as EntityId;
|
|
58
|
+
|
|
59
|
+
if (argCount === 2 && isComponentId(targetEntityId) && typeof componentTypeOrComponent !== "number") {
|
|
60
|
+
assertEntityExists(targetEntityId, "Component entity", exists);
|
|
61
|
+
return {
|
|
62
|
+
entityId: targetEntityId,
|
|
63
|
+
componentType: targetEntityId,
|
|
64
|
+
component: componentTypeOrComponent,
|
|
65
|
+
deprecatedSingletonShorthand: true,
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
|
|
57
69
|
const componentType = componentTypeOrComponent as EntityId;
|
|
58
70
|
assertEntityExists(targetEntityId, "Entity", exists);
|
|
59
71
|
assertSetComponentTypeValid(componentType);
|
|
60
72
|
|
|
61
|
-
return { entityId: targetEntityId, componentType, component: maybeComponent };
|
|
73
|
+
return { entityId: targetEntityId, componentType, component: maybeComponent, deprecatedSingletonShorthand: false };
|
|
62
74
|
}
|
|
63
75
|
|
|
64
76
|
/**
|
package/src/world/singleton.ts
CHANGED
|
@@ -11,8 +11,9 @@ export interface SingletonHandleOps<T> {
|
|
|
11
11
|
/**
|
|
12
12
|
* Explicit handle for a singleton component (component-as-entity).
|
|
13
13
|
*
|
|
14
|
-
* This
|
|
15
|
-
*
|
|
14
|
+
* This is the preferred API for singleton components.
|
|
15
|
+
* `world.set(componentId, value)` remains available only as a deprecated
|
|
16
|
+
* compatibility shorthand.
|
|
16
17
|
*
|
|
17
18
|
* @example
|
|
18
19
|
* const config = world.singleton(Config);
|
package/src/world/world.ts
CHANGED
|
@@ -52,6 +52,9 @@ import { SingletonHandle } from "./singleton";
|
|
|
52
52
|
* Manages entities and components
|
|
53
53
|
*/
|
|
54
54
|
export class World {
|
|
55
|
+
private static readonly DEPRECATED_SINGLETON_SET_SHORTHAND_WARNING =
|
|
56
|
+
"world.set(componentId, value) for singleton components is deprecated; use world.singleton(componentId).set(value) or world.set(componentId, componentId, value) instead.";
|
|
57
|
+
|
|
55
58
|
// Core data structures for entity and archetype management
|
|
56
59
|
private entityIdManager = new EntityIdManager();
|
|
57
60
|
private entityReferences: EntityReferencesMap = new Map();
|
|
@@ -270,46 +273,59 @@ export class World {
|
|
|
270
273
|
}
|
|
271
274
|
|
|
272
275
|
/**
|
|
273
|
-
*
|
|
276
|
+
* Marks a void component as present on an entity.
|
|
274
277
|
* The change is buffered and takes effect after calling `world.sync()`.
|
|
275
|
-
* If the entity does not exist, throws an error.
|
|
276
278
|
*
|
|
277
|
-
* @
|
|
278
|
-
*
|
|
279
|
+
* @throws {Error} If the entity does not exist
|
|
280
|
+
* @throws {Error} If the component type is invalid or is a wildcard relation
|
|
281
|
+
*
|
|
282
|
+
* @example
|
|
283
|
+
* world.set(entity, Marker);
|
|
284
|
+
* world.sync();
|
|
285
|
+
*/
|
|
286
|
+
set(entityId: EntityId, componentType: EntityId<void>): void;
|
|
287
|
+
/**
|
|
288
|
+
* @deprecated Use `world.singleton(componentId).set(value)` or `world.set(componentId, componentId, value)` instead.
|
|
289
|
+
* Compatibility shorthand for singleton component data when the second argument is not a number.
|
|
279
290
|
*
|
|
280
|
-
* @
|
|
281
|
-
*
|
|
291
|
+
* @throws {Error} If the component entity does not exist
|
|
292
|
+
*
|
|
293
|
+
* @example
|
|
294
|
+
* world.set(GlobalConfig, { debug: true });
|
|
295
|
+
* world.sync();
|
|
296
|
+
*/
|
|
297
|
+
set<T>(componentId: ComponentId<T>, component: Exclude<NoInfer<T>, number>): void;
|
|
298
|
+
/**
|
|
299
|
+
* Adds or updates component data on an entity.
|
|
300
|
+
* The change is buffered and takes effect after calling `world.sync()`.
|
|
282
301
|
*
|
|
283
302
|
* @throws {Error} If the entity does not exist
|
|
284
303
|
* @throws {Error} If the component type is invalid or is a wildcard relation
|
|
285
304
|
*
|
|
286
305
|
* @example
|
|
287
306
|
* world.set(entity, Position, { x: 10, y: 20 });
|
|
288
|
-
* world.
|
|
289
|
-
* world.singleton(GlobalConfig).set({ debug: true }); // singleton component
|
|
290
|
-
* world.sync(); // Apply changes
|
|
307
|
+
* world.sync();
|
|
291
308
|
*/
|
|
292
|
-
set(entityId: EntityId, componentType: EntityId<void>): void;
|
|
293
309
|
set<T>(entityId: EntityId, componentType: EntityId<T>, component: NoInfer<T>): void;
|
|
310
|
+
/** Internal implementation for `set()` overloads. */
|
|
294
311
|
set(entityId: EntityId | ComponentId, componentTypeOrComponent?: EntityId | any, maybeComponent?: any): void {
|
|
295
312
|
const {
|
|
296
313
|
entityId: targetEntityId,
|
|
297
314
|
componentType,
|
|
298
315
|
component,
|
|
299
|
-
|
|
316
|
+
deprecatedSingletonShorthand,
|
|
317
|
+
} = resolveSetOperation(entityId, componentTypeOrComponent, maybeComponent, arguments.length, (id) =>
|
|
318
|
+
this.exists(id),
|
|
319
|
+
);
|
|
320
|
+
if (deprecatedSingletonShorthand) {
|
|
321
|
+
console.warn(World.DEPRECATED_SINGLETON_SET_SHORTHAND_WARNING);
|
|
322
|
+
}
|
|
300
323
|
this.commandBuffer.set(targetEntityId, componentType, component);
|
|
301
324
|
}
|
|
302
325
|
|
|
303
326
|
/**
|
|
304
327
|
* Removes a component from an entity.
|
|
305
328
|
* The change is buffered and takes effect after calling `world.sync()`.
|
|
306
|
-
* If the entity does not exist, throws an error.
|
|
307
|
-
*
|
|
308
|
-
* @overload remove<T>(entityId: EntityId, componentType: EntityId<T>): void
|
|
309
|
-
* Removes a component from an entity.
|
|
310
|
-
*
|
|
311
|
-
* @overload remove<T>(componentId: ComponentId<T>): void
|
|
312
|
-
* Removes a singleton component (shorthand for remove(componentId, componentId)).
|
|
313
329
|
*
|
|
314
330
|
* @template T - The component data type
|
|
315
331
|
* @param entityId - The entity identifier
|
|
@@ -320,11 +336,22 @@ export class World {
|
|
|
320
336
|
*
|
|
321
337
|
* @example
|
|
322
338
|
* world.remove(entity, Position);
|
|
339
|
+
* world.sync(); // Apply changes
|
|
340
|
+
*/
|
|
341
|
+
remove<T>(entityId: EntityId, componentType: EntityId<T>): void;
|
|
342
|
+
/**
|
|
343
|
+
* Removes a singleton component (shorthand for remove(componentId, componentId)).
|
|
344
|
+
* The change is buffered and takes effect after calling `world.sync()`.
|
|
345
|
+
*
|
|
346
|
+
* @template T - The component data type
|
|
347
|
+
*
|
|
348
|
+
* @throws {Error} If the component entity does not exist
|
|
349
|
+
*
|
|
350
|
+
* @example
|
|
323
351
|
* world.remove(GlobalConfig); // Remove singleton component
|
|
324
352
|
* world.sync(); // Apply changes
|
|
325
353
|
*/
|
|
326
354
|
remove<T>(componentId: ComponentId<T>): void;
|
|
327
|
-
remove<T>(entityId: EntityId, componentType: EntityId<T>): void;
|
|
328
355
|
remove<T>(entityId: EntityId | ComponentId, componentType?: EntityId<T>): void {
|
|
329
356
|
const { entityId: targetEntityId, componentType: targetComponentType } = resolveRemoveOperation(
|
|
330
357
|
entityId,
|
|
@@ -384,15 +411,8 @@ export class World {
|
|
|
384
411
|
*
|
|
385
412
|
* Immediately reflects the current state without waiting for `sync()`.
|
|
386
413
|
*
|
|
387
|
-
* @overload has<T>(entityId: EntityId, componentType: EntityId<T>): boolean
|
|
388
|
-
* Checks if a specific component type is present on the entity.
|
|
389
|
-
*
|
|
390
|
-
* @overload has<T>(componentId: ComponentId<T>): boolean
|
|
391
|
-
* Shorthand for checking a **singleton component** — a component that is its own
|
|
392
|
-
* entity (component-as-entity pattern). Equivalent to `has(componentId, componentId)`.
|
|
393
|
-
*
|
|
394
414
|
* @template T - The component data type
|
|
395
|
-
* @param entityId - The entity identifier
|
|
415
|
+
* @param entityId - The entity identifier
|
|
396
416
|
* @param componentType - The component type to check
|
|
397
417
|
* @returns `true` if the entity has the component, `false` otherwise
|
|
398
418
|
*
|
|
@@ -401,17 +421,24 @@ export class World {
|
|
|
401
421
|
* if (world.has(entity, Position)) {
|
|
402
422
|
* const pos = world.get(entity, Position);
|
|
403
423
|
* }
|
|
424
|
+
*/
|
|
425
|
+
has<T>(entityId: EntityId, componentType: EntityId<T>): boolean;
|
|
426
|
+
/**
|
|
427
|
+
* Checks if a **singleton component** (component-as-entity) is present.
|
|
428
|
+
* Equivalent to `has(componentId, componentId)`.
|
|
429
|
+
*
|
|
430
|
+
* Immediately reflects the current state without waiting for `sync()`.
|
|
404
431
|
*
|
|
405
|
-
*
|
|
432
|
+
* @template T - The component data type
|
|
433
|
+
* @param componentId - The singleton component ID
|
|
434
|
+
* @returns `true` if the singleton component exists, `false` otherwise
|
|
435
|
+
*
|
|
436
|
+
* @example
|
|
406
437
|
* if (world.has(GlobalConfig)) {
|
|
407
438
|
* const config = world.get(GlobalConfig);
|
|
408
439
|
* }
|
|
409
|
-
*
|
|
410
|
-
* // Use exists() for entity liveness checks
|
|
411
|
-
* if (world.exists(entity)) { ... }
|
|
412
440
|
*/
|
|
413
441
|
has<T>(componentId: ComponentId<T>): boolean;
|
|
414
|
-
has<T>(entityId: EntityId, componentType: EntityId<T>): boolean;
|
|
415
442
|
has<T>(entityId: EntityId | ComponentId, componentType?: EntityId<T>): boolean {
|
|
416
443
|
// Handle singleton component overload: has(componentId)
|
|
417
444
|
if (componentType === undefined) {
|
|
@@ -445,28 +472,45 @@ export class World {
|
|
|
445
472
|
|
|
446
473
|
/**
|
|
447
474
|
* Retrieves a component from an entity.
|
|
448
|
-
* For wildcard relations, returns all relations of that type.
|
|
449
475
|
* Throws an error if the component does not exist; use `has()` to check first or use `getOptional()`.
|
|
450
476
|
*
|
|
451
|
-
* @
|
|
452
|
-
*
|
|
477
|
+
* @template T - The component data type
|
|
478
|
+
* @param entityId - The entity identifier
|
|
479
|
+
* @param componentType - The component type to retrieve
|
|
453
480
|
*
|
|
454
|
-
* @
|
|
455
|
-
*
|
|
481
|
+
* @throws {Error} If the entity does not exist
|
|
482
|
+
* @throws {Error} If the component does not exist on the entity
|
|
456
483
|
*
|
|
457
|
-
* @
|
|
458
|
-
*
|
|
484
|
+
* @example
|
|
485
|
+
* const position = world.get(entity, Position);
|
|
486
|
+
*/
|
|
487
|
+
get<T>(entityId: EntityId, componentType: EntityId<T>): T;
|
|
488
|
+
/**
|
|
489
|
+
* Retrieves all relations of a given wildcard type for an entity.
|
|
490
|
+
* Returns an array of [target entity, component value] pairs.
|
|
491
|
+
*
|
|
492
|
+
* @template T - The component data type
|
|
493
|
+
* @param entityId - The entity identifier
|
|
494
|
+
* @param componentType - The wildcard relation type
|
|
495
|
+
* @returns Array of [target entity, component value] pairs
|
|
459
496
|
*
|
|
460
497
|
* @throws {Error} If the entity does not exist
|
|
461
|
-
* @throws {Error} If the component does not exist on the entity
|
|
462
498
|
*
|
|
463
499
|
* @example
|
|
464
|
-
* const
|
|
465
|
-
* const relations = world.get(entity, relation(Parent, "*")); // Wildcard relation
|
|
500
|
+
* const relations = world.get(entity, relation(Parent, "*"));
|
|
466
501
|
*/
|
|
467
|
-
get<T>(entityId: EntityId<T>): T;
|
|
468
502
|
get<T>(entityId: EntityId, componentType: WildcardRelationId<T>): [EntityId<unknown>, T][];
|
|
469
|
-
|
|
503
|
+
/**
|
|
504
|
+
* Retrieves the entity's primary component when called with only an entity ID.
|
|
505
|
+
*
|
|
506
|
+
* @template T - The component data type
|
|
507
|
+
* @param entityId - The entity identifier
|
|
508
|
+
* @returns The component value
|
|
509
|
+
*
|
|
510
|
+
* @throws {Error} If the entity does not exist
|
|
511
|
+
* @throws {Error} If the component does not exist on the entity
|
|
512
|
+
*/
|
|
513
|
+
get<T>(entityId: EntityId<T>): T;
|
|
470
514
|
get<T>(
|
|
471
515
|
entityId: EntityId,
|
|
472
516
|
componentType: EntityId<T> | WildcardRelationId<T> = entityId as EntityId<T>,
|
|
@@ -505,17 +549,11 @@ export class World {
|
|
|
505
549
|
/**
|
|
506
550
|
* Safely retrieves a component from an entity without throwing an error.
|
|
507
551
|
* Returns `undefined` if the component does not exist.
|
|
508
|
-
* For wildcard relations, returns `undefined` if there are no relations.
|
|
509
552
|
*
|
|
510
553
|
* @template T - The component data type
|
|
511
|
-
* @
|
|
512
|
-
*
|
|
513
|
-
*
|
|
514
|
-
* @overload getOptional<T>(entityId: EntityId, componentType: WildcardRelationId<T>): { value: [EntityId<unknown>, T][] } | undefined
|
|
515
|
-
* Retrieves all matching relation values safely.
|
|
516
|
-
*
|
|
517
|
-
* @overload getOptional<T>(entityId: EntityId, componentType: EntityId<T>): { value: T } | undefined
|
|
518
|
-
* Retrieves a specific component safely.
|
|
554
|
+
* @param entityId - The entity identifier
|
|
555
|
+
* @param componentType - The component type to retrieve
|
|
556
|
+
* @returns The component value wrapped in `{ value }`, or `undefined` if absent
|
|
519
557
|
*
|
|
520
558
|
* @throws {Error} If the entity does not exist
|
|
521
559
|
*
|
|
@@ -525,12 +563,33 @@ export class World {
|
|
|
525
563
|
* console.log(position.value.x);
|
|
526
564
|
* }
|
|
527
565
|
*/
|
|
528
|
-
getOptional<T>(entityId: EntityId<T>): { value: T } | undefined;
|
|
566
|
+
getOptional<T>(entityId: EntityId, componentType: EntityId<T>): { value: T } | undefined;
|
|
567
|
+
/**
|
|
568
|
+
* Safely retrieves all matching relation values for a wildcard relation type.
|
|
569
|
+
* Returns `undefined` if there are no relations.
|
|
570
|
+
*
|
|
571
|
+
* @template T - The component data type
|
|
572
|
+
* @param entityId - The entity identifier
|
|
573
|
+
* @param componentType - The wildcard relation type
|
|
574
|
+
* @returns Array of [target, value] pairs wrapped in `{ value }`, or `undefined` if none
|
|
575
|
+
*
|
|
576
|
+
* @throws {Error} If the entity does not exist
|
|
577
|
+
*/
|
|
529
578
|
getOptional<T>(
|
|
530
579
|
entityId: EntityId,
|
|
531
580
|
componentType: WildcardRelationId<T>,
|
|
532
581
|
): { value: [EntityId<unknown>, T][] } | undefined;
|
|
533
|
-
|
|
582
|
+
/**
|
|
583
|
+
* Safely retrieves the entity's primary component without throwing an error.
|
|
584
|
+
* Returns `undefined` if the component does not exist.
|
|
585
|
+
*
|
|
586
|
+
* @template T - The component data type
|
|
587
|
+
* @param entityId - The entity identifier
|
|
588
|
+
* @returns The component value wrapped in `{ value }`, or `undefined` if absent
|
|
589
|
+
*
|
|
590
|
+
* @throws {Error} If the entity does not exist
|
|
591
|
+
*/
|
|
592
|
+
getOptional<T>(entityId: EntityId<T>): { value: T } | undefined;
|
|
534
593
|
getOptional<T>(
|
|
535
594
|
entityId: EntityId,
|
|
536
595
|
componentType: EntityId<T> | WildcardRelationId<T> = entityId as EntityId<T>,
|
|
@@ -770,21 +829,15 @@ export class World {
|
|
|
770
829
|
|
|
771
830
|
/**
|
|
772
831
|
* Registers a lifecycle hook that responds to component changes.
|
|
773
|
-
* The hook callback is invoked when components matching the specified types
|
|
774
|
-
*
|
|
775
|
-
* componentTypes: T,
|
|
776
|
-
* hook: LifecycleHook<T> | LifecycleCallback<T>,
|
|
777
|
-
* filter?: QueryFilter,
|
|
778
|
-
* ): () => void
|
|
779
|
-
* Registers a hook for multiple component types.
|
|
780
|
-
* The hook is triggered when entities enter/exit the matching set.
|
|
832
|
+
* The hook callback is invoked when components matching the specified types
|
|
833
|
+
* are added, updated, or removed.
|
|
781
834
|
*
|
|
782
835
|
* @param componentTypes - Component types that define the matching entity set
|
|
783
836
|
* @param hook - Either a hook object with on_init/on_set/on_remove handlers, or a callback function
|
|
784
837
|
* @param filter - Optional query-style filter applied to the hook match set
|
|
785
838
|
* @returns A function that unsubscribes the hook when called
|
|
786
839
|
*
|
|
787
|
-
* @throws {Error} If no required components are specified
|
|
840
|
+
* @throws {Error} If no required components are specified
|
|
788
841
|
*
|
|
789
842
|
* @example
|
|
790
843
|
* const unsubscribe = world.hook([Position, Velocity], {
|
|
@@ -1069,32 +1122,30 @@ export class World {
|
|
|
1069
1122
|
|
|
1070
1123
|
/**
|
|
1071
1124
|
* Queries entities with specific components.
|
|
1072
|
-
* For simpler use cases, prefer using `createQuery()` with `forEach()` which is cached and more efficient.
|
|
1073
|
-
*
|
|
1074
|
-
* @overload query(componentTypes: EntityId<any>[]): EntityId[]
|
|
1075
1125
|
* Returns an array of entity IDs that have all specified components.
|
|
1076
|
-
*
|
|
1077
|
-
* @overload query<const T extends readonly EntityId<any>[]>(
|
|
1078
|
-
* componentTypes: T,
|
|
1079
|
-
* includeComponents: true,
|
|
1080
|
-
* ): Array<{ entity: EntityId; components: ComponentTuple<T> }>
|
|
1081
|
-
* Returns entities along with their component data.
|
|
1126
|
+
* For simpler use cases, prefer using `createQuery()` with `forEach()` which is cached and more efficient.
|
|
1082
1127
|
*
|
|
1083
1128
|
* @param componentTypes - Array of component types to query
|
|
1084
|
-
* @
|
|
1085
|
-
* @returns Array of entity IDs or objects with entities and components
|
|
1129
|
+
* @returns Array of entity IDs matching the query
|
|
1086
1130
|
*
|
|
1087
1131
|
* @example
|
|
1088
|
-
* // Just entity IDs
|
|
1089
1132
|
* const entities = world.query([Position, Velocity]);
|
|
1133
|
+
*/
|
|
1134
|
+
query(componentTypes: EntityId<any>[]): EntityId[];
|
|
1135
|
+
/**
|
|
1136
|
+
* Queries entities with specific components and returns their component data.
|
|
1137
|
+
*
|
|
1138
|
+
* @template T - The tuple of component types
|
|
1139
|
+
* @param componentTypes - Array of component types to query
|
|
1140
|
+
* @param includeComponents - Must be `true` to include component data
|
|
1141
|
+
* @returns Array of objects with entity and component data
|
|
1090
1142
|
*
|
|
1091
|
-
*
|
|
1143
|
+
* @example
|
|
1092
1144
|
* const results = world.query([Position, Velocity], true);
|
|
1093
1145
|
* results.forEach(({ entity, components: [pos, vel] }) => {
|
|
1094
1146
|
* pos.x += vel.x;
|
|
1095
1147
|
* });
|
|
1096
1148
|
*/
|
|
1097
|
-
query(componentTypes: EntityId<any>[]): EntityId[];
|
|
1098
1149
|
query<const T extends readonly EntityId<any>[]>(
|
|
1099
1150
|
componentTypes: T,
|
|
1100
1151
|
includeComponents: true,
|