@@ -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