0
\$\begingroup\$

Which is best?

I have a bunch of components in my projects. It's related to Ashley (a java entity system) to libgdx (a game engine).

this components are like that:

public class SpriteComponent extends Component {

    private Sprite sprite;

    private SpriteComponent(Sprite sprite) {
        this.sprite = sprite;
    }

    public static SpriteComponent newInstance(Sprite sprite) {
        return new SpriteComponent(sprite);
    }

    public Sprite getSprite() {
        return sprite;
    }

}

public class PositionComponent extends Component {
    private Vector2 position = new Vector2();
    private float rotation;

    private PositionComponent() {
    }

    public static PositionComponent newInstance() {
        return new PositionComponent();
    }

    public Vector2 getPosition() {
        return position;
    }

    public void setPosition(Vector2 position) {
        this.position = position;
    }

    public float getRotation() {
        return rotation;
    }

    public void setRotation(float rotation) {
        this.rotation = rotation;
    }

    public void setPosition(float x, float y, float rotation) {
        position.x = x;
        position.y = y;
        this.rotation = rotation;
    }    
}

I have Entities that are compounded by these components.

Like:

Entity player = new Entity ();
player.add(SpriteComponent.newInstance(sprite));
player.add(PositionComponent.newInstance());

When we need to use these entities and components we do something like:

public class CameraPositionSystem extends EntitySystem {

    private ImmutableArray<Entity> entities;

    @Override
    public void addedToEngine(Engine engine) {
        entities = engine.getEntitiesFor(Family.all(PositionComponent.class, CameraFollowerComponent.class).get());
    }

    @Override
    public void update(float deltaTime) {
        for (Entity entity : entities) {
            /*get and use the component for that entity */
            final PositionComponent positionComponent = ComponentMapper.getFor(PositionComponent.class).get(entity);;
            final Vector2 position = positionComponent.getPosition();

        }
    }
}

Whenever I use a component I need to do this kind o calls: ComponentMapper.getFor(PositionComponent.class).get(entity)

There are many calls like that so I decided to put this is an separated util class:

public class ComponentMappers {
    public static final ComponentMapper<CameraComponent> CAMERA = ComponentMapper.getFor(CameraComponent.class);
    public static final ComponentMapper<TouchDownInputComponent> TOUCH_DOWN_INPUT = ComponentMapper
            .getFor(TouchDownInputComponent.class);
    public static final ComponentMapper<PositionComponent> POSITION = ComponentMapper.getFor(PositionComponent.class);
    public static final ComponentMapper<BodyComponent> BODY = ComponentMapper.getFor(BodyComponent.class);
    public static final ComponentMapper<CameraFollowerComponent> CAMERA_FOLLOWER = ComponentMapper
            .getFor(CameraFollowerComponent.class);
    public static final ComponentMapper<SpriteComponent> SPRITE_COMPONENT = ComponentMapper
            .getFor(SpriteComponent.class);

}

All this explanation are to ask:

What is the best, use a util class like that or put each calls in they own respective classes. For example:

public class PositionComponent extends Component {
    public static final ComponentMapper<PositionComponent> POSITION = ComponentMapper.getFor(PositionComponent.class);

    private Vector2 position = new Vector2();
    private float rotation;

    private PositionComponent() {
    }

    public static PositionComponent newInstance() {
        return new PositionComponent();
    }

    public Vector2 getPosition() {
        return position;
    }

    public void setPosition(Vector2 position) {
        this.position = position;
    }

    public float getRotation() {
        return rotation;
    }

    public void setRotation(float rotation) {
        this.rotation = rotation;
    }

    public void setPosition(float x, float y, float rotation) {
        position.x = x;
        position.y = y;
        this.rotation = rotation;
    }
}

Or a better alternative?

\$\endgroup\$

1 Answer 1

1
\$\begingroup\$

There really is not a wrong answer to this. Different places in the Java libraries use different strategies. For example, the new Java 8 code uses Collectors with a bunch of utility methods, and the same is true for the Arrays and Collections utility classes. On the other hand, these require specific imports to make them happen.

In your case, since you have to import the ComponentMapper class anyway, it makes sense to make the utility constants part of that class, instead of a new utility ComponentMappers class. I see nothing wrong with:

ComponentMapper<PositionComponent> position = ComponentMapper.POSITION;

You already have the static methods on that class, why not make them constants: ComponentMapper.getFor(PositionComponent.class)?

As for the remainder of your code, your code is neat, the generics look clean, There's no need to add another level of abstraction.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.