ecspresso 0.11.0 → 0.12.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 +200 -148
- package/dist/asset-manager.d.ts +1 -1
- package/dist/asset-types.d.ts +2 -2
- package/dist/command-buffer.d.ts +34 -24
- package/dist/ecspresso-builder.d.ts +100 -72
- package/dist/ecspresso.d.ts +257 -122
- package/dist/entity-manager.d.ts +57 -47
- package/dist/index.d.ts +5 -4
- package/dist/plugin.d.ts +61 -0
- package/dist/{bundles → plugins}/audio.d.ts +27 -47
- package/dist/{bundles → plugins}/bounds.d.ts +17 -25
- package/dist/{bundles → plugins}/camera.d.ts +8 -9
- package/dist/{bundles → plugins}/collision.d.ts +22 -26
- package/dist/plugins/coroutine.d.ts +126 -0
- package/dist/{bundles → plugins}/diagnostics.d.ts +5 -4
- package/dist/{bundles → plugins}/input.d.ts +9 -15
- package/dist/plugins/particles.d.ts +225 -0
- package/dist/{bundles → plugins}/physics2D.d.ts +27 -23
- package/dist/{bundles → plugins}/renderers/renderer2D.d.ts +40 -39
- package/dist/{bundles → plugins}/spatial-index.d.ts +11 -10
- package/dist/plugins/sprite-animation.d.ts +150 -0
- package/dist/{bundles → plugins}/state-machine.d.ts +50 -104
- package/dist/plugins/timers.d.ts +151 -0
- package/dist/{bundles → plugins}/transform.d.ts +18 -19
- package/dist/{bundles → plugins}/tween.d.ts +36 -71
- package/dist/resource-manager.d.ts +32 -7
- package/dist/screen-manager.d.ts +17 -11
- package/dist/screen-types.d.ts +5 -2
- package/dist/src/index.js +2 -2
- package/dist/src/index.js.map +17 -17
- package/dist/src/plugins/audio.js +4 -0
- package/dist/src/plugins/audio.js.map +10 -0
- package/dist/src/plugins/bounds.js +4 -0
- package/dist/src/plugins/bounds.js.map +10 -0
- package/dist/src/plugins/camera.js +4 -0
- package/dist/src/plugins/camera.js.map +10 -0
- package/dist/src/plugins/collision.js +4 -0
- package/dist/src/plugins/collision.js.map +11 -0
- package/dist/src/plugins/coroutine.js +4 -0
- package/dist/src/plugins/coroutine.js.map +10 -0
- package/dist/src/plugins/diagnostics.js +5 -0
- package/dist/src/plugins/diagnostics.js.map +10 -0
- package/dist/src/plugins/input.js +4 -0
- package/dist/src/plugins/input.js.map +10 -0
- package/dist/src/plugins/particles.js +4 -0
- package/dist/src/plugins/particles.js.map +10 -0
- package/dist/src/plugins/physics2D.js +4 -0
- package/dist/src/plugins/physics2D.js.map +11 -0
- package/dist/src/plugins/renderers/renderer2D.js +4 -0
- package/dist/src/plugins/renderers/renderer2D.js.map +10 -0
- package/dist/src/plugins/spatial-index.js +4 -0
- package/dist/src/plugins/spatial-index.js.map +11 -0
- package/dist/src/plugins/sprite-animation.js +4 -0
- package/dist/src/plugins/sprite-animation.js.map +10 -0
- package/dist/src/plugins/state-machine.js +4 -0
- package/dist/src/plugins/state-machine.js.map +10 -0
- package/dist/src/plugins/timers.js +4 -0
- package/dist/src/plugins/timers.js.map +10 -0
- package/dist/src/plugins/transform.js +4 -0
- package/dist/src/plugins/transform.js.map +10 -0
- package/dist/src/plugins/tween.js +4 -0
- package/dist/src/plugins/tween.js.map +11 -0
- package/dist/system-builder.d.ts +66 -97
- package/dist/type-utils.d.ts +218 -27
- package/dist/types.d.ts +52 -24
- package/dist/utils/check-required-cycle.d.ts +1 -1
- package/dist/utils/narrowphase.d.ts +7 -7
- package/package.json +53 -45
- package/dist/bundle.d.ts +0 -173
- package/dist/bundles/timers.d.ts +0 -173
- package/dist/src/bundles/audio.js +0 -4
- package/dist/src/bundles/audio.js.map +0 -10
- package/dist/src/bundles/bounds.js +0 -4
- package/dist/src/bundles/bounds.js.map +0 -10
- package/dist/src/bundles/camera.js +0 -4
- package/dist/src/bundles/camera.js.map +0 -10
- package/dist/src/bundles/collision.js +0 -4
- package/dist/src/bundles/collision.js.map +0 -11
- package/dist/src/bundles/diagnostics.js +0 -5
- package/dist/src/bundles/diagnostics.js.map +0 -10
- package/dist/src/bundles/input.js +0 -4
- package/dist/src/bundles/input.js.map +0 -10
- package/dist/src/bundles/physics2D.js +0 -4
- package/dist/src/bundles/physics2D.js.map +0 -11
- package/dist/src/bundles/renderers/renderer2D.js +0 -4
- package/dist/src/bundles/renderers/renderer2D.js.map +0 -10
- package/dist/src/bundles/spatial-index.js +0 -4
- package/dist/src/bundles/spatial-index.js.map +0 -11
- package/dist/src/bundles/state-machine.js +0 -4
- package/dist/src/bundles/state-machine.js.map +0 -10
- package/dist/src/bundles/timers.js +0 -4
- package/dist/src/bundles/timers.js.map +0 -10
- package/dist/src/bundles/transform.js +0 -4
- package/dist/src/bundles/transform.js.map +0 -10
- package/dist/src/bundles/tween.js +0 -4
- package/dist/src/bundles/tween.js.map +0 -11
package/dist/type-utils.d.ts
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
* Utility types for ECSpresso ECS framework
|
|
3
3
|
* This file contains reusable type helpers used across the codebase
|
|
4
4
|
*/
|
|
5
|
+
import type { ScreenDefinition } from './screen-types';
|
|
5
6
|
/**
|
|
6
7
|
* Check if two types are exactly the same for overlapping keys
|
|
7
8
|
*/
|
|
@@ -16,11 +17,89 @@ export type TypesAreCompatible<T extends Record<string, any>, U extends Record<s
|
|
|
16
17
|
[K in keyof T & keyof U]: ExactlyCompatible<T[K], U[K]>;
|
|
17
18
|
}[keyof T & keyof U] extends false ? false : true;
|
|
18
19
|
/**
|
|
19
|
-
*
|
|
20
|
-
*
|
|
21
|
-
*
|
|
20
|
+
* Single config object that bundles all 5 world type dimensions.
|
|
21
|
+
* Replaces the 5 positional type params (ComponentTypes, EventTypes,
|
|
22
|
+
* ResourceTypes, AssetTypes, ScreenStates) throughout the codebase.
|
|
22
23
|
*/
|
|
23
|
-
export
|
|
24
|
+
export interface WorldConfig {
|
|
25
|
+
readonly components: Record<string, any>;
|
|
26
|
+
readonly events: Record<string, any>;
|
|
27
|
+
readonly resources: Record<string, any>;
|
|
28
|
+
readonly assets: Record<string, unknown>;
|
|
29
|
+
readonly screens: Record<string, ScreenDefinition<any, any>>;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Construct a WorldConfig from individual type dimensions.
|
|
33
|
+
* All parameters default to empty records.
|
|
34
|
+
*/
|
|
35
|
+
export type WorldConfigFrom<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>> = {}> = {
|
|
36
|
+
readonly components: C;
|
|
37
|
+
readonly events: E;
|
|
38
|
+
readonly resources: R;
|
|
39
|
+
readonly assets: A;
|
|
40
|
+
readonly screens: S;
|
|
41
|
+
};
|
|
42
|
+
/**
|
|
43
|
+
* Empty WorldConfig with all slots defaulting to {}.
|
|
44
|
+
*/
|
|
45
|
+
export type EmptyConfig = WorldConfigFrom;
|
|
46
|
+
/**
|
|
47
|
+
* Merge two WorldConfig types by intersecting each slot.
|
|
48
|
+
*/
|
|
49
|
+
export type MergeConfigs<A extends WorldConfig, B extends WorldConfig> = {
|
|
50
|
+
readonly components: A['components'] & B['components'];
|
|
51
|
+
readonly events: A['events'] & B['events'];
|
|
52
|
+
readonly resources: A['resources'] & B['resources'];
|
|
53
|
+
readonly assets: A['assets'] & B['assets'];
|
|
54
|
+
readonly screens: A['screens'] & B['screens'];
|
|
55
|
+
};
|
|
56
|
+
export type WithComponents<Cfg extends WorldConfig, T> = {
|
|
57
|
+
readonly components: Cfg['components'] & T;
|
|
58
|
+
readonly events: Cfg['events'];
|
|
59
|
+
readonly resources: Cfg['resources'];
|
|
60
|
+
readonly assets: Cfg['assets'];
|
|
61
|
+
readonly screens: Cfg['screens'];
|
|
62
|
+
};
|
|
63
|
+
export type WithEvents<Cfg extends WorldConfig, T> = {
|
|
64
|
+
readonly components: Cfg['components'];
|
|
65
|
+
readonly events: Cfg['events'] & T;
|
|
66
|
+
readonly resources: Cfg['resources'];
|
|
67
|
+
readonly assets: Cfg['assets'];
|
|
68
|
+
readonly screens: Cfg['screens'];
|
|
69
|
+
};
|
|
70
|
+
export type WithResources<Cfg extends WorldConfig, T> = {
|
|
71
|
+
readonly components: Cfg['components'];
|
|
72
|
+
readonly events: Cfg['events'];
|
|
73
|
+
readonly resources: Cfg['resources'] & T;
|
|
74
|
+
readonly assets: Cfg['assets'];
|
|
75
|
+
readonly screens: Cfg['screens'];
|
|
76
|
+
};
|
|
77
|
+
export type WithAssets<Cfg extends WorldConfig, T> = {
|
|
78
|
+
readonly components: Cfg['components'];
|
|
79
|
+
readonly events: Cfg['events'];
|
|
80
|
+
readonly resources: Cfg['resources'];
|
|
81
|
+
readonly assets: Cfg['assets'] & T;
|
|
82
|
+
readonly screens: Cfg['screens'];
|
|
83
|
+
};
|
|
84
|
+
export type WithScreens<Cfg extends WorldConfig, T> = {
|
|
85
|
+
readonly components: Cfg['components'];
|
|
86
|
+
readonly events: Cfg['events'];
|
|
87
|
+
readonly resources: Cfg['resources'];
|
|
88
|
+
readonly assets: Cfg['assets'];
|
|
89
|
+
readonly screens: Cfg['screens'] & T;
|
|
90
|
+
};
|
|
91
|
+
/**
|
|
92
|
+
* Check if two WorldConfig types are compatible (no conflicting keys
|
|
93
|
+
* across any slot).
|
|
94
|
+
*/
|
|
95
|
+
export type ConfigsAreCompatible<A extends WorldConfig, B extends WorldConfig> = TypesAreCompatible<A['components'], B['components']> extends true ? TypesAreCompatible<A['events'], B['events']> extends true ? TypesAreCompatible<A['resources'], B['resources']> extends true ? TypesAreCompatible<A['assets'], B['assets']> extends true ? TypesAreCompatible<A['screens'], B['screens']> : false : false : false : false;
|
|
96
|
+
/**
|
|
97
|
+
* Check if a Requires config is satisfied by an Accumulated config.
|
|
98
|
+
* Checks all five WorldConfig slots (components, events, resources, assets, screens).
|
|
99
|
+
* When Required is EmptyConfig, all slots have `keyof {} = never`,
|
|
100
|
+
* and `never extends X = true`, so empty requirements are always satisfied.
|
|
101
|
+
*/
|
|
102
|
+
export type RequirementsSatisfied<Accumulated extends WorldConfig, Required extends WorldConfig> = keyof Required['components'] extends keyof Accumulated['components'] ? keyof Required['events'] extends keyof Accumulated['events'] ? keyof Required['resources'] extends keyof Accumulated['resources'] ? keyof Required['assets'] extends keyof Accumulated['assets'] ? keyof Required['screens'] extends keyof Accumulated['screens'] ? true : false : false : false : false : false;
|
|
24
103
|
/**
|
|
25
104
|
* Utility type for merging two types
|
|
26
105
|
*/
|
|
@@ -30,55 +109,167 @@ export type Merge<T1, T2> = T1 & T2;
|
|
|
30
109
|
*/
|
|
31
110
|
export type MergeAll<T extends any[]> = T extends [infer First, ...infer Rest] ? Rest extends [] ? First : Merge<First, MergeAll<Rest>> : {};
|
|
32
111
|
/**
|
|
33
|
-
*
|
|
112
|
+
* Wildcard ECSpresso type that any concrete instance is assignable to.
|
|
113
|
+
* Use as a generic constraint for functions that accept any ECSpresso world.
|
|
114
|
+
* Matches the phantom _cfg property declared on the ECSpresso class.
|
|
34
115
|
*/
|
|
35
|
-
export type
|
|
116
|
+
export type AnyECSpresso = {
|
|
117
|
+
readonly _cfg: WorldConfig;
|
|
118
|
+
};
|
|
36
119
|
/**
|
|
37
|
-
*
|
|
120
|
+
* Wildcard Plugin type that any concrete plugin is assignable to.
|
|
121
|
+
* Matches the phantom _cfg and _requires properties declared on the Plugin interface.
|
|
38
122
|
*/
|
|
39
|
-
export type
|
|
123
|
+
export type AnyPlugin = {
|
|
124
|
+
readonly _cfg?: WorldConfig;
|
|
125
|
+
readonly _requires?: WorldConfig;
|
|
126
|
+
};
|
|
40
127
|
/**
|
|
41
|
-
* Extract the
|
|
128
|
+
* Extract the full WorldConfig from a Plugin or ECSpresso instance
|
|
42
129
|
*/
|
|
43
|
-
export type
|
|
130
|
+
export type ConfigOf<B> = B extends {
|
|
131
|
+
readonly _cfg: infer Cfg extends WorldConfig;
|
|
132
|
+
} ? Cfg : never;
|
|
44
133
|
/**
|
|
45
|
-
* Extract the
|
|
134
|
+
* Extract the ComponentTypes from a Plugin or ECSpresso instance
|
|
46
135
|
*/
|
|
47
|
-
export type
|
|
136
|
+
export type ComponentsOf<B> = B extends {
|
|
137
|
+
readonly _cfg: {
|
|
138
|
+
components: infer C extends Record<string, any>;
|
|
139
|
+
};
|
|
140
|
+
} ? C : B extends {
|
|
141
|
+
readonly _cfg?: {
|
|
142
|
+
components: infer C extends Record<string, any>;
|
|
143
|
+
};
|
|
144
|
+
} ? C : never;
|
|
48
145
|
/**
|
|
49
|
-
* Extract the
|
|
146
|
+
* Extract the EventTypes from a Plugin or ECSpresso instance
|
|
50
147
|
*/
|
|
51
|
-
export type
|
|
148
|
+
export type EventsOf<B> = B extends {
|
|
149
|
+
readonly _cfg: {
|
|
150
|
+
events: infer E extends Record<string, any>;
|
|
151
|
+
};
|
|
152
|
+
} ? E : B extends {
|
|
153
|
+
readonly _cfg?: {
|
|
154
|
+
events: infer E extends Record<string, any>;
|
|
155
|
+
};
|
|
156
|
+
} ? E : never;
|
|
52
157
|
/**
|
|
53
|
-
* Extract the
|
|
158
|
+
* Extract the ResourceTypes from a Plugin or ECSpresso instance
|
|
54
159
|
*/
|
|
55
|
-
export type
|
|
160
|
+
export type ResourcesOf<B> = B extends {
|
|
161
|
+
readonly _cfg: {
|
|
162
|
+
resources: infer R extends Record<string, any>;
|
|
163
|
+
};
|
|
164
|
+
} ? R : B extends {
|
|
165
|
+
readonly _cfg?: {
|
|
166
|
+
resources: infer R extends Record<string, any>;
|
|
167
|
+
};
|
|
168
|
+
} ? R : never;
|
|
56
169
|
/**
|
|
57
|
-
* Extract
|
|
170
|
+
* Extract AssetTypes from a Plugin or ECSpresso instance
|
|
58
171
|
*/
|
|
59
|
-
export type
|
|
172
|
+
export type AssetTypesOf<B> = B extends {
|
|
173
|
+
readonly _cfg: {
|
|
174
|
+
assets: infer A extends Record<string, unknown>;
|
|
175
|
+
};
|
|
176
|
+
} ? A : B extends {
|
|
177
|
+
readonly _cfg?: {
|
|
178
|
+
assets: infer A extends Record<string, unknown>;
|
|
179
|
+
};
|
|
180
|
+
} ? A : never;
|
|
60
181
|
/**
|
|
61
|
-
* Extract
|
|
182
|
+
* Extract ScreenStates from a Plugin or ECSpresso instance
|
|
62
183
|
*/
|
|
63
|
-
export type
|
|
184
|
+
export type ScreenStatesOf<B> = B extends {
|
|
185
|
+
readonly _cfg: {
|
|
186
|
+
screens: infer S extends Record<string, ScreenDefinition<any, any>>;
|
|
187
|
+
};
|
|
188
|
+
} ? S : B extends {
|
|
189
|
+
readonly _cfg?: {
|
|
190
|
+
screens: infer S extends Record<string, ScreenDefinition<any, any>>;
|
|
191
|
+
};
|
|
192
|
+
} ? S : never;
|
|
64
193
|
/**
|
|
65
|
-
* Extract
|
|
194
|
+
* Extract the system Labels from a Plugin instance
|
|
66
195
|
*/
|
|
67
|
-
export type
|
|
196
|
+
export type LabelsOf<B> = B extends {
|
|
197
|
+
readonly _labels?: infer L;
|
|
198
|
+
} ? L extends string ? L : never : never;
|
|
68
199
|
/**
|
|
69
|
-
* Extract
|
|
200
|
+
* Extract the system Groups from a Plugin instance
|
|
70
201
|
*/
|
|
71
|
-
export type
|
|
202
|
+
export type GroupsOf<B> = B extends {
|
|
203
|
+
readonly _groups?: infer G;
|
|
204
|
+
} ? G extends string ? G : never : never;
|
|
205
|
+
/**
|
|
206
|
+
* Extract the AssetGroupNames from a Plugin instance
|
|
207
|
+
*/
|
|
208
|
+
export type AssetGroupNamesOf<B> = B extends {
|
|
209
|
+
readonly _assetGroupNames?: infer AG;
|
|
210
|
+
} ? AG extends string ? AG : never : never;
|
|
211
|
+
/**
|
|
212
|
+
* Extract the ReactiveQueryNames from a Plugin instance
|
|
213
|
+
*/
|
|
214
|
+
export type ReactiveQueryNamesOf<B> = B extends {
|
|
215
|
+
readonly _reactiveQueryNames?: infer RQ;
|
|
216
|
+
} ? RQ extends string ? RQ : never : never;
|
|
72
217
|
/**
|
|
73
218
|
* Extract ComponentTypes from an ECSpresso world instance type.
|
|
74
219
|
*/
|
|
75
|
-
export type ComponentsOfWorld<W> = W extends
|
|
220
|
+
export type ComponentsOfWorld<W> = W extends {
|
|
221
|
+
readonly _cfg: {
|
|
222
|
+
components: infer C extends Record<string, any>;
|
|
223
|
+
};
|
|
224
|
+
} ? C : never;
|
|
76
225
|
/**
|
|
77
226
|
* Extract EventTypes from an ECSpresso world instance type.
|
|
78
227
|
*/
|
|
79
|
-
export type EventsOfWorld<W> = W extends
|
|
228
|
+
export type EventsOfWorld<W> = W extends {
|
|
229
|
+
readonly _cfg: {
|
|
230
|
+
events: infer E extends Record<string, any>;
|
|
231
|
+
};
|
|
232
|
+
} ? E : never;
|
|
80
233
|
/**
|
|
81
234
|
* Extract AssetTypes from an ECSpresso world instance type.
|
|
82
235
|
*/
|
|
83
|
-
export type AssetsOfWorld<W> = W extends
|
|
236
|
+
export type AssetsOfWorld<W> = W extends {
|
|
237
|
+
readonly _cfg: {
|
|
238
|
+
assets: infer A extends Record<string, unknown>;
|
|
239
|
+
};
|
|
240
|
+
} ? A : never;
|
|
241
|
+
/**
|
|
242
|
+
* Extract ScreenStates from an ECSpresso world instance type
|
|
243
|
+
*/
|
|
244
|
+
export type ScreenStatesOfWorld<W> = W extends {
|
|
245
|
+
readonly _cfg: {
|
|
246
|
+
screens: infer S extends Record<string, ScreenDefinition<any, any>>;
|
|
247
|
+
};
|
|
248
|
+
} ? S : never;
|
|
249
|
+
/**
|
|
250
|
+
* Extract event names from an EventTypes record whose payload extends the given shape.
|
|
251
|
+
* Eliminates the need for each plugin to define its own mapped filter type.
|
|
252
|
+
*
|
|
253
|
+
* @example
|
|
254
|
+
* ```typescript
|
|
255
|
+
* interface MyEventData { entityId: number }
|
|
256
|
+
* type MyEventName<ET> = EventNameMatching<ET, MyEventData>;
|
|
257
|
+
* ```
|
|
258
|
+
*/
|
|
259
|
+
export type EventNameMatching<ET extends Record<string, any>, Payload> = {
|
|
260
|
+
[K in keyof ET & string]: ET[K] extends Payload ? K : never;
|
|
261
|
+
}[keyof ET & string];
|
|
262
|
+
/**
|
|
263
|
+
* Extract the channel type from a world's AudioSource component.
|
|
264
|
+
* Falls back to `string` if the world has no audioSource component.
|
|
265
|
+
*/
|
|
266
|
+
export type ChannelOfWorld<W> = W extends {
|
|
267
|
+
readonly _cfg: {
|
|
268
|
+
components: {
|
|
269
|
+
audioSource: {
|
|
270
|
+
channel: infer Ch extends string;
|
|
271
|
+
};
|
|
272
|
+
};
|
|
273
|
+
};
|
|
274
|
+
} ? Ch : string;
|
|
84
275
|
export {};
|
package/dist/types.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import ECSpresso from "./ecspresso";
|
|
2
|
+
import type { WorldConfig, EmptyConfig, WorldConfigFrom } from "./type-utils";
|
|
2
3
|
/**
|
|
3
4
|
* Execution phase for systems. Systems are grouped by phase and executed
|
|
4
5
|
* in this fixed order: preUpdate -> fixedUpdate -> update -> postUpdate -> render.
|
|
@@ -109,7 +110,7 @@ export type QueryDefinition<ComponentTypes extends Record<string, any>, WithComp
|
|
|
109
110
|
*
|
|
110
111
|
* world.addSystem('movement')
|
|
111
112
|
* .addQuery('entities', movingEntitiesQuery)
|
|
112
|
-
* .setProcess((queries) => {
|
|
113
|
+
* .setProcess(({ queries }) => {
|
|
113
114
|
* for (const entity of queries.entities) {
|
|
114
115
|
* updatePosition(entity);
|
|
115
116
|
* }
|
|
@@ -123,7 +124,7 @@ export declare function createQueryDefinition<ComponentTypes extends Record<stri
|
|
|
123
124
|
optional?: ReadonlyArray<keyof ComponentTypes>;
|
|
124
125
|
parentHas?: ReadonlyArray<keyof ComponentTypes>;
|
|
125
126
|
}>(queryDef: QueryDef): QueryDef;
|
|
126
|
-
export interface System<
|
|
127
|
+
export interface System<Cfg extends WorldConfig = EmptyConfig, WithComponents extends keyof Cfg['components'] = never, WithoutComponents extends keyof Cfg['components'] = never> {
|
|
127
128
|
label: string;
|
|
128
129
|
/**
|
|
129
130
|
* System priority - higher values execute first (default: 0)
|
|
@@ -144,17 +145,17 @@ export interface System<ComponentTypes extends Record<string, any> = {}, WithCom
|
|
|
144
145
|
* Screens where this system should run. If specified, system only runs
|
|
145
146
|
* when current screen is in this list.
|
|
146
147
|
*/
|
|
147
|
-
inScreens?: ReadonlyArray<keyof
|
|
148
|
+
inScreens?: ReadonlyArray<keyof Cfg['screens'] & string>;
|
|
148
149
|
/**
|
|
149
150
|
* Screens where this system should NOT run. If specified, system skips
|
|
150
151
|
* when current screen is in this list.
|
|
151
152
|
*/
|
|
152
|
-
excludeScreens?: ReadonlyArray<keyof
|
|
153
|
+
excludeScreens?: ReadonlyArray<keyof Cfg['screens'] & string>;
|
|
153
154
|
/**
|
|
154
155
|
* Assets that must be loaded for this system to run.
|
|
155
156
|
* System will be skipped if any required asset is not loaded.
|
|
156
157
|
*/
|
|
157
|
-
requiredAssets?: ReadonlyArray<keyof
|
|
158
|
+
requiredAssets?: ReadonlyArray<keyof Cfg['assets'] & string>;
|
|
158
159
|
/**
|
|
159
160
|
* When true, the system's process function runs even when all queries
|
|
160
161
|
* return zero entities. Default is false (system is skipped when all
|
|
@@ -162,41 +163,68 @@ export interface System<ComponentTypes extends Record<string, any> = {}, WithCom
|
|
|
162
163
|
*/
|
|
163
164
|
runWhenEmpty?: boolean;
|
|
164
165
|
entityQueries?: {
|
|
165
|
-
[queryName: string]: QueryConfig<
|
|
166
|
+
[queryName: string]: QueryConfig<Cfg['components'], WithComponents, WithoutComponents>;
|
|
166
167
|
};
|
|
167
168
|
/**
|
|
168
|
-
* Process method that runs during each update cycle
|
|
169
|
-
*
|
|
170
|
-
* @param deltaTime Time elapsed since the last update in seconds
|
|
171
|
-
* @param ecs The ECSpresso instance providing access to all ECS functionality
|
|
169
|
+
* Process method that runs during each update cycle.
|
|
170
|
+
* Receives a single context object with queries, dt, and ecs.
|
|
172
171
|
*/
|
|
173
|
-
process?(
|
|
174
|
-
|
|
175
|
-
|
|
172
|
+
process?(ctx: {
|
|
173
|
+
queries: {
|
|
174
|
+
[queryName: string]: Array<FilteredEntity<Cfg['components'], WithComponents, WithoutComponents>>;
|
|
175
|
+
};
|
|
176
|
+
dt: number;
|
|
177
|
+
ecs: ECSpresso<Cfg>;
|
|
178
|
+
}): void;
|
|
176
179
|
/**
|
|
177
180
|
* Lifecycle hook called when the system is initialized
|
|
178
181
|
* This is called when ECSpresso.initialize() is invoked, after resources are initialized
|
|
179
182
|
* Use this for one-time initialization that depends on resources
|
|
180
183
|
* @param ecs The ECSpresso instance providing access to all ECS functionality
|
|
181
184
|
*/
|
|
182
|
-
onInitialize?(ecs: ECSpresso<
|
|
185
|
+
onInitialize?(ecs: ECSpresso<Cfg>): void | Promise<void>;
|
|
183
186
|
/**
|
|
184
187
|
* Lifecycle hook called when the system is detached from the ECS
|
|
185
188
|
* @param ecs The ECSpresso instance providing access to all ECS functionality
|
|
186
189
|
*/
|
|
187
|
-
onDetach?(ecs: import("./ecspresso").default<
|
|
190
|
+
onDetach?(ecs: import("./ecspresso").default<Cfg>): void;
|
|
191
|
+
/**
|
|
192
|
+
* Per-query callbacks that fire once per entity the first time it appears
|
|
193
|
+
* in a query's results. Fires before process. Automatic cleanup when
|
|
194
|
+
* entity leaves query (component removed, entity destroyed) so re-entry
|
|
195
|
+
* fires the callback again.
|
|
196
|
+
*/
|
|
197
|
+
onEntityEnter?: Record<string, (ctx: {
|
|
198
|
+
entity: FilteredEntity<Cfg['components'], WithComponents, WithoutComponents>;
|
|
199
|
+
ecs: ECSpresso<Cfg>;
|
|
200
|
+
}) => void>;
|
|
188
201
|
/**
|
|
189
202
|
* Event handlers for specific event types
|
|
190
203
|
*/
|
|
191
204
|
eventHandlers?: {
|
|
192
|
-
[EventName in keyof
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
* @param ecs The ECSpresso instance providing access to all ECS functionality
|
|
197
|
-
*/
|
|
198
|
-
handler(data: EventTypes[EventName], ecs: ECSpresso<ComponentTypes, EventTypes, ResourceTypes, AssetTypes, ScreenStates>): void;
|
|
199
|
-
};
|
|
205
|
+
[EventName in keyof Cfg['events']]?: (ctx: {
|
|
206
|
+
data: Cfg['events'][EventName];
|
|
207
|
+
ecs: ECSpresso<Cfg>;
|
|
208
|
+
}) => void;
|
|
200
209
|
};
|
|
201
210
|
}
|
|
202
|
-
|
|
211
|
+
/**
|
|
212
|
+
* Typed world interface for plugin helpers and structural typing.
|
|
213
|
+
*
|
|
214
|
+
* Generic over component types `C`:
|
|
215
|
+
* - `BaseWorld` (no param): defaults to `{}`, meaning component-accessing methods
|
|
216
|
+
* cannot be called (keys resolve to `never`). Use for functions that only need
|
|
217
|
+
* `removeEntity`, `getResource`, etc.
|
|
218
|
+
* - `BaseWorld<MyComponents>`: narrows `getComponent`, `hasComponent`, `markChanged`,
|
|
219
|
+
* `spawn`, and command buffer methods to the declared component map.
|
|
220
|
+
*
|
|
221
|
+
* Structural typing ensures any `ECSpresso<Cfg>` where `Cfg['components']` is a
|
|
222
|
+
* superset of `C` satisfies `BaseWorld<C>`.
|
|
223
|
+
*/
|
|
224
|
+
type _BaseWorldCfg<C extends Record<string, any>> = WorldConfigFrom<C, Record<string, any>, Record<string, any>, Record<string, unknown>, Record<string, any>>;
|
|
225
|
+
type _EventBus = import("./event-bus").default<Record<string, any>>;
|
|
226
|
+
export type BaseWorld<C extends Record<string, any> = {}> = Pick<ECSpresso<_BaseWorldCfg<C>>, 'getComponent' | 'hasComponent' | 'removeEntity' | 'spawn' | 'markChanged' | 'getResource' | 'hasResource'> & {
|
|
227
|
+
eventBus: Pick<_EventBus, 'publish'>;
|
|
228
|
+
commands: Pick<import("./command-buffer").default<_BaseWorldCfg<C>>, 'spawn' | 'removeEntity' | 'addComponent' | 'removeComponent'>;
|
|
229
|
+
};
|
|
230
|
+
export type { Merge, MergeAll, TypesAreCompatible, ComponentsOf, EventsOf, ResourcesOf, LabelsOf, GroupsOf, AssetGroupNamesOf, ReactiveQueryNamesOf, AssetTypesOf, ScreenStatesOf, ComponentsOfWorld, EventsOfWorld, AssetsOfWorld, ScreenStatesOfWorld, AnyECSpresso, AnyPlugin, EventNameMatching, ChannelOfWorld, WorldConfig, EmptyConfig, WorldConfigFrom, MergeConfigs, ConfigsAreCompatible, ConfigOf, WithComponents, WithEvents, WithResources, WithAssets, WithScreens } from './type-utils';
|
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
* Shared Narrowphase Module
|
|
3
3
|
*
|
|
4
4
|
* Provides contact-computing narrowphase tests and a generic collision
|
|
5
|
-
* iteration pipeline used by both the collision
|
|
6
|
-
* the physics2D
|
|
5
|
+
* iteration pipeline used by both the collision plugin (event-only) and
|
|
6
|
+
* the physics2D plugin (impulse response).
|
|
7
7
|
*/
|
|
8
8
|
import type { SpatialIndex } from './spatial-hash';
|
|
9
9
|
/** Contact result from a narrowphase test. Normal points from A toward B. */
|
|
@@ -31,7 +31,7 @@ export interface BaseColliderInfo<L extends string = string> {
|
|
|
31
31
|
/**
|
|
32
32
|
* Build a BaseColliderInfo from raw entity/collider component data.
|
|
33
33
|
* Returns null if the entity has neither an AABB nor circle collider.
|
|
34
|
-
* Shared by collision
|
|
34
|
+
* Shared by collision plugin (event-only) and physics2D plugin (impulse response).
|
|
35
35
|
*/
|
|
36
36
|
export declare function buildBaseColliderInfo<L extends string>(entityId: number, x: number, y: number, layer: L, collidesWith: readonly L[], aabb: {
|
|
37
37
|
width: number;
|
|
@@ -44,11 +44,11 @@ export declare function buildBaseColliderInfo<L extends string>(entityId: number
|
|
|
44
44
|
offsetY?: number;
|
|
45
45
|
} | undefined): BaseColliderInfo<L> | null;
|
|
46
46
|
/**
|
|
47
|
-
* Retrieve the optional spatialIndex resource, returning
|
|
48
|
-
* Centralizes the cross-
|
|
47
|
+
* Retrieve the optional spatialIndex resource, returning undefined when absent.
|
|
48
|
+
* Centralizes the cross-plugin typed lookup so individual plugins don't each
|
|
49
49
|
* need to import SpatialIndex or repeat the tryGetResource pattern.
|
|
50
50
|
*/
|
|
51
|
-
export declare function tryGetSpatialIndex(tryGetResource: <T>(key: string) => T | undefined): SpatialIndex |
|
|
51
|
+
export declare function tryGetSpatialIndex(tryGetResource: <T>(key: string) => T | undefined): SpatialIndex | undefined;
|
|
52
52
|
export declare function computeAABBvsAABB(ax: number, ay: number, ahw: number, ahh: number, bx: number, by: number, bhw: number, bhh: number): Contact | null;
|
|
53
53
|
export declare function computeCircleVsCircle(ax: number, ay: number, ar: number, bx: number, by: number, br: number): Contact | null;
|
|
54
54
|
export declare function computeAABBvsCircle(aabbX: number, aabbY: number, ahw: number, ahh: number, circleX: number, circleY: number, radius: number): Contact | null;
|
|
@@ -60,4 +60,4 @@ export declare function computeContact(a: BaseColliderInfo, b: BaseColliderInfo)
|
|
|
60
60
|
* Uses a context parameter forwarded to the callback to avoid
|
|
61
61
|
* per-frame closure allocation.
|
|
62
62
|
*/
|
|
63
|
-
export declare function detectCollisions<I extends BaseColliderInfo, C>(colliders: I[], spatialIndex: SpatialIndex |
|
|
63
|
+
export declare function detectCollisions<I extends BaseColliderInfo, C>(colliders: I[], spatialIndex: SpatialIndex | undefined, onContact: (a: I, b: I, contact: Contact, context: C) => void, context: C): void;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ecspresso",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.12.0",
|
|
4
4
|
"main": "dist/index.js",
|
|
5
5
|
"module": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -11,57 +11,65 @@
|
|
|
11
11
|
"import": "./dist/index.js",
|
|
12
12
|
"types": "./dist/index.d.ts"
|
|
13
13
|
},
|
|
14
|
-
"./
|
|
15
|
-
"import": "./dist/
|
|
16
|
-
"types": "./dist/
|
|
14
|
+
"./plugins/renderers/renderer2D": {
|
|
15
|
+
"import": "./dist/plugins/renderers/renderer2D.js",
|
|
16
|
+
"types": "./dist/plugins/renderers/renderer2D.d.ts"
|
|
17
17
|
},
|
|
18
|
-
"./
|
|
19
|
-
"import": "./dist/
|
|
20
|
-
"types": "./dist/
|
|
18
|
+
"./plugins/bounds": {
|
|
19
|
+
"import": "./dist/plugins/bounds.js",
|
|
20
|
+
"types": "./dist/plugins/bounds.d.ts"
|
|
21
21
|
},
|
|
22
|
-
"./
|
|
23
|
-
"import": "./dist/
|
|
24
|
-
"types": "./dist/
|
|
22
|
+
"./plugins/camera": {
|
|
23
|
+
"import": "./dist/plugins/camera.js",
|
|
24
|
+
"types": "./dist/plugins/camera.d.ts"
|
|
25
25
|
},
|
|
26
|
-
"./
|
|
27
|
-
"import": "./dist/
|
|
28
|
-
"types": "./dist/
|
|
26
|
+
"./plugins/collision": {
|
|
27
|
+
"import": "./dist/plugins/collision.js",
|
|
28
|
+
"types": "./dist/plugins/collision.d.ts"
|
|
29
29
|
},
|
|
30
|
-
"./
|
|
31
|
-
"import": "./dist/
|
|
32
|
-
"types": "./dist/
|
|
30
|
+
"./plugins/diagnostics": {
|
|
31
|
+
"import": "./dist/plugins/diagnostics.js",
|
|
32
|
+
"types": "./dist/plugins/diagnostics.d.ts"
|
|
33
33
|
},
|
|
34
|
-
"./
|
|
35
|
-
"import": "./dist/
|
|
36
|
-
"types": "./dist/
|
|
34
|
+
"./plugins/input": {
|
|
35
|
+
"import": "./dist/plugins/input.js",
|
|
36
|
+
"types": "./dist/plugins/input.d.ts"
|
|
37
37
|
},
|
|
38
|
-
"./
|
|
39
|
-
"import": "./dist/
|
|
40
|
-
"types": "./dist/
|
|
38
|
+
"./plugins/physics2D": {
|
|
39
|
+
"import": "./dist/plugins/physics2D.js",
|
|
40
|
+
"types": "./dist/plugins/physics2D.d.ts"
|
|
41
41
|
},
|
|
42
|
-
"./
|
|
43
|
-
"import": "./dist/
|
|
44
|
-
"types": "./dist/
|
|
42
|
+
"./plugins/spatial-index": {
|
|
43
|
+
"import": "./dist/plugins/spatial-index.js",
|
|
44
|
+
"types": "./dist/plugins/spatial-index.d.ts"
|
|
45
45
|
},
|
|
46
|
-
"./
|
|
47
|
-
"import": "./dist/
|
|
48
|
-
"types": "./dist/
|
|
46
|
+
"./plugins/state-machine": {
|
|
47
|
+
"import": "./dist/plugins/state-machine.js",
|
|
48
|
+
"types": "./dist/plugins/state-machine.d.ts"
|
|
49
49
|
},
|
|
50
|
-
"./
|
|
51
|
-
"import": "./dist/
|
|
52
|
-
"types": "./dist/
|
|
50
|
+
"./plugins/timers": {
|
|
51
|
+
"import": "./dist/plugins/timers.js",
|
|
52
|
+
"types": "./dist/plugins/timers.d.ts"
|
|
53
53
|
},
|
|
54
|
-
"./
|
|
55
|
-
"import": "./dist/
|
|
56
|
-
"types": "./dist/
|
|
54
|
+
"./plugins/transform": {
|
|
55
|
+
"import": "./dist/plugins/transform.js",
|
|
56
|
+
"types": "./dist/plugins/transform.d.ts"
|
|
57
57
|
},
|
|
58
|
-
"./
|
|
59
|
-
"import": "./dist/
|
|
60
|
-
"types": "./dist/
|
|
58
|
+
"./plugins/tween": {
|
|
59
|
+
"import": "./dist/plugins/tween.js",
|
|
60
|
+
"types": "./dist/plugins/tween.d.ts"
|
|
61
61
|
},
|
|
62
|
-
"./
|
|
63
|
-
"import": "./dist/
|
|
64
|
-
"types": "./dist/
|
|
62
|
+
"./plugins/audio": {
|
|
63
|
+
"import": "./dist/plugins/audio.js",
|
|
64
|
+
"types": "./dist/plugins/audio.d.ts"
|
|
65
|
+
},
|
|
66
|
+
"./plugins/sprite-animation": {
|
|
67
|
+
"import": "./dist/plugins/sprite-animation.js",
|
|
68
|
+
"types": "./dist/plugins/sprite-animation.d.ts"
|
|
69
|
+
},
|
|
70
|
+
"./plugins/particles": {
|
|
71
|
+
"import": "./dist/plugins/particles.js",
|
|
72
|
+
"types": "./dist/plugins/particles.d.ts"
|
|
65
73
|
}
|
|
66
74
|
},
|
|
67
75
|
"publishConfig": {
|
|
@@ -84,13 +92,13 @@
|
|
|
84
92
|
"devDependencies": {
|
|
85
93
|
"@types/bun": "latest",
|
|
86
94
|
"@types/howler": "^2.2.12",
|
|
87
|
-
"@types/three": "^0.
|
|
88
|
-
"howler": "^2.2.
|
|
89
|
-
"pixi.js": "^8.
|
|
90
|
-
"three": "^0.
|
|
95
|
+
"@types/three": "^0.183.1",
|
|
96
|
+
"howler": "^2.2.4",
|
|
97
|
+
"pixi.js": "^8.16.0",
|
|
98
|
+
"three": "^0.183.2"
|
|
91
99
|
},
|
|
92
100
|
"peerDependencies": {
|
|
93
|
-
"typescript": "^5.9.
|
|
101
|
+
"typescript": "^5.9.3",
|
|
94
102
|
"pixi.js": "^8.0.0",
|
|
95
103
|
"howler": "^2.2.0"
|
|
96
104
|
},
|