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(
world
.spawn()
.insert_bundle((
.insert((
A(Mat4::from_scale(Vec3::ONE)),
B(Mat4::from_scale(Vec3::ONE)),
C(Mat4::from_scale(Vec3::ONE)),

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -276,10 +276,10 @@ struct PlayerBundle {
let mut world = World::new();
// 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
world.spawn().insert_bundle(PlayerBundle {
world.spawn().insert(PlayerBundle {
position: Position { x: 1.0, y: 1.0 },
..Default::default()
});

View file

@ -65,7 +65,7 @@ enum SimulationSystem {
// If an entity gets spawned, we increase the counter in the EntityCounter resource
fn spawn_entities(mut commands: Commands, mut entity_counter: ResMut<EntityCounter>) {
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);
entity_counter.value += 1;
}

View file

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

View file

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

View file

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

View file

@ -493,7 +493,7 @@ mod tests {
stage.run(&mut world);
assert_eq!(receive_events(&world), vec![StartedSystems(2),]);
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_u32(_: Query<(&mut W<u32>, &W<f32>)>) {}
let mut stage = SystemStage::parallel()

View file

@ -1477,7 +1477,7 @@ mod tests {
world.insert_resource(R(0));
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);
assert_eq!(world.resource::<R>().0, 1);
@ -1497,7 +1497,7 @@ mod tests {
let mut stage = SystemStage::parallel();
stage.add_system(query_count_system);
let entity = world.spawn().insert_bundle(()).id();
let entity = world.spawn().insert(()).id();
stage.run(&mut world);
assert_eq!(world.resource::<R>().0, 1);
@ -1522,7 +1522,7 @@ mod tests {
}
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>) {
@ -1564,7 +1564,7 @@ mod tests {
}
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>) {

View file

@ -3,7 +3,6 @@ mod parallel_scope;
use crate::{
bundle::Bundle,
component::Component,
entity::{Entities, Entity},
world::{FromWorld, World},
};
@ -147,7 +146,7 @@ impl<'w, 's> Commands<'w, 's> {
/// // Create another empty entity, then add some component to it
/// commands.spawn()
/// // 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
/// .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".
/// .spawn_bundle((Component1, Component2))
/// // 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:
/// .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.
pub fn spawn_bundle<'a, T: Bundle>(&'a mut self, bundle: T) -> EntityCommands<'w, 's, 'a> {
let mut e = self.spawn();
e.insert_bundle(bundle);
e.insert(bundle);
e
}
@ -262,7 +261,7 @@ impl<'w, 's> Commands<'w, 's> {
///
/// commands.entity(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
/// .insert(Label("hello world"));
/// }
@ -554,77 +553,62 @@ impl<'w, 's, 'a> EntityCommands<'w, 's, 'a> {
///
/// ```
/// # use bevy_ecs::prelude::*;
/// #
/// # #[derive(Resource)]
/// # struct PlayerEntity { entity: Entity }
/// # #[derive(Component)]
/// # struct Health(u32);
/// # #[derive(Component)]
/// # struct Strength(u32);
/// # #[derive(Component)]
/// # struct Defense(u32);
/// #
/// # #[derive(Bundle)]
/// # struct CombatBundle {
/// # health: Health,
/// # strength: Strength,
/// # defense: Defense,
/// # }
/// #
/// #[derive(Component)]
/// struct Health(u32);
/// #[derive(Component)]
/// struct Strength(u32);
/// #[derive(Component)]
/// struct Defense(u32);
///
/// #[derive(Bundle)]
/// struct CombatBundle {
/// health: Health,
/// strength: Strength,
/// }
///
/// fn add_combat_stats_system(mut commands: Commands, player: Res<PlayerEntity>) {
/// commands.entity(player.entity).insert_bundle(CombatBundle {
/// health: Health(100),
/// strength: Strength(40),
/// defense: Defense(20),
/// });
/// commands
/// .entity(player.entity)
/// // You can insert individual components:
/// .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);
/// ```
pub fn insert_bundle(&mut self, bundle: impl Bundle) -> &mut Self {
self.commands.add(InsertBundle {
pub fn insert(&mut self, bundle: impl Bundle) -> &mut Self {
self.commands.add(Insert {
entity: self.entity,
bundle,
});
self
}
/// Adds a single [`Component`] to the entity.
///
/// # Example
///
/// `Self::insert` can be chained with [`Commands::spawn`].
///
/// ```
/// # 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
#[deprecated(
since = "0.9.0",
note = "Use `insert` instead, which now accepts bundles, components, and tuples of bundles and components."
)]
pub fn insert_bundle(&mut self, bundle: impl Bundle) -> &mut Self {
self.insert(bundle)
}
/// 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.
///
/// # Example
@ -634,50 +618,35 @@ impl<'w, 's, 'a> EntityCommands<'w, 's, 'a> {
/// #
/// # #[derive(Resource)]
/// # struct PlayerEntity { entity: Entity }
/// #
/// # #[derive(Component)]
/// struct Dummy;
/// # #[derive(Bundle)]
/// # struct CombatBundle { a: Dummy }; // dummy field, unit bundles are not permitted.
/// #
/// #[derive(Component)]
/// struct Health(u32);
/// #[derive(Component)]
/// struct Strength(u32);
/// #[derive(Component)]
/// struct Defense(u32);
///
/// #[derive(Bundle)]
/// struct CombatBundle {
/// health: Health,
/// strength: Strength,
/// }
///
/// 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);
/// ```
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
where
T: Component,
T: Bundle,
{
self.commands.add(Remove::<T> {
entity: self.entity,
@ -686,6 +655,17 @@ impl<'w, 's, 'a> EntityCommands<'w, 's, 'a> {
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.
///
/// See [`World::despawn`] for more details.
@ -745,7 +725,7 @@ where
T: Bundle,
{
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 bundle: T,
}
impl<T> Command for InsertBundle<T>
impl<T> Command for Insert<T>
where
T: Bundle + 'static,
{
fn write(self, world: &mut World) {
if let Some(mut entity) = world.get_entity_mut(self.entity) {
entity.insert_bundle(self.bundle);
entity.insert(self.bundle);
} 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);
}
}
}
#[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)]
pub struct Remove<T> {
pub entity: Entity,
@ -860,23 +821,6 @@ pub struct 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
T: Bundle,
{
@ -884,7 +828,7 @@ where
if let Some(mut entity_mut) = world.get_entity_mut(self.entity) {
// remove intersection to gracefully handle components that were removed before running
// this command
entity_mut.remove_bundle_intersection::<T>();
entity_mut.remove_intersection::<T>();
}
}
}
@ -972,7 +916,7 @@ mod tests {
struct W<T>(T);
fn simple_command(world: &mut World) {
world.spawn().insert_bundle((W(0u32), W(42u64)));
world.spawn().insert((W(0u32), W(42u64)));
}
#[test]
@ -1010,7 +954,7 @@ mod tests {
// set up a simple command using a closure that adds one additional entity
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
@ -1037,7 +981,7 @@ mod tests {
let entity = Commands::new(&mut command_queue, &world)
.spawn()
.insert_bundle((W(1u32), W(2u64), dense_dropck, sparse_dropck))
.insert((W(1u32), W(2u64), dense_dropck, sparse_dropck))
.id();
command_queue.apply(&mut world);
let results_before = world
@ -1051,7 +995,7 @@ mod tests {
Commands::new(&mut command_queue, &world)
.entity(entity)
.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!(sparse_is_dropped.load(Ordering::Relaxed), 0);

View file

@ -158,7 +158,7 @@ mod tests {
struct CountEntities(Vec<usize>);
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>) {

View file

@ -245,10 +245,10 @@ mod tests {
let mut world = World::default();
world.insert_resource(SystemRan::No);
world.spawn().insert_bundle((A,));
world.spawn().insert_bundle((A, B));
world.spawn().insert_bundle((A, C));
world.spawn().insert_bundle((A, D));
world.spawn().insert(A);
world.spawn().insert((A, B));
world.spawn().insert((A, C));
world.spawn().insert((A, D));
run_system(&mut world, query_system);
@ -276,7 +276,7 @@ mod tests {
let mut world = World::default();
world.insert_resource(SystemRan::No);
world.spawn().insert_bundle((A, B));
world.spawn().insert((A, B));
run_system(&mut world, query_system);
@ -654,7 +654,7 @@ mod tests {
fn world_collections_system() {
let mut world = World::default();
world.insert_resource(SystemRan::No);
world.spawn().insert_bundle((W(42), W(true)));
world.spawn().insert((W(42), W(true)));
fn sys(
archetypes: &Archetypes,
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);
assert_eq!(
@ -1114,7 +1114,7 @@ mod tests {
expected_ids.insert(
world
.spawn()
.insert_bundle((A,))
.insert(A)
.archetype()
.get_archetype_component_id(a_id)
.unwrap(),
@ -1122,15 +1122,15 @@ mod tests {
expected_ids.insert(
world
.spawn()
.insert_bundle((A, C))
.insert((A, C))
.archetype()
.get_archetype_component_id(a_id)
.unwrap(),
);
// add some entities with archetypes that should not match
world.spawn().insert_bundle((A, B));
world.spawn().insert_bundle((B, C));
world.spawn().insert((A, B));
world.spawn().insert((B, C));
// update system and verify its accesses are correct
system.update_archetype_component_access(&world);
@ -1146,12 +1146,12 @@ mod tests {
expected_ids.insert(
world
.spawn()
.insert_bundle((A, D))
.insert((A, D))
.archetype()
.get_archetype_component_id(a_id)
.unwrap(),
);
world.spawn().insert_bundle((A, B, D));
world.spawn().insert((A, B, D));
system.update_archetype_component_access(&world);
assert_eq!(
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 {
self.insert(bundle)
}
pub fn insert<T: Bundle>(&mut self, bundle: T) -> &mut Self {
let change_tick = self.world.change_tick();
let bundle_info = self
.world
@ -260,8 +268,16 @@ impl<'w> EntityMut<'w> {
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> {
self.remove::<T>()
}
// TODO: move to BundleInfo
pub fn remove<T: Bundle>(&mut self) -> Option<T> {
let archetypes = &mut self.world.archetypes;
let storages = &mut self.world.storages;
let components = &mut self.world.components;
@ -384,9 +400,17 @@ impl<'w> EntityMut<'w> {
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
/// 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 storages = &mut self.world.storages;
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) {
let world = self.world;
world.flush();

View file

@ -376,7 +376,7 @@ impl World {
/// let mut world = World::new();
/// let entity = world.spawn()
/// .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();
///
/// let position = world.entity(entity).get::<Position>().unwrap();
@ -570,9 +570,9 @@ impl World {
/// struct Label(&'static str);
///
/// let mut world = World::new();
/// let a = world.spawn().insert_bundle((Order(2), Label("second"))).id();
/// let b = world.spawn().insert_bundle((Order(3), Label("third"))).id();
/// let c = world.spawn().insert_bundle((Order(1), Label("first"))).id();
/// let a = world.spawn().insert((Order(2), Label("second"))).id();
/// let b = world.spawn().insert((Order(3), Label("third"))).id();
/// let c = world.spawn().insert((Order(1), Label("first"))).id();
/// let mut entities = world.query::<(Entity, &Order, &Label)>()
/// .iter(&world)
/// .collect::<Vec<_>>();
@ -602,7 +602,7 @@ impl World {
///
/// let mut world = World::new();
/// 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 matching_entities = query.iter(&world).collect::<Vec<Entity>>();
@ -1782,13 +1782,13 @@ mod tests {
#[test]
fn inspect_entity_components() {
let mut world = World::new();
let ent0 = world.spawn().insert_bundle((Foo, Bar, Baz)).id();
let ent1 = world.spawn().insert_bundle((Foo, Bar)).id();
let ent2 = world.spawn().insert_bundle((Bar, Baz)).id();
let ent3 = world.spawn().insert_bundle((Foo, Baz)).id();
let ent4 = world.spawn().insert_bundle((Foo,)).id();
let ent5 = world.spawn().insert_bundle((Bar,)).id();
let ent6 = world.spawn().insert_bundle((Baz,)).id();
let ent0 = world.spawn().insert((Foo, Bar, Baz)).id();
let ent1 = world.spawn().insert((Foo, Bar)).id();
let ent2 = world.spawn().insert((Bar, Baz)).id();
let ent3 = world.spawn().insert((Foo, Baz)).id();
let ent4 = world.spawn().insert(Foo).id();
let ent5 = world.spawn().insert(Bar).id();
let ent6 = world.spawn().insert(Baz).id();
fn to_type_ids(component_infos: Vec<&ComponentInfo>) -> HashSet<Option<TypeId>> {
component_infos

View file

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

View file

@ -331,8 +331,7 @@ impl<'w> WorldChildBuilder<'w> {
let entity = self
.world
.spawn()
.insert_bundle(bundle)
.insert(Parent(parent_entity))
.insert((bundle, Parent(parent_entity)))
.id();
push_child_unchecked(self.world, parent_entity, entity);
self.current_entity = Some(entity);
@ -534,12 +533,12 @@ mod tests {
let mut queue = CommandQueue::default();
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| {
[
parent.spawn().insert(C(2)).id(),
parent.spawn().insert(C(3)).id(),
parent.spawn().insert(C(4)).id(),
parent.spawn_bundle(C(2)).id(),
parent.spawn_bundle(C(3)).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
commands
.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>>>,
) {
for (entity, clusters) in &views {
commands.get_or_spawn(entity).insert_bundle((
commands.get_or_spawn(entity).insert((
ExtractedClustersPointLights {
data: clusters.lights.clone(),
},
@ -564,7 +564,7 @@ pub fn extract_lights(
largest_dimension / directional_light_shadow_map.size as f32;
// TODO: As above
let render_visible_entities = visible_entities.clone();
commands.get_or_spawn(entity).insert_bundle((
commands.get_or_spawn(entity).insert((
ExtractedDirectionalLight {
color: directional_light.color,
illuminance: directional_light.illuminance,
@ -1013,8 +1013,7 @@ pub fn prepare_lights(
});
let view_light_entity = commands
.spawn()
.insert_bundle((
.spawn_bundle((
ShadowView {
depth_texture_view,
pass_name: format!(
@ -1073,8 +1072,7 @@ pub fn prepare_lights(
});
let view_light_entity = commands
.spawn()
.insert_bundle((
.spawn_bundle((
ShadowView {
depth_texture_view,
pass_name: format!("shadow pass spot light {}", light_index,),
@ -1157,8 +1155,7 @@ pub fn prepare_lights(
});
let view_light_entity = commands
.spawn()
.insert_bundle((
.spawn_bundle((
ShadowView {
depth_texture_view,
pass_name: format!("shadow pass directional light {}", i),
@ -1212,7 +1209,7 @@ pub fn prepare_lights(
array_layer_count: None,
});
commands.entity(entity).insert_bundle((
commands.entity(entity).insert((
ViewShadowBindings {
point_light_depth_texture: point_light_depth_texture.texture,
point_light_depth_texture_view,

View file

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

View file

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

View file

@ -121,12 +121,12 @@ mod test {
// Root entity
world
.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();
world
.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| {
children.push(
parent
@ -209,22 +209,11 @@ mod test {
let mut command_queue = CommandQueue::default();
let mut commands = Commands::new(&mut command_queue, &world);
let parent = commands
.spawn()
.insert(Transform::from_xyz(1.0, 0.0, 0.0))
.spawn_bundle(Transform::from_xyz(1.0, 0.0, 0.0))
.id();
commands.entity(parent).with_children(|parent| {
children.push(
parent
.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(),
);
children.push(parent.spawn_bundle(Transform::from_xyz(0.0, 2.0, 0.0)).id());
children.push(parent.spawn_bundle(Transform::from_xyz(0.0, 3.0, 0.0)).id());
});
command_queue.apply(&mut world);
schedule.run(&mut world);
@ -339,12 +328,9 @@ mod test {
let mut grandchild = Entity::from_raw(0);
let child = world
.spawn()
.insert_bundle(TransformBundle::IDENTITY)
.insert(TransformBundle::IDENTITY)
.with_children(|builder| {
grandchild = builder
.spawn()
.insert_bundle(TransformBundle::IDENTITY)
.id();
grandchild = builder.spawn_bundle(TransformBundle::IDENTITY).id();
})
.id();
(child, grandchild)
@ -358,7 +344,7 @@ mod test {
app.world
.spawn()
.insert_bundle(TransformBundle::IDENTITY)
.insert(TransformBundle::IDENTITY)
.push_children(&[child]);
std::mem::swap(
&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);
let default_camera_view = commands
.spawn()
.insert(ExtractedView {
.spawn_bundle(ExtractedView {
projection: projection.get_projection_matrix(),
transform: GlobalTransform::from_xyz(
0.0,
@ -266,7 +265,7 @@ pub fn extract_default_ui_camera_view<T: Component>(
),
})
.id();
commands.get_or_spawn(entity).insert_bundle((
commands.get_or_spawn(entity).insert((
DefaultCameraView(default_camera_view),
RenderPhase::<TransparentUi>::default(),
));

View file

@ -27,7 +27,7 @@ fn setup(
mut materials: ResMut<Assets<LineMaterial>>,
) {
// 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 {
lines: vec![
(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
commands.spawn().insert_bundle(MaterialMeshBundle {
commands.spawn_bundle(MaterialMeshBundle {
mesh: meshes.add(Mesh::from(LineStrip {
points: vec![
Vec3::ZERO,

View file

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

View file

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

View file

@ -17,8 +17,8 @@ fn main() {
struct MyComponent(f64);
fn setup(mut commands: Commands) {
commands.spawn().insert(MyComponent(0.));
commands.spawn().insert(Transform::IDENTITY);
commands.spawn_bundle(MyComponent(0.));
commands.spawn_bundle(Transform::IDENTITY);
}
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) {
commands
.spawn()
.insert(ComponentA)
.insert(ComponentB)
.insert(ComponentC)
.insert(ComponentD);
commands.spawn_bundle((ComponentA, ComponentB, ComponentC, ComponentD));
}
fn print_components_iter_mut(

View file

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

View file

@ -50,19 +50,17 @@ fn main() {
}
fn setup_system(mut commands: Commands) {
commands
.spawn()
.insert(PrinterTick(Timer::from_seconds(1.0, true)))
.insert(TextToPrint(
"I will print until you press space.".to_string(),
))
.insert(MenuClose);
commands.spawn_bundle((
PrinterTick(Timer::from_seconds(1.0, true)),
TextToPrint("I will print until you press space.".to_string()),
MenuClose,
));
commands
.spawn()
.insert(PrinterTick(Timer::from_seconds(1.0, true)))
.insert(TextToPrint("I will always print".to_string()))
.insert(LevelUnload);
commands.spawn_bundle((
PrinterTick(Timer::from_seconds(1.0, true)),
TextToPrint("I will always print".to_string()),
LevelUnload,
));
}
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
fn spawn(mut commands: Commands) {
commands.spawn().insert(Player);
commands.spawn().insert(Player);
commands.spawn().insert(Player);
commands.spawn_bundle(Player);
commands.spawn_bundle(Player);
commands.spawn_bundle(Player);
}
/// 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) {
// Add an entity to the world with a timer
commands
.spawn()
.insert(PrintOnCompletionTimer(Timer::from_seconds(5.0, false)));
commands.spawn_bundle(PrintOnCompletionTimer(Timer::from_seconds(5.0, false)));
}
/// This system ticks all the `Timer` components on entities within the scene

View file

@ -187,10 +187,8 @@ fn setup(
// Paddle
let paddle_y = BOTTOM_WALL + GAP_BETWEEN_PADDLE_AND_FLOOR;
commands
.spawn()
.insert(Paddle)
.insert_bundle(SpriteBundle {
commands.spawn_bundle((
SpriteBundle {
transform: Transform {
translation: Vec3::new(0.0, paddle_y, 0.0),
scale: PADDLE_SIZE,
@ -201,20 +199,22 @@ fn setup(
..default()
},
..default()
})
.insert(Collider);
},
Paddle,
Collider,
));
// Ball
commands
.spawn()
.insert(Ball)
.insert_bundle(MaterialMesh2dBundle {
commands.spawn_bundle((
MaterialMesh2dBundle {
mesh: meshes.add(shape::Circle::default().into()).into(),
material: materials.add(ColorMaterial::from(BALL_COLOR)),
transform: Transform::from_translation(BALL_STARTING_POSITION).with_scale(BALL_SIZE),
..default()
})
.insert(Velocity(INITIAL_BALL_DIRECTION.normalize() * BALL_SPEED));
},
Ball,
Velocity(INITIAL_BALL_DIRECTION.normalize() * BALL_SPEED),
));
// Scoreboard
commands.spawn_bundle(
@ -290,10 +290,8 @@ fn setup(
);
// brick
commands
.spawn()
.insert(Brick)
.insert_bundle(SpriteBundle {
commands.spawn_bundle((
SpriteBundle {
sprite: Sprite {
color: BRICK_COLOR,
..default()
@ -304,8 +302,10 @@ fn setup(
..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 entity = commands
.spawn()
.insert_bundle((
.spawn_bundle((
Contributor { name, hue },
Velocity {
translation: velocity,
rotation: -dir * 5.0,
},
))
.insert_bundle(SpriteBundle {
sprite: Sprite {
custom_size: Some(Vec2::new(1.0, 1.0) * SPRITE_SIZE),
color: Color::hsla(hue, SATURATION_DESELECTED, LIGHTNESS_DESELECTED, ALPHA),
flip_x: flipped,
SpriteBundle {
sprite: Sprite {
custom_size: Some(Vec2::new(1.0, 1.0) * SPRITE_SIZE),
color: Color::hsla(hue, SATURATION_DESELECTED, LIGHTNESS_DESELECTED, ALPHA),
flip_x: flipped,
..default()
},
texture: texture_handle.clone(),
transform,
..default()
},
texture: texture_handle.clone(),
transform,
..default()
})
))
.id();
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>) {
commands.spawn_bundle(Camera2dBundle::default());
commands.spawn().insert(ContributorDisplay).insert_bundle(
commands.spawn_bundle((
TextBundle::from_sections([
TextSection::new(
"Contributor showcase",
@ -156,7 +155,8 @@ fn setup(mut commands: Commands, asset_server: Res<AssetServer>) {
align_self: AlignSelf::FlexEnd,
..default()
}),
);
ContributorDisplay,
));
}
/// 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 component_b = ComponentB::from_world(world);
component_b.value = "hello".to_string();
scene_world.spawn().insert_bundle((
scene_world.spawn().insert((
component_b,
ComponentA { x: 1.0, y: 2.0 },
Transform::IDENTITY,
));
scene_world
.spawn()
.insert_bundle((ComponentA { x: 3.0, y: 4.0 },));
scene_world.spawn().insert(ComponentA { x: 3.0, y: 4.0 });
// The TypeRegistry resource contains information about all registered types (including
// 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>>) {
// cube
commands.spawn().insert_bundle((
commands.spawn_bundle((
meshes.add(Mesh::from(shape::Cube { size: 1.0 })),
Transform::from_xyz(0.0, 0.5, 0.0),
GlobalTransform::default(),

View file

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

View file

@ -27,7 +27,7 @@ fn setup(
mut materials: ResMut<Assets<CustomMaterial>>,
) {
// blue cube
commands.spawn().insert_bundle(MaterialMeshBundle {
commands.spawn_bundle(MaterialMeshBundle {
mesh: meshes.add(Mesh::from(shape::Cube { size: 1.0 })),
transform: Transform::from_xyz(-1.0, 0.5, 0.0),
material: materials.add(CustomMaterial {
@ -38,7 +38,7 @@ fn setup(
});
// 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 })),
transform: Transform::from_xyz(1.0, 0.5, 0.0),
material: materials.add(CustomMaterial {

View file

@ -30,7 +30,7 @@ fn main() {
}
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 })),
Transform::from_xyz(0.0, 0.0, 0.0),
GlobalTransform::default(),

View file

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

View file

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

View file

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

View file

@ -50,10 +50,10 @@ fn setup(
let texture_atlas_handle = texture_atlases.add(texture_atlas);
// Spawns the camera
commands
.spawn()
.insert_bundle(Camera2dBundle::default())
.insert(Transform::from_xyz(0.0, 0.0, 1000.0));
commands.spawn_bundle((
Camera2dBundle::default(),
Transform::from_xyz(0.0, 0.0, 1000.0),
));
// Builds and spawns the sprites
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");
// Spawns the camera
commands
.spawn()
.insert_bundle(Camera2dBundle::default())
.insert(Transform::from_xyz(0.0, 0.0, 1000.0));
commands.spawn_bundle((
Camera2dBundle::default(),
Transform::from_xyz(0.0, 0.0, 1000.0),
));
// Builds and spawns the sprites
let mut sprites = vec![];

View file

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

View file

@ -50,43 +50,45 @@ fn setup(
// This example focuses on translation only to clearly demonstrate the differences.
// Spawn a basic cube to have an entity as reference.
let mut main_entity = commands.spawn();
main_entity
.insert_bundle(PbrBundle {
mesh: meshes.add(Mesh::from(shape::Cube { size: 1.0 })),
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),
commands
.spawn_bundle((
PbrBundle {
mesh: meshes.add(Mesh::from(shape::Cube { size: 1.0 })),
material: materials.add(Color::YELLOW.into()),
..default()
})
.insert(ChangeGlobal)
.insert(Move)
.insert(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()
})
.insert(ChangeLocal)
.insert(Move)
.insert(ToggledBy(KeyCode::Key3));
});
},
ChangeGlobal,
Move,
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.
.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()
},
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.
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>>) {
if keyboard_input.just_pressed(KeyCode::Space) {
commands.spawn().insert(Enemy {
commands.spawn_bundle(Enemy {
hit_points: 5,
score_value: 3,
});