Skip to content
This repository was archived by the owner on Apr 13, 2025. It is now read-only.
This repository was archived by the owner on Apr 13, 2025. It is now read-only.

The removal queries can react pooled entity when removing entity inside system #278

Description

@ukjhsa

I found that the removal queries of the former order system would get the wrong.

According to the docs, if an application has a running order as: SystemA > SystemB > SystemC and SystemB removes an entity, just SystemC will be able to react to it and SystemA will not be able to read that data. But I found that the SystemA will be able to react the entity that is in pools.

The example

    class TestComponent extends Component {}
    
    class BeforeSystem extends System {
      execute() {
        this.queries.as.added.forEach(entity => {
          console.log(`In BeforeSystem: entity id ${entity.id} added`);
        });
    
        this.queries.as.removed.forEach(entity => {
          console.log(`In BeforeSystem: entity id ${entity.id} removed, its alive: ${entity.alive}, its removed comp: ${!!entity.getRemovedComponent(TestComponent)}`);
        })
    
        this.queries.as.results.forEach(entity => {
          console.log(`In BeforeSystem: entity id ${entity.id} present`);
        })
      }
    }
    
    BeforeSystem.queries = {
      as: {
        components: [TestComponent],
        listen: {
          added: true,
          removed: true,
        }
      },
    }
    
    class RemoveSystem extends System {
      count = 0;
      execute() {
        this.queries.as.added.forEach(entity => {
          console.log(`In RemoveSystem: entity id ${entity.id} added`);
        });
    
        this.queries.as.removed.forEach(entity => {
          console.log(`In RemoveSystem: entity id ${entity.id} removed, its alive: ${entity.alive}, its removed comp: ${!!entity.getRemovedComponent(TestComponent)}`);
        })
    
        this.queries.as.results.forEach(entity => {
          console.log(`In RemoveSystem: entity id ${entity.id} present`);
          
          if (this.count === 1) {
            entity.remove();
            console.log(`In RemoveSystem: entity id ${entity.id} to be removed`);
          }
        })
    
        this.count++;
      }
    }
    
    RemoveSystem.queries = {
      as: {
        components: [TestComponent],
        listen: {
          added: true,
          removed: true,
        }
      },
    }
    
    class AfterSystem extends System {
      execute() {
        this.queries.as.added.forEach(entity => {
          console.log(`In AfterSystem: entity id ${entity.id} added`);
        });
    
        this.queries.as.removed.forEach(entity => {
          console.log(`In AfterSystem: entity id ${entity.id} removed, its alive: ${entity.alive}, its removed comp: ${!!entity.getRemovedComponent(TestComponent)}`);
        })
    
        this.queries.as.results.forEach(entity => {
          console.log(`In AfterSystem: entity id ${entity.id} present`);
        })
      }
    }
    
    AfterSystem.queries = {
      as: {
        components: [TestComponent],
        listen: {
          added: true,
          removed: true,
        }
      },
    }
    
    const world = new World();
    world.registerComponent(TestComponent);
    
    world.registerSystem(BeforeSystem);
    world.registerSystem(RemoveSystem);
    world.registerSystem(AfterSystem);
    
    const entity = world.createEntity();
    entity.addComponent(TestComponent);
    
    console.log('=== First frame ==');
    world.execute();
    console.log('=== Second frame ===');
    world.execute();
    console.log('=== Third frame ===');
    world.execute();

The output is

    === First frame ==
    In BeforeSystem: entity id 0 added
    In BeforeSystem: entity id 0 present
    In RemoveSystem: entity id 0 added
    In RemoveSystem: entity id 0 present
    In AfterSystem: entity id 0 added
    In AfterSystem: entity id 0 present
    === Second frame ===
    In BeforeSystem: entity id 0 present
    In RemoveSystem: entity id 0 present
    In RemoveSystem: entity id 0 to be removed
    In AfterSystem: entity id 0 removed, its alive: false, its removed comp: true
    === Third frame ===
    In BeforeSystem: entity id 1 removed, its alive: false, its removed comp: false

You can see that the BeforeSystem can react the entity with id 1 on second frame, is it a normal behavior?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions