libgdx/ashley

Bug when adding component in EntityListener

Nauktis opened this issue · 1 comments

I found a bug when an EntityListener is used to add/remove Component to an entity.

Explanation:
I have two EntityListeners:

new EntityListener() {
  @Override
  public void entityAdded(Entity entity) {
    entity.add(new HasEngineFlagComponent());
  }

  @Override
  public void entityRemoved(Entity entity) {
    entity.remove(HasEngineFlagComponent.class);
  }
}

and

new EntityListener() {
  @Override
  public void entityAdded(Entity entity) {
    entity.add(new UUIDComponent());
  }

  @Override
  public void entityRemoved(Entity entity) {
    entity.remove(UUIDComponent.class);
  }
}

When issuing the following code:

Entity e = new Entity()
engine.addEntity(e)

As expected, the entity receives a HasEngineFlagComponent and then a UUIDComponent

But when doing engine.removeEntity(e)

The following happens:
HasEngineFlagComponent is removed from the entity
HasEngineFlagComponent is added to the entity
UUIDComponent is added to the entity
UUIDComponent is removed from the entity

This happens because the call to removeEntity enters the method updateFamilyMembership(e, true)
All families are reviewed and the entity is removed from them. But the listeners are then called which calls entity.remove(ComponentX) in this case.

This triggers an inner call to updateFamilyMembership(e, false) which will add back some components that were already removed by the outer updateFamilyMembership(e, true).

I wrote a UnitTest that shows this behaviour. See #204

Thanks for the report, it is indeed a bug. Will look into it.