Skip to main content

bundle

Macro bundle 

Source
macro_rules! bundle {
    [] => { ... };
    [@list $bundle:ident, ..$spread:expr, $($rest:tt)*] => { ... };
    [@list $bundle:ident, ..$spread:expr] => { ... };
    [@list $bundle:ident, $leaf:expr, $($rest:tt)*] => { ... };
    [@list $bundle:ident,] => { ... };
    [@list $bundle:ident, $leaf:expr] => { ... };
    [$($item:tt)+] => { ... };
}
Expand description

Builds a bundle from the components written between the brackets.

The items are components, separated by commas: bundle![a, b] is two components. A list of one needs no comma, so bundle![a] is the single component a. An item is one component however it is written, because every 'static type is one: bundle![(a, b)] names a single tuple component, and bundle![()] a single empty-tuple one.

The macro is written with brackets, bundle![a, b], throughout this crate and its dependents. Rust accepts any of the three delimiters after the !, so the brackets are a convention that keeps a bundle’s items, which are not call arguments, visibly distinct.

let mut world = World::new();
let entity = world.root_scope_mut().spawn(bundle![1u32, 2.0f32, true]);
assert!(world.root_scope().query_one::<Has<u32>>(entity).unwrap().get());
assert!(world.root_scope().query_one::<Has<f32>>(entity).unwrap().get());
assert!(world.root_scope().query_one::<Has<bool>>(entity).unwrap().get());

// A tuple is one component.
let entity = world.root_scope_mut().spawn(bundle![(1u8, 2u8)]);
assert!(world.root_scope().query_one::<Has<(u8, u8)>>(entity).unwrap().get());
assert!(!world.root_scope().query_one::<Has<u8>>(entity).unwrap().get());

A bundle written as ..value is unwrapped into its own components, the way spawning it alone would. The syntax is needed because the macro walks the source and cannot tell a bundle from a component; written plainly, a bundle is one component.

let mut gathered = DynamicBundle::new();
gathered.push_component(1u32);
let mut world = World::new();
let entity = world.root_scope_mut().spawn(bundle![..gathered, true]);
assert!(world.root_scope().query_one::<Has<u32>>(entity).unwrap().get());
assert!(world.root_scope().query_one::<Has<bool>>(entity).unwrap().get());

The width is bounded by the compiler’s recursion limit rather than by a fixed count: each item costs a level of macro recursion, so roughly a hundred components fit at the default limit of 128. A wider bundle is built by raising #![recursion_limit] in the calling crate, or by pushing onto a DynamicBundle directly.

A type that appears twice panics when the bundle is spawned.