libgdx/ashley

Reliably listening for component removal is (nearly?) impossible

ttencate opened this issue · 4 comments

On the wiki, it says:

For example, you may want to know whenever a PhysicsComponent is removed from an entity so you can destroy the physics body from the Box2D World.

This is exactly what I want to do, so I added a listener for when entities leave the family Family.all(BodyComponent.class).get(). This works fine if the entity itself is removed. However, when the BodyComponent is merely removed from the entity, I cannot destroy the Box2D Body, because the component is already gone at the time the listener is called.

Then I tried to make the listener trigger when the entity is added to the family, and in response hook up a componentRemoved listener to the entity that checks for a BodyComponent and cleans it up. However, the signal handler just gets told which entity a component was removed from, but not which component! That makes it rather useless, at least for my purposes, but probably for many others. Also, this approach won't catch cases where the entire entity is removed, rather than just the BodyComponent.

Maybe we need an engine-wide component listener? Something like:

public class Engine {
  ...
  public void addComponentListener(ComponentListener listener) { ... }
  public void removeComponentListener(ComponentListener listener) { ... }
  ...
}

public interface ComponentListener {
  /** Called when the component was added to the entity
   * and when an entity containing the component was added to the engine. */
  void componentAdded(Entity entity, Component component);

  /** Called when the component was removed from the entity
   * and when an entity containing the component was removed from the engine. */
  void componentRemoved(Entity entity, Component component);
} 

Or am I missing something? This seems like a common thing to want to do, so maybe everyone is doing it differently and I'm on the wrong track.

lukz commented

I had same issue #188

Ah, thanks. I searched but did not find it.

lukz commented

I think that at least misleading information on wiki page should be changed.

Done.