Ralith / hecs

A handy ECS
Apache License 2.0
921 stars 79 forks source link

[Question/Clarification] Are bundles suppose to be able to be used as queries? #323

Closed TrevorCow closed 1 year ago

TrevorCow commented 1 year ago

If I have:

#[derive(Bundle, Debug)]
pub struct EntityPlayer {
    pub name: String,
    pub movable_comp: MovableComp,
}

I can spawn it in a world with something like this:

 let player = EntityPlayer {
    name: "TrevorCow".to_string(),
    movable_comp: Default::default(),
};
let _player_entity = world.spawn(player);

However, I can not get all the EntityPlayers with

for (id, player) in &mut world.query::<&EntityPlayer>() {
    println!("Player {:?}: {:?}", id, player)
}

Is this correct behavior? It can easily be fixed with a Query struct like

#[derive(Query, Debug)]
pub struct EntityPlayerQuery<'a>{
    pub name: &'a String,
    pub movable_comp: &'a MovableComp,
}

but I'd rather not have to make a bunch of queries for my Bundles. Is there another way I should be doing this?

Ralith commented 1 year ago

Bundles own components, whereas queries borrow them, so they must be different types. Further, a query has to decide whether it should take a shared or unique borrow of a component, whereas no such distinction exists for bundles, so even generating a query type from a bundle wouldn't make sense; we'd need 2^n variants to cover every use case.

TrevorCow commented 1 year ago

Oh I see you could have (&String, &MovableComp), (&mut String, &MovableComp), (&String, &mut MovableComp), or (&mut String, &mut MovableComp). Interesting and very cool! Thanks for the explanation.