JaimeGensler / thyseus

An archetypal Entity Component System, built entirely in Typescript
MIT License
74 stars 3 forks source link

[FEAT] Cleaner query filter API #40

Closed JaimeGensler closed 1 year ago

JaimeGensler commented 1 year ago

Query filtering gets nasty pretty quickly when you need queries of any depth/complexity. Also, tuples to represent And filters sound nice in theory but are just less readable than the alternatives. The current API should be reworked to be cleaner and more readable.

Proposed API

The new API should introduce explicit And and remove tuples. Additionally, we can allow more generic arguments to be passed to And, Or, With, and Without - likely 4 to start, though this could be extended in the future. This should dramatically reduce the need for nesting and be significantly easier to parse at a glance.

This allows filtering for multiple components to be expressed with a simple With<A, B> rather than And<With<A>, And<With<B>>, but does not provide the same ergonomics for Or filters. This is intentional - And filtering adds to one possible condition and further restricts results, while Or filters create new branches of possible matches. As a result, overly-ergonomic Or filters would likely end up harder to parse by making it more difficult to determine all the possible combinations that could match.

Examples

// As before!
function mySystem(
  query: Query<[], With<A>
) { }

// Has all of A, B, C, & D
function mySystem(
  query: Query<[], With<A, B, C, D>
) { }

// Has none of A, B, C, & D
function mySystem(
  query: Query<[], Without<A, B, C, D>
) { }

// Has A, does not have B, and either has C or does not have D
function mySystem(
  query: Query<[], And<With<A>, Without<B>, Or<With<C>, Without<D>>>>
) { }