@codehz/ecs 0.3.5 → 0.3.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/archetype.d.ts +17 -0
- package/index.js +68 -46
- package/package.json +1 -1
- package/query.d.ts +8 -0
package/archetype.d.ts
CHANGED
|
@@ -117,6 +117,14 @@ export declare class Archetype {
|
|
|
117
117
|
* @returns An array of component data or undefined if not present
|
|
118
118
|
*/
|
|
119
119
|
getOptionalComponentData<T>(componentType: EntityId<T>): T[] | undefined;
|
|
120
|
+
/**
|
|
121
|
+
* Helper: compute or return cached data sources for provided componentTypes
|
|
122
|
+
*/
|
|
123
|
+
private getCachedComponentDataSources;
|
|
124
|
+
/**
|
|
125
|
+
* Helper: build component tuples for a specific entity index using precomputed data sources
|
|
126
|
+
*/
|
|
127
|
+
private buildComponentsForIndex;
|
|
120
128
|
/**
|
|
121
129
|
* Get entities with their component data for specified component types
|
|
122
130
|
* Optimized for bulk component access with pre-computed indices
|
|
@@ -127,6 +135,15 @@ export declare class Archetype {
|
|
|
127
135
|
entity: EntityId;
|
|
128
136
|
components: ComponentTuple<T>;
|
|
129
137
|
}>;
|
|
138
|
+
/**
|
|
139
|
+
* Iterate over entities with their component data for specified component types
|
|
140
|
+
* implemented as a generator returning each entity/components pair lazily
|
|
141
|
+
* @param componentTypes Array of component types to retrieve
|
|
142
|
+
*/
|
|
143
|
+
iterateWithComponents<const T extends readonly ComponentType<any>[]>(componentTypes: T): IterableIterator<{
|
|
144
|
+
entity: EntityId;
|
|
145
|
+
components: ComponentTuple<T>;
|
|
146
|
+
}>;
|
|
130
147
|
/**
|
|
131
148
|
* Iterate over entities with their component data for specified component types
|
|
132
149
|
* Optimized for bulk component access
|
package/index.js
CHANGED
|
@@ -402,16 +402,9 @@ class Archetype {
|
|
|
402
402
|
getOptionalComponentData(componentType) {
|
|
403
403
|
return this.componentData.get(componentType);
|
|
404
404
|
}
|
|
405
|
-
|
|
406
|
-
const result = [];
|
|
407
|
-
this.forEachWithComponents(componentTypes, (entity, ...components) => {
|
|
408
|
-
result.push({ entity, components });
|
|
409
|
-
});
|
|
410
|
-
return result;
|
|
411
|
-
}
|
|
412
|
-
forEachWithComponents(componentTypes, callback) {
|
|
405
|
+
getCachedComponentDataSources(componentTypes) {
|
|
413
406
|
const cacheKey = componentTypes.map((id) => isOptionalEntityId(id) ? `opt(${id.optional})` : `${id}`).join(",");
|
|
414
|
-
|
|
407
|
+
return getOrComputeCache(this.componentDataSourcesCache, cacheKey, () => {
|
|
415
408
|
return componentTypes.map((compType) => {
|
|
416
409
|
let optional = false;
|
|
417
410
|
if (isOptionalEntityId(compType)) {
|
|
@@ -433,46 +426,67 @@ class Archetype {
|
|
|
433
426
|
}
|
|
434
427
|
});
|
|
435
428
|
});
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
}
|
|
452
|
-
}
|
|
453
|
-
const matchingRelations = dataSource;
|
|
454
|
-
const relations = [];
|
|
455
|
-
for (const relType of matchingRelations) {
|
|
456
|
-
const dataArray = this.getComponentData(relType);
|
|
457
|
-
const data = dataArray[entityIndex];
|
|
458
|
-
const decodedRel = decodeRelationId(relType);
|
|
459
|
-
relations.push([decodedRel.targetId, data === MISSING_COMPONENT ? undefined : data]);
|
|
460
|
-
}
|
|
461
|
-
return optional ? { value: relations } : relations;
|
|
462
|
-
} else {
|
|
463
|
-
if (dataSource === undefined) {
|
|
464
|
-
if (optional) {
|
|
465
|
-
return;
|
|
466
|
-
} else {
|
|
467
|
-
throw new Error(`No matching relations found for mandatory wildcard relation component type`);
|
|
468
|
-
}
|
|
429
|
+
}
|
|
430
|
+
buildComponentsForIndex(componentTypes, componentDataSources, entityIndex) {
|
|
431
|
+
return componentDataSources.map((dataSource, i) => {
|
|
432
|
+
let compType = componentTypes[i];
|
|
433
|
+
let optional = false;
|
|
434
|
+
if (isOptionalEntityId(compType)) {
|
|
435
|
+
compType = compType.optional;
|
|
436
|
+
optional = true;
|
|
437
|
+
}
|
|
438
|
+
if (getIdType(compType) === "wildcard-relation") {
|
|
439
|
+
if (dataSource === undefined) {
|
|
440
|
+
if (optional) {
|
|
441
|
+
return;
|
|
442
|
+
} else {
|
|
443
|
+
throw new Error(`No matching relations found for mandatory wildcard relation component type`);
|
|
469
444
|
}
|
|
470
|
-
|
|
445
|
+
}
|
|
446
|
+
const matchingRelations = dataSource;
|
|
447
|
+
const relations = [];
|
|
448
|
+
for (const relType of matchingRelations) {
|
|
449
|
+
const dataArray = this.getComponentData(relType);
|
|
471
450
|
const data = dataArray[entityIndex];
|
|
472
|
-
const
|
|
473
|
-
|
|
451
|
+
const decodedRel = decodeRelationId(relType);
|
|
452
|
+
relations.push([decodedRel.targetId, data === MISSING_COMPONENT ? undefined : data]);
|
|
474
453
|
}
|
|
475
|
-
|
|
454
|
+
return optional ? { value: relations } : relations;
|
|
455
|
+
} else {
|
|
456
|
+
if (dataSource === undefined) {
|
|
457
|
+
if (optional) {
|
|
458
|
+
return;
|
|
459
|
+
} else {
|
|
460
|
+
throw new Error(`No matching relations found for mandatory wildcard relation component type`);
|
|
461
|
+
}
|
|
462
|
+
}
|
|
463
|
+
const dataArray = dataSource;
|
|
464
|
+
const data = dataArray[entityIndex];
|
|
465
|
+
const result = data === MISSING_COMPONENT ? undefined : data;
|
|
466
|
+
return optional ? { value: result } : result;
|
|
467
|
+
}
|
|
468
|
+
});
|
|
469
|
+
}
|
|
470
|
+
getEntitiesWithComponents(componentTypes) {
|
|
471
|
+
const result = [];
|
|
472
|
+
this.forEachWithComponents(componentTypes, (entity, ...components) => {
|
|
473
|
+
result.push({ entity, components });
|
|
474
|
+
});
|
|
475
|
+
return result;
|
|
476
|
+
}
|
|
477
|
+
*iterateWithComponents(componentTypes) {
|
|
478
|
+
const componentDataSources = this.getCachedComponentDataSources(componentTypes);
|
|
479
|
+
for (let entityIndex = 0;entityIndex < this.entities.length; entityIndex++) {
|
|
480
|
+
const entity = this.entities[entityIndex];
|
|
481
|
+
const components = this.buildComponentsForIndex(componentTypes, componentDataSources, entityIndex);
|
|
482
|
+
yield { entity, components };
|
|
483
|
+
}
|
|
484
|
+
}
|
|
485
|
+
forEachWithComponents(componentTypes, callback) {
|
|
486
|
+
const componentDataSources = this.getCachedComponentDataSources(componentTypes);
|
|
487
|
+
for (let entityIndex = 0;entityIndex < this.entities.length; entityIndex++) {
|
|
488
|
+
const entity = this.entities[entityIndex];
|
|
489
|
+
const components = this.buildComponentsForIndex(componentTypes, componentDataSources, entityIndex);
|
|
476
490
|
callback(entity, ...components);
|
|
477
491
|
}
|
|
478
492
|
}
|
|
@@ -756,6 +770,14 @@ class Query {
|
|
|
756
770
|
archetype.forEachWithComponents(componentTypes, callback);
|
|
757
771
|
}
|
|
758
772
|
}
|
|
773
|
+
*iterate(componentTypes) {
|
|
774
|
+
if (this.isDisposed) {
|
|
775
|
+
throw new Error("Query has been disposed");
|
|
776
|
+
}
|
|
777
|
+
for (const archetype of this.cachedArchetypes) {
|
|
778
|
+
yield* archetype.iterateWithComponents(componentTypes);
|
|
779
|
+
}
|
|
780
|
+
}
|
|
759
781
|
getComponentData(componentType) {
|
|
760
782
|
if (this.isDisposed) {
|
|
761
783
|
throw new Error("Query has been disposed");
|
package/package.json
CHANGED
package/query.d.ts
CHANGED
|
@@ -32,6 +32,14 @@ export declare class Query {
|
|
|
32
32
|
* @param callback Function called for each entity with its components
|
|
33
33
|
*/
|
|
34
34
|
forEach<const T extends readonly ComponentType<any>[]>(componentTypes: T, callback: (entity: EntityId, ...components: ComponentTuple<T>) => void): void;
|
|
35
|
+
/**
|
|
36
|
+
* Iterate over entities with their component data (generator)
|
|
37
|
+
* @param componentTypes Array of component types to retrieve
|
|
38
|
+
*/
|
|
39
|
+
iterate<const T extends readonly ComponentType<any>[]>(componentTypes: T): IterableIterator<{
|
|
40
|
+
entity: EntityId;
|
|
41
|
+
components: ComponentTuple<T>;
|
|
42
|
+
}>;
|
|
35
43
|
/**
|
|
36
44
|
* Get component data arrays for all matching entities
|
|
37
45
|
* @param componentType The component type to retrieve
|