iris-ecs 0.0.4 → 0.0.6
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 +129 -50
- package/dist/component.d.ts +7 -3
- package/dist/component.d.ts.map +1 -1
- package/dist/component.js +0 -30
- package/dist/component.js.map +1 -1
- package/dist/encoding.d.ts +10 -0
- package/dist/encoding.d.ts.map +1 -1
- package/dist/encoding.js.map +1 -1
- package/dist/event.d.ts +15 -3
- package/dist/event.d.ts.map +1 -1
- package/dist/event.js +38 -61
- package/dist/event.js.map +1 -1
- package/dist/filters.d.ts +16 -14
- package/dist/filters.d.ts.map +1 -1
- package/dist/filters.js +78 -37
- package/dist/filters.js.map +1 -1
- package/dist/index.d.ts +6 -6
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -2
- package/dist/index.js.map +1 -1
- package/dist/name.d.ts +2 -2
- package/dist/name.d.ts.map +1 -1
- package/dist/name.js.map +1 -1
- package/dist/observer.d.ts +0 -1
- package/dist/observer.d.ts.map +1 -1
- package/dist/observer.js.map +1 -1
- package/dist/query.d.ts +32 -37
- package/dist/query.d.ts.map +1 -1
- package/dist/query.js +22 -104
- package/dist/query.js.map +1 -1
- package/dist/resource.d.ts +12 -6
- package/dist/resource.d.ts.map +1 -1
- package/dist/resource.js +3 -27
- package/dist/resource.js.map +1 -1
- package/dist/scheduler.d.ts +65 -2
- package/dist/scheduler.d.ts.map +1 -1
- package/dist/scheduler.js +63 -4
- package/dist/scheduler.js.map +1 -1
- package/dist/world.d.ts +4 -0
- package/dist/world.d.ts.map +1 -1
- package/dist/world.js +7 -11
- package/dist/world.js.map +1 -1
- package/package.json +1 -1
package/dist/query.d.ts
CHANGED
|
@@ -1,13 +1,16 @@
|
|
|
1
|
-
import type { EntityId } from "./encoding.js";
|
|
1
|
+
import type { EntityId, EntityWith } from "./encoding.js";
|
|
2
2
|
import type { FilterMeta } from "./filters.js";
|
|
3
|
-
import type { Observer } from "./observer.js";
|
|
4
3
|
import type { World } from "./world.js";
|
|
4
|
+
/**
|
|
5
|
+
* Phantom brand for carrying guaranteed-present component types on QueryMeta.
|
|
6
|
+
*/
|
|
7
|
+
declare const QUERY_COMPONENTS_BRAND: unique symbol;
|
|
5
8
|
/**
|
|
6
9
|
* Query metadata for registry caching.
|
|
7
10
|
*
|
|
8
11
|
* Stores required and excluded components with reference to underlying filter.
|
|
9
12
|
*/
|
|
10
|
-
export type QueryMeta = {
|
|
13
|
+
export type QueryMeta<C extends EntityId = EntityId> = {
|
|
11
14
|
/**
|
|
12
15
|
* Required components.
|
|
13
16
|
*/
|
|
@@ -20,10 +23,6 @@ export type QueryMeta = {
|
|
|
20
23
|
* Direct reference to underlying filter.
|
|
21
24
|
*/
|
|
22
25
|
filter: FilterMeta;
|
|
23
|
-
/**
|
|
24
|
-
* Observer callback for filter destruction.
|
|
25
|
-
*/
|
|
26
|
-
onFilterDestroy: Observer<"filterDestroyed">;
|
|
27
26
|
/**
|
|
28
27
|
* Components with added() modifier.
|
|
29
28
|
*/
|
|
@@ -36,19 +35,23 @@ export type QueryMeta = {
|
|
|
36
35
|
* Per-system execution ticks for change detection: systemId -> tick.
|
|
37
36
|
*/
|
|
38
37
|
lastTick: Map<string, number>;
|
|
38
|
+
/**
|
|
39
|
+
* Phantom field carrying guaranteed-present component types via contravariance.
|
|
40
|
+
*/
|
|
41
|
+
readonly [QUERY_COMPONENTS_BRAND]: (c: C) => void;
|
|
39
42
|
};
|
|
40
43
|
export type ModifierType = "not" | "added" | "changed";
|
|
41
|
-
export type NotModifier = {
|
|
44
|
+
export type NotModifier<C extends EntityId = EntityId> = {
|
|
42
45
|
type: "not";
|
|
43
|
-
componentId:
|
|
46
|
+
componentId: C;
|
|
44
47
|
};
|
|
45
|
-
export type AddedModifier = {
|
|
48
|
+
export type AddedModifier<C extends EntityId = EntityId> = {
|
|
46
49
|
type: "added";
|
|
47
|
-
componentId:
|
|
50
|
+
componentId: C;
|
|
48
51
|
};
|
|
49
|
-
export type ChangedModifier = {
|
|
52
|
+
export type ChangedModifier<C extends EntityId = EntityId> = {
|
|
50
53
|
type: "changed";
|
|
51
|
-
componentId:
|
|
54
|
+
componentId: C;
|
|
52
55
|
};
|
|
53
56
|
export type QueryModifier = NotModifier | AddedModifier | ChangedModifier;
|
|
54
57
|
/**
|
|
@@ -62,7 +65,7 @@ export type QueryModifier = NotModifier | AddedModifier | ChangedModifier;
|
|
|
62
65
|
* queryEntities(world, [Position, not(Dead)], (entity) => { ... });
|
|
63
66
|
* ```
|
|
64
67
|
*/
|
|
65
|
-
export declare function not(componentId:
|
|
68
|
+
export declare function not<C extends EntityId>(componentId: C): NotModifier<C>;
|
|
66
69
|
/**
|
|
67
70
|
* Create added modifier for change detection.
|
|
68
71
|
*
|
|
@@ -74,7 +77,7 @@ export declare function not(componentId: EntityId): NotModifier;
|
|
|
74
77
|
* @example
|
|
75
78
|
* queryEntities(world, [added(Enemy)], (entity) => { ... });
|
|
76
79
|
*/
|
|
77
|
-
export declare function added(componentId:
|
|
80
|
+
export declare function added<C extends EntityId>(componentId: C): AddedModifier<C>;
|
|
78
81
|
/**
|
|
79
82
|
* Create changed modifier for change detection.
|
|
80
83
|
*
|
|
@@ -86,7 +89,11 @@ export declare function added(componentId: EntityId): AddedModifier;
|
|
|
86
89
|
* @example
|
|
87
90
|
* queryEntities(world, [changed(Health)], (entity) => { ... });
|
|
88
91
|
*/
|
|
89
|
-
export declare function changed(componentId:
|
|
92
|
+
export declare function changed<C extends EntityId>(componentId: C): ChangedModifier<C>;
|
|
93
|
+
/**
|
|
94
|
+
* Extract union of guaranteed-present component IDs from query terms tuple.
|
|
95
|
+
*/
|
|
96
|
+
export type ExtractIncluded<T extends unknown[]> = T extends [infer Head, ...infer Tail] ? Head extends NotModifier ? ExtractIncluded<Tail> : Head extends AddedModifier<infer C> ? C | ExtractIncluded<Tail> : Head extends ChangedModifier<infer C> ? C | ExtractIncluded<Tail> : Head extends EntityId ? Head | ExtractIncluded<Tail> : ExtractIncluded<Tail> : never;
|
|
90
97
|
/**
|
|
91
98
|
* Hash query terms to unique string ID for cache lookup.
|
|
92
99
|
*
|
|
@@ -113,23 +120,7 @@ export declare function hashQuery(include: EntityId[], exclude: EntityId[], adde
|
|
|
113
120
|
* @example
|
|
114
121
|
* const query = ensureQuery(world, Position, Velocity, not(Dead));
|
|
115
122
|
*/
|
|
116
|
-
export declare function ensureQuery(world: World, ...terms:
|
|
117
|
-
/**
|
|
118
|
-
* Destroy query and clean up associated resources.
|
|
119
|
-
*
|
|
120
|
-
* Unregisters observer callbacks and removes from query registry.
|
|
121
|
-
*
|
|
122
|
-
* @param world - World instance
|
|
123
|
-
* @param queryMeta - Query metadata to destroy
|
|
124
|
-
*
|
|
125
|
-
* @example
|
|
126
|
-
* ```typescript
|
|
127
|
-
* const query = ensureQuery(world, Position);
|
|
128
|
-
* // ... use query ...
|
|
129
|
-
* destroyQuery(world, query);
|
|
130
|
-
* ```
|
|
131
|
-
*/
|
|
132
|
-
export declare function destroyQuery(world: World, queryMeta: QueryMeta): void;
|
|
123
|
+
export declare function ensureQuery<T extends (EntityId | QueryModifier)[]>(world: World, ...terms: [...T]): QueryMeta<ExtractIncluded<T>>;
|
|
133
124
|
/**
|
|
134
125
|
* Iterate entities matching components and modifiers via callback.
|
|
135
126
|
*
|
|
@@ -157,7 +148,8 @@ export declare function destroyQuery(world: World, queryMeta: QueryMeta): void;
|
|
|
157
148
|
* });
|
|
158
149
|
* ```
|
|
159
150
|
*/
|
|
160
|
-
export declare function queryEntities
|
|
151
|
+
export declare function queryEntities<T extends (EntityId | QueryModifier)[]>(world: World, terms: [...T], callback: (entity: EntityWith<ExtractIncluded<T>>) => unknown): void;
|
|
152
|
+
export declare function queryEntities<C extends EntityId>(world: World, query: QueryMeta<C>, callback: (entity: EntityWith<C>) => unknown): void;
|
|
161
153
|
/**
|
|
162
154
|
* Get first entity matching components and modifiers.
|
|
163
155
|
*
|
|
@@ -171,11 +163,12 @@ export declare function queryEntities(world: World, termsOrQuery: (EntityId | Qu
|
|
|
171
163
|
* ```typescript
|
|
172
164
|
* const player = queryFirstEntity(world, [Player, not(Dead)]);
|
|
173
165
|
* if (player !== undefined) {
|
|
174
|
-
* const health = getComponentValue(world, player, Health, "value");
|
|
166
|
+
* const health = getComponentValue(world, player, Health, "value"); // narrowed
|
|
175
167
|
* }
|
|
176
168
|
* ```
|
|
177
169
|
*/
|
|
178
|
-
export declare function queryFirstEntity
|
|
170
|
+
export declare function queryFirstEntity<T extends (EntityId | QueryModifier)[]>(world: World, terms: [...T]): EntityWith<ExtractIncluded<T>> | undefined;
|
|
171
|
+
export declare function queryFirstEntity<C extends EntityId>(world: World, query: QueryMeta<C>): EntityWith<C> | undefined;
|
|
179
172
|
/**
|
|
180
173
|
* Collect all matching entities into an array.
|
|
181
174
|
*
|
|
@@ -192,5 +185,7 @@ export declare function queryFirstEntity(world: World, termsOrQuery: (EntityId |
|
|
|
192
185
|
* sorted.sort((a, b) => getComponentValue(world, a, Position, "x")! - getComponentValue(world, b, Position, "x")!);
|
|
193
186
|
* ```
|
|
194
187
|
*/
|
|
195
|
-
export declare function collectEntities
|
|
188
|
+
export declare function collectEntities<T extends (EntityId | QueryModifier)[]>(world: World, terms: [...T]): EntityWith<ExtractIncluded<T>>[];
|
|
189
|
+
export declare function collectEntities<C extends EntityId>(world: World, query: QueryMeta<C>): EntityWith<C>[];
|
|
190
|
+
export {};
|
|
196
191
|
//# sourceMappingURL=query.d.ts.map
|
package/dist/query.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"query.d.ts","sourceRoot":"","sources":["../src/query.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"query.d.ts","sourceRoot":"","sources":["../src/query.ts"],"names":[],"mappings":"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"}
|
package/dist/query.js
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { assert, InvalidArgument } from "./error.js";
|
|
2
2
|
import { ensureFilter } from "./filters.js";
|
|
3
|
-
import { registerObserverCallback, unregisterObserverCallback } from "./observer.js";
|
|
4
3
|
/**
|
|
5
4
|
* Create exclusion modifier for query.
|
|
6
5
|
*
|
|
@@ -123,42 +122,11 @@ export function ensureQuery(world, ...terms) {
|
|
|
123
122
|
changed,
|
|
124
123
|
filter: filterMeta,
|
|
125
124
|
lastTick: new Map(),
|
|
126
|
-
// Callback to clean up query when its underlying filter is destroyed
|
|
127
|
-
onFilterDestroy: (destroyedFilter) => {
|
|
128
|
-
if (destroyedFilter !== filterMeta) {
|
|
129
|
-
return;
|
|
130
|
-
}
|
|
131
|
-
// Self-cleanup: unregister callback and remove from registry
|
|
132
|
-
unregisterObserverCallback(world, "filterDestroyed", queryMeta.onFilterDestroy);
|
|
133
|
-
world.queries.byId.delete(queryId);
|
|
134
|
-
},
|
|
135
125
|
};
|
|
136
126
|
world.queries.byId.set(queryId, queryMeta);
|
|
137
|
-
// Register for filter destruction events to enable automatic cleanup
|
|
138
|
-
registerObserverCallback(world, "filterDestroyed", queryMeta.onFilterDestroy);
|
|
139
127
|
}
|
|
140
128
|
return queryMeta;
|
|
141
129
|
}
|
|
142
|
-
/**
|
|
143
|
-
* Destroy query and clean up associated resources.
|
|
144
|
-
*
|
|
145
|
-
* Unregisters observer callbacks and removes from query registry.
|
|
146
|
-
*
|
|
147
|
-
* @param world - World instance
|
|
148
|
-
* @param queryMeta - Query metadata to destroy
|
|
149
|
-
*
|
|
150
|
-
* @example
|
|
151
|
-
* ```typescript
|
|
152
|
-
* const query = ensureQuery(world, Position);
|
|
153
|
-
* // ... use query ...
|
|
154
|
-
* destroyQuery(world, query);
|
|
155
|
-
* ```
|
|
156
|
-
*/
|
|
157
|
-
export function destroyQuery(world, queryMeta) {
|
|
158
|
-
const queryId = hashQuery(queryMeta.include, queryMeta.exclude, queryMeta.added, queryMeta.changed);
|
|
159
|
-
unregisterObserverCallback(world, "filterDestroyed", queryMeta.onFilterDestroy);
|
|
160
|
-
world.queries.byId.delete(queryId);
|
|
161
|
-
}
|
|
162
130
|
// ============================================================================
|
|
163
131
|
// Query Iteration (Internal)
|
|
164
132
|
// ============================================================================
|
|
@@ -167,12 +135,25 @@ export function destroyQuery(world, queryMeta) {
|
|
|
167
135
|
*/
|
|
168
136
|
function queryEntitiesWithMeta(world, queryMeta, callback) {
|
|
169
137
|
const hasChangeModifiers = queryMeta.added.length > 0 || queryMeta.changed.length > 0;
|
|
138
|
+
// Fast path: no change modifiers
|
|
139
|
+
if (!hasChangeModifiers) {
|
|
140
|
+
const archetypes = queryMeta.filter.archetypes;
|
|
141
|
+
for (let a = 0; a < archetypes.length; a++) {
|
|
142
|
+
const entities = archetypes[a].entities;
|
|
143
|
+
for (let i = entities.length - 1; i >= 0; i--) {
|
|
144
|
+
if (callback(entities[i]) === false) {
|
|
145
|
+
return;
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
return;
|
|
150
|
+
}
|
|
151
|
+
// Slow path: change detection requires system context
|
|
170
152
|
const { systemId, tick } = world.execution;
|
|
171
|
-
|
|
172
|
-
if (hasChangeModifiers && systemId === null) {
|
|
153
|
+
if (systemId === null) {
|
|
173
154
|
return;
|
|
174
155
|
}
|
|
175
|
-
const lastTick =
|
|
156
|
+
const lastTick = queryMeta.lastTick.get(systemId) ?? 0;
|
|
176
157
|
const archetypes = queryMeta.filter.archetypes;
|
|
177
158
|
// Pre-allocated arrays reused across archetypes to avoid allocation in hot loop
|
|
178
159
|
const addedTickArrays = [];
|
|
@@ -219,11 +200,9 @@ function queryEntitiesWithMeta(world, queryMeta, callback) {
|
|
|
219
200
|
}
|
|
220
201
|
}
|
|
221
202
|
finally {
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
queryMeta.lastTick.set(systemId, tick);
|
|
226
|
-
}
|
|
203
|
+
// Update lastTick after iteration completes or on early exit, this ensures
|
|
204
|
+
// subsequent iterations only see changes since this execution
|
|
205
|
+
queryMeta.lastTick.set(systemId, tick);
|
|
227
206
|
}
|
|
228
207
|
}
|
|
229
208
|
/**
|
|
@@ -235,56 +214,11 @@ function resolveQuery(world, termsOrQuery) {
|
|
|
235
214
|
}
|
|
236
215
|
return ensureQuery(world, ...termsOrQuery);
|
|
237
216
|
}
|
|
238
|
-
|
|
239
|
-
//
|
|
240
|
-
|
|
241
|
-
/**
|
|
242
|
-
* Iterate entities matching components and modifiers via callback.
|
|
243
|
-
*
|
|
244
|
-
* Iterates backward for safe entity destruction during iteration.
|
|
245
|
-
* Creates/reuses cached query internally.
|
|
246
|
-
*
|
|
247
|
-
* @param world - World instance
|
|
248
|
-
* @param termsOrQuery - Array of component IDs and query modifiers, or pre-built QueryMeta
|
|
249
|
-
* @param callback - Called for each matching entity. Return `false` to stop iteration early
|
|
250
|
-
*
|
|
251
|
-
* @example
|
|
252
|
-
* ```typescript
|
|
253
|
-
* // With inline terms
|
|
254
|
-
* queryEntities(world, [Position, Velocity, not(Dead)], (entity) => {
|
|
255
|
-
* const pos = getComponentValue(world, entity, Position, "x");
|
|
256
|
-
* });
|
|
257
|
-
*
|
|
258
|
-
* // With pre-built query
|
|
259
|
-
* const q = ensureQuery(world, Position, Velocity);
|
|
260
|
-
* queryEntities(world, q, (entity) => { ... });
|
|
261
|
-
*
|
|
262
|
-
* // Early exit
|
|
263
|
-
* queryEntities(world, [Position], (entity) => {
|
|
264
|
-
* if (done) return false;
|
|
265
|
-
* });
|
|
266
|
-
* ```
|
|
267
|
-
*/
|
|
268
|
-
export function queryEntities(world, termsOrQuery, callback) {
|
|
217
|
+
export function queryEntities(world, termsOrQuery,
|
|
218
|
+
// biome-ignore lint/suspicious/noExplicitAny: implementation overload must be wider than public overloads
|
|
219
|
+
callback) {
|
|
269
220
|
queryEntitiesWithMeta(world, resolveQuery(world, termsOrQuery), callback);
|
|
270
221
|
}
|
|
271
|
-
/**
|
|
272
|
-
* Get first entity matching components and modifiers.
|
|
273
|
-
*
|
|
274
|
-
* Useful for singleton patterns or when only one match is expected.
|
|
275
|
-
*
|
|
276
|
-
* @param world - World instance
|
|
277
|
-
* @param termsOrQuery - Array of component IDs and query modifiers, or pre-built QueryMeta
|
|
278
|
-
* @returns First matching entity ID, or undefined if no matches
|
|
279
|
-
*
|
|
280
|
-
* @example
|
|
281
|
-
* ```typescript
|
|
282
|
-
* const player = queryFirstEntity(world, [Player, not(Dead)]);
|
|
283
|
-
* if (player !== undefined) {
|
|
284
|
-
* const health = getComponentValue(world, player, Health, "value");
|
|
285
|
-
* }
|
|
286
|
-
* ```
|
|
287
|
-
*/
|
|
288
222
|
export function queryFirstEntity(world, termsOrQuery) {
|
|
289
223
|
let result;
|
|
290
224
|
queryEntitiesWithMeta(world, resolveQuery(world, termsOrQuery), (entity) => {
|
|
@@ -293,22 +227,6 @@ export function queryFirstEntity(world, termsOrQuery) {
|
|
|
293
227
|
});
|
|
294
228
|
return result;
|
|
295
229
|
}
|
|
296
|
-
/**
|
|
297
|
-
* Collect all matching entities into an array.
|
|
298
|
-
*
|
|
299
|
-
* @param world - World instance
|
|
300
|
-
* @param termsOrQuery - Array of component IDs and query modifiers, or pre-built QueryMeta
|
|
301
|
-
* @returns Array of matching entity IDs
|
|
302
|
-
*
|
|
303
|
-
* @example
|
|
304
|
-
* ```typescript
|
|
305
|
-
* const entities = collectEntities(world, [Position, Velocity]);
|
|
306
|
-
*
|
|
307
|
-
* // Pre-sort before iteration
|
|
308
|
-
* const sorted = collectEntities(world, [Position]);
|
|
309
|
-
* sorted.sort((a, b) => getComponentValue(world, a, Position, "x")! - getComponentValue(world, b, Position, "x")!);
|
|
310
|
-
* ```
|
|
311
|
-
*/
|
|
312
230
|
export function collectEntities(world, termsOrQuery) {
|
|
313
231
|
const result = [];
|
|
314
232
|
queryEntitiesWithMeta(world, resolveQuery(world, termsOrQuery), (entity) => {
|
package/dist/query.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"query.js","sourceRoot":"","sources":["../src/query.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAErD,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"query.js","sourceRoot":"","sources":["../src/query.ts"],"names":[],"mappings":"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"}
|
package/dist/resource.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { Component, EntityId } from "./encoding.js";
|
|
1
|
+
import type { Component, EntityId, EntityWith } from "./encoding.js";
|
|
2
2
|
import type { InferSchema, InferSchemaRecord, SchemaRecord } from "./schema.js";
|
|
3
3
|
import type { World } from "./world.js";
|
|
4
4
|
/**
|
|
@@ -36,29 +36,35 @@ export declare function removeResource(world: World, component: EntityId): void;
|
|
|
36
36
|
*
|
|
37
37
|
* @param world - World instance
|
|
38
38
|
* @param component - Component definition (acting as resource handle)
|
|
39
|
-
* @returns True if the resource exists,
|
|
39
|
+
* @returns True if the resource exists, narrowing the component for non-null access
|
|
40
40
|
*
|
|
41
41
|
* @example
|
|
42
42
|
* ```typescript
|
|
43
43
|
* if (hasResource(world, Time)) {
|
|
44
|
-
* // Time
|
|
44
|
+
* // Time narrowed to Component<S> & EntityWith<Component<S>>
|
|
45
|
+
* const dt = getResourceValue(world, Time, "delta"); // non-null
|
|
45
46
|
* }
|
|
46
47
|
* ```
|
|
47
48
|
*/
|
|
49
|
+
export declare function hasResource<S extends SchemaRecord>(world: World, component: Component<S>): component is Component<S> & EntityWith<Component<S>>;
|
|
48
50
|
export declare function hasResource(world: World, component: EntityId): boolean;
|
|
49
51
|
/**
|
|
50
52
|
* Gets the value of a specific field on a global resource.
|
|
51
53
|
*
|
|
52
54
|
* @param world - World instance
|
|
53
|
-
* @param component - Component definition
|
|
55
|
+
* @param component - Component definition (narrowed via hasResource for non-null access)
|
|
54
56
|
* @param key - Field name to retrieve
|
|
55
|
-
* @returns The field value, or undefined if
|
|
57
|
+
* @returns The field value (non-null if narrowed), or undefined if not present
|
|
56
58
|
*
|
|
57
59
|
* @example
|
|
58
60
|
* ```typescript
|
|
59
|
-
*
|
|
61
|
+
* if (hasResource(world, Time)) {
|
|
62
|
+
* const dt = getResourceValue(world, Time, "delta"); // number
|
|
63
|
+
* }
|
|
64
|
+
* const current = getResourceValue(world, Time, "current"); // number | undefined
|
|
60
65
|
* ```
|
|
61
66
|
*/
|
|
67
|
+
export declare function getResourceValue<S extends SchemaRecord, K extends keyof S>(world: World, component: Component<S> & EntityWith<Component<S>>, key: K): InferSchema<S[K]>;
|
|
62
68
|
export declare function getResourceValue<S extends SchemaRecord, K extends keyof S>(world: World, component: Component<S>, key: K): InferSchema<S[K]> | undefined;
|
|
63
69
|
/**
|
|
64
70
|
* Sets the value of a specific field on a global resource.
|
package/dist/resource.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"resource.d.ts","sourceRoot":"","sources":["../src/resource.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"resource.d.ts","sourceRoot":"","sources":["../src/resource.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AACrE,OAAO,KAAK,EAAE,WAAW,EAAE,iBAAiB,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAChF,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAMxC;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,WAAW,CAAC,CAAC,SAAS,YAAY,EAChD,KAAK,EAAE,KAAK,EACZ,SAAS,EAAE,SAAS,CAAC,CAAC,CAAC,EACvB,IAAI,EAAE,iBAAiB,CAAC,CAAC,CAAC,GACzB,IAAI,CAEN;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,KAAK,EAAE,SAAS,EAAE,QAAQ,GAAG,IAAI,CAEtE;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,WAAW,CAAC,CAAC,SAAS,YAAY,EAChD,KAAK,EAAE,KAAK,EACZ,SAAS,EAAE,SAAS,CAAC,CAAC,CAAC,GACtB,SAAS,IAAI,SAAS,CAAC,CAAC,CAAC,GAAG,UAAU,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC;AAExD,wBAAgB,WAAW,CAAC,KAAK,EAAE,KAAK,EAAE,SAAS,EAAE,QAAQ,GAAG,OAAO,CAAC;AAMxE;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,gBAAgB,CAAC,CAAC,SAAS,YAAY,EAAE,CAAC,SAAS,MAAM,CAAC,EACxE,KAAK,EAAE,KAAK,EACZ,SAAS,EAAE,SAAS,CAAC,CAAC,CAAC,GAAG,UAAU,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,EAClD,GAAG,EAAE,CAAC,GACL,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAErB,wBAAgB,gBAAgB,CAAC,CAAC,SAAS,YAAY,EAAE,CAAC,SAAS,MAAM,CAAC,EACxE,KAAK,EAAE,KAAK,EACZ,SAAS,EAAE,SAAS,CAAC,CAAC,CAAC,EACvB,GAAG,EAAE,CAAC,GACL,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,SAAS,CAAC;AAUjC;;;;;;;;;;;;;GAaG;AACH,wBAAgB,gBAAgB,CAAC,CAAC,SAAS,YAAY,EAAE,CAAC,SAAS,MAAM,CAAC,EACxE,KAAK,EAAE,KAAK,EACZ,SAAS,EAAE,SAAS,CAAC,CAAC,CAAC,EACvB,GAAG,EAAE,CAAC,EACN,KAAK,EAAE,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GACvB,IAAI,CAEN"}
|
package/dist/resource.js
CHANGED
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
import { addComponent, getComponentValue, hasComponent, removeComponent, setComponentValue } from "./component.js";
|
|
2
|
+
// ============================================================================
|
|
3
|
+
// Resource Operations
|
|
4
|
+
// ============================================================================
|
|
2
5
|
/**
|
|
3
6
|
* Adds a global resource (singleton) to the world using the component-on-self pattern.
|
|
4
7
|
*
|
|
@@ -33,36 +36,9 @@ export function addResource(world, component, data) {
|
|
|
33
36
|
export function removeResource(world, component) {
|
|
34
37
|
removeComponent(world, component, component);
|
|
35
38
|
}
|
|
36
|
-
/**
|
|
37
|
-
* Checks if a global resource exists in the world.
|
|
38
|
-
*
|
|
39
|
-
* @param world - World instance
|
|
40
|
-
* @param component - Component definition (acting as resource handle)
|
|
41
|
-
* @returns True if the resource exists, false otherwise
|
|
42
|
-
*
|
|
43
|
-
* @example
|
|
44
|
-
* ```typescript
|
|
45
|
-
* if (hasResource(world, Time)) {
|
|
46
|
-
* // Time resource is available
|
|
47
|
-
* }
|
|
48
|
-
* ```
|
|
49
|
-
*/
|
|
50
39
|
export function hasResource(world, component) {
|
|
51
40
|
return hasComponent(world, component, component);
|
|
52
41
|
}
|
|
53
|
-
/**
|
|
54
|
-
* Gets the value of a specific field on a global resource.
|
|
55
|
-
*
|
|
56
|
-
* @param world - World instance
|
|
57
|
-
* @param component - Component definition
|
|
58
|
-
* @param key - Field name to retrieve
|
|
59
|
-
* @returns The field value, or undefined if the resource is not present
|
|
60
|
-
*
|
|
61
|
-
* @example
|
|
62
|
-
* ```typescript
|
|
63
|
-
* const dt = getResourceValue(world, Time, "delta");
|
|
64
|
-
* ```
|
|
65
|
-
*/
|
|
66
42
|
export function getResourceValue(world, component, key) {
|
|
67
43
|
return getComponentValue(world, component, component, key);
|
|
68
44
|
}
|
package/dist/resource.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"resource.js","sourceRoot":"","sources":["../src/resource.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,iBAAiB,EAAE,YAAY,EAAE,eAAe,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAKnH;;;;;;;;;;;;;;;GAeG;AACH,MAAM,UAAU,WAAW,CACzB,KAAY,EACZ,SAAuB,EACvB,IAA0B;IAE1B,YAAY,CAAC,KAAK,EAAE,SAAS,EAAE,SAAS,EAAE,IAAI,CAAC,CAAC;AAClD,CAAC;AAED;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,cAAc,CAAC,KAAY,EAAE,SAAmB;IAC9D,eAAe,CAAC,KAAK,EAAE,SAAS,EAAE,SAAS,CAAC,CAAC;AAC/C,CAAC;
|
|
1
|
+
{"version":3,"file":"resource.js","sourceRoot":"","sources":["../src/resource.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,iBAAiB,EAAE,YAAY,EAAE,eAAe,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAKnH,+EAA+E;AAC/E,sBAAsB;AACtB,+EAA+E;AAE/E;;;;;;;;;;;;;;;GAeG;AACH,MAAM,UAAU,WAAW,CACzB,KAAY,EACZ,SAAuB,EACvB,IAA0B;IAE1B,YAAY,CAAC,KAAK,EAAE,SAAS,EAAE,SAAS,EAAE,IAAI,CAAC,CAAC;AAClD,CAAC;AAED;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,cAAc,CAAC,KAAY,EAAE,SAAmB;IAC9D,eAAe,CAAC,KAAK,EAAE,SAAS,EAAE,SAAS,CAAC,CAAC;AAC/C,CAAC;AAwBD,MAAM,UAAU,WAAW,CAAC,KAAY,EAAE,SAAmB;IAC3D,OAAO,YAAY,CAAC,KAAK,EAAE,SAAS,EAAE,SAAS,CAAC,CAAC;AACnD,CAAC;AA8BD,MAAM,UAAU,gBAAgB,CAC9B,KAAY,EACZ,SAAuB,EACvB,GAAM;IAEN,OAAO,iBAAiB,CAAC,KAAK,EAAE,SAAS,EAAE,SAAS,EAAE,GAAG,CAAC,CAAC;AAC7D,CAAC;AAED;;;;;;;;;;;;;GAaG;AACH,MAAM,UAAU,gBAAgB,CAC9B,KAAY,EACZ,SAAuB,EACvB,GAAM,EACN,KAAwB;IAExB,iBAAiB,CAAC,KAAK,EAAE,SAAS,EAAE,SAAS,EAAE,GAAG,EAAE,KAAK,CAAC,CAAC;AAC7D,CAAC"}
|
package/dist/scheduler.d.ts
CHANGED
|
@@ -70,6 +70,27 @@ export declare const Last: ScheduleLabel;
|
|
|
70
70
|
* Takes world, returns void or Promise for async systems.
|
|
71
71
|
*/
|
|
72
72
|
export type SystemRunner = (world: World) => void | Promise<void>;
|
|
73
|
+
/**
|
|
74
|
+
* System tick function returned by a SystemFactory's init.
|
|
75
|
+
*
|
|
76
|
+
* Runs every frame. The world is captured in the init closure scope,
|
|
77
|
+
* not passed as a parameter.
|
|
78
|
+
*/
|
|
79
|
+
export type SystemTick = () => void | Promise<void>;
|
|
80
|
+
/**
|
|
81
|
+
* System factory with init/tick separation.
|
|
82
|
+
*
|
|
83
|
+
* Created via `defineSystem()`. The init function runs once at registration
|
|
84
|
+
* time (`addSystem`), the returned tick function runs every frame.
|
|
85
|
+
*/
|
|
86
|
+
export type SystemFactory = {
|
|
87
|
+
/** @internal Runtime brand for discriminating SystemFactory from SystemRunner. */
|
|
88
|
+
readonly __systemFactory: true;
|
|
89
|
+
/** System name for scheduling constraints and execution context. */
|
|
90
|
+
readonly name: string;
|
|
91
|
+
/** Init function. Receives world, returns tick function. */
|
|
92
|
+
readonly init: (world: World) => SystemTick;
|
|
93
|
+
};
|
|
73
94
|
/**
|
|
74
95
|
* Options for system registration.
|
|
75
96
|
*/
|
|
@@ -119,17 +140,59 @@ export type SystemMeta = {
|
|
|
119
140
|
/**
|
|
120
141
|
* Registers a system in the world for later scheduling.
|
|
121
142
|
*
|
|
143
|
+
* Accepts either a `SystemRunner` function or a `SystemFactory` created by
|
|
144
|
+
* `defineSystem()`. When a factory is passed, its init function runs
|
|
145
|
+
* immediately and the returned tick function is registered as the runner.
|
|
146
|
+
*
|
|
122
147
|
* @param world - World instance
|
|
123
|
-
* @param
|
|
148
|
+
* @param system - System function or factory (must be named unless name option provided)
|
|
124
149
|
* @param options - Registration options (name, schedule, before, after)
|
|
125
150
|
*
|
|
126
151
|
* @example
|
|
127
152
|
* ```typescript
|
|
128
153
|
* addSystem(world, physicsSystem);
|
|
129
154
|
* addSystem(world, renderSystem, { schedule: PostUpdate, after: "physicsSystem" });
|
|
155
|
+
* addSystem(world, movementFactory); // SystemFactory from defineSystem()
|
|
156
|
+
* ```
|
|
157
|
+
*/
|
|
158
|
+
export declare function addSystem(world: World, system: SystemRunner | SystemFactory, options?: SystemOptions): void;
|
|
159
|
+
/**
|
|
160
|
+
* Define a system with separate init and tick phases.
|
|
161
|
+
*
|
|
162
|
+
* The init function runs once when the system is registered via `addSystem()`.
|
|
163
|
+
* Use it to cache query references, action getters, and other one-time setup.
|
|
164
|
+
* The returned tick function runs every frame during schedule execution.
|
|
165
|
+
*
|
|
166
|
+
* Local state can be declared as variables in the init closure — use it for
|
|
167
|
+
* system-internal bookkeeping (frame counters, cooldowns, cached computations).
|
|
168
|
+
* Use resources for state other systems need to read, components for per-entity state.
|
|
169
|
+
*
|
|
170
|
+
* @param name - System name
|
|
171
|
+
* @param init - Init function that receives the world and returns a tick function
|
|
172
|
+
* @returns SystemFactory to pass to `addSystem()`
|
|
173
|
+
*
|
|
174
|
+
* @example
|
|
175
|
+
* ```typescript
|
|
176
|
+
* const movementSystem = defineSystem("movementSystem", (world) => {
|
|
177
|
+
* // Init: runs once at addSystem() time
|
|
178
|
+
* const movers = ensureQuery(world, Position, Velocity);
|
|
179
|
+
*
|
|
180
|
+
* // Tick: runs every frame
|
|
181
|
+
* return () => {
|
|
182
|
+
* const dt = getResourceValue(world, Time, "delta") ?? 0;
|
|
183
|
+
* queryEntities(world, movers, (entity) => {
|
|
184
|
+
* const x = getComponentValue(world, entity, Position, "x")!;
|
|
185
|
+
* const vx = getComponentValue(world, entity, Velocity, "vx")!;
|
|
186
|
+
* setComponentValue(world, entity, Position, "x", x + vx * dt);
|
|
187
|
+
* });
|
|
188
|
+
* };
|
|
189
|
+
* });
|
|
190
|
+
*
|
|
191
|
+
* addSystem(world, movementSystem);
|
|
192
|
+
* addSystem(world, movementSystem, { schedule: PostUpdate, name: "lateMovement" });
|
|
130
193
|
* ```
|
|
131
194
|
*/
|
|
132
|
-
export declare function
|
|
195
|
+
export declare function defineSystem(name: string, init: (world: World) => SystemTick): SystemFactory;
|
|
133
196
|
/**
|
|
134
197
|
* Insert a schedule before an existing schedule in the pipeline.
|
|
135
198
|
*
|
package/dist/scheduler.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"scheduler.d.ts","sourceRoot":"","sources":["../src/scheduler.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAMxC;;GAEG;AACH,OAAO,CAAC,MAAM,oBAAoB,EAAE,OAAO,MAAM,CAAC;AAElD;;;;;GAKG;AACH,MAAM,MAAM,aAAa,GAAG,MAAM,GAAG;IAAE,CAAC,oBAAoB,CAAC,EAAE,IAAI,CAAA;CAAE,CAAC;AAMtE;;;;;;;;;;;;GAYG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,aAAa,CAE1D;AAMD;;GAEG;AACH,eAAO,MAAM,OAAO,eAA4B,CAAC;AAEjD;;GAEG;AACH,eAAO,MAAM,QAAQ,eAA6B,CAAC;AAEnD;;;;;;;GAOG;AACH,eAAO,MAAM,KAAK,eAA0B,CAAC;AAE7C;;GAEG;AACH,eAAO,MAAM,SAAS,eAA8B,CAAC;AAErD;;;;;;;GAOG;AACH,eAAO,MAAM,MAAM,eAA2B,CAAC;AAE/C;;GAEG;AACH,eAAO,MAAM,UAAU,eAA+B,CAAC;AAEvD;;GAEG;AACH,eAAO,MAAM,IAAI,eAAyB,CAAC;AAM3C;;;;GAIG;AACH,MAAM,MAAM,YAAY,GAAG,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;AAElE;;GAEG;AACH,MAAM,MAAM,aAAa,GAAG;IAC1B;;OAEG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC;IAEd;;OAEG;IACH,QAAQ,CAAC,EAAE,aAAa,CAAC;IAEzB;;OAEG;IACH,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IAE3B;;OAEG;IACH,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;CAC3B,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,UAAU,GAAG;IACvB;;OAEG;IACH,MAAM,EAAE,YAAY,CAAC;IAErB;;OAEG;IACH,QAAQ,EAAE,aAAa,CAAC;IAExB;;OAEG;IACH,KAAK,EAAE,MAAM,CAAC;IAEd;;OAEG;IACH,MAAM,EAAE,MAAM,EAAE,CAAC;IAEjB;;OAEG;IACH,KAAK,EAAE,MAAM,EAAE,CAAC;CACjB,CAAC;AAMF
|
|
1
|
+
{"version":3,"file":"scheduler.d.ts","sourceRoot":"","sources":["../src/scheduler.ts"],"names":[],"mappings":"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"}
|