SortedSubIteratingSystem - GameDevWeek/CodeBase GitHub Wiki

If you have to iterate over sorted entities in a big system with different subtasks you might want to consider implementing sub systems to divide the work and keep your code readable and maintainable. The SortedSubIteratingSystem will make your life easier by providing the required infrastructure.

What is a SubSystem?

The SubSystem is a part of a bigger system to provide related functionality. It is responsible to process a user defined family of entities.

Requirements:

  • Extend the SubSystem class
  • Entity family
  • Definition of a processEntity() function

What is a SortedSubIteratingSystem?

The SortedSubIteratingSystem is a subclass of the SortedIteratingSystem and encapsulates a collection of SubSystems. It iterates over a sorted user defined family of entities and delegates to the SubSystem with a matching family.

Note: The SortedSubIteratingSystem can also perform pre- and/or postprocessing before delegation but make sure to call its super functions (super.update() and super.processEntity()).

Note: The family of the SortedSubIteratingSystem is "global" and affects all SubSystems. The family of a SubSystem is a closer definition of its area of responsibility.

Requirements:

  • Extend the SortedSubIteratingSystem
  • Entity family
  • Provide a comparator to define the order of the entity collection
  • Use addSubSystem() to add SubSystems

Note: The order of addSubSystem() calls defines the order of delegation. If SubSystem A and B are responsible for family F and A was added before B then A processes the entity first.

How to use it

Let’s say we want to create a RenderSystem in a 2D sidescroller.

To support multiple layers (background, foreground…) we create a LayerComponent:

public class LayerComponent extends Component implements Pool.Poolable {
    public int layer = 0;

    @Override
    public void reset() {
        layer = 0;
    }
}

To render our entities in the correct order we use this component in our comparator:

private static final class RenderComparator implements Comparator<Entity> {
    @Override
    public int compare(Entity e1, Entity e2) {
        LayerComponent l1 = ComponentMappers.layer.get(e1);
        LayerComponent l2 = ComponentMappers.layer.get(e2);
             
        return l1.layer - l2.layer;
    }
 }

Our RenderSystem has multiple sub systems like TextureRenderer, ParticleRenderer and LightRenderer. The TextureRenderer could look like this:

public class TextureRenderer extends SortedSubIteratingSystem.SubSystem {
    public TextureRenderer() {
        super(Family.all(TextureComponent.class).get());
    }

    @Override
    public void processEntity(Entity entity, float deltaTime) {
        render(entity);
    }
}

And finally in the RenderSystem we have to add our sub systems (renderer classes) and let them do the magic in the update function:

public class RenderSystem extends SortedSubIteratingSystem {

    private final static RenderComparator renderComparator = new RenderComparator();

    public RenderSystem(int priority) {
        super(Family.all(PositionComponent.class, LayerComponent.class).get(), 
              renderComparator, priority);

        addSubSystem(new TextureRenderer());
        addSubSystem(new ParticleRenderer());
        addSubSystem(new LightRenderer());
    }

    @Override
    public void processEntity(Entity entity, float deltaTime) {
    	// Some preprocessing
    	super.processEntity(entity, deltaTime);
        // Some postprocessing
    }

    @Override
    public void update(float deltaTime) {
        // Some preprocessing
        super.update(deltaTime); // SubSystems will take care of things
        // Some postprocessing
    }
}

The family of the SortedSubIteratingSystem imposes a restriction on all of its SubSystems to only allow entities of that family. In this case the RenderSystem only accepts entities which have a PositionComponent and a LayerComponent.

⚠️ **GitHub.com Fallback** ⚠️