Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Explore annotation-based component retrieval #1

Open
Alexander-Prime opened this issue Sep 28, 2016 · 0 comments
Open

Explore annotation-based component retrieval #1

Alexander-Prime opened this issue Sep 28, 2016 · 0 comments

Comments

@Alexander-Prime
Copy link
Contributor

The problem

Currently, EntitySystems must submit filtering parameters their components from a passed Entity directly:

public CustomEntitySystem() {
    requireAll(
            ComponentTypeA.class,
            ComponentTypeB.class );
}

@Override public void onHandleEntity( Entity entity, double deltaTime ) {
    ComponentTypeA aComp = entity.get( ComponentTypeA.class );
    ComponentTypeB bComp = entity.get( ComponentTypeB.class );
    // Use aComp and bComp...
}

This is verbose and redundant. ComponentTypeA is mentioned three times, .classis called twice, and one is just a hack to get around Java's type erasure.

A solution

A preferred API might look like this:

@EntityHandler void onHandleEntityA(
        Entity entity,
        double deltaTime,
        @Component ComponentTypeA aComp,
        @Component ComponentTypeB bComp ) {
    // Use aComp and bComp...
}

This is better because it requires no special setup in the constructor, and allows for multiple filters; there is nothing stopping you from writing @EntityHandler in front of several methods. No further variable declaration need be made inside the method, and the compiler and library can work together to ensure that none of these arguments is null.

Complications

  1. I have no idea how to write an annotation processor
  2. requireOne() and forbid() filters are not accounted for
  3. This may introduce a lot of library code just for a small amount of API elegance

Number 1 is restated as "I haven't read a tutorial yet". One day, tops.

Number 2 is already "solved" conceptually. When you can annotate several methods, requireOne() is reproduced by using one method for each optional component. This makes for larger code, but it brings some benefits: it's a more accurate reflection of what's probably desired (distinct behavior for each kind of entity), and it allows the engine to select from several whole sets of components, which also flexibly handles awkward corner cases that would normally need extra filtering methods like requireOneGroup().

Number 3 is the biggest hangup. Flare is meant to be exceptionally lightweight, and right now that means the bare minimum number of classes to accomplish each task.

That's kind of being violated already, in a way: EntitySystem extends GameSystem, and filters for entities while iterating in its onUpdate() method, which is something that a user of the library could do if Engine.ENTITIES were not package-private. I think this leads to a conclusion that the real goal here is not to have as few classes as possible, but to require as few classes to be used per task as possible.

Desireable? Helpful?

Please comment on this issue if you have some opinion on whether or how this should be implemented.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant