Skip to content

Commit 51542a6

Browse files
committed
refactor(world): optimize archetype change logic
1 parent 4c67db6 commit 51542a6

File tree

1 file changed

+23
-2
lines changed

1 file changed

+23
-2
lines changed

src/world.ts

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -846,8 +846,19 @@ export class World<UpdateParams extends any[] = []> {
846846
const removedComponents = new Map<EntityId<any>, any>();
847847

848848
if (finalComponentTypes) {
849-
// Move to new archetype
850-
this.moveEntityToNewArchetype(entityId, currentArchetype, finalComponentTypes, changeset, removedComponents);
849+
// Check if archetype-affecting components actually changed
850+
// (dontFragment components don't affect archetype signature)
851+
const currentRegularTypes = this.filterRegularComponentTypes(allCurrentComponentTypes);
852+
const finalRegularTypes = this.filterRegularComponentTypes(finalComponentTypes);
853+
const archetypeChanged = !this.areComponentTypesEqual(currentRegularTypes, finalRegularTypes);
854+
855+
if (archetypeChanged) {
856+
// Move to new archetype (regular components changed)
857+
this.moveEntityToNewArchetype(entityId, currentArchetype, finalComponentTypes, changeset, removedComponents);
858+
} else {
859+
// Only dontFragment components changed, stay in same archetype
860+
this.updateEntityInSameArchetype(entityId, currentArchetype, changeset, removedComponents);
861+
}
851862
} else {
852863
// Update in same archetype
853864
this.updateEntityInSameArchetype(entityId, currentArchetype, changeset, removedComponents);
@@ -1012,6 +1023,16 @@ export class World<UpdateParams extends any[] = []> {
10121023
return getOrCreateWithSideEffect(this.archetypeBySignature, hashKey, () => this.createNewArchetype(sortedTypes));
10131024
}
10141025

1026+
/**
1027+
* Compare two arrays of component types for equality (order-independent)
1028+
*/
1029+
private areComponentTypesEqual(types1: EntityId<any>[], types2: EntityId<any>[]): boolean {
1030+
if (types1.length !== types2.length) return false;
1031+
const sorted1 = [...types1].sort((a, b) => a - b);
1032+
const sorted2 = [...types2].sort((a, b) => a - b);
1033+
return sorted1.every((v, i) => v === sorted2[i]);
1034+
}
1035+
10151036
/**
10161037
* Filter out dontFragment relations from component types, but keep wildcard markers
10171038
*/

0 commit comments

Comments
 (0)