#Making a function that accepts any query

6 messages · Page 1 of 1 (latest)

visual drum
#

Hi! There's a function that would make my life much easier if I managed to make it work, and I feel like I am very close to a solution, but stuck.

What I would like is a function that tells me if any of the entities in a tile is present in a certain query.

The following code works fine:

pub fn is_tile_blocked (
        &self, x_grid: &i32, y_grid: &i32,
        blocker_query: &Query<Entity, With<components::BlocksMovement>>,
        ) -> bool {

        let entities_selected = &self.entities_in_tile(x_grid, y_grid);

        // Returns true if at least one of the entities_selected is also in the query
        return entities_selected.iter().any(|x| blocker_query.contains(*x));
    }

However I would need to write one of these for every query I want to use. I suspect I create a function that works for any query if I use generic traits. The closest I have gotten is this:

pub fn entities_in_query<T>(&self, x_grid: &i32, y_grid: &i32, query: &T) -> bool {

        let entities_selected = &self.entities_in_tile(x_grid, y_grid);

        // Returns true if at least one of the entities_selected is also in the query
        return entities_selected.iter().any(|x| query.contains(x));
    }

This compiles, but fails if I try to use it. It complains about the "contains" function, saying that it's not found in &T. I believe that could be solved if I added bounds to the generic type T so that only queries would fit. However I can't figure out what those traits should be for queries. I see in the documentation that Query implements Debug, IntoIterator and some others, are those what I need to add? Cargo suggests adding RangeBounds, as that includes a contains() function, but I'm pretty sure that's wrong.

Thanks in advance!

daring oyster
#
    return entities_selected.iter().any(|x| query.contains(x));

There was a deref above, but it's missing here

#

You probably also need a PartialEq bound on T

granite turret
#

You can probably also use something like query.iter_many(ents).next().is_some(). I'm not sure which approach would be more efficient off the top of my head.

quartz yarrow
#

Try this instead:

pub fn entities_in_query<Q,F>(&self, x_grid: &i32, y_grid: &i32, query: &Query<Q,F>) -> bool
where Q: WorldQuery, F: ReadOnlyWorldQuery
{
visual drum