ecspresso 0.10.2 → 0.11.0
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 +73 -17
- package/dist/asset-manager.d.ts +15 -15
- package/dist/asset-types.d.ts +16 -14
- package/dist/bundle.d.ts +66 -16
- package/dist/bundles/audio.d.ts +293 -0
- package/dist/bundles/{utils/bounds.d.ts → bounds.d.ts} +9 -7
- package/dist/bundles/camera.d.ts +89 -0
- package/dist/bundles/collision.d.ts +289 -0
- package/dist/bundles/diagnostics.d.ts +48 -0
- package/dist/bundles/{utils/input.d.ts → input.d.ts} +16 -17
- package/dist/bundles/physics2D.d.ts +159 -0
- package/dist/bundles/renderers/renderer2D.d.ts +65 -24
- package/dist/bundles/spatial-index.d.ts +57 -0
- package/dist/bundles/state-machine.d.ts +298 -0
- package/dist/bundles/{utils/timers.d.ts → timers.d.ts} +9 -8
- package/dist/bundles/{utils/transform.d.ts → transform.d.ts} +10 -10
- package/dist/bundles/tween.d.ts +197 -0
- package/dist/command-buffer.d.ts +20 -20
- package/dist/ecspresso-builder.d.ts +165 -0
- package/dist/ecspresso.d.ts +157 -178
- package/dist/entity-manager.d.ts +76 -40
- package/dist/event-bus.d.ts +6 -1
- package/dist/index.d.ts +1 -9
- package/dist/reactive-query-manager.d.ts +14 -3
- package/dist/resource-manager.d.ts +35 -19
- package/dist/screen-manager.d.ts +4 -4
- package/dist/screen-types.d.ts +12 -11
- package/dist/src/bundles/audio.js +4 -0
- package/dist/src/bundles/audio.js.map +10 -0
- package/dist/src/bundles/bounds.js +4 -0
- package/dist/src/bundles/bounds.js.map +10 -0
- package/dist/src/bundles/camera.js +4 -0
- package/dist/src/bundles/camera.js.map +10 -0
- package/dist/src/bundles/collision.js +4 -0
- package/dist/src/bundles/collision.js.map +11 -0
- package/dist/src/bundles/diagnostics.js +5 -0
- package/dist/src/bundles/diagnostics.js.map +10 -0
- package/dist/src/bundles/input.js +4 -0
- package/dist/src/bundles/input.js.map +10 -0
- package/dist/src/bundles/physics2D.js +4 -0
- package/dist/src/bundles/physics2D.js.map +11 -0
- package/dist/src/bundles/renderers/renderer2D.js +4 -0
- package/dist/src/bundles/renderers/renderer2D.js.map +10 -0
- package/dist/src/bundles/spatial-index.js +4 -0
- package/dist/src/bundles/spatial-index.js.map +11 -0
- package/dist/src/bundles/state-machine.js +4 -0
- package/dist/src/bundles/state-machine.js.map +10 -0
- package/dist/src/bundles/timers.js +4 -0
- package/dist/src/bundles/timers.js.map +10 -0
- package/dist/src/bundles/transform.js +4 -0
- package/dist/src/bundles/transform.js.map +10 -0
- package/dist/src/bundles/tween.js +4 -0
- package/dist/src/bundles/tween.js.map +11 -0
- package/dist/src/index.js +4 -0
- package/dist/src/index.js.map +25 -0
- package/dist/system-builder.d.ts +36 -42
- package/dist/type-utils.d.ts +52 -3
- package/dist/types.d.ts +10 -19
- package/dist/utils/check-required-cycle.d.ts +12 -0
- package/dist/utils/easing.d.ts +71 -0
- package/dist/utils/math.d.ts +67 -0
- package/dist/utils/narrowphase.d.ts +63 -0
- package/dist/utils/spatial-hash.d.ts +53 -0
- package/package.json +50 -20
- package/dist/bundles/renderers/renderer2D.js +0 -4
- package/dist/bundles/renderers/renderer2D.js.map +0 -10
- package/dist/bundles/utils/bounds.js +0 -4
- package/dist/bundles/utils/bounds.js.map +0 -10
- package/dist/bundles/utils/collision.d.ts +0 -204
- package/dist/bundles/utils/collision.js +0 -4
- package/dist/bundles/utils/collision.js.map +0 -10
- package/dist/bundles/utils/input.js +0 -4
- package/dist/bundles/utils/input.js.map +0 -10
- package/dist/bundles/utils/movement.d.ts +0 -86
- package/dist/bundles/utils/movement.js +0 -4
- package/dist/bundles/utils/movement.js.map +0 -10
- package/dist/bundles/utils/timers.js +0 -4
- package/dist/bundles/utils/timers.js.map +0 -10
- package/dist/bundles/utils/transform.js +0 -4
- package/dist/bundles/utils/transform.js.map +0 -10
- package/dist/index.js +0 -4
- package/dist/index.js.map +0 -22
package/dist/ecspresso.d.ts
CHANGED
|
@@ -1,29 +1,30 @@
|
|
|
1
1
|
import EntityManager from "./entity-manager";
|
|
2
2
|
import EventBus from "./event-bus";
|
|
3
|
+
import { type ResourceFactoryWithDeps } from "./resource-manager";
|
|
3
4
|
import AssetManager from "./asset-manager";
|
|
4
5
|
import ScreenManager from "./screen-manager";
|
|
5
6
|
import { type ReactiveQueryDefinition } from "./reactive-query-manager";
|
|
6
7
|
import CommandBuffer from "./command-buffer";
|
|
7
8
|
import type { System, SystemPhase, FilteredEntity, Entity, RemoveEntityOptions, HierarchyEntry, HierarchyIteratorOptions } from "./types";
|
|
8
9
|
import type Bundle from "./bundle";
|
|
9
|
-
import type {
|
|
10
|
-
import type {
|
|
11
|
-
import
|
|
10
|
+
import type { AssetHandle } from "./asset-types";
|
|
11
|
+
import type { ScreenDefinition } from "./screen-types";
|
|
12
|
+
import { ECSpressoBuilder } from "./ecspresso-builder";
|
|
12
13
|
/**
|
|
13
14
|
* Interface declaration for ECSpresso constructor to ensure type augmentation works properly.
|
|
14
15
|
* This merges with the class declaration below.
|
|
15
16
|
*/
|
|
16
|
-
export default interface ECSpresso<ComponentTypes extends Record<string, any> = {}, EventTypes extends Record<string, any> = {}, ResourceTypes extends Record<string, any> = {}, AssetTypes extends Record<string, unknown> = {}, ScreenStates extends Record<string, ScreenDefinition<any, any>> = {}> {
|
|
17
|
+
export default interface ECSpresso<ComponentTypes extends Record<string, any> = {}, EventTypes extends Record<string, any> = {}, ResourceTypes extends Record<string, any> = {}, AssetTypes extends Record<string, unknown> = {}, ScreenStates extends Record<string, ScreenDefinition<any, any>> = {}, Labels extends string = string, Groups extends string = string, AssetGroupNames extends string = string, ReactiveQueryNames extends string = string> {
|
|
17
18
|
/**
|
|
18
19
|
* Default constructor
|
|
19
20
|
*/
|
|
20
|
-
new (): ECSpresso<ComponentTypes, EventTypes, ResourceTypes, AssetTypes, ScreenStates>;
|
|
21
|
+
new (): ECSpresso<ComponentTypes, EventTypes, ResourceTypes, AssetTypes, ScreenStates, Labels, Groups, AssetGroupNames, ReactiveQueryNames>;
|
|
21
22
|
}
|
|
22
23
|
/**
|
|
23
24
|
* ECSpresso is the central ECS framework class that connects all features.
|
|
24
25
|
* It handles creation and management of entities, components, and systems, and provides lifecycle hooks.
|
|
25
26
|
*/
|
|
26
|
-
export default class ECSpresso<ComponentTypes extends Record<string, any> = {}, EventTypes extends Record<string, any> = {}, ResourceTypes extends Record<string, any> = {}, AssetTypes extends Record<string, unknown> = {}, ScreenStates extends Record<string, ScreenDefinition<any, any>> = {}> {
|
|
27
|
+
export default class ECSpresso<ComponentTypes extends Record<string, any> = {}, EventTypes extends Record<string, any> = {}, ResourceTypes extends Record<string, any> = {}, AssetTypes extends Record<string, unknown> = {}, ScreenStates extends Record<string, ScreenDefinition<any, any>> = {}, Labels extends string = string, Groups extends string = string, AssetGroupNames extends string = string, ReactiveQueryNames extends string = string> {
|
|
27
28
|
/** Library version*/
|
|
28
29
|
static readonly VERSION: string;
|
|
29
30
|
/** Access/modify stored components and entities*/
|
|
@@ -64,36 +65,57 @@ export default class ECSpresso<ComponentTypes extends Record<string, any> = {},
|
|
|
64
65
|
private _interpolationAlpha;
|
|
65
66
|
/** Maximum fixed update steps per frame (spiral-of-death protection) */
|
|
66
67
|
private _maxFixedSteps;
|
|
68
|
+
/** Registry of required component relationships: trigger -> [{component, factory}] */
|
|
69
|
+
private _requiredComponents;
|
|
70
|
+
/** Pending bundle assets awaiting manager creation at build time */
|
|
71
|
+
private _pendingBundleAssets;
|
|
72
|
+
/** Pending bundle screens awaiting manager creation at build time */
|
|
73
|
+
private _pendingBundleScreens;
|
|
74
|
+
/** Whether diagnostics timing collection is enabled */
|
|
75
|
+
private _diagnosticsEnabled;
|
|
76
|
+
/** Per-system timing in ms, populated when diagnostics enabled */
|
|
77
|
+
private _systemTimings;
|
|
78
|
+
/** Per-phase timing in ms, populated when diagnostics enabled */
|
|
79
|
+
private _phaseTimings;
|
|
67
80
|
/**
|
|
68
81
|
* Creates a new ECSpresso instance.
|
|
69
82
|
*/
|
|
70
83
|
constructor();
|
|
71
84
|
/**
|
|
72
|
-
*
|
|
85
|
+
* Subscribes to EntityManager lifecycle hooks for change detection,
|
|
86
|
+
* required component auto-addition, and reactive query tracking.
|
|
73
87
|
* @private
|
|
74
88
|
*/
|
|
75
|
-
private
|
|
89
|
+
private _subscribeLifecycleHooks;
|
|
76
90
|
/**
|
|
77
91
|
* Creates a new ECSpresso builder for type-safe bundle installation.
|
|
78
92
|
* This is the preferred way to create an ECSpresso instance with bundles.
|
|
93
|
+
* Types are inferred from the builder chain — use `.withBundle()`,
|
|
94
|
+
* `.withComponentTypes<T>()`, `.withEventTypes<T>()`, and `.withResource()`
|
|
95
|
+
* to accumulate types without manual aggregate interfaces.
|
|
79
96
|
*
|
|
80
97
|
* @returns A builder instance for fluent method chaining
|
|
81
98
|
*
|
|
82
99
|
* @example
|
|
83
100
|
* ```typescript
|
|
84
|
-
* const ecs = ECSpresso.create
|
|
85
|
-
* .withBundle(
|
|
86
|
-
* .withBundle(
|
|
101
|
+
* const ecs = ECSpresso.create()
|
|
102
|
+
* .withBundle(createRenderer2DBundle({ ... }))
|
|
103
|
+
* .withBundle(createPhysics2DBundle())
|
|
104
|
+
* .withComponentTypes<{ player: true; enemy: { type: string } }>()
|
|
105
|
+
* .withEventTypes<{ gameStart: true }>()
|
|
106
|
+
* .withResource('score', { value: 0 })
|
|
87
107
|
* .build();
|
|
108
|
+
*
|
|
109
|
+
* type ECS = typeof ecs;
|
|
88
110
|
* ```
|
|
89
111
|
*/
|
|
90
|
-
static create<C extends Record<string, any> = {}, E extends Record<string, any> = {}, R extends Record<string, any> = {}, A extends Record<string, unknown> = {}, S extends Record<string, ScreenDefinition<any, any>> = {}>(): ECSpressoBuilder<C, E, R, A, S>;
|
|
112
|
+
static create<C extends Record<string, any> = {}, E extends Record<string, any> = {}, R extends Record<string, any> = {}, A extends Record<string, unknown> = {}, S extends Record<string, ScreenDefinition<any, any>> = {}>(): ECSpressoBuilder<C, E, R, A, S, never, never, never, never>;
|
|
91
113
|
/**
|
|
92
114
|
* Adds a system directly to this ECSpresso instance
|
|
93
115
|
* @param label Unique name to identify the system
|
|
94
116
|
* @returns A SystemBuilder instance for method chaining
|
|
95
117
|
*/
|
|
96
|
-
addSystem(label: string): import("./system-builder").SystemBuilderWithEcspresso<ComponentTypes, EventTypes, ResourceTypes, {}>;
|
|
118
|
+
addSystem(label: string): import("./system-builder").SystemBuilderWithEcspresso<ComponentTypes, EventTypes, ResourceTypes, AssetTypes, ScreenStates, {}, string, never>;
|
|
97
119
|
/**
|
|
98
120
|
* Update all systems across execution phases.
|
|
99
121
|
* Phases run in order: preUpdate -> fixedUpdate -> update -> postUpdate -> render.
|
|
@@ -106,6 +128,11 @@ export default class ECSpresso<ComponentTypes extends Record<string, any> = {},
|
|
|
106
128
|
* @private
|
|
107
129
|
*/
|
|
108
130
|
private _executePhase;
|
|
131
|
+
/**
|
|
132
|
+
* Execute a non-fixed phase with optional timing, then play back the command buffer.
|
|
133
|
+
* @private
|
|
134
|
+
*/
|
|
135
|
+
private _runPhase;
|
|
109
136
|
/**
|
|
110
137
|
* Initialize all resources and systems
|
|
111
138
|
* This method:
|
|
@@ -141,14 +168,14 @@ export default class ECSpresso<ComponentTypes extends Record<string, any> = {},
|
|
|
141
168
|
* @param priority The new priority value (higher values execute first)
|
|
142
169
|
* @returns true if the system was found and updated, false otherwise
|
|
143
170
|
*/
|
|
144
|
-
updateSystemPriority(label:
|
|
171
|
+
updateSystemPriority(label: Labels, priority: number): boolean;
|
|
145
172
|
/**
|
|
146
173
|
* Move a system to a different execution phase at runtime.
|
|
147
174
|
* @param label The unique label of the system to move
|
|
148
175
|
* @param phase The target phase
|
|
149
176
|
* @returns true if the system was found and updated, false otherwise
|
|
150
177
|
*/
|
|
151
|
-
updateSystemPhase(label:
|
|
178
|
+
updateSystemPhase(label: Labels, phase: SystemPhase): boolean;
|
|
152
179
|
/**
|
|
153
180
|
* The interpolation alpha between fixed update steps.
|
|
154
181
|
* Ranges from 0 to <1, representing how far into the next
|
|
@@ -164,31 +191,31 @@ export default class ECSpresso<ComponentTypes extends Record<string, any> = {},
|
|
|
164
191
|
* Disable a system group. Systems in this group will be skipped during update().
|
|
165
192
|
* @param groupName The name of the group to disable
|
|
166
193
|
*/
|
|
167
|
-
disableSystemGroup(groupName:
|
|
194
|
+
disableSystemGroup(groupName: Groups): void;
|
|
168
195
|
/**
|
|
169
196
|
* Enable a system group. Systems in this group will run during update().
|
|
170
197
|
* @param groupName The name of the group to enable
|
|
171
198
|
*/
|
|
172
|
-
enableSystemGroup(groupName:
|
|
199
|
+
enableSystemGroup(groupName: Groups): void;
|
|
173
200
|
/**
|
|
174
201
|
* Check if a system group is enabled.
|
|
175
202
|
* @param groupName The name of the group to check
|
|
176
203
|
* @returns true if the group is enabled (or doesn't exist), false if disabled
|
|
177
204
|
*/
|
|
178
|
-
isSystemGroupEnabled(groupName:
|
|
205
|
+
isSystemGroupEnabled(groupName: Groups): boolean;
|
|
179
206
|
/**
|
|
180
207
|
* Get all system labels that belong to a specific group.
|
|
181
208
|
* @param groupName The name of the group
|
|
182
209
|
* @returns Array of system labels in the group
|
|
183
210
|
*/
|
|
184
|
-
getSystemsInGroup(groupName:
|
|
211
|
+
getSystemsInGroup(groupName: Groups): string[];
|
|
185
212
|
/**
|
|
186
213
|
* Remove a system by its label
|
|
187
214
|
* Calls the system's onDetach method with this ECSpresso instance if defined
|
|
188
215
|
* @param label The unique label of the system to remove
|
|
189
216
|
* @returns true if the system was found and removed, false otherwise
|
|
190
217
|
*/
|
|
191
|
-
removeSystem(label:
|
|
218
|
+
removeSystem(label: Labels): boolean;
|
|
192
219
|
/**
|
|
193
220
|
* Internal method to register a system with this ECSpresso instance
|
|
194
221
|
* @internal Used by SystemBuilder - replaces direct private property access
|
|
@@ -199,17 +226,36 @@ export default class ECSpresso<ComponentTypes extends Record<string, any> = {},
|
|
|
199
226
|
*/
|
|
200
227
|
hasResource<K extends keyof ResourceTypes>(key: K): boolean;
|
|
201
228
|
/**
|
|
202
|
-
|
|
203
|
-
|
|
229
|
+
* Get a resource by key. Throws if the resource is not found.
|
|
230
|
+
* @param key The resource key
|
|
231
|
+
* @returns The resource value
|
|
232
|
+
* @throws Error if resource not found
|
|
233
|
+
* @see tryGetResource — the non-throwing alternative that returns undefined
|
|
234
|
+
*/
|
|
204
235
|
getResource<K extends keyof ResourceTypes>(key: K): ResourceTypes[K];
|
|
236
|
+
/**
|
|
237
|
+
* Try to get a resource by key. Returns undefined if the resource is not found.
|
|
238
|
+
* Inspired by Bevy's `World::get_resource::<T>()` which returns `Option<&T>`.
|
|
239
|
+
*
|
|
240
|
+
* Two overloads:
|
|
241
|
+
* 1. Known key — full type safety from `ResourceTypes`
|
|
242
|
+
* 2. String key with explicit type param — for cross-bundle optional dependencies
|
|
243
|
+
*
|
|
244
|
+
* @example
|
|
245
|
+
* ```typescript
|
|
246
|
+
* // Known key (type inferred from ResourceTypes)
|
|
247
|
+
* const score = ecs.tryGetResource('score'); // ScoreResource | undefined
|
|
248
|
+
*
|
|
249
|
+
* // Cross-bundle optional dependency (caller specifies expected type)
|
|
250
|
+
* const si = ecs.tryGetResource<SpatialIndex>('spatialIndex') ?? null;
|
|
251
|
+
* ```
|
|
252
|
+
*/
|
|
253
|
+
tryGetResource<K extends keyof ResourceTypes>(key: K): ResourceTypes[K] | undefined;
|
|
254
|
+
tryGetResource<T>(key: unknown extends T ? never : string): T | undefined;
|
|
205
255
|
/**
|
|
206
256
|
* Add a resource to the ECS instance
|
|
207
257
|
*/
|
|
208
|
-
addResource<K extends keyof ResourceTypes>(key: K, resource: ResourceTypes[K] | ((ecs: ECSpresso<ComponentTypes, EventTypes, ResourceTypes>) => ResourceTypes[K] | Promise<ResourceTypes[K]>) |
|
|
209
|
-
dependsOn?: readonly string[];
|
|
210
|
-
factory: (ecs: ECSpresso<ComponentTypes, EventTypes, ResourceTypes>) => ResourceTypes[K] | Promise<ResourceTypes[K]>;
|
|
211
|
-
onDispose?: (resource: ResourceTypes[K], ecs?: ECSpresso<ComponentTypes, EventTypes, ResourceTypes>) => void | Promise<void>;
|
|
212
|
-
}): this;
|
|
258
|
+
addResource<K extends keyof ResourceTypes>(key: K, resource: ResourceTypes[K] | ((ecs: ECSpresso<ComponentTypes, EventTypes, ResourceTypes, AssetTypes, ScreenStates>) => ResourceTypes[K] | Promise<ResourceTypes[K]>) | ResourceFactoryWithDeps<ResourceTypes[K], ECSpresso<ComponentTypes, EventTypes, ResourceTypes, AssetTypes, ScreenStates>, keyof ResourceTypes & string>): this;
|
|
213
259
|
/**
|
|
214
260
|
* Remove a resource from the ECS instance (without calling onDispose)
|
|
215
261
|
* @param key The resource key to remove
|
|
@@ -258,7 +304,7 @@ export default class ECSpresso<ComponentTypes extends Record<string, any> = {},
|
|
|
258
304
|
*/
|
|
259
305
|
spawn<T extends {
|
|
260
306
|
[K in keyof ComponentTypes]?: ComponentTypes[K];
|
|
261
|
-
}>(components: T & Record<Exclude<keyof T, keyof ComponentTypes>, never>): FilteredEntity<ComponentTypes, keyof T & keyof ComponentTypes
|
|
307
|
+
}>(components: T & Record<Exclude<keyof T, keyof ComponentTypes>, never>): FilteredEntity<ComponentTypes, keyof T & keyof ComponentTypes>;
|
|
262
308
|
/**
|
|
263
309
|
* Get all entities with specific components
|
|
264
310
|
*/
|
|
@@ -289,89 +335,89 @@ export default class ECSpresso<ComponentTypes extends Record<string, any> = {},
|
|
|
289
335
|
removeEntity(entityOrId: number | Entity<ComponentTypes>, options?: RemoveEntityOptions): boolean;
|
|
290
336
|
/**
|
|
291
337
|
* Create an entity as a child of another entity with initial components
|
|
292
|
-
* @param
|
|
338
|
+
* @param parentOrId The parent entity or entity ID
|
|
293
339
|
* @param components Initial components to add
|
|
294
340
|
* @returns The created child entity
|
|
295
341
|
*/
|
|
296
342
|
spawnChild<T extends {
|
|
297
343
|
[K in keyof ComponentTypes]?: ComponentTypes[K];
|
|
298
|
-
}>(
|
|
344
|
+
}>(parentOrId: number | Entity<ComponentTypes>, components: T & Record<Exclude<keyof T, keyof ComponentTypes>, never>): FilteredEntity<ComponentTypes, keyof T & keyof ComponentTypes>;
|
|
299
345
|
/**
|
|
300
346
|
* Set the parent of an entity
|
|
301
|
-
* @param
|
|
302
|
-
* @param
|
|
347
|
+
* @param childOrId The entity or entity ID to set as a child
|
|
348
|
+
* @param parentOrId The entity or entity ID to set as the parent
|
|
303
349
|
*/
|
|
304
|
-
setParent(
|
|
350
|
+
setParent(childOrId: number | Entity<ComponentTypes>, parentOrId: number | Entity<ComponentTypes>): this;
|
|
305
351
|
/**
|
|
306
352
|
* Remove the parent relationship for an entity (orphan it)
|
|
307
|
-
* @param
|
|
353
|
+
* @param childOrId The entity or entity ID to orphan
|
|
308
354
|
* @returns true if a parent was removed, false if entity had no parent
|
|
309
355
|
*/
|
|
310
|
-
removeParent(
|
|
356
|
+
removeParent(childOrId: number | Entity<ComponentTypes>): boolean;
|
|
311
357
|
/**
|
|
312
358
|
* Get the parent of an entity
|
|
313
|
-
* @param
|
|
359
|
+
* @param entityOrId The entity or entity ID to get the parent of
|
|
314
360
|
* @returns The parent entity ID, or null if no parent
|
|
315
361
|
*/
|
|
316
|
-
getParent(
|
|
362
|
+
getParent(entityOrId: number | Entity<ComponentTypes>): number | null;
|
|
317
363
|
/**
|
|
318
364
|
* Get all children of an entity in insertion order
|
|
319
|
-
* @param
|
|
365
|
+
* @param parentOrId The parent entity or entity ID
|
|
320
366
|
* @returns Readonly array of child entity IDs
|
|
321
367
|
*/
|
|
322
|
-
getChildren(
|
|
368
|
+
getChildren(parentOrId: number | Entity<ComponentTypes>): readonly number[];
|
|
323
369
|
/**
|
|
324
370
|
* Get a child at a specific index
|
|
325
|
-
* @param
|
|
371
|
+
* @param parentOrId The parent entity or entity ID
|
|
326
372
|
* @param index The index of the child
|
|
327
373
|
* @returns The child entity ID, or null if index is out of bounds
|
|
328
374
|
*/
|
|
329
|
-
getChildAt(
|
|
375
|
+
getChildAt(parentOrId: number | Entity<ComponentTypes>, index: number): number | null;
|
|
330
376
|
/**
|
|
331
377
|
* Get the index of a child within its parent's children list
|
|
332
|
-
* @param
|
|
333
|
-
* @param
|
|
378
|
+
* @param parentOrId The parent entity or entity ID
|
|
379
|
+
* @param childOrId The child entity or entity ID to find
|
|
334
380
|
* @returns The index of the child, or -1 if not found
|
|
335
381
|
*/
|
|
336
|
-
getChildIndex(
|
|
382
|
+
getChildIndex(parentOrId: number | Entity<ComponentTypes>, childOrId: number | Entity<ComponentTypes>): number;
|
|
337
383
|
/**
|
|
338
384
|
* Get all ancestors of an entity in order [parent, grandparent, ...]
|
|
339
|
-
* @param
|
|
385
|
+
* @param entityOrId The entity or entity ID to get ancestors of
|
|
340
386
|
* @returns Readonly array of ancestor entity IDs
|
|
341
387
|
*/
|
|
342
|
-
getAncestors(
|
|
388
|
+
getAncestors(entityOrId: number | Entity<ComponentTypes>): readonly number[];
|
|
343
389
|
/**
|
|
344
390
|
* Get all descendants of an entity in depth-first order
|
|
345
|
-
* @param
|
|
391
|
+
* @param entityOrId The entity or entity ID to get descendants of
|
|
346
392
|
* @returns Readonly array of descendant entity IDs
|
|
347
393
|
*/
|
|
348
|
-
getDescendants(
|
|
394
|
+
getDescendants(entityOrId: number | Entity<ComponentTypes>): readonly number[];
|
|
349
395
|
/**
|
|
350
396
|
* Get the root ancestor of an entity (topmost parent), or self if no parent
|
|
351
|
-
* @param
|
|
397
|
+
* @param entityOrId The entity or entity ID to get the root of
|
|
352
398
|
* @returns The root entity ID
|
|
353
399
|
*/
|
|
354
|
-
getRoot(
|
|
400
|
+
getRoot(entityOrId: number | Entity<ComponentTypes>): number;
|
|
355
401
|
/**
|
|
356
402
|
* Get siblings of an entity (other children of the same parent)
|
|
357
|
-
* @param
|
|
403
|
+
* @param entityOrId The entity or entity ID to get siblings of
|
|
358
404
|
* @returns Readonly array of sibling entity IDs
|
|
359
405
|
*/
|
|
360
|
-
getSiblings(
|
|
406
|
+
getSiblings(entityOrId: number | Entity<ComponentTypes>): readonly number[];
|
|
361
407
|
/**
|
|
362
408
|
* Check if an entity is a descendant of another entity
|
|
363
|
-
* @param
|
|
364
|
-
* @param
|
|
365
|
-
* @returns true if
|
|
409
|
+
* @param entityOrId The potential descendant (entity or ID)
|
|
410
|
+
* @param ancestorOrId The potential ancestor (entity or ID)
|
|
411
|
+
* @returns true if entityOrId is a descendant of ancestorOrId
|
|
366
412
|
*/
|
|
367
|
-
isDescendantOf(
|
|
413
|
+
isDescendantOf(entityOrId: number | Entity<ComponentTypes>, ancestorOrId: number | Entity<ComponentTypes>): boolean;
|
|
368
414
|
/**
|
|
369
415
|
* Check if an entity is an ancestor of another entity
|
|
370
|
-
* @param
|
|
371
|
-
* @param
|
|
372
|
-
* @returns true if
|
|
416
|
+
* @param entityOrId The potential ancestor (entity or ID)
|
|
417
|
+
* @param descendantOrId The potential descendant (entity or ID)
|
|
418
|
+
* @returns true if entityOrId is an ancestor of descendantOrId
|
|
373
419
|
*/
|
|
374
|
-
isAncestorOf(
|
|
420
|
+
isAncestorOf(entityOrId: number | Entity<ComponentTypes>, descendantOrId: number | Entity<ComponentTypes>): boolean;
|
|
375
421
|
/**
|
|
376
422
|
* Get all root entities (entities that have children but no parent)
|
|
377
423
|
* @returns Readonly array of root entity IDs
|
|
@@ -413,7 +459,7 @@ export default class ECSpresso<ComponentTypes extends Record<string, any> = {},
|
|
|
413
459
|
* ecs.commands.spawn({ position: { x: 0, y: 0 } });
|
|
414
460
|
* ```
|
|
415
461
|
*/
|
|
416
|
-
get commands(): CommandBuffer<ComponentTypes, EventTypes, ResourceTypes>;
|
|
462
|
+
get commands(): CommandBuffer<ComponentTypes, EventTypes, ResourceTypes, AssetTypes, ScreenStates>;
|
|
417
463
|
/**
|
|
418
464
|
* The current tick number, incremented at the end of each update()
|
|
419
465
|
*/
|
|
@@ -425,14 +471,47 @@ export default class ECSpresso<ComponentTypes extends Record<string, any> = {},
|
|
|
425
471
|
* Manual change detection should compare: getChangeSeq(...) > changeThreshold
|
|
426
472
|
*/
|
|
427
473
|
get changeThreshold(): number;
|
|
474
|
+
/**
|
|
475
|
+
* Toggle diagnostics timing collection. When enabled, system and phase
|
|
476
|
+
* timings are recorded each frame. When disabled, timing maps are cleared
|
|
477
|
+
* and no overhead is incurred.
|
|
478
|
+
*/
|
|
479
|
+
enableDiagnostics(enabled: boolean): void;
|
|
480
|
+
get diagnosticsEnabled(): boolean;
|
|
481
|
+
get systemTimings(): ReadonlyMap<string, number>;
|
|
482
|
+
get phaseTimings(): Readonly<Record<SystemPhase, number>>;
|
|
483
|
+
get entityCount(): number;
|
|
428
484
|
/**
|
|
429
485
|
* Mark a component as changed on an entity.
|
|
430
486
|
* Each call increments a global monotonic sequence; systems with changed
|
|
431
487
|
* queries will see the mark exactly once (on their next execution).
|
|
432
|
-
* @param
|
|
488
|
+
* @param entityOrId The entity or entity ID
|
|
433
489
|
* @param componentName The component that was changed
|
|
434
490
|
*/
|
|
435
|
-
markChanged<K extends keyof ComponentTypes>(
|
|
491
|
+
markChanged<K extends keyof ComponentTypes>(entityOrId: number | Entity<ComponentTypes>, componentName: K): void;
|
|
492
|
+
/**
|
|
493
|
+
* Register a dispose callback for a component type.
|
|
494
|
+
* Called when a component is removed (explicit removal, entity destruction, or replacement).
|
|
495
|
+
* Later registrations replace earlier ones for the same component type.
|
|
496
|
+
* @param componentName The component type to register disposal for
|
|
497
|
+
* @param callback Function receiving the component value being disposed
|
|
498
|
+
*/
|
|
499
|
+
registerDispose<K extends keyof ComponentTypes>(componentName: K, callback: (value: ComponentTypes[K]) => void): void;
|
|
500
|
+
/**
|
|
501
|
+
* Register a required component relationship.
|
|
502
|
+
* When an entity gains `trigger`, the `required` component is auto-added
|
|
503
|
+
* (using `factory` for the default value) if not already present.
|
|
504
|
+
* Enforced at insertion time (spawn/addComponent) only — removal is unrestricted.
|
|
505
|
+
* @param trigger The component whose presence triggers auto-addition
|
|
506
|
+
* @param required The component to auto-add
|
|
507
|
+
* @param factory Function that creates the default value for the required component
|
|
508
|
+
*/
|
|
509
|
+
registerRequired<Trigger extends keyof ComponentTypes, Required extends keyof ComponentTypes>(trigger: Trigger, required: Required, factory: (triggerValue: ComponentTypes[Trigger]) => ComponentTypes[Required]): void;
|
|
510
|
+
/**
|
|
511
|
+
* Check for circular dependencies in the required components graph.
|
|
512
|
+
* @throws Error if adding trigger→newRequired would create a cycle
|
|
513
|
+
*/
|
|
514
|
+
private _checkRequiredCycle;
|
|
436
515
|
/**
|
|
437
516
|
* Register a callback when a specific component is added to any entity
|
|
438
517
|
* @param componentName The component key
|
|
@@ -452,13 +531,13 @@ export default class ECSpresso<ComponentTypes extends Record<string, any> = {},
|
|
|
452
531
|
* @param name Unique name for the query
|
|
453
532
|
* @param definition Query definition with with/without arrays and onEnter/onExit callbacks
|
|
454
533
|
*/
|
|
455
|
-
addReactiveQuery<WithComponents extends keyof ComponentTypes, WithoutComponents extends keyof ComponentTypes = never, OptionalComponents extends keyof ComponentTypes = never>(name:
|
|
534
|
+
addReactiveQuery<WithComponents extends keyof ComponentTypes, WithoutComponents extends keyof ComponentTypes = never, OptionalComponents extends keyof ComponentTypes = never>(name: ReactiveQueryNames, definition: ReactiveQueryDefinition<ComponentTypes, WithComponents, WithoutComponents, OptionalComponents>): void;
|
|
456
535
|
/**
|
|
457
536
|
* Remove a reactive query by name.
|
|
458
537
|
* @param name Name of the query to remove
|
|
459
538
|
* @returns true if the query existed and was removed, false otherwise
|
|
460
539
|
*/
|
|
461
|
-
removeReactiveQuery(name:
|
|
540
|
+
removeReactiveQuery(name: ReactiveQueryNames): boolean;
|
|
462
541
|
/**
|
|
463
542
|
* Subscribe to an event (convenience wrapper for eventBus.subscribe)
|
|
464
543
|
* @param eventType The event type to subscribe to
|
|
@@ -478,7 +557,8 @@ export default class ECSpresso<ComponentTypes extends Record<string, any> = {},
|
|
|
478
557
|
* @param callback The hook to call after all systems have processed
|
|
479
558
|
* @returns An unsubscribe function to remove the hook
|
|
480
559
|
*/
|
|
481
|
-
onPostUpdate(callback: (ecs: ECSpresso<ComponentTypes, EventTypes, ResourceTypes>, deltaTime: number) => void): () => void;
|
|
560
|
+
onPostUpdate(callback: (ecs: ECSpresso<ComponentTypes, EventTypes, ResourceTypes, AssetTypes, ScreenStates>, deltaTime: number) => void): () => void;
|
|
561
|
+
private requireAssetManager;
|
|
482
562
|
/**
|
|
483
563
|
* Get a loaded asset by key. Throws if not loaded.
|
|
484
564
|
*/
|
|
@@ -502,15 +582,16 @@ export default class ECSpresso<ComponentTypes extends Record<string, any> = {},
|
|
|
502
582
|
/**
|
|
503
583
|
* Load all assets in a group
|
|
504
584
|
*/
|
|
505
|
-
loadAssetGroup(groupName:
|
|
585
|
+
loadAssetGroup(groupName: AssetGroupNames): Promise<void>;
|
|
506
586
|
/**
|
|
507
587
|
* Check if all assets in a group are loaded
|
|
508
588
|
*/
|
|
509
|
-
isAssetGroupLoaded(groupName:
|
|
589
|
+
isAssetGroupLoaded(groupName: AssetGroupNames): boolean;
|
|
510
590
|
/**
|
|
511
591
|
* Get the loading progress of a group (0-1)
|
|
512
592
|
*/
|
|
513
|
-
getAssetGroupProgress(groupName:
|
|
593
|
+
getAssetGroupProgress(groupName: AssetGroupNames): number;
|
|
594
|
+
private requireScreenManager;
|
|
514
595
|
/**
|
|
515
596
|
* Transition to a new screen, clearing the stack
|
|
516
597
|
*/
|
|
@@ -560,15 +641,19 @@ export default class ECSpresso<ComponentTypes extends Record<string, any> = {},
|
|
|
560
641
|
*/
|
|
561
642
|
getScreenStackDepth(): number;
|
|
562
643
|
/**
|
|
563
|
-
* Internal method to set the asset manager
|
|
644
|
+
* Internal method to set the asset manager and drain pending bundle assets
|
|
564
645
|
* @internal Used by ECSpressoBuilder
|
|
565
646
|
*/
|
|
566
647
|
_setAssetManager(manager: AssetManager<AssetTypes>): void;
|
|
567
648
|
/**
|
|
568
|
-
* Internal method to set the screen manager
|
|
649
|
+
* Internal method to set the screen manager and drain pending bundle screens
|
|
569
650
|
* @internal Used by ECSpressoBuilder
|
|
570
651
|
*/
|
|
571
652
|
_setScreenManager(manager: ScreenManager<ScreenStates>): void;
|
|
653
|
+
/** @internal */
|
|
654
|
+
_hasPendingBundleAssets(): boolean;
|
|
655
|
+
/** @internal */
|
|
656
|
+
_hasPendingBundleScreens(): boolean;
|
|
572
657
|
/**
|
|
573
658
|
* Internal method to set the fixed timestep interval
|
|
574
659
|
* @internal Used by ECSpressoBuilder
|
|
@@ -579,111 +664,5 @@ export default class ECSpresso<ComponentTypes extends Record<string, any> = {},
|
|
|
579
664
|
* Called by the ECSpressoBuilder during the build process.
|
|
580
665
|
* The type safety is guaranteed by the builder's type system.
|
|
581
666
|
*/
|
|
582
|
-
_installBundle<C extends Record<string, any>, E extends Record<string, any>, R extends Record<string, any>, A extends Record<string, unknown> = {}, S extends Record<string, ScreenDefinition<any, any>> = {}>(bundle: Bundle<C, E, R, A, S>): this;
|
|
583
|
-
}
|
|
584
|
-
/**
|
|
585
|
-
* Resource factory with optional dependencies and disposal callback
|
|
586
|
-
*/
|
|
587
|
-
type ResourceFactoryWithDeps<T> = {
|
|
588
|
-
dependsOn?: readonly string[];
|
|
589
|
-
factory: (context?: any) => T | Promise<T>;
|
|
590
|
-
onDispose?: (resource: T, context?: any) => void | Promise<void>;
|
|
591
|
-
};
|
|
592
|
-
/**
|
|
593
|
-
* Builder class for ECSpresso that provides fluent type-safe bundle installation.
|
|
594
|
-
* Handles type checking during build process to ensure type safety.
|
|
595
|
-
*/
|
|
596
|
-
export declare class ECSpressoBuilder<C extends Record<string, any> = {}, E extends Record<string, any> = {}, R extends Record<string, any> = {}, A extends Record<string, unknown> = {}, S extends Record<string, ScreenDefinition<any, any>> = {}> {
|
|
597
|
-
/** The ECSpresso instance being built*/
|
|
598
|
-
private ecspresso;
|
|
599
|
-
/** Asset configurator for collecting asset definitions */
|
|
600
|
-
private assetConfigurator;
|
|
601
|
-
/** Screen configurator for collecting screen definitions */
|
|
602
|
-
private screenConfigurator;
|
|
603
|
-
/** Pending resources to add during build */
|
|
604
|
-
private pendingResources;
|
|
605
|
-
/** Fixed timestep interval (null means use default 1/60) */
|
|
606
|
-
private _fixedDt;
|
|
607
|
-
constructor();
|
|
608
|
-
/**
|
|
609
|
-
* Add the first bundle when starting with empty types.
|
|
610
|
-
* This overload allows any bundle to be added to an empty ECSpresso instance.
|
|
611
|
-
*/
|
|
612
|
-
withBundle<BC extends Record<string, any>, BE extends Record<string, any>, BR extends Record<string, any>>(this: ECSpressoBuilder<{}, {}, {}, A, S>, bundle: Bundle<BC, BE, BR>): ECSpressoBuilder<BC, BE, BR, A, S>;
|
|
613
|
-
/**
|
|
614
|
-
* Add a subsequent bundle with type checking.
|
|
615
|
-
* This overload enforces bundle type compatibility.
|
|
616
|
-
*/
|
|
617
|
-
withBundle<BC extends Record<string, any>, BE extends Record<string, any>, BR extends Record<string, any>>(bundle: BundlesAreCompatible<C, BC, E, BE, R, BR> extends true ? Bundle<BC, BE, BR> : never): ECSpressoBuilder<C & BC, E & BE, R & BR, A, S>;
|
|
618
|
-
/**
|
|
619
|
-
* Add a resource during ECSpresso construction
|
|
620
|
-
* @param key The resource key
|
|
621
|
-
* @param resource The resource value, factory function, or factory with dependencies/disposal
|
|
622
|
-
* @returns This builder with updated resource types
|
|
623
|
-
*
|
|
624
|
-
* @example
|
|
625
|
-
* ```typescript
|
|
626
|
-
* ECSpresso.create<Components, Events, Resources>()
|
|
627
|
-
* .withResource('config', { debug: true })
|
|
628
|
-
* .withResource('counter', () => 42)
|
|
629
|
-
* .withResource('derived', {
|
|
630
|
-
* dependsOn: ['base'],
|
|
631
|
-
* factory: (ecs) => ecs.getResource('base') * 2,
|
|
632
|
-
* onDispose: (value) => console.log('Disposed:', value)
|
|
633
|
-
* })
|
|
634
|
-
* .build();
|
|
635
|
-
* ```
|
|
636
|
-
*/
|
|
637
|
-
withResource<K extends string, V>(key: K, resource: V | ((context?: any) => V | Promise<V>) | ResourceFactoryWithDeps<V>): ECSpressoBuilder<C, E, R & Record<K, V>, A, S>;
|
|
638
|
-
/**
|
|
639
|
-
* Configure assets for this ECSpresso instance
|
|
640
|
-
* @param configurator Function that receives an AssetConfigurator and returns it after adding assets
|
|
641
|
-
* @returns This builder with updated asset types
|
|
642
|
-
*
|
|
643
|
-
* @example
|
|
644
|
-
* ```typescript
|
|
645
|
-
* ECSpresso.create<Components, Events, Resources>()
|
|
646
|
-
* .withAssets(assets => assets
|
|
647
|
-
* .add('playerSprite', () => loadTexture('player.png'))
|
|
648
|
-
* .addGroup('level1', {
|
|
649
|
-
* background: () => loadTexture('level1-bg.png'),
|
|
650
|
-
* music: () => loadAudio('level1.mp3'),
|
|
651
|
-
* })
|
|
652
|
-
* )
|
|
653
|
-
* .build();
|
|
654
|
-
* ```
|
|
655
|
-
*/
|
|
656
|
-
withAssets<NewA extends Record<string, unknown>>(configurator: (assets: AssetConfigurator<{}>) => AssetConfigurator<NewA>): ECSpressoBuilder<C, E, R, A & NewA, S>;
|
|
657
|
-
/**
|
|
658
|
-
* Configure screens for this ECSpresso instance
|
|
659
|
-
* @param configurator Function that receives a ScreenConfigurator and returns it after adding screens
|
|
660
|
-
* @returns This builder with updated screen types
|
|
661
|
-
*
|
|
662
|
-
* @example
|
|
663
|
-
* ```typescript
|
|
664
|
-
* ECSpresso.create<Components, Events, Resources>()
|
|
665
|
-
* .withScreens(screens => screens
|
|
666
|
-
* .add('loading', {
|
|
667
|
-
* initialState: () => ({ progress: 0 }),
|
|
668
|
-
* })
|
|
669
|
-
* .add('gameplay', {
|
|
670
|
-
* initialState: ({ level }) => ({ score: 0, level }),
|
|
671
|
-
* requiredAssetGroups: ['level1'],
|
|
672
|
-
* })
|
|
673
|
-
* )
|
|
674
|
-
* .build();
|
|
675
|
-
* ```
|
|
676
|
-
*/
|
|
677
|
-
withScreens<NewS extends Record<string, ScreenDefinition<any, any>>>(configurator: (screens: ScreenConfigurator<{}>) => ScreenConfigurator<NewS>): ECSpressoBuilder<C, E, R, A, S & NewS>;
|
|
678
|
-
/**
|
|
679
|
-
* Configure the fixed timestep interval for the fixedUpdate phase.
|
|
680
|
-
* @param dt The fixed timestep in seconds (e.g., 1/60 for 60Hz physics)
|
|
681
|
-
* @returns This builder for method chaining
|
|
682
|
-
*/
|
|
683
|
-
withFixedTimestep(dt: number): this;
|
|
684
|
-
/**
|
|
685
|
-
* Complete the build process and return the built ECSpresso instance
|
|
686
|
-
*/
|
|
687
|
-
build(): ECSpresso<C, E, R, A, S>;
|
|
667
|
+
_installBundle<C extends Record<string, any>, E extends Record<string, any>, R extends Record<string, any>, A extends Record<string, unknown> = {}, S extends Record<string, ScreenDefinition<any, any>> = {}>(bundle: Bundle<C, E, R, A, S, any, any, any, any>): this;
|
|
688
668
|
}
|
|
689
|
-
export {};
|