Skip to content

Commit 59c5e4e

Browse files
committed
refactor(world): improve empty archetype removal logic
- Simplified the conditions for removing empty archetypes during component removal and entity destruction. - Added a new private method `removeEmptyArchetype` to handle the removal of empty archetypes from internal data structures. - Ensured that archetypes are only removed if they are truly empty, improving data integrity and performance.
1 parent cd8a6e2 commit 59c5e4e

File tree

1 file changed

+41
-1
lines changed

1 file changed

+41
-1
lines changed

src/world.ts

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ export class World<ExtraParams extends any[] = [deltaTime: number]> {
8585
for (const { sourceEntityId, componentType } of componentReferences) {
8686
// Directly remove the component from the source entity
8787
const sourceArchetype = this.entityToArchetype.get(sourceEntityId);
88-
if (sourceArchetype && sourceArchetype.componentTypes.includes(componentType)) {
88+
if (sourceArchetype) {
8989
// Remove from current archetype and move to new archetype without this component
9090
const currentComponents = new Map<EntityId<any>, any>();
9191
for (const compType of sourceArchetype.componentTypes) {
@@ -102,6 +102,9 @@ export class World<ExtraParams extends any[] = [deltaTime: number]> {
102102

103103
// Remove from current archetype
104104
sourceArchetype.removeEntity(sourceEntityId);
105+
if (sourceArchetype.getEntities().length === 0) {
106+
this.removeEmptyArchetype(sourceArchetype);
107+
}
105108

106109
// Add to new archetype
107110
newArchetype.addEntity(sourceEntityId, currentComponents);
@@ -116,6 +119,9 @@ export class World<ExtraParams extends any[] = [deltaTime: number]> {
116119
this.entityReverseIndex.delete(entityId);
117120

118121
archetype.removeEntity(entityId);
122+
if (archetype.getEntities().length === 0) {
123+
this.removeEmptyArchetype(archetype);
124+
}
119125
this.entityToArchetype.delete(entityId);
120126
this.entityIdManager.deallocate(entityId);
121127
}
@@ -575,4 +581,38 @@ export class World<ExtraParams extends any[] = [deltaTime: number]> {
575581
const references = this.entityReverseIndex.get(targetEntityId);
576582
return references ? Array.from(references) : [];
577583
}
584+
585+
/**
586+
* Remove an empty archetype from all internal data structures
587+
*/
588+
private removeEmptyArchetype(archetype: Archetype): void {
589+
// Only remove if archetype is actually empty
590+
if (archetype.getEntities().length > 0) {
591+
return;
592+
}
593+
594+
// Remove from archetypes array
595+
const index = this.archetypes.indexOf(archetype);
596+
if (index !== -1) {
597+
this.archetypes.splice(index, 1);
598+
}
599+
600+
// Remove from archetypeMap
601+
const hashKey = this.getComponentTypesHash(archetype.componentTypes);
602+
this.archetypeMap.delete(hashKey);
603+
604+
// Remove from componentToArchetypes
605+
for (const componentType of archetype.componentTypes) {
606+
const archetypes = this.componentToArchetypes.get(componentType);
607+
if (archetypes) {
608+
const compIndex = archetypes.indexOf(archetype);
609+
if (compIndex !== -1) {
610+
archetypes.splice(compIndex, 1);
611+
if (archetypes.length === 0) {
612+
this.componentToArchetypes.delete(componentType);
613+
}
614+
}
615+
}
616+
}
617+
}
578618
}

0 commit comments

Comments
 (0)