Ralith / hecs

A handy ECS
Apache License 2.0
967 stars 82 forks source link

Query by DynamicBundle #360

Closed cjhowedev closed 9 months ago

cjhowedev commented 9 months ago

Allow for issuing queries using DynamicBundle. We currently have to use a separate struct with #[derive(Query)]. It would be nice if we could query a bundle, for example:

use hecs::{World};

let mut world = World::new();
let mut target_world = World::new();

#[derive(Bundle, DynamicBundleClone, BundleQuery)]
struct MyBundle {
  integer: i32,
  float: f32,
}

let bundle_to_spawn = MyBundle { integer: 1, float: 2.0 };
let spawned = world.spawn(bundle);

for (entity, bundle) in world.query_mut::<MyBundleQuery>() {
  assert_eq!(entity, spawned);
  assert_eq!(bundle, bundle_to_spawn);
  target_world.spawn(bundle.clone())
}

Presumably, MyBundleQuery is generated by the #[derive(BundleQuery)]. This is necessary because each field needs to be wrapped in a reference to work as a query type, so we can't use the original MyBundle.

cjhowedev commented 9 months ago

After some thought, this is externally implementable. Nevermind

Ralith commented 9 months ago

This has come up a few times before. The tricky part is that you might reasonably want either shared or unique references for each component of a bundle, so a clean general-purpose solution becomes complex. You could bodge something ugly but serviceable pretty easy with a declarative macro though, yeah.

Ralith commented 9 months ago

If your goal is actually just to do some asserts like that, you might be interested in https://github.com/Ralith/hecs/pull/354.