Accept Bundles for insert and remove. Deprecate insert/remove_bundle (#6039)

# Objective

Take advantage of the "impl Bundle for Component" changes in #2975 / add the follow up changes discussed there.

## Solution

- Change `insert` and `remove` to accept a Bundle instead of a Component (for both Commands and World)
- Deprecate `insert_bundle`, `remove_bundle`, and `remove_bundle_intersection`
- Add `remove_intersection`

---

## Changelog

- Change `insert` and `remove` now accept a Bundle instead of a Component (for both Commands and World)
- `insert_bundle` and `remove_bundle` are deprecated
 

## Migration Guide

Replace `insert_bundle` with `insert`:
```rust
// Old (0.8)
commands.spawn().insert_bundle(SomeBundle::default());
// New (0.9)
commands.spawn().insert(SomeBundle::default());
```

Replace `remove_bundle` with `remove`:
```rust
// Old (0.8)
commands.entity(some_entity).remove_bundle::<SomeBundle>();
// New (0.9)
commands.entity(some_entity).remove::<SomeBundle>();
```

Replace `remove_bundle_intersection` with `remove_intersection`:
```rust
// Old (0.8)
world.entity_mut(some_entity).remove_bundle_intersection::<SomeBundle>();
// New (0.9)
world.entity_mut(some_entity).remove_intersection::<SomeBundle>();
```

Consider consolidating as many operations as possible to improve ergonomics and cut down on archetype moves:
```rust
// Old (0.8)
commands.spawn()
  .insert_bundle(SomeBundle::default())
  .insert(SomeComponent);

// New (0.9) - Option 1
commands.spawn().insert((
  SomeBundle::default(),
  SomeComponent,
))

// New (0.9) - Option 2
commands.spawn_bundle((
  SomeBundle::default(),
  SomeComponent,
))
```

## Next Steps

Consider changing `spawn` to accept a bundle and deprecate `spawn_bundle`.
This commit is contained in:
Carter Anderson 2022-09-21 21:47:53 +00:00
parent d9e99cd80c
commit cd15f0f5be
65 changed files with 494 additions and 609 deletions

View file

@ -27,7 +27,7 @@ impl Benchmark {
entities.push( entities.push(
world world
.spawn() .spawn()
.insert_bundle(( .insert((
A(Mat4::from_scale(Vec3::ONE)), A(Mat4::from_scale(Vec3::ONE)),
B(Mat4::from_scale(Vec3::ONE)), B(Mat4::from_scale(Vec3::ONE)),
C(Mat4::from_scale(Vec3::ONE)), C(Mat4::from_scale(Vec3::ONE)),

View file

@ -26,7 +26,7 @@ impl Benchmark {
entities.push( entities.push(
world world
.spawn() .spawn()
.insert_bundle(( .insert((
A(Mat4::from_scale(Vec3::ONE)), A(Mat4::from_scale(Vec3::ONE)),
B(Mat4::from_scale(Vec3::ONE)), B(Mat4::from_scale(Vec3::ONE)),
C(Mat4::from_scale(Vec3::ONE)), C(Mat4::from_scale(Vec3::ONE)),

View file

@ -23,7 +23,7 @@ impl Benchmark {
pub fn run(&mut self) { pub fn run(&mut self) {
let mut world = World::new(); let mut world = World::new();
for _ in 0..10_000 { for _ in 0..10_000 {
world.spawn().insert_bundle(( world.spawn().insert((
Transform(Mat4::from_scale(Vec3::ONE)), Transform(Mat4::from_scale(Vec3::ONE)),
Position(Vec3::X), Position(Vec3::X),
Rotation(Vec3::X), Rotation(Vec3::X),

View file

@ -6,7 +6,7 @@ macro_rules! create_entities {
#[derive(Component)] #[derive(Component)]
struct $variants(f32); struct $variants(f32);
for _ in 0..20 { for _ in 0..20 {
$world.spawn().insert_bundle(($variants(0.0), Data(1.0))); $world.spawn().insert(($variants(0.0), Data(1.0)));
} }
)* )*
}; };

View file

@ -6,7 +6,7 @@ macro_rules! create_entities {
#[derive(Component)] #[derive(Component)]
struct $variants(f32); struct $variants(f32);
for _ in 0..20 { for _ in 0..20 {
$world.spawn().insert_bundle(($variants(0.0), Data(1.0))); $world.spawn().insert(($variants(0.0), Data(1.0)));
} }
)* )*
}; };

View file

@ -6,7 +6,7 @@ macro_rules! create_entities {
#[derive(Component)] #[derive(Component)]
struct $variants(f32); struct $variants(f32);
for _ in 0..20 { for _ in 0..20 {
$world.spawn().insert_bundle(( $world.spawn().insert((
$variants(0.0), $variants(0.0),
Data::<0>(1.0), Data::<0>(1.0),
Data::<1>(1.0), Data::<1>(1.0),

View file

@ -36,7 +36,7 @@ impl<'w> Benchmark<'w> {
pub fn new() -> Self { pub fn new() -> Self {
let mut world = World::new(); let mut world = World::new();
for _ in 0..5 { for _ in 0..5 {
world.spawn().insert_bundle(( world.spawn().insert((
Data::<0>(1.0), Data::<0>(1.0),
Data::<1>(1.0), Data::<1>(1.0),
Data::<2>(1.0), Data::<2>(1.0),

View file

@ -6,7 +6,7 @@ macro_rules! create_entities {
#[derive(Component)] #[derive(Component)]
struct $variants(f32); struct $variants(f32);
for _ in 0..20 { for _ in 0..20 {
$world.spawn().insert_bundle(( $world.spawn().insert((
$variants(0.0), $variants(0.0),
Data::<0>(1.0), Data::<0>(1.0),
Data::<1>(1.0), Data::<1>(1.0),

View file

@ -36,7 +36,7 @@ impl<'w> Benchmark<'w> {
let mut world = World::new(); let mut world = World::new();
for _ in 0..5 { for _ in 0..5 {
world.spawn().insert_bundle(( world.spawn().insert((
Data::<0>(1.0), Data::<0>(1.0),
Data::<1>(1.0), Data::<1>(1.0),
Data::<2>(1.0), Data::<2>(1.0),

View file

@ -21,7 +21,7 @@ impl<'w> Benchmark<'w> {
// TODO: batch this // TODO: batch this
for _ in 0..10_000 { for _ in 0..10_000 {
world.spawn().insert_bundle(( world.spawn().insert((
Transform(Mat4::from_scale(Vec3::ONE)), Transform(Mat4::from_scale(Vec3::ONE)),
Position(Vec3::X), Position(Vec3::X),
Rotation(Vec3::X), Rotation(Vec3::X),

View file

@ -21,7 +21,7 @@ impl<'w> Benchmark<'w> {
// TODO: batch this // TODO: batch this
for _ in 0..10_000 { for _ in 0..10_000 {
world.spawn().insert_bundle(( world.spawn().insert((
Transform(Mat4::from_scale(Vec3::ONE)), Transform(Mat4::from_scale(Vec3::ONE)),
Position(Vec3::X), Position(Vec3::X),
Rotation(Vec3::X), Rotation(Vec3::X),

View file

@ -23,7 +23,7 @@ impl<'w> Benchmark<'w> {
// TODO: batch this // TODO: batch this
for _ in 0..10_000 { for _ in 0..10_000 {
world.spawn().insert_bundle(( world.spawn().insert((
Transform(Mat4::from_scale(Vec3::ONE)), Transform(Mat4::from_scale(Vec3::ONE)),
Position(Vec3::X), Position(Vec3::X),
Rotation(Vec3::X), Rotation(Vec3::X),

View file

@ -35,7 +35,7 @@ impl<'w> Benchmark<'w> {
// TODO: batch this // TODO: batch this
for _ in 0..10_000 { for _ in 0..10_000 {
world.spawn().insert_bundle(( world.spawn().insert((
Transform(Mat4::from_scale(Vec3::ONE)), Transform(Mat4::from_scale(Vec3::ONE)),
Rotation(Vec3::X), Rotation(Vec3::X),
Position::<0>(Vec3::X), Position::<0>(Vec3::X),

View file

@ -37,7 +37,7 @@ impl<'w> Benchmark<'w> {
// TODO: batch this // TODO: batch this
for _ in 0..10_000 { for _ in 0..10_000 {
world.spawn().insert_bundle(( world.spawn().insert((
Transform(Mat4::from_scale(Vec3::ONE)), Transform(Mat4::from_scale(Vec3::ONE)),
Rotation(Vec3::X), Rotation(Vec3::X),
Position::<0>(Vec3::X), Position::<0>(Vec3::X),

View file

@ -23,7 +23,7 @@ impl<'w> Benchmark<'w> {
// TODO: batch this // TODO: batch this
for _ in 0..10_000 { for _ in 0..10_000 {
world.spawn().insert_bundle(( world.spawn().insert((
Transform(Mat4::from_scale(Vec3::ONE)), Transform(Mat4::from_scale(Vec3::ONE)),
Position(Vec3::X), Position(Vec3::X),
Rotation(Vec3::X), Rotation(Vec3::X),

View file

@ -21,7 +21,7 @@ impl Benchmark {
// TODO: batch this // TODO: batch this
for _ in 0..10_000 { for _ in 0..10_000 {
world.spawn().insert_bundle(( world.spawn().insert((
Transform(Mat4::from_scale(Vec3::ONE)), Transform(Mat4::from_scale(Vec3::ONE)),
Position(Vec3::X), Position(Vec3::X),
Rotation(Vec3::X), Rotation(Vec3::X),

View file

@ -35,7 +35,7 @@ impl<'w> Benchmark<'w> {
// TODO: batch this // TODO: batch this
for _ in 0..10_000 { for _ in 0..10_000 {
world.spawn().insert_bundle(( world.spawn().insert((
Transform(Mat4::from_scale(Vec3::ONE)), Transform(Mat4::from_scale(Vec3::ONE)),
Rotation(Vec3::X), Rotation(Vec3::X),
Position::<0>(Vec3::X), Position::<0>(Vec3::X),

View file

@ -37,7 +37,7 @@ impl<'w> Benchmark<'w> {
// TODO: batch this // TODO: batch this
for _ in 0..10_000 { for _ in 0..10_000 {
world.spawn().insert_bundle(( world.spawn().insert((
Transform(Mat4::from_scale(Vec3::ONE)), Transform(Mat4::from_scale(Vec3::ONE)),
Rotation(Vec3::X), Rotation(Vec3::X),
Position::<0>(Vec3::X), Position::<0>(Vec3::X),

View file

@ -95,7 +95,7 @@ pub fn insert_commands(criterion: &mut Criterion) {
for entity in &entities { for entity in &entities {
commands commands
.entity(*entity) .entity(*entity)
.insert_bundle((Matrix::default(), Vec3::default())); .insert((Matrix::default(), Vec3::default()));
} }
drop(commands); drop(commands);
command_queue.apply(&mut world); command_queue.apply(&mut world);
@ -238,7 +238,7 @@ pub fn get_or_spawn(criterion: &mut Criterion) {
for i in 0..10_000 { for i in 0..10_000 {
commands commands
.get_or_spawn(Entity::from_raw(i)) .get_or_spawn(Entity::from_raw(i))
.insert_bundle((Matrix::default(), Vec3::default())); .insert((Matrix::default(), Vec3::default()));
} }
command_queue.apply(&mut world); command_queue.apply(&mut world);
}); });

View file

@ -213,7 +213,7 @@ pub fn extract_core_3d_camera_phases(
) { ) {
for (entity, camera) in &cameras_3d { for (entity, camera) in &cameras_3d {
if camera.is_active { if camera.is_active {
commands.get_or_spawn(entity).insert_bundle(( commands.get_or_spawn(entity).insert((
RenderPhase::<Opaque3d>::default(), RenderPhase::<Opaque3d>::default(),
RenderPhase::<AlphaMask3d>::default(), RenderPhase::<AlphaMask3d>::default(),
RenderPhase::<Transparent3d>::default(), RenderPhase::<Transparent3d>::default(),

View file

@ -276,10 +276,10 @@ struct PlayerBundle {
let mut world = World::new(); let mut world = World::new();
// Spawn a new entity and insert the default PlayerBundle // Spawn a new entity and insert the default PlayerBundle
world.spawn().insert_bundle(PlayerBundle::default()); world.spawn().insert(PlayerBundle::default());
// Bundles play well with Rust's struct update syntax // Bundles play well with Rust's struct update syntax
world.spawn().insert_bundle(PlayerBundle { world.spawn().insert(PlayerBundle {
position: Position { x: 1.0, y: 1.0 }, position: Position { x: 1.0, y: 1.0 },
..Default::default() ..Default::default()
}); });

View file

@ -65,7 +65,7 @@ enum SimulationSystem {
// If an entity gets spawned, we increase the counter in the EntityCounter resource // If an entity gets spawned, we increase the counter in the EntityCounter resource
fn spawn_entities(mut commands: Commands, mut entity_counter: ResMut<EntityCounter>) { fn spawn_entities(mut commands: Commands, mut entity_counter: ResMut<EntityCounter>) {
if rand::thread_rng().gen_bool(0.6) { if rand::thread_rng().gen_bool(0.6) {
let entity_id = commands.spawn().insert(Age::default()).id(); let entity_id = commands.spawn_bundle(Age::default()).id();
println!(" spawning {:?}", entity_id); println!(" spawning {:?}", entity_id);
entity_counter.value += 1; entity_counter.value += 1;
} }

View file

@ -16,22 +16,19 @@
//! |Spawn a new entity|[`Commands::spawn`]|[`World::spawn`]| //! |Spawn a new entity|[`Commands::spawn`]|[`World::spawn`]|
//! |Spawn an entity with components|[`Commands::spawn_bundle`]|---| //! |Spawn an entity with components|[`Commands::spawn_bundle`]|---|
//! |Despawn an entity|[`EntityCommands::despawn`]|[`World::despawn`]| //! |Despawn an entity|[`EntityCommands::despawn`]|[`World::despawn`]|
//! |Insert a component to an entity|[`EntityCommands::insert`]|[`EntityMut::insert`]| //! |Insert a component, bundle, or tuple of components and bundles to an entity|[`EntityCommands::insert`]|[`EntityMut::insert`]|
//! |Insert multiple components to an entity|[`EntityCommands::insert_bundle`]|[`EntityMut::insert_bundle`]| //! |Remove a component, bundle, or tuple of components and bundles from an entity|[`EntityCommands::remove`]|[`EntityMut::remove`]|
//! |Remove a component from an entity|[`EntityCommands::remove`]|[`EntityMut::remove`]|
//! //!
//! [`World`]: crate::world::World //! [`World`]: crate::world::World
//! [`Commands::spawn`]: crate::system::Commands::spawn //! [`Commands::spawn`]: crate::system::Commands::spawn
//! [`Commands::spawn_bundle`]: crate::system::Commands::spawn_bundle //! [`Commands::spawn_bundle`]: crate::system::Commands::spawn_bundle
//! [`EntityCommands::despawn`]: crate::system::EntityCommands::despawn //! [`EntityCommands::despawn`]: crate::system::EntityCommands::despawn
//! [`EntityCommands::insert`]: crate::system::EntityCommands::insert //! [`EntityCommands::insert`]: crate::system::EntityCommands::insert
//! [`EntityCommands::insert_bundle`]: crate::system::EntityCommands::insert_bundle
//! [`EntityCommands::remove`]: crate::system::EntityCommands::remove //! [`EntityCommands::remove`]: crate::system::EntityCommands::remove
//! [`World::spawn`]: crate::world::World::spawn //! [`World::spawn`]: crate::world::World::spawn
//! [`World::spawn_bundle`]: crate::world::World::spawn_bundle //! [`World::spawn_bundle`]: crate::world::World::spawn_bundle
//! [`World::despawn`]: crate::world::World::despawn //! [`World::despawn`]: crate::world::World::despawn
//! [`EntityMut::insert`]: crate::world::EntityMut::insert //! [`EntityMut::insert`]: crate::world::EntityMut::insert
//! [`EntityMut::insert_bundle`]: crate::world::EntityMut::insert_bundle
//! [`EntityMut::remove`]: crate::world::EntityMut::remove //! [`EntityMut::remove`]: crate::world::EntityMut::remove
mod map_entities; mod map_entities;
mod serde; mod serde;

View file

@ -111,11 +111,11 @@ mod tests {
let e = world let e = world
.spawn() .spawn()
.insert_bundle((TableStored("abc"), SparseStored(123))) .insert((TableStored("abc"), SparseStored(123)))
.id(); .id();
let f = world let f = world
.spawn() .spawn()
.insert_bundle((TableStored("def"), SparseStored(456), A(1))) .insert((TableStored("def"), SparseStored(456), A(1)))
.id(); .id();
assert_eq!(world.get::<TableStored>(e).unwrap().0, "abc"); assert_eq!(world.get::<TableStored>(e).unwrap().0, "abc");
assert_eq!(world.get::<SparseStored>(e).unwrap().0, 123); assert_eq!(world.get::<SparseStored>(e).unwrap().0, 123);
@ -136,14 +136,18 @@ mod tests {
let mut world = World::new(); let mut world = World::new();
#[derive(Bundle, PartialEq, Debug)] #[derive(Bundle, PartialEq, Debug)]
struct Foo { struct FooBundle {
x: TableStored, x: TableStored,
y: SparseStored, y: SparseStored,
} }
let mut ids = Vec::new(); let mut ids = Vec::new();
<Foo as Bundle>::component_ids(&mut world.components, &mut world.storages, &mut |id| { <FooBundle as Bundle>::component_ids(
ids.push(id); &mut world.components,
}); &mut world.storages,
&mut |id| {
ids.push(id);
},
);
assert_eq!( assert_eq!(
ids, ids,
@ -155,14 +159,14 @@ mod tests {
let e1 = world let e1 = world
.spawn() .spawn()
.insert_bundle(Foo { .insert(FooBundle {
x: TableStored("abc"), x: TableStored("abc"),
y: SparseStored(123), y: SparseStored(123),
}) })
.id(); .id();
let e2 = world let e2 = world
.spawn() .spawn()
.insert_bundle((TableStored("def"), SparseStored(456), A(1))) .insert((TableStored("def"), SparseStored(456), A(1)))
.id(); .id();
assert_eq!(world.get::<TableStored>(e1).unwrap().0, "abc"); assert_eq!(world.get::<TableStored>(e1).unwrap().0, "abc");
assert_eq!(world.get::<SparseStored>(e1).unwrap().0, 123); assert_eq!(world.get::<SparseStored>(e1).unwrap().0, 123);
@ -178,24 +182,28 @@ mod tests {
assert_eq!(world.get::<SparseStored>(e2).unwrap().0, 42); assert_eq!(world.get::<SparseStored>(e2).unwrap().0, 42);
assert_eq!( assert_eq!(
world.entity_mut(e1).remove_bundle::<Foo>().unwrap(), world.entity_mut(e1).remove::<FooBundle>().unwrap(),
Foo { FooBundle {
x: TableStored("xyz"), x: TableStored("xyz"),
y: SparseStored(123), y: SparseStored(123),
} }
); );
#[derive(Bundle, PartialEq, Debug)] #[derive(Bundle, PartialEq, Debug)]
struct Nested { struct NestedBundle {
a: A, a: A,
foo: Foo, foo: FooBundle,
b: B, b: B,
} }
let mut ids = Vec::new(); let mut ids = Vec::new();
<Nested as Bundle>::component_ids(&mut world.components, &mut world.storages, &mut |id| { <NestedBundle as Bundle>::component_ids(
ids.push(id); &mut world.components,
}); &mut world.storages,
&mut |id| {
ids.push(id);
},
);
assert_eq!( assert_eq!(
ids, ids,
@ -209,9 +217,9 @@ mod tests {
let e3 = world let e3 = world
.spawn() .spawn()
.insert_bundle(Nested { .insert(NestedBundle {
a: A(1), a: A(1),
foo: Foo { foo: FooBundle {
x: TableStored("ghi"), x: TableStored("ghi"),
y: SparseStored(789), y: SparseStored(789),
}, },
@ -224,10 +232,10 @@ mod tests {
assert_eq!(world.get::<A>(e3).unwrap().0, 1); assert_eq!(world.get::<A>(e3).unwrap().0, 1);
assert_eq!(world.get::<B>(e3).unwrap().0, 2); assert_eq!(world.get::<B>(e3).unwrap().0, 2);
assert_eq!( assert_eq!(
world.entity_mut(e3).remove_bundle::<Nested>().unwrap(), world.entity_mut(e3).remove::<NestedBundle>().unwrap(),
Nested { NestedBundle {
a: A(1), a: A(1),
foo: Foo { foo: FooBundle {
x: TableStored("ghi"), x: TableStored("ghi"),
y: SparseStored(789), y: SparseStored(789),
}, },
@ -239,14 +247,8 @@ mod tests {
#[test] #[test]
fn despawn_table_storage() { fn despawn_table_storage() {
let mut world = World::new(); let mut world = World::new();
let e = world let e = world.spawn().insert((TableStored("abc"), A(123))).id();
.spawn() let f = world.spawn().insert((TableStored("def"), A(456))).id();
.insert_bundle((TableStored("abc"), A(123)))
.id();
let f = world
.spawn()
.insert_bundle((TableStored("def"), A(456)))
.id();
assert_eq!(world.entities.len(), 2); assert_eq!(world.entities.len(), 2);
assert!(world.despawn(e)); assert!(world.despawn(e));
assert_eq!(world.entities.len(), 1); assert_eq!(world.entities.len(), 1);
@ -262,11 +264,11 @@ mod tests {
let e = world let e = world
.spawn() .spawn()
.insert_bundle((TableStored("abc"), SparseStored(123))) .insert((TableStored("abc"), SparseStored(123)))
.id(); .id();
let f = world let f = world
.spawn() .spawn()
.insert_bundle((TableStored("def"), SparseStored(456))) .insert((TableStored("def"), SparseStored(456)))
.id(); .id();
assert_eq!(world.entities.len(), 2); assert_eq!(world.entities.len(), 2);
assert!(world.despawn(e)); assert!(world.despawn(e));
@ -280,14 +282,8 @@ mod tests {
#[test] #[test]
fn query_all() { fn query_all() {
let mut world = World::new(); let mut world = World::new();
let e = world let e = world.spawn().insert((TableStored("abc"), A(123))).id();
.spawn() let f = world.spawn().insert((TableStored("def"), A(456))).id();
.insert_bundle((TableStored("abc"), A(123)))
.id();
let f = world
.spawn()
.insert_bundle((TableStored("def"), A(456)))
.id();
let ents = world let ents = world
.query::<(Entity, &A, &TableStored)>() .query::<(Entity, &A, &TableStored)>()
@ -306,14 +302,8 @@ mod tests {
#[test] #[test]
fn query_all_for_each() { fn query_all_for_each() {
let mut world = World::new(); let mut world = World::new();
let e = world let e = world.spawn().insert((TableStored("abc"), A(123))).id();
.spawn() let f = world.spawn().insert((TableStored("def"), A(456))).id();
.insert_bundle((TableStored("abc"), A(123)))
.id();
let f = world
.spawn()
.insert_bundle((TableStored("def"), A(456)))
.id();
let mut results = Vec::new(); let mut results = Vec::new();
world world
@ -331,13 +321,10 @@ mod tests {
#[test] #[test]
fn query_single_component() { fn query_single_component() {
let mut world = World::new(); let mut world = World::new();
let e = world let e = world.spawn().insert((TableStored("abc"), A(123))).id();
.spawn()
.insert_bundle((TableStored("abc"), A(123)))
.id();
let f = world let f = world
.spawn() .spawn()
.insert_bundle((TableStored("def"), A(456), B(1))) .insert((TableStored("def"), A(456), B(1)))
.id(); .id();
let ents = world let ents = world
.query::<(Entity, &A)>() .query::<(Entity, &A)>()
@ -350,10 +337,7 @@ mod tests {
#[test] #[test]
fn stateful_query_handles_new_archetype() { fn stateful_query_handles_new_archetype() {
let mut world = World::new(); let mut world = World::new();
let e = world let e = world.spawn().insert((TableStored("abc"), A(123))).id();
.spawn()
.insert_bundle((TableStored("abc"), A(123)))
.id();
let mut query = world.query::<(Entity, &A)>(); let mut query = world.query::<(Entity, &A)>();
let ents = query.iter(&world).map(|(e, &i)| (e, i)).collect::<Vec<_>>(); let ents = query.iter(&world).map(|(e, &i)| (e, i)).collect::<Vec<_>>();
@ -361,7 +345,7 @@ mod tests {
let f = world let f = world
.spawn() .spawn()
.insert_bundle((TableStored("def"), A(456), B(1))) .insert((TableStored("def"), A(456), B(1)))
.id(); .id();
let ents = query.iter(&world).map(|(e, &i)| (e, i)).collect::<Vec<_>>(); let ents = query.iter(&world).map(|(e, &i)| (e, i)).collect::<Vec<_>>();
assert_eq!(ents, &[(e, A(123)), (f, A(456))]); assert_eq!(ents, &[(e, A(123)), (f, A(456))]);
@ -370,13 +354,10 @@ mod tests {
#[test] #[test]
fn query_single_component_for_each() { fn query_single_component_for_each() {
let mut world = World::new(); let mut world = World::new();
let e = world let e = world.spawn().insert((TableStored("abc"), A(123))).id();
.spawn()
.insert_bundle((TableStored("abc"), A(123)))
.id();
let f = world let f = world
.spawn() .spawn()
.insert_bundle((TableStored("def"), A(456), B(1))) .insert((TableStored("def"), A(456), B(1)))
.id(); .id();
let mut results = Vec::new(); let mut results = Vec::new();
world world
@ -392,8 +373,8 @@ mod tests {
let e1 = world.spawn().insert(A(1)).id(); let e1 = world.spawn().insert(A(1)).id();
let e2 = world.spawn().insert(A(2)).id(); let e2 = world.spawn().insert(A(2)).id();
let e3 = world.spawn().insert(A(3)).id(); let e3 = world.spawn().insert(A(3)).id();
let e4 = world.spawn().insert_bundle((A(4), B(1))).id(); let e4 = world.spawn().insert((A(4), B(1))).id();
let e5 = world.spawn().insert_bundle((A(5), B(1))).id(); let e5 = world.spawn().insert((A(5), B(1))).id();
let results = Arc::new(Mutex::new(Vec::new())); let results = Arc::new(Mutex::new(Vec::new()));
world world
.query::<(Entity, &A)>() .query::<(Entity, &A)>()
@ -414,8 +395,8 @@ mod tests {
let e1 = world.spawn().insert(SparseStored(1)).id(); let e1 = world.spawn().insert(SparseStored(1)).id();
let e2 = world.spawn().insert(SparseStored(2)).id(); let e2 = world.spawn().insert(SparseStored(2)).id();
let e3 = world.spawn().insert(SparseStored(3)).id(); let e3 = world.spawn().insert(SparseStored(3)).id();
let e4 = world.spawn().insert_bundle((SparseStored(4), A(1))).id(); let e4 = world.spawn().insert((SparseStored(4), A(1))).id();
let e5 = world.spawn().insert_bundle((SparseStored(5), A(1))).id(); let e5 = world.spawn().insert((SparseStored(5), A(1))).id();
let results = Arc::new(Mutex::new(Vec::new())); let results = Arc::new(Mutex::new(Vec::new()));
world.query::<(Entity, &SparseStored)>().par_for_each( world.query::<(Entity, &SparseStored)>().par_for_each(
&world, &world,
@ -432,18 +413,18 @@ mod tests {
#[test] #[test]
fn query_missing_component() { fn query_missing_component() {
let mut world = World::new(); let mut world = World::new();
world.spawn().insert_bundle((TableStored("abc"), A(123))); world.spawn().insert((TableStored("abc"), A(123)));
world.spawn().insert_bundle((TableStored("def"), A(456))); world.spawn().insert((TableStored("def"), A(456)));
assert!(world.query::<(&B, &A)>().iter(&world).next().is_none()); assert!(world.query::<(&B, &A)>().iter(&world).next().is_none());
} }
#[test] #[test]
fn query_sparse_component() { fn query_sparse_component() {
let mut world = World::new(); let mut world = World::new();
world.spawn().insert_bundle((TableStored("abc"), A(123))); world.spawn().insert((TableStored("abc"), A(123)));
let f = world let f = world
.spawn() .spawn()
.insert_bundle((TableStored("def"), A(456), B(1))) .insert((TableStored("def"), A(456), B(1)))
.id(); .id();
let ents = world let ents = world
.query::<(Entity, &B)>() .query::<(Entity, &B)>()
@ -456,7 +437,7 @@ mod tests {
#[test] #[test]
fn query_filter_with() { fn query_filter_with() {
let mut world = World::new(); let mut world = World::new();
world.spawn().insert_bundle((A(123), B(1))); world.spawn().insert((A(123), B(1)));
world.spawn().insert(A(456)); world.spawn().insert(A(456));
let result = world let result = world
.query_filtered::<&A, With<B>>() .query_filtered::<&A, With<B>>()
@ -469,7 +450,7 @@ mod tests {
#[test] #[test]
fn query_filter_with_for_each() { fn query_filter_with_for_each() {
let mut world = World::new(); let mut world = World::new();
world.spawn().insert_bundle((A(123), B(1))); world.spawn().insert((A(123), B(1)));
world.spawn().insert(A(456)); world.spawn().insert(A(456));
let mut results = Vec::new(); let mut results = Vec::new();
@ -483,7 +464,7 @@ mod tests {
fn query_filter_with_sparse() { fn query_filter_with_sparse() {
let mut world = World::new(); let mut world = World::new();
world.spawn().insert_bundle((A(123), SparseStored(321))); world.spawn().insert((A(123), SparseStored(321)));
world.spawn().insert(A(456)); world.spawn().insert(A(456));
let result = world let result = world
.query_filtered::<&A, With<SparseStored>>() .query_filtered::<&A, With<SparseStored>>()
@ -497,7 +478,7 @@ mod tests {
fn query_filter_with_sparse_for_each() { fn query_filter_with_sparse_for_each() {
let mut world = World::new(); let mut world = World::new();
world.spawn().insert_bundle((A(123), SparseStored(321))); world.spawn().insert((A(123), SparseStored(321)));
world.spawn().insert(A(456)); world.spawn().insert(A(456));
let mut results = Vec::new(); let mut results = Vec::new();
world world
@ -509,7 +490,7 @@ mod tests {
#[test] #[test]
fn query_filter_without() { fn query_filter_without() {
let mut world = World::new(); let mut world = World::new();
world.spawn().insert_bundle((A(123), B(321))); world.spawn().insert((A(123), B(321)));
world.spawn().insert(A(456)); world.spawn().insert(A(456));
let result = world let result = world
.query_filtered::<&A, Without<B>>() .query_filtered::<&A, Without<B>>()
@ -522,13 +503,10 @@ mod tests {
#[test] #[test]
fn query_optional_component_table() { fn query_optional_component_table() {
let mut world = World::new(); let mut world = World::new();
let e = world let e = world.spawn().insert((TableStored("abc"), A(123))).id();
.spawn()
.insert_bundle((TableStored("abc"), A(123)))
.id();
let f = world let f = world
.spawn() .spawn()
.insert_bundle((TableStored("def"), A(456), B(1))) .insert((TableStored("def"), A(456), B(1)))
.id(); .id();
// this should be skipped // this should be skipped
world.spawn().insert(TableStored("abc")); world.spawn().insert(TableStored("abc"));
@ -544,13 +522,10 @@ mod tests {
fn query_optional_component_sparse() { fn query_optional_component_sparse() {
let mut world = World::new(); let mut world = World::new();
let e = world let e = world.spawn().insert((TableStored("abc"), A(123))).id();
.spawn()
.insert_bundle((TableStored("abc"), A(123)))
.id();
let f = world let f = world
.spawn() .spawn()
.insert_bundle((TableStored("def"), A(456), SparseStored(1))) .insert((TableStored("def"), A(456), SparseStored(1)))
.id(); .id();
// // this should be skipped // // this should be skipped
// SparseStored(1).spawn().insert("abc"); // SparseStored(1).spawn().insert("abc");
@ -569,14 +544,8 @@ mod tests {
fn query_optional_component_sparse_no_match() { fn query_optional_component_sparse_no_match() {
let mut world = World::new(); let mut world = World::new();
let e = world let e = world.spawn().insert((TableStored("abc"), A(123))).id();
.spawn() let f = world.spawn().insert((TableStored("def"), A(456))).id();
.insert_bundle((TableStored("abc"), A(123)))
.id();
let f = world
.spawn()
.insert_bundle((TableStored("def"), A(456)))
.id();
// // this should be skipped // // this should be skipped
world.spawn().insert(TableStored("abc")); world.spawn().insert(TableStored("abc"));
let ents = world let ents = world
@ -593,12 +562,12 @@ mod tests {
let e1 = world let e1 = world
.spawn() .spawn()
.insert(A(1)) .insert(A(1))
.insert_bundle((B(3), TableStored("abc"))) .insert((B(3), TableStored("abc")))
.id(); .id();
let e2 = world let e2 = world
.spawn() .spawn()
.insert(A(2)) .insert(A(2))
.insert_bundle((B(4), TableStored("xyz"))) .insert((B(4), TableStored("xyz")))
.id(); .id();
assert_eq!( assert_eq!(
@ -698,10 +667,7 @@ mod tests {
#[test] #[test]
fn remove_missing() { fn remove_missing() {
let mut world = World::new(); let mut world = World::new();
let e = world let e = world.spawn().insert((TableStored("abc"), A(123))).id();
.spawn()
.insert_bundle((TableStored("abc"), A(123)))
.id();
assert!(world.entity_mut(e).remove::<B>().is_none()); assert!(world.entity_mut(e).remove::<B>().is_none());
} }
@ -721,17 +687,11 @@ mod tests {
#[test] #[test]
fn query_get() { fn query_get() {
let mut world = World::new(); let mut world = World::new();
let a = world let a = world.spawn().insert((TableStored("abc"), A(123))).id();
.spawn() let b = world.spawn().insert((TableStored("def"), A(456))).id();
.insert_bundle((TableStored("abc"), A(123)))
.id();
let b = world
.spawn()
.insert_bundle((TableStored("def"), A(456)))
.id();
let c = world let c = world
.spawn() .spawn()
.insert_bundle((TableStored("ghi"), A(789), B(1))) .insert((TableStored("ghi"), A(789), B(1)))
.id(); .id();
let mut i32_query = world.query::<&A>(); let mut i32_query = world.query::<&A>();
@ -749,8 +709,8 @@ mod tests {
fn remove_tracking() { fn remove_tracking() {
let mut world = World::new(); let mut world = World::new();
let a = world.spawn().insert_bundle((SparseStored(0), A(123))).id(); let a = world.spawn().insert((SparseStored(0), A(123))).id();
let b = world.spawn().insert_bundle((SparseStored(1), A(123))).id(); let b = world.spawn().insert((SparseStored(1), A(123))).id();
world.entity_mut(a).despawn(); world.entity_mut(a).despawn();
assert_eq!( assert_eq!(
@ -796,8 +756,8 @@ mod tests {
); );
// TODO: uncomment when world.clear() is implemented // TODO: uncomment when world.clear() is implemented
// let c = world.spawn().insert_bundle(("abc", 123)).id(); // let c = world.spawn().insert(("abc", 123)).id();
// let d = world.spawn().insert_bundle(("abc", 123)).id(); // let d = world.spawn().insert(("abc", 123)).id();
// world.clear(); // world.clear();
// assert_eq!( // assert_eq!(
// world.removed::<i32>(), // world.removed::<i32>(),
@ -885,7 +845,7 @@ mod tests {
world.clear_trackers(); world.clear_trackers();
assert!(get_added::<A>(&mut world).is_empty()); assert!(get_added::<A>(&mut world).is_empty());
let e2 = world.spawn().insert_bundle((A(1), B(1))).id(); let e2 = world.spawn().insert((A(1), B(1))).id();
assert_eq!(get_added::<A>(&mut world), vec![e2]); assert_eq!(get_added::<A>(&mut world), vec![e2]);
assert_eq!(get_added::<B>(&mut world), vec![e2]); assert_eq!(get_added::<B>(&mut world), vec![e2]);
@ -899,10 +859,10 @@ mod tests {
#[test] #[test]
fn changed_trackers() { fn changed_trackers() {
let mut world = World::default(); let mut world = World::default();
let e1 = world.spawn().insert_bundle((A(0), B(0))).id(); let e1 = world.spawn().insert((A(0), B(0))).id();
let e2 = world.spawn().insert_bundle((A(0), B(0))).id(); let e2 = world.spawn().insert((A(0), B(0))).id();
let e3 = world.spawn().insert_bundle((A(0), B(0))).id(); let e3 = world.spawn().insert((A(0), B(0))).id();
world.spawn().insert_bundle((A(0), B(0))); world.spawn().insert((A(0), B(0)));
world.clear_trackers(); world.clear_trackers();
@ -927,7 +887,7 @@ mod tests {
assert_eq!(get_filtered::<Changed<A>>(&mut world), vec![e3, e1], "changed entities list should not change (although the order will due to archetype moves)"); assert_eq!(get_filtered::<Changed<A>>(&mut world), vec![e3, e1], "changed entities list should not change (although the order will due to archetype moves)");
// spawning a new A entity should not change existing changed state // spawning a new A entity should not change existing changed state
world.entity_mut(e1).insert_bundle((A(0), B(0))); world.entity_mut(e1).insert((A(0), B(0)));
assert_eq!( assert_eq!(
get_filtered::<Changed<A>>(&mut world), get_filtered::<Changed<A>>(&mut world),
vec![e3, e1], vec![e3, e1],
@ -967,7 +927,7 @@ mod tests {
// ensure inserting multiple components set changed state for all components and set added // ensure inserting multiple components set changed state for all components and set added
// state for non existing components even when changing archetype. // state for non existing components even when changing archetype.
world.entity_mut(e4).insert_bundle((A(0), B(0))); world.entity_mut(e4).insert((A(0), B(0)));
assert!(get_filtered::<Added<A>>(&mut world).is_empty()); assert!(get_filtered::<Added<A>>(&mut world).is_empty());
assert_eq!(get_filtered::<Changed<A>>(&mut world), vec![e4]); assert_eq!(get_filtered::<Changed<A>>(&mut world), vec![e4]);
@ -997,7 +957,7 @@ mod tests {
#[test] #[test]
fn changed_query() { fn changed_query() {
let mut world = World::default(); let mut world = World::default();
let e1 = world.spawn().insert_bundle((A(0), B(0))).id(); let e1 = world.spawn().insert((A(0), B(0))).id();
fn get_changed(world: &mut World) -> Vec<Entity> { fn get_changed(world: &mut World) -> Vec<Entity> {
world world
@ -1115,10 +1075,7 @@ mod tests {
#[test] #[test]
fn remove_intersection() { fn remove_intersection() {
let mut world = World::default(); let mut world = World::default();
let e1 = world let e1 = world.spawn().insert((A(1), B(1), TableStored("a"))).id();
.spawn()
.insert_bundle((A(1), B(1), TableStored("a")))
.id();
let mut e = world.entity_mut(e1); let mut e = world.entity_mut(e1);
assert_eq!(e.get::<TableStored>(), Some(&TableStored("a"))); assert_eq!(e.get::<TableStored>(), Some(&TableStored("a")));
@ -1130,7 +1087,7 @@ mod tests {
"C is not in the entity, so it should not exist" "C is not in the entity, so it should not exist"
); );
e.remove_bundle_intersection::<(A, B, C)>(); e.remove_intersection::<(A, B, C)>();
assert_eq!( assert_eq!(
e.get::<TableStored>(), e.get::<TableStored>(),
Some(&TableStored("a")), Some(&TableStored("a")),
@ -1156,12 +1113,9 @@ mod tests {
#[test] #[test]
fn remove_bundle() { fn remove_bundle() {
let mut world = World::default(); let mut world = World::default();
world.spawn().insert_bundle((A(1), B(1), TableStored("1"))); world.spawn().insert((A(1), B(1), TableStored("1")));
let e2 = world let e2 = world.spawn().insert((A(2), B(2), TableStored("2"))).id();
.spawn() world.spawn().insert((A(3), B(3), TableStored("3")));
.insert_bundle((A(2), B(2), TableStored("2")))
.id();
world.spawn().insert_bundle((A(3), B(3), TableStored("3")));
let mut query = world.query::<(&B, &TableStored)>(); let mut query = world.query::<(&B, &TableStored)>();
let results = query let results = query
@ -1170,10 +1124,7 @@ mod tests {
.collect::<Vec<_>>(); .collect::<Vec<_>>();
assert_eq!(results, vec![(1, "1"), (2, "2"), (3, "3"),]); assert_eq!(results, vec![(1, "1"), (2, "2"), (3, "3"),]);
let removed_bundle = world let removed_bundle = world.entity_mut(e2).remove::<(B, TableStored)>().unwrap();
.entity_mut(e2)
.remove_bundle::<(B, TableStored)>()
.unwrap();
assert_eq!(removed_bundle, (B(2), TableStored("2"))); assert_eq!(removed_bundle, (B(2), TableStored("2")));
let results = query let results = query
@ -1228,7 +1179,7 @@ mod tests {
#[test] #[test]
fn trackers_query() { fn trackers_query() {
let mut world = World::default(); let mut world = World::default();
let e1 = world.spawn().insert_bundle((A(0), B(0))).id(); let e1 = world.spawn().insert((A(0), B(0))).id();
world.spawn().insert(B(0)); world.spawn().insert(B(0));
let mut trackers_query = world.query::<Option<ChangeTrackers<A>>>(); let mut trackers_query = world.query::<Option<ChangeTrackers<A>>>();
@ -1252,9 +1203,9 @@ mod tests {
#[test] #[test]
fn exact_size_query() { fn exact_size_query() {
let mut world = World::default(); let mut world = World::default();
world.spawn().insert_bundle((A(0), B(0))); world.spawn().insert((A(0), B(0)));
world.spawn().insert_bundle((A(0), B(0))); world.spawn().insert((A(0), B(0)));
world.spawn().insert_bundle((A(0), B(0), C)); world.spawn().insert((A(0), B(0), C));
world.spawn().insert(C); world.spawn().insert(C);
let mut query = world.query::<(&A, &B)>(); let mut query = world.query::<(&A, &B)>();
@ -1265,7 +1216,7 @@ mod tests {
#[should_panic] #[should_panic]
fn duplicate_components_panic() { fn duplicate_components_panic() {
let mut world = World::new(); let mut world = World::new();
world.spawn().insert_bundle((A(1), A(2))); world.spawn().insert((A(1), A(2)));
} }
#[test] #[test]
@ -1434,10 +1385,10 @@ mod tests {
}; };
} }
world.spawn().insert_bundle((A(1), B(1), C)); world.spawn().insert((A(1), B(1), C));
world.spawn().insert_bundle((A(1), C)); world.spawn().insert((A(1), C));
world.spawn().insert_bundle((A(1), B(1))); world.spawn().insert((A(1), B(1)));
world.spawn().insert_bundle((B(1), C)); world.spawn().insert((B(1), C));
world.spawn().insert(A(1)); world.spawn().insert(A(1));
world.spawn().insert(C); world.spawn().insert(C);
assert_eq!(2, query_min_size![(), (With<A>, Without<B>)],); assert_eq!(2, query_min_size![(), (With<A>, Without<B>)],);

View file

@ -43,8 +43,8 @@ mod tests {
#[test] #[test]
fn query() { fn query() {
let mut world = World::new(); let mut world = World::new();
world.spawn().insert_bundle((A(1), B(1))); world.spawn().insert((A(1), B(1)));
world.spawn().insert_bundle((A(2),)); world.spawn().insert(A(2));
let values = world.query::<&A>().iter(&world).collect::<Vec<&A>>(); let values = world.query::<&A>().iter(&world).collect::<Vec<&A>>();
assert_eq!(values, vec![&A(1), &A(2)]); assert_eq!(values, vec![&A(1), &A(2)]);
@ -127,24 +127,24 @@ count(): {count}"#
} }
let mut world = World::new(); let mut world = World::new();
world.spawn().insert_bundle((A(1), B(1))); world.spawn().insert((A(1), B(1)));
world.spawn().insert_bundle((A(2),)); world.spawn().insert(A(2));
world.spawn().insert_bundle((A(3),)); world.spawn().insert(A(3));
assert_all_sizes_equal::<&A, With<B>>(&mut world, 1); assert_all_sizes_equal::<&A, With<B>>(&mut world, 1);
assert_all_sizes_equal::<&A, Without<B>>(&mut world, 2); assert_all_sizes_equal::<&A, Without<B>>(&mut world, 2);
let mut world = World::new(); let mut world = World::new();
world.spawn().insert_bundle((A(1), B(1), C(1))); world.spawn().insert((A(1), B(1), C(1)));
world.spawn().insert_bundle((A(2), B(2))); world.spawn().insert((A(2), B(2)));
world.spawn().insert_bundle((A(3), B(3))); world.spawn().insert((A(3), B(3)));
world.spawn().insert_bundle((A(4), C(4))); world.spawn().insert((A(4), C(4)));
world.spawn().insert_bundle((A(5), C(5))); world.spawn().insert((A(5), C(5)));
world.spawn().insert_bundle((A(6), C(6))); world.spawn().insert((A(6), C(6)));
world.spawn().insert_bundle((A(7),)); world.spawn().insert(A(7));
world.spawn().insert_bundle((A(8),)); world.spawn().insert(A(8));
world.spawn().insert_bundle((A(9),)); world.spawn().insert(A(9));
world.spawn().insert_bundle((A(10),)); world.spawn().insert(A(10));
// With/Without for B and C // With/Without for B and C
assert_all_sizes_equal::<&A, With<B>>(&mut world, 3); assert_all_sizes_equal::<&A, With<B>>(&mut world, 3);
@ -167,7 +167,7 @@ count(): {count}"#
assert_all_sizes_equal::<&A, Or<(Or<(With<B>, With<C>)>, With<D>)>>(&mut world, 6); assert_all_sizes_equal::<&A, Or<(Or<(With<B>, With<C>)>, With<D>)>>(&mut world, 6);
for i in 11..14 { for i in 11..14 {
world.spawn().insert_bundle((A(i), D(i))); world.spawn().insert((A(i), D(i)));
} }
assert_all_sizes_equal::<&A, Or<(Or<(With<B>, With<C>)>, With<D>)>>(&mut world, 9); assert_all_sizes_equal::<&A, Or<(Or<(With<B>, With<C>)>, With<D>)>>(&mut world, 9);
@ -175,7 +175,7 @@ count(): {count}"#
// a fair amount of entities // a fair amount of entities
for i in 14..20 { for i in 14..20 {
world.spawn().insert_bundle((C(i), D(i))); world.spawn().insert((C(i), D(i)));
} }
assert_all_sizes_equal::<Entity, (With<C>, With<D>)>(&mut world, 6); assert_all_sizes_equal::<Entity, (With<C>, With<D>)>(&mut world, 6);
} }
@ -184,10 +184,10 @@ count(): {count}"#
fn query_iter_combinations() { fn query_iter_combinations() {
let mut world = World::new(); let mut world = World::new();
world.spawn().insert_bundle((A(1), B(1))); world.spawn().insert((A(1), B(1)));
world.spawn().insert_bundle((A(2),)); world.spawn().insert(A(2));
world.spawn().insert_bundle((A(3),)); world.spawn().insert(A(3));
world.spawn().insert_bundle((A(4),)); world.spawn().insert(A(4));
let values: Vec<[&A; 2]> = world.query::<&A>().iter_combinations(&world).collect(); let values: Vec<[&A; 2]> = world.query::<&A>().iter_combinations(&world).collect();
assert_eq!( assert_eq!(
@ -247,10 +247,10 @@ count(): {count}"#
let mut world = World::new(); let mut world = World::new();
world.spawn().insert_bundle((A(1), B(1))); world.spawn().insert((A(1), B(1)));
world.spawn().insert_bundle((A(2),)); world.spawn().insert(A(2));
world.spawn().insert_bundle((A(3),)); world.spawn().insert(A(3));
world.spawn().insert_bundle((A(4),)); world.spawn().insert(A(4));
let mut a_wout_b = world.query_filtered::<&A, Without<B>>(); let mut a_wout_b = world.query_filtered::<&A, Without<B>>();
let values: HashSet<[&A; 2]> = a_wout_b.iter_combinations(&world).collect(); let values: HashSet<[&A; 2]> = a_wout_b.iter_combinations(&world).collect();
@ -302,28 +302,28 @@ count(): {count}"#
// Check if Added<T>, Changed<T> works // Check if Added<T>, Changed<T> works
let mut world = World::new(); let mut world = World::new();
world.spawn().insert_bundle((A(1), B(1))); world.spawn().insert((A(1), B(1)));
world.spawn().insert_bundle((A(2), B(2))); world.spawn().insert((A(2), B(2)));
world.spawn().insert_bundle((A(3), B(3))); world.spawn().insert((A(3), B(3)));
world.spawn().insert_bundle((A(4), B(4))); world.spawn().insert((A(4), B(4)));
let mut query_added = world.query_filtered::<&A, Added<A>>(); let mut query_added = world.query_filtered::<&A, Added<A>>();
world.clear_trackers(); world.clear_trackers();
world.spawn().insert_bundle((A(5),)); world.spawn().insert(A(5));
assert_eq!(query_added.iter_combinations::<2>(&world).count(), 0); assert_eq!(query_added.iter_combinations::<2>(&world).count(), 0);
world.clear_trackers(); world.clear_trackers();
world.spawn().insert_bundle((A(6),)); world.spawn().insert(A(6));
world.spawn().insert_bundle((A(7),)); world.spawn().insert(A(7));
assert_eq!(query_added.iter_combinations::<2>(&world).count(), 1); assert_eq!(query_added.iter_combinations::<2>(&world).count(), 1);
world.clear_trackers(); world.clear_trackers();
world.spawn().insert_bundle((A(8),)); world.spawn().insert(A(8));
world.spawn().insert_bundle((A(9),)); world.spawn().insert(A(9));
world.spawn().insert_bundle((A(10),)); world.spawn().insert(A(10));
assert_eq!(query_added.iter_combinations::<2>(&world).count(), 3); assert_eq!(query_added.iter_combinations::<2>(&world).count(), 3);
@ -384,8 +384,8 @@ count(): {count}"#
fn multi_storage_query() { fn multi_storage_query() {
let mut world = World::new(); let mut world = World::new();
world.spawn().insert_bundle((Sparse(1), B(2))); world.spawn().insert((Sparse(1), B(2)));
world.spawn().insert_bundle((Sparse(2),)); world.spawn().insert(Sparse(2));
let values = world let values = world
.query::<&Sparse>() .query::<&Sparse>()
@ -405,9 +405,9 @@ count(): {count}"#
fn any_query() { fn any_query() {
let mut world = World::new(); let mut world = World::new();
world.spawn().insert_bundle((A(1), B(2))); world.spawn().insert((A(1), B(2)));
world.spawn().insert_bundle((A(2),)); world.spawn().insert(A(2));
world.spawn().insert_bundle((C(3),)); world.spawn().insert(C(3));
let values: Vec<(Option<&A>, Option<&B>)> = let values: Vec<(Option<&A>, Option<&B>)> =
world.query::<AnyOf<(&A, &B)>>().iter(&world).collect(); world.query::<AnyOf<(&A, &B)>>().iter(&world).collect();
@ -436,24 +436,24 @@ count(): {count}"#
fn derived_worldqueries() { fn derived_worldqueries() {
let mut world = World::new(); let mut world = World::new();
world.spawn().insert_bundle((A(10), B(18), C(3), Sparse(4))); world.spawn().insert((A(10), B(18), C(3), Sparse(4)));
world.spawn().insert_bundle((A(101), B(148), C(13))); world.spawn().insert((A(101), B(148), C(13)));
world.spawn().insert_bundle((A(51), B(46), Sparse(72))); world.spawn().insert((A(51), B(46), Sparse(72)));
world.spawn().insert_bundle((A(398), C(6), Sparse(9))); world.spawn().insert((A(398), C(6), Sparse(9)));
world.spawn().insert_bundle((B(11), C(28), Sparse(92))); world.spawn().insert((B(11), C(28), Sparse(92)));
world.spawn().insert_bundle((C(18348), Sparse(101))); world.spawn().insert((C(18348), Sparse(101)));
world.spawn().insert_bundle((B(839), Sparse(5))); world.spawn().insert((B(839), Sparse(5)));
world.spawn().insert_bundle((B(6721), C(122))); world.spawn().insert((B(6721), C(122)));
world.spawn().insert_bundle((A(220), Sparse(63))); world.spawn().insert((A(220), Sparse(63)));
world.spawn().insert_bundle((A(1092), C(382))); world.spawn().insert((A(1092), C(382)));
world.spawn().insert_bundle((A(2058), B(3019))); world.spawn().insert((A(2058), B(3019)));
world.spawn().insert_bundle((B(38), C(8), Sparse(100))); world.spawn().insert((B(38), C(8), Sparse(100)));
world.spawn().insert_bundle((A(111), C(52), Sparse(1))); world.spawn().insert((A(111), C(52), Sparse(1)));
world.spawn().insert_bundle((A(599), B(39), Sparse(13))); world.spawn().insert((A(599), B(39), Sparse(13)));
world.spawn().insert_bundle((A(55), B(66), C(77))); world.spawn().insert((A(55), B(66), C(77)));
world.spawn(); world.spawn();
@ -619,8 +619,8 @@ count(): {count}"#
#[test] #[test]
fn many_entities() { fn many_entities() {
let mut world = World::new(); let mut world = World::new();
world.spawn().insert_bundle((A(0), B(0))); world.spawn().insert((A(0), B(0)));
world.spawn().insert_bundle((A(0), B(0))); world.spawn().insert((A(0), B(0)));
world.spawn().insert(A(0)); world.spawn().insert(A(0));
world.spawn().insert(B(0)); world.spawn().insert(B(0));
{ {

View file

@ -493,7 +493,7 @@ mod tests {
stage.run(&mut world); stage.run(&mut world);
assert_eq!(receive_events(&world), vec![StartedSystems(2),]); assert_eq!(receive_events(&world), vec![StartedSystems(2),]);
let mut world = World::new(); let mut world = World::new();
world.spawn().insert_bundle((W(0usize), W(0u32), W(0f32))); world.spawn().insert((W(0usize), W(0u32), W(0f32)));
fn wants_mut_usize(_: Query<(&mut W<usize>, &W<f32>)>) {} fn wants_mut_usize(_: Query<(&mut W<usize>, &W<f32>)>) {}
fn wants_mut_u32(_: Query<(&mut W<u32>, &W<f32>)>) {} fn wants_mut_u32(_: Query<(&mut W<u32>, &W<f32>)>) {}
let mut stage = SystemStage::parallel() let mut stage = SystemStage::parallel()

View file

@ -1477,7 +1477,7 @@ mod tests {
world.insert_resource(R(0)); world.insert_resource(R(0));
let mut stage = SystemStage::single(query_count_system); let mut stage = SystemStage::single(query_count_system);
let entity = world.spawn().insert_bundle(()).id(); let entity = world.spawn().insert(()).id();
stage.run(&mut world); stage.run(&mut world);
assert_eq!(world.resource::<R>().0, 1); assert_eq!(world.resource::<R>().0, 1);
@ -1497,7 +1497,7 @@ mod tests {
let mut stage = SystemStage::parallel(); let mut stage = SystemStage::parallel();
stage.add_system(query_count_system); stage.add_system(query_count_system);
let entity = world.spawn().insert_bundle(()).id(); let entity = world.spawn().insert(()).id();
stage.run(&mut world); stage.run(&mut world);
assert_eq!(world.resource::<R>().0, 1); assert_eq!(world.resource::<R>().0, 1);
@ -1522,7 +1522,7 @@ mod tests {
} }
fn spawn_entity(mut commands: crate::prelude::Commands) { fn spawn_entity(mut commands: crate::prelude::Commands) {
commands.spawn().insert(Foo); commands.spawn_bundle(Foo);
} }
fn count_entities(query: Query<&Foo>, mut res: ResMut<EntityCount>) { fn count_entities(query: Query<&Foo>, mut res: ResMut<EntityCount>) {
@ -1564,7 +1564,7 @@ mod tests {
} }
fn spawn_entity(mut commands: crate::prelude::Commands) { fn spawn_entity(mut commands: crate::prelude::Commands) {
commands.spawn().insert(Foo); commands.spawn_bundle(Foo);
} }
fn count_entities(query: Query<&Foo>, mut res: ResMut<EntityCount>) { fn count_entities(query: Query<&Foo>, mut res: ResMut<EntityCount>) {

View file

@ -3,7 +3,6 @@ mod parallel_scope;
use crate::{ use crate::{
bundle::Bundle, bundle::Bundle,
component::Component,
entity::{Entities, Entity}, entity::{Entities, Entity},
world::{FromWorld, World}, world::{FromWorld, World},
}; };
@ -147,7 +146,7 @@ impl<'w, 's> Commands<'w, 's> {
/// // Create another empty entity, then add some component to it /// // Create another empty entity, then add some component to it
/// commands.spawn() /// commands.spawn()
/// // adds a new component bundle to the entity /// // adds a new component bundle to the entity
/// .insert_bundle((Strength(1), Agility(2))) /// .insert((Strength(1), Agility(2)))
/// // adds a single component to the entity /// // adds a single component to the entity
/// .insert(Label("hello world")); /// .insert(Label("hello world"));
/// } /// }
@ -221,7 +220,7 @@ impl<'w, 's> Commands<'w, 's> {
/// // Create a new entity with two components using a "tuple bundle". /// // Create a new entity with two components using a "tuple bundle".
/// .spawn_bundle((Component1, Component2)) /// .spawn_bundle((Component1, Component2))
/// // spawn_bundle returns a builder, so you can insert more bundles like this: /// // spawn_bundle returns a builder, so you can insert more bundles like this:
/// .insert_bundle((Strength(1), Agility(2))) /// .insert((Strength(1), Agility(2)))
/// // or insert single components like this: /// // or insert single components like this:
/// .insert(Label("hello world")); /// .insert(Label("hello world"));
/// } /// }
@ -234,7 +233,7 @@ impl<'w, 's> Commands<'w, 's> {
/// - [`spawn_batch`](Self::spawn_batch) to spawn entities with a bundle each. /// - [`spawn_batch`](Self::spawn_batch) to spawn entities with a bundle each.
pub fn spawn_bundle<'a, T: Bundle>(&'a mut self, bundle: T) -> EntityCommands<'w, 's, 'a> { pub fn spawn_bundle<'a, T: Bundle>(&'a mut self, bundle: T) -> EntityCommands<'w, 's, 'a> {
let mut e = self.spawn(); let mut e = self.spawn();
e.insert_bundle(bundle); e.insert(bundle);
e e
} }
@ -262,7 +261,7 @@ impl<'w, 's> Commands<'w, 's> {
/// ///
/// commands.entity(entity) /// commands.entity(entity)
/// // adds a new component bundle to the entity /// // adds a new component bundle to the entity
/// .insert_bundle((Strength(1), Agility(2))) /// .insert((Strength(1), Agility(2)))
/// // adds a single component to the entity /// // adds a single component to the entity
/// .insert(Label("hello world")); /// .insert(Label("hello world"));
/// } /// }
@ -554,77 +553,62 @@ impl<'w, 's, 'a> EntityCommands<'w, 's, 'a> {
/// ///
/// ``` /// ```
/// # use bevy_ecs::prelude::*; /// # use bevy_ecs::prelude::*;
/// #
/// # #[derive(Resource)] /// # #[derive(Resource)]
/// # struct PlayerEntity { entity: Entity } /// # struct PlayerEntity { entity: Entity }
/// # #[derive(Component)] /// #[derive(Component)]
/// # struct Health(u32); /// struct Health(u32);
/// # #[derive(Component)] /// #[derive(Component)]
/// # struct Strength(u32); /// struct Strength(u32);
/// # #[derive(Component)] /// #[derive(Component)]
/// # struct Defense(u32); /// struct Defense(u32);
/// # ///
/// # #[derive(Bundle)] /// #[derive(Bundle)]
/// # struct CombatBundle { /// struct CombatBundle {
/// # health: Health, /// health: Health,
/// # strength: Strength, /// strength: Strength,
/// # defense: Defense, /// }
/// # } ///
/// #
/// fn add_combat_stats_system(mut commands: Commands, player: Res<PlayerEntity>) { /// fn add_combat_stats_system(mut commands: Commands, player: Res<PlayerEntity>) {
/// commands.entity(player.entity).insert_bundle(CombatBundle { /// commands
/// health: Health(100), /// .entity(player.entity)
/// strength: Strength(40), /// // You can insert individual components:
/// defense: Defense(20), /// .insert(Defense(10))
/// }); /// // You can also insert pre-defined bundles of components:
/// .insert(CombatBundle {
/// health: Health(100),
/// strength: Strength(40),
/// })
/// // You can also insert tuples of components and bundles.
/// // This is equivalent to the calls above:
/// .insert((
/// Defense(10),
/// CombatBundle {
/// health: Health(100),
/// strength: Strength(40),
/// },
/// ));
/// } /// }
/// # bevy_ecs::system::assert_is_system(add_combat_stats_system); /// # bevy_ecs::system::assert_is_system(add_combat_stats_system);
/// ``` /// ```
pub fn insert_bundle(&mut self, bundle: impl Bundle) -> &mut Self { pub fn insert(&mut self, bundle: impl Bundle) -> &mut Self {
self.commands.add(InsertBundle { self.commands.add(Insert {
entity: self.entity, entity: self.entity,
bundle, bundle,
}); });
self self
} }
/// Adds a single [`Component`] to the entity. #[deprecated(
/// since = "0.9.0",
/// # Example note = "Use `insert` instead, which now accepts bundles, components, and tuples of bundles and components."
/// )]
/// `Self::insert` can be chained with [`Commands::spawn`]. pub fn insert_bundle(&mut self, bundle: impl Bundle) -> &mut Self {
/// self.insert(bundle)
/// ```
/// # use bevy_ecs::prelude::*;
/// #
/// # #[derive(Component)]
/// # struct Component1;
/// # #[derive(Component)]
/// # struct Component2;
/// #
/// fn example_system(mut commands: Commands) {
/// // Create a new entity with `Component1` and `Component2`
/// commands.spawn()
/// .insert(Component1)
/// .insert(Component2);
///
/// // The following statements are equivalent to above one.
/// commands.spawn().insert_bundle((Component1, Component2));
/// commands.spawn_bundle((Component1, Component2));
/// }
/// # bevy_ecs::system::assert_is_system(example_system);
/// ```
pub fn insert(&mut self, component: impl Component) -> &mut Self {
self.commands.add(Insert {
entity: self.entity,
component,
});
self
} }
/// Removes a [`Bundle`] of components from the entity. /// Removes a [`Bundle`] of components from the entity.
/// ///
/// See [`EntityMut::remove_bundle`](crate::world::EntityMut::remove_bundle) for more /// See [`EntityMut::remove`](crate::world::EntityMut::remove) for more
/// details. /// details.
/// ///
/// # Example /// # Example
@ -634,50 +618,35 @@ impl<'w, 's, 'a> EntityCommands<'w, 's, 'a> {
/// # /// #
/// # #[derive(Resource)] /// # #[derive(Resource)]
/// # struct PlayerEntity { entity: Entity } /// # struct PlayerEntity { entity: Entity }
/// # /// #[derive(Component)]
/// # #[derive(Component)] /// struct Health(u32);
/// struct Dummy; /// #[derive(Component)]
/// # #[derive(Bundle)] /// struct Strength(u32);
/// # struct CombatBundle { a: Dummy }; // dummy field, unit bundles are not permitted. /// #[derive(Component)]
/// # /// struct Defense(u32);
///
/// #[derive(Bundle)]
/// struct CombatBundle {
/// health: Health,
/// strength: Strength,
/// }
///
/// fn remove_combat_stats_system(mut commands: Commands, player: Res<PlayerEntity>) { /// fn remove_combat_stats_system(mut commands: Commands, player: Res<PlayerEntity>) {
/// commands.entity(player.entity).remove_bundle::<CombatBundle>(); /// commands
/// .entity(player.entity)
/// // You can remove individual components:
/// .remove::<Defense>()
/// // You can also remove pre-defined Bundles of components:
/// .remove::<CombatBundle>()
/// // You can also remove tuples of components and bundles.
/// // This is equivalent to the calls above:
/// .remove::<(Defense, CombatBundle)>();
/// } /// }
/// # bevy_ecs::system::assert_is_system(remove_combat_stats_system); /// # bevy_ecs::system::assert_is_system(remove_combat_stats_system);
/// ``` /// ```
pub fn remove_bundle<T>(&mut self) -> &mut Self
where
T: Bundle,
{
self.commands.add(RemoveBundle::<T> {
entity: self.entity,
phantom: PhantomData,
});
self
}
/// Removes a single component from the entity.
///
/// See [`EntityMut::remove`](crate::world::EntityMut::remove) for more details.
///
/// # Example
///
/// ```
/// # use bevy_ecs::prelude::*;
/// #
/// # #[derive(Resource)]
/// # struct TargetEnemy { entity: Entity }
/// # #[derive(Component)]
/// # struct Enemy;
/// #
/// fn convert_enemy_system(mut commands: Commands, enemy: Res<TargetEnemy>) {
/// commands.entity(enemy.entity).remove::<Enemy>();
/// }
/// # bevy_ecs::system::assert_is_system(convert_enemy_system);
/// ```
pub fn remove<T>(&mut self) -> &mut Self pub fn remove<T>(&mut self) -> &mut Self
where where
T: Component, T: Bundle,
{ {
self.commands.add(Remove::<T> { self.commands.add(Remove::<T> {
entity: self.entity, entity: self.entity,
@ -686,6 +655,17 @@ impl<'w, 's, 'a> EntityCommands<'w, 's, 'a> {
self self
} }
#[deprecated(
since = "0.9.0",
note = "Use `remove` instead, which now accepts bundles, components, and tuples of bundles and components."
)]
pub fn remove_bundle<T>(&mut self) -> &mut Self
where
T: Bundle,
{
self.remove::<T>()
}
/// Despawns the entity. /// Despawns the entity.
/// ///
/// See [`World::despawn`] for more details. /// See [`World::despawn`] for more details.
@ -745,7 +725,7 @@ where
T: Bundle, T: Bundle,
{ {
fn write(self, world: &mut World) { fn write(self, world: &mut World) {
world.spawn().insert_bundle(self.bundle); world.spawn().insert(self.bundle);
} }
} }
@ -816,43 +796,24 @@ impl Command for Despawn {
} }
} }
pub struct InsertBundle<T> { pub struct Insert<T> {
pub entity: Entity, pub entity: Entity,
pub bundle: T, pub bundle: T,
} }
impl<T> Command for InsertBundle<T> impl<T> Command for Insert<T>
where where
T: Bundle + 'static, T: Bundle + 'static,
{ {
fn write(self, world: &mut World) { fn write(self, world: &mut World) {
if let Some(mut entity) = world.get_entity_mut(self.entity) { if let Some(mut entity) = world.get_entity_mut(self.entity) {
entity.insert_bundle(self.bundle); entity.insert(self.bundle);
} else { } else {
panic!("error[B0003]: Could not insert a bundle (of type `{}`) for entity {:?} because it doesn't exist in this World.", std::any::type_name::<T>(), self.entity); panic!("error[B0003]: Could not insert a bundle (of type `{}`) for entity {:?} because it doesn't exist in this World.", std::any::type_name::<T>(), self.entity);
} }
} }
} }
#[derive(Debug)]
pub struct Insert<T> {
pub entity: Entity,
pub component: T,
}
impl<T> Command for Insert<T>
where
T: Component,
{
fn write(self, world: &mut World) {
if let Some(mut entity) = world.get_entity_mut(self.entity) {
entity.insert(self.component);
} else {
panic!("error[B0003]: Could not add a component (of type `{}`) to entity {:?} because it doesn't exist in this World.", std::any::type_name::<T>(), self.entity);
}
}
}
#[derive(Debug)] #[derive(Debug)]
pub struct Remove<T> { pub struct Remove<T> {
pub entity: Entity, pub entity: Entity,
@ -860,23 +821,6 @@ pub struct Remove<T> {
} }
impl<T> Command for Remove<T> impl<T> Command for Remove<T>
where
T: Component,
{
fn write(self, world: &mut World) {
if let Some(mut entity_mut) = world.get_entity_mut(self.entity) {
entity_mut.remove::<T>();
}
}
}
#[derive(Debug)]
pub struct RemoveBundle<T> {
pub entity: Entity,
pub phantom: PhantomData<T>,
}
impl<T> Command for RemoveBundle<T>
where where
T: Bundle, T: Bundle,
{ {
@ -884,7 +828,7 @@ where
if let Some(mut entity_mut) = world.get_entity_mut(self.entity) { if let Some(mut entity_mut) = world.get_entity_mut(self.entity) {
// remove intersection to gracefully handle components that were removed before running // remove intersection to gracefully handle components that were removed before running
// this command // this command
entity_mut.remove_bundle_intersection::<T>(); entity_mut.remove_intersection::<T>();
} }
} }
} }
@ -972,7 +916,7 @@ mod tests {
struct W<T>(T); struct W<T>(T);
fn simple_command(world: &mut World) { fn simple_command(world: &mut World) {
world.spawn().insert_bundle((W(0u32), W(42u64))); world.spawn().insert((W(0u32), W(42u64)));
} }
#[test] #[test]
@ -1010,7 +954,7 @@ mod tests {
// set up a simple command using a closure that adds one additional entity // set up a simple command using a closure that adds one additional entity
commands.add(|world: &mut World| { commands.add(|world: &mut World| {
world.spawn().insert_bundle((W(42u32), W(0u64))); world.spawn().insert((W(42u32), W(0u64)));
}); });
// set up a simple command using a function that adds one additional entity // set up a simple command using a function that adds one additional entity
@ -1037,7 +981,7 @@ mod tests {
let entity = Commands::new(&mut command_queue, &world) let entity = Commands::new(&mut command_queue, &world)
.spawn() .spawn()
.insert_bundle((W(1u32), W(2u64), dense_dropck, sparse_dropck)) .insert((W(1u32), W(2u64), dense_dropck, sparse_dropck))
.id(); .id();
command_queue.apply(&mut world); command_queue.apply(&mut world);
let results_before = world let results_before = world
@ -1051,7 +995,7 @@ mod tests {
Commands::new(&mut command_queue, &world) Commands::new(&mut command_queue, &world)
.entity(entity) .entity(entity)
.remove::<W<u32>>() .remove::<W<u32>>()
.remove_bundle::<(W<u32>, W<u64>, SparseDropCk, DropCk)>(); .remove::<(W<u32>, W<u64>, SparseDropCk, DropCk)>();
assert_eq!(dense_is_dropped.load(Ordering::Relaxed), 0); assert_eq!(dense_is_dropped.load(Ordering::Relaxed), 0);
assert_eq!(sparse_is_dropped.load(Ordering::Relaxed), 0); assert_eq!(sparse_is_dropped.load(Ordering::Relaxed), 0);

View file

@ -158,7 +158,7 @@ mod tests {
struct CountEntities(Vec<usize>); struct CountEntities(Vec<usize>);
fn spawn_entity(mut commands: crate::prelude::Commands) { fn spawn_entity(mut commands: crate::prelude::Commands) {
commands.spawn().insert(Foo(0.0)); commands.spawn_bundle(Foo(0.0));
} }
fn count_entities(query: Query<&Foo>, mut res: ResMut<CountEntities>) { fn count_entities(query: Query<&Foo>, mut res: ResMut<CountEntities>) {

View file

@ -245,10 +245,10 @@ mod tests {
let mut world = World::default(); let mut world = World::default();
world.insert_resource(SystemRan::No); world.insert_resource(SystemRan::No);
world.spawn().insert_bundle((A,)); world.spawn().insert(A);
world.spawn().insert_bundle((A, B)); world.spawn().insert((A, B));
world.spawn().insert_bundle((A, C)); world.spawn().insert((A, C));
world.spawn().insert_bundle((A, D)); world.spawn().insert((A, D));
run_system(&mut world, query_system); run_system(&mut world, query_system);
@ -276,7 +276,7 @@ mod tests {
let mut world = World::default(); let mut world = World::default();
world.insert_resource(SystemRan::No); world.insert_resource(SystemRan::No);
world.spawn().insert_bundle((A, B)); world.spawn().insert((A, B));
run_system(&mut world, query_system); run_system(&mut world, query_system);
@ -654,7 +654,7 @@ mod tests {
fn world_collections_system() { fn world_collections_system() {
let mut world = World::default(); let mut world = World::default();
world.insert_resource(SystemRan::No); world.insert_resource(SystemRan::No);
world.spawn().insert_bundle((W(42), W(true))); world.spawn().insert((W(42), W(true)));
fn sys( fn sys(
archetypes: &Archetypes, archetypes: &Archetypes,
components: &Components, components: &Components,
@ -893,7 +893,7 @@ mod tests {
); );
} }
world.spawn().insert_bundle((A(2), B(2))); world.spawn().insert((A(2), B(2)));
{ {
let query = system_state.get(&world); let query = system_state.get(&world);
assert_eq!( assert_eq!(
@ -1114,7 +1114,7 @@ mod tests {
expected_ids.insert( expected_ids.insert(
world world
.spawn() .spawn()
.insert_bundle((A,)) .insert(A)
.archetype() .archetype()
.get_archetype_component_id(a_id) .get_archetype_component_id(a_id)
.unwrap(), .unwrap(),
@ -1122,15 +1122,15 @@ mod tests {
expected_ids.insert( expected_ids.insert(
world world
.spawn() .spawn()
.insert_bundle((A, C)) .insert((A, C))
.archetype() .archetype()
.get_archetype_component_id(a_id) .get_archetype_component_id(a_id)
.unwrap(), .unwrap(),
); );
// add some entities with archetypes that should not match // add some entities with archetypes that should not match
world.spawn().insert_bundle((A, B)); world.spawn().insert((A, B));
world.spawn().insert_bundle((B, C)); world.spawn().insert((B, C));
// update system and verify its accesses are correct // update system and verify its accesses are correct
system.update_archetype_component_access(&world); system.update_archetype_component_access(&world);
@ -1146,12 +1146,12 @@ mod tests {
expected_ids.insert( expected_ids.insert(
world world
.spawn() .spawn()
.insert_bundle((A, D)) .insert((A, D))
.archetype() .archetype()
.get_archetype_component_id(a_id) .get_archetype_component_id(a_id)
.unwrap(), .unwrap(),
); );
world.spawn().insert_bundle((A, B, D)); world.spawn().insert((A, B, D));
system.update_archetype_component_access(&world); system.update_archetype_component_access(&world);
assert_eq!( assert_eq!(
system system

View file

@ -238,7 +238,15 @@ impl<'w> EntityMut<'w> {
}) })
} }
#[deprecated(
since = "0.9.0",
note = "Use `insert` instead, which now accepts bundles, components, and tuples of bundles and components."
)]
pub fn insert_bundle<T: Bundle>(&mut self, bundle: T) -> &mut Self { pub fn insert_bundle<T: Bundle>(&mut self, bundle: T) -> &mut Self {
self.insert(bundle)
}
pub fn insert<T: Bundle>(&mut self, bundle: T) -> &mut Self {
let change_tick = self.world.change_tick(); let change_tick = self.world.change_tick();
let bundle_info = self let bundle_info = self
.world .world
@ -260,8 +268,16 @@ impl<'w> EntityMut<'w> {
self self
} }
// TODO: move to BundleInfo #[deprecated(
since = "0.9.0",
note = "Use `remove` instead, which now accepts bundles, components, and tuples of bundles and components."
)]
pub fn remove_bundle<T: Bundle>(&mut self) -> Option<T> { pub fn remove_bundle<T: Bundle>(&mut self) -> Option<T> {
self.remove::<T>()
}
// TODO: move to BundleInfo
pub fn remove<T: Bundle>(&mut self) -> Option<T> {
let archetypes = &mut self.world.archetypes; let archetypes = &mut self.world.archetypes;
let storages = &mut self.world.storages; let storages = &mut self.world.storages;
let components = &mut self.world.components; let components = &mut self.world.components;
@ -384,9 +400,17 @@ impl<'w> EntityMut<'w> {
entities.meta[entity.id as usize].location = new_location; entities.meta[entity.id as usize].location = new_location;
} }
#[deprecated(
since = "0.9.0",
note = "Use `remove_intersection` instead, which now accepts bundles, components, and tuples of bundles and components."
)]
pub fn remove_bundle_intersection<T: Bundle>(&mut self) {
self.remove_intersection::<T>();
}
// TODO: move to BundleInfo // TODO: move to BundleInfo
/// Remove any components in the bundle that the entity has. /// Remove any components in the bundle that the entity has.
pub fn remove_bundle_intersection<T: Bundle>(&mut self) { pub fn remove_intersection<T: Bundle>(&mut self) {
let archetypes = &mut self.world.archetypes; let archetypes = &mut self.world.archetypes;
let storages = &mut self.world.storages; let storages = &mut self.world.storages;
let components = &mut self.world.components; let components = &mut self.world.components;
@ -449,14 +473,6 @@ impl<'w> EntityMut<'w> {
} }
} }
pub fn insert<T: Component>(&mut self, value: T) -> &mut Self {
self.insert_bundle((value,))
}
pub fn remove<T: Component>(&mut self) -> Option<T> {
self.remove_bundle::<(T,)>().map(|v| v.0)
}
pub fn despawn(self) { pub fn despawn(self) {
let world = self.world; let world = self.world;
world.flush(); world.flush();

View file

@ -376,7 +376,7 @@ impl World {
/// let mut world = World::new(); /// let mut world = World::new();
/// let entity = world.spawn() /// let entity = world.spawn()
/// .insert(Position { x: 0.0, y: 0.0 }) // add a single component /// .insert(Position { x: 0.0, y: 0.0 }) // add a single component
/// .insert_bundle((Num(1), Label("hello"))) // add a bundle of components /// .insert((Num(1), Label("hello"))) // add a bundle of components
/// .id(); /// .id();
/// ///
/// let position = world.entity(entity).get::<Position>().unwrap(); /// let position = world.entity(entity).get::<Position>().unwrap();
@ -570,9 +570,9 @@ impl World {
/// struct Label(&'static str); /// struct Label(&'static str);
/// ///
/// let mut world = World::new(); /// let mut world = World::new();
/// let a = world.spawn().insert_bundle((Order(2), Label("second"))).id(); /// let a = world.spawn().insert((Order(2), Label("second"))).id();
/// let b = world.spawn().insert_bundle((Order(3), Label("third"))).id(); /// let b = world.spawn().insert((Order(3), Label("third"))).id();
/// let c = world.spawn().insert_bundle((Order(1), Label("first"))).id(); /// let c = world.spawn().insert((Order(1), Label("first"))).id();
/// let mut entities = world.query::<(Entity, &Order, &Label)>() /// let mut entities = world.query::<(Entity, &Order, &Label)>()
/// .iter(&world) /// .iter(&world)
/// .collect::<Vec<_>>(); /// .collect::<Vec<_>>();
@ -602,7 +602,7 @@ impl World {
/// ///
/// let mut world = World::new(); /// let mut world = World::new();
/// let e1 = world.spawn().insert(A).id(); /// let e1 = world.spawn().insert(A).id();
/// let e2 = world.spawn().insert_bundle((A, B)).id(); /// let e2 = world.spawn().insert((A, B)).id();
/// ///
/// let mut query = world.query_filtered::<Entity, With<B>>(); /// let mut query = world.query_filtered::<Entity, With<B>>();
/// let matching_entities = query.iter(&world).collect::<Vec<Entity>>(); /// let matching_entities = query.iter(&world).collect::<Vec<Entity>>();
@ -1782,13 +1782,13 @@ mod tests {
#[test] #[test]
fn inspect_entity_components() { fn inspect_entity_components() {
let mut world = World::new(); let mut world = World::new();
let ent0 = world.spawn().insert_bundle((Foo, Bar, Baz)).id(); let ent0 = world.spawn().insert((Foo, Bar, Baz)).id();
let ent1 = world.spawn().insert_bundle((Foo, Bar)).id(); let ent1 = world.spawn().insert((Foo, Bar)).id();
let ent2 = world.spawn().insert_bundle((Bar, Baz)).id(); let ent2 = world.spawn().insert((Bar, Baz)).id();
let ent3 = world.spawn().insert_bundle((Foo, Baz)).id(); let ent3 = world.spawn().insert((Foo, Baz)).id();
let ent4 = world.spawn().insert_bundle((Foo,)).id(); let ent4 = world.spawn().insert(Foo).id();
let ent5 = world.spawn().insert_bundle((Bar,)).id(); let ent5 = world.spawn().insert(Bar).id();
let ent6 = world.spawn().insert_bundle((Baz,)).id(); let ent6 = world.spawn().insert(Baz).id();
fn to_type_ids(component_infos: Vec<&ComponentInfo>) -> HashSet<Option<TypeId>> { fn to_type_ids(component_infos: Vec<&ComponentInfo>) -> HashSet<Option<TypeId>> {
component_infos component_infos

View file

@ -466,7 +466,7 @@ async fn load_gltf<'a, 'b>(
world world
.spawn() .spawn()
.insert_bundle(SpatialBundle::VISIBLE_IDENTITY) .insert(SpatialBundle::VISIBLE_IDENTITY)
.with_children(|parent| { .with_children(|parent| {
for node in scene.nodes() { for node in scene.nodes() {
let result = load_node( let result = load_node(
@ -748,7 +748,7 @@ fn load_node(
} }
}; };
node.insert_bundle(( node.insert((
projection, projection,
Camera { Camera {
is_active: !*active_camera_found, is_active: !*active_camera_found,

View file

@ -331,8 +331,7 @@ impl<'w> WorldChildBuilder<'w> {
let entity = self let entity = self
.world .world
.spawn() .spawn()
.insert_bundle(bundle) .insert((bundle, Parent(parent_entity)))
.insert(Parent(parent_entity))
.id(); .id();
push_child_unchecked(self.world, parent_entity, entity); push_child_unchecked(self.world, parent_entity, entity);
self.current_entity = Some(entity); self.current_entity = Some(entity);
@ -534,12 +533,12 @@ mod tests {
let mut queue = CommandQueue::default(); let mut queue = CommandQueue::default();
let mut commands = Commands::new(&mut queue, &world); let mut commands = Commands::new(&mut queue, &world);
let parent = commands.spawn().insert(C(1)).id(); let parent = commands.spawn_bundle(C(1)).id();
let children = commands.entity(parent).add_children(|parent| { let children = commands.entity(parent).add_children(|parent| {
[ [
parent.spawn().insert(C(2)).id(), parent.spawn_bundle(C(2)).id(),
parent.spawn().insert(C(3)).id(), parent.spawn_bundle(C(3)).id(),
parent.spawn().insert(C(4)).id(), parent.spawn_bundle(C(4)).id(),
] ]
}); });

View file

@ -467,7 +467,7 @@ pub fn add_clusters(
// actual settings here don't matter - they will be overwritten in assign_lights_to_clusters // actual settings here don't matter - they will be overwritten in assign_lights_to_clusters
commands commands
.entity(entity) .entity(entity)
.insert_bundle((Clusters::default(), config)); .insert((Clusters::default(), config));
} }
} }

View file

@ -394,7 +394,7 @@ pub fn extract_clusters(
views: Extract<Query<(Entity, &Clusters), With<Camera>>>, views: Extract<Query<(Entity, &Clusters), With<Camera>>>,
) { ) {
for (entity, clusters) in &views { for (entity, clusters) in &views {
commands.get_or_spawn(entity).insert_bundle(( commands.get_or_spawn(entity).insert((
ExtractedClustersPointLights { ExtractedClustersPointLights {
data: clusters.lights.clone(), data: clusters.lights.clone(),
}, },
@ -564,7 +564,7 @@ pub fn extract_lights(
largest_dimension / directional_light_shadow_map.size as f32; largest_dimension / directional_light_shadow_map.size as f32;
// TODO: As above // TODO: As above
let render_visible_entities = visible_entities.clone(); let render_visible_entities = visible_entities.clone();
commands.get_or_spawn(entity).insert_bundle(( commands.get_or_spawn(entity).insert((
ExtractedDirectionalLight { ExtractedDirectionalLight {
color: directional_light.color, color: directional_light.color,
illuminance: directional_light.illuminance, illuminance: directional_light.illuminance,
@ -1013,8 +1013,7 @@ pub fn prepare_lights(
}); });
let view_light_entity = commands let view_light_entity = commands
.spawn() .spawn_bundle((
.insert_bundle((
ShadowView { ShadowView {
depth_texture_view, depth_texture_view,
pass_name: format!( pass_name: format!(
@ -1073,8 +1072,7 @@ pub fn prepare_lights(
}); });
let view_light_entity = commands let view_light_entity = commands
.spawn() .spawn_bundle((
.insert_bundle((
ShadowView { ShadowView {
depth_texture_view, depth_texture_view,
pass_name: format!("shadow pass spot light {}", light_index,), pass_name: format!("shadow pass spot light {}", light_index,),
@ -1157,8 +1155,7 @@ pub fn prepare_lights(
}); });
let view_light_entity = commands let view_light_entity = commands
.spawn() .spawn_bundle((
.insert_bundle((
ShadowView { ShadowView {
depth_texture_view, depth_texture_view,
pass_name: format!("shadow pass directional light {}", i), pass_name: format!("shadow pass directional light {}", i),
@ -1212,7 +1209,7 @@ pub fn prepare_lights(
array_layer_count: None, array_layer_count: None,
}); });
commands.entity(entity).insert_bundle(( commands.entity(entity).insert((
ViewShadowBindings { ViewShadowBindings {
point_light_depth_texture: point_light_depth_texture.texture, point_light_depth_texture: point_light_depth_texture.texture,
point_light_depth_texture_view, point_light_depth_texture_view,

View file

@ -426,7 +426,7 @@ pub fn extract_cameras(
if target_size.x == 0 || target_size.y == 0 { if target_size.x == 0 || target_size.y == 0 {
continue; continue;
} }
commands.get_or_spawn(entity).insert_bundle(( commands.get_or_spawn(entity).insert((
ExtractedCamera { ExtractedCamera {
target: camera.target.clone(), target: camera.target.clone(),
viewport: camera.viewport.clone(), viewport: camera.viewport.clone(),

View file

@ -429,7 +429,7 @@ mod test {
let root1 = app let root1 = app
.world .world
.spawn() .spawn()
.insert_bundle(( .insert((
Visibility { is_visible: false }, Visibility { is_visible: false },
ComputedVisibility::default(), ComputedVisibility::default(),
)) ))
@ -437,12 +437,12 @@ mod test {
let root1_child1 = app let root1_child1 = app
.world .world
.spawn() .spawn()
.insert_bundle((Visibility::default(), ComputedVisibility::default())) .insert((Visibility::default(), ComputedVisibility::default()))
.id(); .id();
let root1_child2 = app let root1_child2 = app
.world .world
.spawn() .spawn()
.insert_bundle(( .insert((
Visibility { is_visible: false }, Visibility { is_visible: false },
ComputedVisibility::default(), ComputedVisibility::default(),
)) ))
@ -450,12 +450,12 @@ mod test {
let root1_child1_grandchild1 = app let root1_child1_grandchild1 = app
.world .world
.spawn() .spawn()
.insert_bundle((Visibility::default(), ComputedVisibility::default())) .insert((Visibility::default(), ComputedVisibility::default()))
.id(); .id();
let root1_child2_grandchild1 = app let root1_child2_grandchild1 = app
.world .world
.spawn() .spawn()
.insert_bundle((Visibility::default(), ComputedVisibility::default())) .insert((Visibility::default(), ComputedVisibility::default()))
.id(); .id();
app.world app.world
@ -471,17 +471,17 @@ mod test {
let root2 = app let root2 = app
.world .world
.spawn() .spawn()
.insert_bundle((Visibility::default(), ComputedVisibility::default())) .insert((Visibility::default(), ComputedVisibility::default()))
.id(); .id();
let root2_child1 = app let root2_child1 = app
.world .world
.spawn() .spawn()
.insert_bundle((Visibility::default(), ComputedVisibility::default())) .insert((Visibility::default(), ComputedVisibility::default()))
.id(); .id();
let root2_child2 = app let root2_child2 = app
.world .world
.spawn() .spawn()
.insert_bundle(( .insert((
Visibility { is_visible: false }, Visibility { is_visible: false },
ComputedVisibility::default(), ComputedVisibility::default(),
)) ))
@ -489,12 +489,12 @@ mod test {
let root2_child1_grandchild1 = app let root2_child1_grandchild1 = app
.world .world
.spawn() .spawn()
.insert_bundle((Visibility::default(), ComputedVisibility::default())) .insert((Visibility::default(), ComputedVisibility::default()))
.id(); .id();
let root2_child2_grandchild1 = app let root2_child2_grandchild1 = app
.world .world
.spawn() .spawn()
.insert_bundle((Visibility::default(), ComputedVisibility::default())) .insert((Visibility::default(), ComputedVisibility::default()))
.id(); .id();
app.world app.world

View file

@ -121,12 +121,12 @@ mod test {
// Root entity // Root entity
world world
.spawn() .spawn()
.insert_bundle(TransformBundle::from(Transform::from_xyz(1.0, 0.0, 0.0))); .insert(TransformBundle::from(Transform::from_xyz(1.0, 0.0, 0.0)));
let mut children = Vec::new(); let mut children = Vec::new();
world world
.spawn() .spawn()
.insert_bundle(TransformBundle::from(Transform::from_xyz(1.0, 0.0, 0.0))) .insert(TransformBundle::from(Transform::from_xyz(1.0, 0.0, 0.0)))
.with_children(|parent| { .with_children(|parent| {
children.push( children.push(
parent parent
@ -209,22 +209,11 @@ mod test {
let mut command_queue = CommandQueue::default(); let mut command_queue = CommandQueue::default();
let mut commands = Commands::new(&mut command_queue, &world); let mut commands = Commands::new(&mut command_queue, &world);
let parent = commands let parent = commands
.spawn() .spawn_bundle(Transform::from_xyz(1.0, 0.0, 0.0))
.insert(Transform::from_xyz(1.0, 0.0, 0.0))
.id(); .id();
commands.entity(parent).with_children(|parent| { commands.entity(parent).with_children(|parent| {
children.push( children.push(parent.spawn_bundle(Transform::from_xyz(0.0, 2.0, 0.0)).id());
parent children.push(parent.spawn_bundle(Transform::from_xyz(0.0, 3.0, 0.0)).id());
.spawn()
.insert(Transform::from_xyz(0.0, 2.0, 0.0))
.id(),
);
children.push(
parent
.spawn()
.insert(Transform::from_xyz(0.0, 3.0, 0.0))
.id(),
);
}); });
command_queue.apply(&mut world); command_queue.apply(&mut world);
schedule.run(&mut world); schedule.run(&mut world);
@ -339,12 +328,9 @@ mod test {
let mut grandchild = Entity::from_raw(0); let mut grandchild = Entity::from_raw(0);
let child = world let child = world
.spawn() .spawn()
.insert_bundle(TransformBundle::IDENTITY) .insert(TransformBundle::IDENTITY)
.with_children(|builder| { .with_children(|builder| {
grandchild = builder grandchild = builder.spawn_bundle(TransformBundle::IDENTITY).id();
.spawn()
.insert_bundle(TransformBundle::IDENTITY)
.id();
}) })
.id(); .id();
(child, grandchild) (child, grandchild)
@ -358,7 +344,7 @@ mod test {
app.world app.world
.spawn() .spawn()
.insert_bundle(TransformBundle::IDENTITY) .insert(TransformBundle::IDENTITY)
.push_children(&[child]); .push_children(&[child]);
std::mem::swap( std::mem::swap(
&mut *app.world.get_mut::<Parent>(child).unwrap(), &mut *app.world.get_mut::<Parent>(child).unwrap(),

View file

@ -250,8 +250,7 @@ pub fn extract_default_ui_camera_view<T: Component>(
}; };
projection.update(logical_size.x, logical_size.y); projection.update(logical_size.x, logical_size.y);
let default_camera_view = commands let default_camera_view = commands
.spawn() .spawn_bundle(ExtractedView {
.insert(ExtractedView {
projection: projection.get_projection_matrix(), projection: projection.get_projection_matrix(),
transform: GlobalTransform::from_xyz( transform: GlobalTransform::from_xyz(
0.0, 0.0,
@ -266,7 +265,7 @@ pub fn extract_default_ui_camera_view<T: Component>(
), ),
}) })
.id(); .id();
commands.get_or_spawn(entity).insert_bundle(( commands.get_or_spawn(entity).insert((
DefaultCameraView(default_camera_view), DefaultCameraView(default_camera_view),
RenderPhase::<TransparentUi>::default(), RenderPhase::<TransparentUi>::default(),
)); ));

View file

@ -27,7 +27,7 @@ fn setup(
mut materials: ResMut<Assets<LineMaterial>>, mut materials: ResMut<Assets<LineMaterial>>,
) { ) {
// Spawn a list of lines with start and end points for each lines // Spawn a list of lines with start and end points for each lines
commands.spawn().insert_bundle(MaterialMeshBundle { commands.spawn_bundle(MaterialMeshBundle {
mesh: meshes.add(Mesh::from(LineList { mesh: meshes.add(Mesh::from(LineList {
lines: vec![ lines: vec![
(Vec3::ZERO, Vec3::new(1.0, 1.0, 0.0)), (Vec3::ZERO, Vec3::new(1.0, 1.0, 0.0)),
@ -42,7 +42,7 @@ fn setup(
}); });
// Spawn a line strip that goes from point to point // Spawn a line strip that goes from point to point
commands.spawn().insert_bundle(MaterialMeshBundle { commands.spawn_bundle(MaterialMeshBundle {
mesh: meshes.add(Mesh::from(LineStrip { mesh: meshes.add(Mesh::from(LineStrip {
points: vec![ points: vec![
Vec3::ZERO, Vec3::ZERO,

View file

@ -61,14 +61,16 @@ fn setup(
.insert(NotShadowCaster); .insert(NotShadowCaster);
// floating plane - initially not a shadow receiver and not a caster // floating plane - initially not a shadow receiver and not a caster
commands commands.spawn_bundle((
.spawn_bundle(PbrBundle { PbrBundle {
mesh: meshes.add(Mesh::from(shape::Plane { size: 20.0 })), mesh: meshes.add(Mesh::from(shape::Plane { size: 20.0 })),
material: materials.add(Color::GREEN.into()), material: materials.add(Color::GREEN.into()),
transform: Transform::from_xyz(0.0, 1.0, -10.0), transform: Transform::from_xyz(0.0, 1.0, -10.0),
..default() ..default()
}) },
.insert_bundle((NotShadowCaster, NotShadowReceiver)); NotShadowCaster,
NotShadowReceiver,
));
// lower ground plane - initially a shadow receiver // lower ground plane - initially a shadow receiver
commands.spawn_bundle(PbrBundle { commands.spawn_bundle(PbrBundle {

View file

@ -116,13 +116,16 @@ fn setup(
// Create the scene that will be animated // Create the scene that will be animated
// First entity is the planet // First entity is the planet
commands commands
.spawn_bundle(PbrBundle { .spawn_bundle((
mesh: meshes.add(Mesh::from(shape::Icosphere::default())), PbrBundle {
material: materials.add(Color::rgb(0.8, 0.7, 0.6).into()), mesh: meshes.add(Mesh::from(shape::Icosphere::default())),
..default() material: materials.add(Color::rgb(0.8, 0.7, 0.6).into()),
}) ..default()
// Add the Name component, and the animation player },
.insert_bundle((planet, player)) // Add the Name component, and the animation player
planet,
player,
))
.with_children(|p| { .with_children(|p| {
// This entity is just used for animation, but doesn't display anything // This entity is just used for animation, but doesn't display anything
p.spawn_bundle(SpatialBundle::VISIBLE_IDENTITY) p.spawn_bundle(SpatialBundle::VISIBLE_IDENTITY)
@ -130,14 +133,16 @@ fn setup(
.insert(orbit_controller) .insert(orbit_controller)
.with_children(|p| { .with_children(|p| {
// The satellite, placed at a distance of the planet // The satellite, placed at a distance of the planet
p.spawn_bundle(PbrBundle { p.spawn_bundle((
transform: Transform::from_xyz(1.5, 0.0, 0.0), PbrBundle {
mesh: meshes.add(Mesh::from(shape::Cube { size: 0.5 })), transform: Transform::from_xyz(1.5, 0.0, 0.0),
material: materials.add(Color::rgb(0.3, 0.9, 0.3).into()), mesh: meshes.add(Mesh::from(shape::Cube { size: 0.5 })),
..default() material: materials.add(Color::rgb(0.3, 0.9, 0.3).into()),
}) ..default()
// Add the Name component },
.insert(satellite); // Add the Name component
satellite,
));
}); });
}); });
} }

View file

@ -71,7 +71,7 @@ fn spawn_tasks(mut commands: Commands) {
}); });
// Spawn new entity and add our new task as a component // Spawn new entity and add our new task as a component
commands.spawn().insert(ComputeTransform(task)); commands.spawn_bundle(ComputeTransform(task));
} }
} }
} }
@ -90,7 +90,7 @@ fn handle_tasks(
for (entity, mut task) in &mut transform_tasks { for (entity, mut task) in &mut transform_tasks {
if let Some(transform) = future::block_on(future::poll_once(&mut task.0)) { if let Some(transform) = future::block_on(future::poll_once(&mut task.0)) {
// Add our new PbrBundle of components to our tagged entity // Add our new PbrBundle of components to our tagged entity
commands.entity(entity).insert_bundle(PbrBundle { commands.entity(entity).insert(PbrBundle {
mesh: box_mesh_handle.clone(), mesh: box_mesh_handle.clone(),
material: box_material_handle.clone(), material: box_material_handle.clone(),
transform, transform,

View file

@ -17,8 +17,8 @@ fn main() {
struct MyComponent(f64); struct MyComponent(f64);
fn setup(mut commands: Commands) { fn setup(mut commands: Commands) {
commands.spawn().insert(MyComponent(0.)); commands.spawn_bundle(MyComponent(0.));
commands.spawn().insert(Transform::IDENTITY); commands.spawn_bundle(Transform::IDENTITY);
} }
fn change_component(time: Res<Time>, mut query: Query<(Entity, &mut MyComponent)>) { fn change_component(time: Res<Time>, mut query: Query<(Entity, &mut MyComponent)>) {

View file

@ -112,12 +112,7 @@ struct QueryFilter<T: Component, P: Component> {
} }
fn spawn(mut commands: Commands) { fn spawn(mut commands: Commands) {
commands commands.spawn_bundle((ComponentA, ComponentB, ComponentC, ComponentD));
.spawn()
.insert(ComponentA)
.insert(ComponentB)
.insert(ComponentC)
.insert(ComponentD);
} }
fn print_components_iter_mut( fn print_components_iter_mut(

View file

@ -213,7 +213,7 @@ fn exclusive_player_system(world: &mut World) {
// Randomly add a new player // Randomly add a new player
if should_add_player { if should_add_player {
println!("Player {} has joined the game!", total_players + 1); println!("Player {} has joined the game!", total_players + 1);
world.spawn().insert_bundle(( world.spawn().insert((
Player { Player {
name: format!("Player {}", total_players + 1), name: format!("Player {}", total_players + 1),
}, },

View file

@ -50,19 +50,17 @@ fn main() {
} }
fn setup_system(mut commands: Commands) { fn setup_system(mut commands: Commands) {
commands commands.spawn_bundle((
.spawn() PrinterTick(Timer::from_seconds(1.0, true)),
.insert(PrinterTick(Timer::from_seconds(1.0, true))) TextToPrint("I will print until you press space.".to_string()),
.insert(TextToPrint( MenuClose,
"I will print until you press space.".to_string(), ));
))
.insert(MenuClose);
commands commands.spawn_bundle((
.spawn() PrinterTick(Timer::from_seconds(1.0, true)),
.insert(PrinterTick(Timer::from_seconds(1.0, true))) TextToPrint("I will always print".to_string()),
.insert(TextToPrint("I will always print".to_string())) LevelUnload,
.insert(LevelUnload); ));
} }
fn print_text_system(time: Res<Time>, mut query: Query<(&mut PrinterTick, &TextToPrint)>) { fn print_text_system(time: Res<Time>, mut query: Query<(&mut PrinterTick, &TextToPrint)>) {

View file

@ -34,9 +34,9 @@ impl<'w, 's> PlayerCounter<'w, 's> {
/// Spawn some players to count /// Spawn some players to count
fn spawn(mut commands: Commands) { fn spawn(mut commands: Commands) {
commands.spawn().insert(Player); commands.spawn_bundle(Player);
commands.spawn().insert(Player); commands.spawn_bundle(Player);
commands.spawn().insert(Player); commands.spawn_bundle(Player);
} }
/// The [`SystemParam`] can be used directly in a system argument. /// The [`SystemParam`] can be used directly in a system argument.

View file

@ -38,9 +38,7 @@ impl Default for Countdown {
fn setup(mut commands: Commands) { fn setup(mut commands: Commands) {
// Add an entity to the world with a timer // Add an entity to the world with a timer
commands commands.spawn_bundle(PrintOnCompletionTimer(Timer::from_seconds(5.0, false)));
.spawn()
.insert(PrintOnCompletionTimer(Timer::from_seconds(5.0, false)));
} }
/// This system ticks all the `Timer` components on entities within the scene /// This system ticks all the `Timer` components on entities within the scene

View file

@ -187,10 +187,8 @@ fn setup(
// Paddle // Paddle
let paddle_y = BOTTOM_WALL + GAP_BETWEEN_PADDLE_AND_FLOOR; let paddle_y = BOTTOM_WALL + GAP_BETWEEN_PADDLE_AND_FLOOR;
commands commands.spawn_bundle((
.spawn() SpriteBundle {
.insert(Paddle)
.insert_bundle(SpriteBundle {
transform: Transform { transform: Transform {
translation: Vec3::new(0.0, paddle_y, 0.0), translation: Vec3::new(0.0, paddle_y, 0.0),
scale: PADDLE_SIZE, scale: PADDLE_SIZE,
@ -201,20 +199,22 @@ fn setup(
..default() ..default()
}, },
..default() ..default()
}) },
.insert(Collider); Paddle,
Collider,
));
// Ball // Ball
commands commands.spawn_bundle((
.spawn() MaterialMesh2dBundle {
.insert(Ball)
.insert_bundle(MaterialMesh2dBundle {
mesh: meshes.add(shape::Circle::default().into()).into(), mesh: meshes.add(shape::Circle::default().into()).into(),
material: materials.add(ColorMaterial::from(BALL_COLOR)), material: materials.add(ColorMaterial::from(BALL_COLOR)),
transform: Transform::from_translation(BALL_STARTING_POSITION).with_scale(BALL_SIZE), transform: Transform::from_translation(BALL_STARTING_POSITION).with_scale(BALL_SIZE),
..default() ..default()
}) },
.insert(Velocity(INITIAL_BALL_DIRECTION.normalize() * BALL_SPEED)); Ball,
Velocity(INITIAL_BALL_DIRECTION.normalize() * BALL_SPEED),
));
// Scoreboard // Scoreboard
commands.spawn_bundle( commands.spawn_bundle(
@ -290,10 +290,8 @@ fn setup(
); );
// brick // brick
commands commands.spawn_bundle((
.spawn() SpriteBundle {
.insert(Brick)
.insert_bundle(SpriteBundle {
sprite: Sprite { sprite: Sprite {
color: BRICK_COLOR, color: BRICK_COLOR,
..default() ..default()
@ -304,8 +302,10 @@ fn setup(
..default() ..default()
}, },
..default() ..default()
}) },
.insert(Collider); Brick,
Collider,
));
} }
} }
} }

View file

@ -104,25 +104,24 @@ fn setup_contributor_selection(mut commands: Commands, asset_server: Res<AssetSe
let transform = Transform::from_xyz(pos.0, pos.1, 0.0); let transform = Transform::from_xyz(pos.0, pos.1, 0.0);
let entity = commands let entity = commands
.spawn() .spawn_bundle((
.insert_bundle((
Contributor { name, hue }, Contributor { name, hue },
Velocity { Velocity {
translation: velocity, translation: velocity,
rotation: -dir * 5.0, rotation: -dir * 5.0,
}, },
)) SpriteBundle {
.insert_bundle(SpriteBundle { sprite: Sprite {
sprite: Sprite { custom_size: Some(Vec2::new(1.0, 1.0) * SPRITE_SIZE),
custom_size: Some(Vec2::new(1.0, 1.0) * SPRITE_SIZE), color: Color::hsla(hue, SATURATION_DESELECTED, LIGHTNESS_DESELECTED, ALPHA),
color: Color::hsla(hue, SATURATION_DESELECTED, LIGHTNESS_DESELECTED, ALPHA), flip_x: flipped,
flip_x: flipped, ..default()
},
texture: texture_handle.clone(),
transform,
..default() ..default()
}, },
texture: texture_handle.clone(), ))
transform,
..default()
})
.id(); .id();
contributor_selection.order.push(entity); contributor_selection.order.push(entity);
@ -136,7 +135,7 @@ fn setup_contributor_selection(mut commands: Commands, asset_server: Res<AssetSe
fn setup(mut commands: Commands, asset_server: Res<AssetServer>) { fn setup(mut commands: Commands, asset_server: Res<AssetServer>) {
commands.spawn_bundle(Camera2dBundle::default()); commands.spawn_bundle(Camera2dBundle::default());
commands.spawn().insert(ContributorDisplay).insert_bundle( commands.spawn_bundle((
TextBundle::from_sections([ TextBundle::from_sections([
TextSection::new( TextSection::new(
"Contributor showcase", "Contributor showcase",
@ -156,7 +155,8 @@ fn setup(mut commands: Commands, asset_server: Res<AssetServer>) {
align_self: AlignSelf::FlexEnd, align_self: AlignSelf::FlexEnd,
..default() ..default()
}), }),
); ContributorDisplay,
));
} }
/// Finds the next contributor to display and selects the entity /// Finds the next contributor to display and selects the entity

View file

@ -92,14 +92,12 @@ fn save_scene_system(world: &mut World) {
let mut scene_world = World::new(); let mut scene_world = World::new();
let mut component_b = ComponentB::from_world(world); let mut component_b = ComponentB::from_world(world);
component_b.value = "hello".to_string(); component_b.value = "hello".to_string();
scene_world.spawn().insert_bundle(( scene_world.spawn().insert((
component_b, component_b,
ComponentA { x: 1.0, y: 2.0 }, ComponentA { x: 1.0, y: 2.0 },
Transform::IDENTITY, Transform::IDENTITY,
)); ));
scene_world scene_world.spawn().insert(ComponentA { x: 3.0, y: 4.0 });
.spawn()
.insert_bundle((ComponentA { x: 3.0, y: 4.0 },));
// The TypeRegistry resource contains information about all registered types (including // The TypeRegistry resource contains information about all registered types (including
// components). This is used to construct scenes. // components). This is used to construct scenes.

View file

@ -39,7 +39,7 @@ fn main() {
fn setup(mut commands: Commands, mut meshes: ResMut<Assets<Mesh>>) { fn setup(mut commands: Commands, mut meshes: ResMut<Assets<Mesh>>) {
// cube // cube
commands.spawn().insert_bundle(( commands.spawn_bundle((
meshes.add(Mesh::from(shape::Cube { size: 1.0 })), meshes.add(Mesh::from(shape::Cube { size: 1.0 })),
Transform::from_xyz(0.0, 0.5, 0.0), Transform::from_xyz(0.0, 0.5, 0.0),
GlobalTransform::default(), GlobalTransform::default(),

View file

@ -40,7 +40,7 @@ fn setup(
); );
// cube // cube
commands.spawn().insert_bundle(MaterialMeshBundle { commands.spawn_bundle(MaterialMeshBundle {
mesh: meshes.add(mesh), mesh: meshes.add(mesh),
transform: Transform::from_xyz(0.0, 0.5, 0.0), transform: Transform::from_xyz(0.0, 0.5, 0.0),
material: materials.add(CustomMaterial { material: materials.add(CustomMaterial {

View file

@ -27,7 +27,7 @@ fn setup(
mut materials: ResMut<Assets<CustomMaterial>>, mut materials: ResMut<Assets<CustomMaterial>>,
) { ) {
// blue cube // blue cube
commands.spawn().insert_bundle(MaterialMeshBundle { commands.spawn_bundle(MaterialMeshBundle {
mesh: meshes.add(Mesh::from(shape::Cube { size: 1.0 })), mesh: meshes.add(Mesh::from(shape::Cube { size: 1.0 })),
transform: Transform::from_xyz(-1.0, 0.5, 0.0), transform: Transform::from_xyz(-1.0, 0.5, 0.0),
material: materials.add(CustomMaterial { material: materials.add(CustomMaterial {
@ -38,7 +38,7 @@ fn setup(
}); });
// red cube (with green color overridden by the IS_RED "shader def") // red cube (with green color overridden by the IS_RED "shader def")
commands.spawn().insert_bundle(MaterialMeshBundle { commands.spawn_bundle(MaterialMeshBundle {
mesh: meshes.add(Mesh::from(shape::Cube { size: 1.0 })), mesh: meshes.add(Mesh::from(shape::Cube { size: 1.0 })),
transform: Transform::from_xyz(1.0, 0.5, 0.0), transform: Transform::from_xyz(1.0, 0.5, 0.0),
material: materials.add(CustomMaterial { material: materials.add(CustomMaterial {

View file

@ -30,7 +30,7 @@ fn main() {
} }
fn setup(mut commands: Commands, mut meshes: ResMut<Assets<Mesh>>) { fn setup(mut commands: Commands, mut meshes: ResMut<Assets<Mesh>>) {
commands.spawn().insert_bundle(( commands.spawn_bundle((
meshes.add(Mesh::from(shape::Cube { size: 0.5 })), meshes.add(Mesh::from(shape::Cube { size: 0.5 })),
Transform::from_xyz(0.0, 0.0, 0.0), Transform::from_xyz(0.0, 0.0, 0.0),
GlobalTransform::default(), GlobalTransform::default(),

View file

@ -22,7 +22,7 @@ fn setup(
asset_server: Res<AssetServer>, asset_server: Res<AssetServer>,
) { ) {
// cube // cube
commands.spawn().insert_bundle(MaterialMeshBundle { commands.spawn_bundle(MaterialMeshBundle {
mesh: meshes.add(Mesh::from(shape::Cube { size: 1.0 })), mesh: meshes.add(Mesh::from(shape::Cube { size: 1.0 })),
transform: Transform::from_xyz(0.0, 0.5, 0.0), transform: Transform::from_xyz(0.0, 0.5, 0.0),
material: materials.add(CustomMaterial { material: materials.add(CustomMaterial {

View file

@ -28,7 +28,7 @@ fn setup(
asset_server: Res<AssetServer>, asset_server: Res<AssetServer>,
) { ) {
// cube // cube
commands.spawn().insert_bundle(MaterialMeshBundle { commands.spawn_bundle(MaterialMeshBundle {
mesh: meshes.add(Mesh::from(shape::Cube { size: 1.0 })), mesh: meshes.add(Mesh::from(shape::Cube { size: 1.0 })),
transform: Transform::from_xyz(0.0, 0.5, 0.0), transform: Transform::from_xyz(0.0, 0.5, 0.0),
material: materials.add(CustomMaterial { material: materials.add(CustomMaterial {

View file

@ -35,7 +35,7 @@ fn setup(
..default() ..default()
}); });
commands.spawn().insert_bundle(MaterialMeshBundle { commands.spawn_bundle(MaterialMeshBundle {
mesh: meshes.add(Mesh::from(shape::Cube { size: 1.0 })), mesh: meshes.add(Mesh::from(shape::Cube { size: 1.0 })),
transform: Transform::from_xyz(0.0, 0.5, 0.0), transform: Transform::from_xyz(0.0, 0.5, 0.0),
material: custom_materials.add(CustomMaterial { material: custom_materials.add(CustomMaterial {

View file

@ -50,10 +50,10 @@ fn setup(
let texture_atlas_handle = texture_atlases.add(texture_atlas); let texture_atlas_handle = texture_atlases.add(texture_atlas);
// Spawns the camera // Spawns the camera
commands commands.spawn_bundle((
.spawn() Camera2dBundle::default(),
.insert_bundle(Camera2dBundle::default()) Transform::from_xyz(0.0, 0.0, 1000.0),
.insert(Transform::from_xyz(0.0, 0.0, 1000.0)); ));
// Builds and spawns the sprites // Builds and spawns the sprites
for y in -half_y..half_y { for y in -half_y..half_y {

View file

@ -55,10 +55,10 @@ fn setup(mut commands: Commands, assets: Res<AssetServer>, color_tint: Res<Color
let sprite_handle = assets.load("branding/icon.png"); let sprite_handle = assets.load("branding/icon.png");
// Spawns the camera // Spawns the camera
commands commands.spawn_bundle((
.spawn() Camera2dBundle::default(),
.insert_bundle(Camera2dBundle::default()) Transform::from_xyz(0.0, 0.0, 1000.0),
.insert(Transform::from_xyz(0.0, 0.0, 1000.0)); ));
// Builds and spawns the sprites // Builds and spawns the sprites
let mut sprites = vec![]; let mut sprites = vec![];

View file

@ -369,9 +369,7 @@ fn spawn_tree(
// insert root // insert root
ents.push( ents.push(
commands commands
.spawn() .spawn_bundle((root_transform, GlobalTransform::default()))
.insert(root_transform)
.insert(GlobalTransform::default())
.id(), .id(),
); );

View file

@ -50,43 +50,45 @@ fn setup(
// This example focuses on translation only to clearly demonstrate the differences. // This example focuses on translation only to clearly demonstrate the differences.
// Spawn a basic cube to have an entity as reference. // Spawn a basic cube to have an entity as reference.
let mut main_entity = commands.spawn(); commands
main_entity .spawn_bundle((
.insert_bundle(PbrBundle { PbrBundle {
mesh: meshes.add(Mesh::from(shape::Cube { size: 1.0 })), mesh: meshes.add(Mesh::from(shape::Cube { size: 1.0 })),
material: materials.add(Color::YELLOW.into()), material: materials.add(Color::YELLOW.into()),
..default()
})
.insert(ChangeGlobal)
.insert(Move)
.insert(ToggledBy(KeyCode::Key1));
// Spawn two entities as children above the original main entity.
// The red entity spawned here will be changed via its global transform
// where the green one will be changed via its local transform.
main_entity.with_children(|child_builder| {
// also see parenting example
child_builder
.spawn_bundle(PbrBundle {
mesh: meshes.add(Mesh::from(shape::Cube { size: 0.5 })),
material: materials.add(Color::RED.into()),
transform: Transform::from_translation(Vec3::Y - Vec3::Z),
..default() ..default()
}) },
.insert(ChangeGlobal) ChangeGlobal,
.insert(Move) Move,
.insert(ToggledBy(KeyCode::Key2)); ToggledBy(KeyCode::Key1),
child_builder ))
.spawn_bundle(PbrBundle { // Spawn two entities as children above the original main entity.
mesh: meshes.add(Mesh::from(shape::Cube { size: 0.5 })), // The red entity spawned here will be changed via its global transform
material: materials.add(Color::GREEN.into()), // where the green one will be changed via its local transform.
transform: Transform::from_translation(Vec3::Y + Vec3::Z), .with_children(|child_builder| {
..default() // also see parenting example
}) child_builder.spawn_bundle((
.insert(ChangeLocal) PbrBundle {
.insert(Move) mesh: meshes.add(Mesh::from(shape::Cube { size: 0.5 })),
.insert(ToggledBy(KeyCode::Key3)); material: materials.add(Color::RED.into()),
}); transform: Transform::from_translation(Vec3::Y - Vec3::Z),
..default()
},
ChangeGlobal,
Move,
ToggledBy(KeyCode::Key2),
));
child_builder.spawn_bundle((
PbrBundle {
mesh: meshes.add(Mesh::from(shape::Cube { size: 0.5 })),
material: materials.add(Color::GREEN.into()),
transform: Transform::from_translation(Vec3::Y + Vec3::Z),
..default()
},
ChangeLocal,
Move,
ToggledBy(KeyCode::Key3),
));
});
// Spawn a camera looking at the entities to show what's happening in this example. // Spawn a camera looking at the entities to show what's happening in this example.
commands.spawn_bundle(Camera3dBundle { commands.spawn_bundle(Camera3dBundle {

View file

@ -38,7 +38,7 @@ fn hurt_enemies(mut enemies: Query<&mut Enemy>) {
fn spawn_enemy(mut commands: Commands, keyboard_input: Res<Input<KeyCode>>) { fn spawn_enemy(mut commands: Commands, keyboard_input: Res<Input<KeyCode>>) {
if keyboard_input.just_pressed(KeyCode::Space) { if keyboard_input.just_pressed(KeyCode::Space) {
commands.spawn().insert(Enemy { commands.spawn_bundle(Enemy {
hit_points: 5, hit_points: 5,
score_value: 3, score_value: 3,
}); });