Skip to content

[Discussion] New filter API #12

@akhilman

Description

@akhilman

I have two complains about the current edict API:

  • There is no way to get entities if one or another component is modified. The current query::<(Modified<&A>, Modified<&B>)>() means that both components are modified;
  • The tracked query without Modified like query::<(&A, &B)>.tracked(&mut tracks) is meaningless;
  • Mutation of tracks by query is not intuitive. I have to clone tracks to pass it to multiple queries.

I propose this changes:

  • Remove Modified query;
  • Remove methods like World::for_each_tracked and QueryRef::tracked_iter;
  • Move skip_chunk and skip_item from Query to Filter;
  • Add Modified<T> which owns it's tracks and ModifiedSince<T> which refers the tracks from outside.
  • Add Or and And filters;
  • Add constructors with::<T>(), without::<T>(), modified_since::<T>(tracks) and modified::<T>();
  • Add .or(filter) and .and(filter) methods to Filter trait;
  • Add methods like World::for_each_filtered and QueryRef::filter or event World::query_filtered like bevy_ecs does.

Query with this changes will look like:

// the stateful filter is created outside the loop
let mut my_filter = with::<Foo>().or(with::<Bar>()).and(modified::<Baz>());
loop {
    for _, (bar, baz) in world.query_filtered<(&Bar, &Baz)>(&mut my_filter) {
        // do something
    }
}

and with passing the tracks manually:

let mut tracks = world.tracks_now()
loop {
    world.for_each_filtered::<(&Bar, &Baz)>(
        &mut with::<Foo>()
            .or(with::<Bar>())
            .and(modified_since::<Baz>(tracks)),
         |_, (bar. baz)| { ... } );
    tracks = world.tracks_now();  // tracks is updated explicitly 
}

Solves #10

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions