Skip to content

Commit 7b64840

Browse files
committed
Make Commands and World apis consistent
1 parent c78b76b commit 7b64840

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

54 files changed

+1008
-1096
lines changed

crates/bevy_ecs/src/system/commands.rs

Lines changed: 91 additions & 96 deletions
Original file line numberDiff line numberDiff line change
@@ -26,24 +26,27 @@ impl CommandQueue {
2626
}
2727

2828
#[inline]
29-
pub fn push(&mut self, command: Box<dyn Command>) {
29+
pub fn push_boxed(&mut self, command: Box<dyn Command>) {
3030
self.commands.push(command);
3131
}
32+
33+
#[inline]
34+
pub fn push<T: Command>(&mut self, command: T) {
35+
self.push_boxed(Box::new(command));
36+
}
3237
}
3338

3439
/// A list of commands that will be run to modify a `World`
3540
pub struct Commands<'a> {
3641
queue: &'a mut CommandQueue,
3742
entities: &'a Entities,
38-
current_entity: Option<Entity>,
3943
}
4044

4145
impl<'a> Commands<'a> {
4246
pub fn new(queue: &'a mut CommandQueue, world: &'a World) -> Self {
4347
Self {
4448
queue,
4549
entities: world.entities(),
46-
current_entity: None,
4750
}
4851
}
4952

@@ -84,84 +87,74 @@ impl<'a> Commands<'a> {
8487
/// }
8588
/// # example_system.system();
8689
/// ```
87-
pub fn spawn(&mut self, bundle: impl Bundle) -> &mut Self {
90+
pub fn spawn(&mut self) -> EntityCommands<'a, '_> {
8891
let entity = self.entities.reserve_entity();
89-
self.set_current_entity(entity);
90-
self.insert_bundle(entity, bundle);
91-
self
92+
EntityCommands {
93+
entity,
94+
commands: self,
95+
}
96+
}
97+
98+
pub fn spawn_bundle<'b, T: Bundle>(&'b mut self, bundle: T) -> EntityCommands<'a, 'b> {
99+
let mut e = self.spawn();
100+
e.insert_bundle(bundle);
101+
e
102+
}
103+
104+
pub fn entity(&mut self, entity: Entity) -> EntityCommands<'a, '_> {
105+
EntityCommands {
106+
entity,
107+
commands: self,
108+
}
92109
}
93110

94111
/// Equivalent to iterating `bundles_iter` and calling [`Self::spawn`] on each bundle, but
95112
/// slightly more performant.
96-
pub fn spawn_batch<I>(&mut self, bundles_iter: I) -> &mut Self
113+
pub fn spawn_batch<I>(&mut self, bundles_iter: I)
97114
where
98115
I: IntoIterator + Send + Sync + 'static,
99116
I::Item: Bundle,
100117
{
101-
self.add_command(SpawnBatch { bundles_iter })
102-
}
103-
104-
/// Despawns only the specified entity, not including its children.
105-
pub fn despawn(&mut self, entity: Entity) -> &mut Self {
106-
self.add_command(Despawn { entity })
107-
}
108-
109-
/// Inserts a bundle of components into `entity`.
110-
///
111-
/// See [crate::world::EntityMut::insert_bundle].
112-
pub fn insert_bundle(&mut self, entity: Entity, bundle: impl Bundle) -> &mut Self {
113-
self.add_command(InsertBundle { entity, bundle })
118+
self.queue.push(SpawnBatch { bundles_iter });
114119
}
115120

116-
/// Inserts a single component into `entity`.
117-
///
118-
/// See [crate::world::EntityMut::insert].
119-
pub fn insert(&mut self, entity: Entity, component: impl Component) -> &mut Self {
120-
self.add_command(Insert { entity, component })
121+
/// See [World::insert_resource].
122+
pub fn insert_resource<T: Component>(&mut self, resource: T) {
123+
self.queue.push(InsertResource { resource })
121124
}
122125

123-
/// See [crate::world::EntityMut::remove].
124-
pub fn remove<T>(&mut self, entity: Entity) -> &mut Self
125-
where
126-
T: Component,
127-
{
128-
self.add_command(Remove::<T> {
129-
entity,
126+
pub fn remove_resource<T: Component>(&mut self) {
127+
self.queue.push(RemoveResource::<T> {
130128
phantom: PhantomData,
131-
})
129+
});
132130
}
133131

134-
/// See [World::insert_resource].
135-
pub fn insert_resource<T: Component>(&mut self, resource: T) -> &mut Self {
136-
self.add_command(InsertResource { resource })
132+
/// Adds a command directly to the command list. Prefer this to [`Self::add_command_boxed`] if
133+
/// the type of `command` is statically known.
134+
pub fn add<C: Command>(&mut self, command: C) {
135+
self.queue.push(command);
137136
}
137+
}
138138

139-
/// See [crate::world::EntityMut::remove_bundle].
140-
pub fn remove_bundle<T>(&mut self, entity: Entity) -> &mut Self
141-
where
142-
T: Bundle,
143-
{
144-
self.add_command(RemoveBundle::<T> {
145-
entity,
146-
phantom: PhantomData,
147-
})
148-
}
139+
pub struct EntityCommands<'a, 'b> {
140+
entity: Entity,
141+
commands: &'b mut Commands<'a>,
142+
}
149143

150-
pub fn remove_resource<T: Component>(&mut self) -> &mut Self {
151-
self.add_command(RemoveResource::<T> {
152-
phantom: PhantomData,
153-
})
144+
impl<'a, 'b> EntityCommands<'a, 'b> {
145+
#[inline]
146+
pub fn id(&self) -> Entity {
147+
self.entity
154148
}
155149

156150
/// Adds a bundle of components to the current entity.
157151
///
158152
/// See [`Self::with`], [`Self::current_entity`].
159-
pub fn with_bundle(&mut self, bundle: impl Bundle) -> &mut Self {
160-
let current_entity = self.current_entity.expect("Cannot add bundle because the 'current entity' is not set. You should spawn an entity first.");
161-
self.queue.push(Box::new(InsertBundle {
162-
entity: current_entity,
153+
pub fn insert_bundle(&mut self, bundle: impl Bundle) -> &mut Self {
154+
self.commands.add(InsertBundle {
155+
entity: self.entity,
163156
bundle,
164-
}));
157+
});
165158
self
166159
}
167160

@@ -205,47 +198,47 @@ impl<'a> Commands<'a> {
205198
/// }
206199
/// # example_system.system();
207200
/// ```
208-
pub fn with(&mut self, component: impl Component) -> &mut Self {
209-
let current_entity = self.current_entity.expect("Cannot add component because the 'current entity' is not set. You should spawn an entity first.");
210-
self.queue.push(Box::new(Insert {
211-
entity: current_entity,
201+
pub fn insert(&mut self, component: impl Component) -> &mut Self {
202+
self.commands.add(Insert {
203+
entity: self.entity,
212204
component,
213-
}));
205+
});
214206
self
215207
}
216208

217-
/// Adds a command directly to the command list. Prefer this to [`Self::add_command_boxed`] if
218-
/// the type of `command` is statically known.
219-
pub fn add_command<C: Command>(&mut self, command: C) -> &mut Self {
220-
self.queue.push(Box::new(command));
209+
/// See [crate::world::EntityMut::remove_bundle].
210+
pub fn remove_bundle<T>(&mut self) -> &mut Self
211+
where
212+
T: Bundle,
213+
{
214+
self.commands.add(RemoveBundle::<T> {
215+
entity: self.entity,
216+
phantom: PhantomData,
217+
});
221218
self
222219
}
223220

224-
/// See [`Self::add_command`].
225-
pub fn add_command_boxed(&mut self, command: Box<dyn Command>) -> &mut Self {
226-
self.queue.push(command);
221+
/// See [crate::world::EntityMut::remove].
222+
pub fn remove<T>(&mut self) -> &mut Self
223+
where
224+
T: Component,
225+
{
226+
self.commands.add(Remove::<T> {
227+
entity: self.entity,
228+
phantom: PhantomData,
229+
});
227230
self
228231
}
229232

230-
/// Returns the current entity, set by [`Self::spawn`] or with [`Self::set_current_entity`].
231-
pub fn current_entity(&self) -> Option<Entity> {
232-
self.current_entity
233-
}
234-
235-
pub fn set_current_entity(&mut self, entity: Entity) {
236-
self.current_entity = Some(entity);
237-
}
238-
239-
pub fn clear_current_entity(&mut self) {
240-
self.current_entity = None;
233+
/// Despawns only the specified entity, not including its children.
234+
pub fn despawn(&mut self) {
235+
self.commands.add(Despawn {
236+
entity: self.entity,
237+
})
241238
}
242239

243-
pub fn for_current_entity(&mut self, f: impl FnOnce(Entity)) -> &mut Self {
244-
let current_entity = self
245-
.current_entity
246-
.expect("The 'current entity' is not set. You should spawn an entity first.");
247-
f(current_entity);
248-
self
240+
pub fn commands(&mut self) -> &mut Commands<'a> {
241+
self.commands
249242
}
250243
}
251244

@@ -392,9 +385,8 @@ mod tests {
392385
let mut world = World::default();
393386
let mut command_queue = CommandQueue::default();
394387
let entity = Commands::new(&mut command_queue, &world)
395-
.spawn((1u32, 2u64))
396-
.current_entity()
397-
.unwrap();
388+
.spawn_bundle((1u32, 2u64))
389+
.id();
398390
command_queue.apply(&mut world);
399391
assert!(world.entities().len() == 1);
400392
let results = world
@@ -404,9 +396,11 @@ mod tests {
404396
.collect::<Vec<_>>();
405397
assert_eq!(results, vec![(1u32, 2u64)]);
406398
// test entity despawn
407-
Commands::new(&mut command_queue, &world)
408-
.despawn(entity)
409-
.despawn(entity); // double despawn shouldn't panic
399+
{
400+
let mut commands = Commands::new(&mut command_queue, &world);
401+
commands.entity(entity).despawn();
402+
commands.entity(entity).despawn(); // double despawn shouldn't panic
403+
}
410404
command_queue.apply(&mut world);
411405
let results2 = world
412406
.query::<(&u32, &u64)>()
@@ -421,9 +415,9 @@ mod tests {
421415
let mut world = World::default();
422416
let mut command_queue = CommandQueue::default();
423417
let entity = Commands::new(&mut command_queue, &world)
424-
.spawn((1u32, 2u64))
425-
.current_entity()
426-
.unwrap();
418+
.spawn()
419+
.insert_bundle((1u32, 2u64))
420+
.id();
427421
command_queue.apply(&mut world);
428422
let results_before = world
429423
.query::<(&u32, &u64)>()
@@ -434,8 +428,9 @@ mod tests {
434428

435429
// test component removal
436430
Commands::new(&mut command_queue, &world)
437-
.remove::<u32>(entity)
438-
.remove_bundle::<(u32, u64)>(entity);
431+
.entity(entity)
432+
.remove::<u32>()
433+
.remove_bundle::<(u32, u64)>();
439434
command_queue.apply(&mut world);
440435
let results_after = world
441436
.query::<(&u32, &u64)>()

crates/bevy_ecs/src/system/exclusive_system.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,7 @@ mod tests {
131131
) {
132132
for entity in query.iter() {
133133
*counter += 1;
134-
commands.remove::<f32>(entity);
134+
commands.entity(entity).remove::<f32>();
135135
}
136136
}
137137

crates/bevy_gltf/src/loader.rs

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -293,18 +293,18 @@ fn load_node(
293293
) -> Result<(), GltfError> {
294294
let transform = gltf_node.transform();
295295
let mut gltf_error = None;
296-
let node = world_builder.spawn((
296+
let mut node = world_builder.spawn_bundle((
297297
Transform::from_matrix(Mat4::from_cols_array_2d(&transform.matrix())),
298298
GlobalTransform::identity(),
299299
));
300300

301301
if let Some(name) = gltf_node.name() {
302-
node.with(Name::new(name.to_string()));
302+
node.insert(Name::new(name.to_string()));
303303
}
304304

305305
// create camera node
306306
if let Some(camera) = gltf_node.camera() {
307-
node.with(VisibleEntities {
307+
node.insert(VisibleEntities {
308308
..Default::default()
309309
});
310310

@@ -322,12 +322,12 @@ fn load_node(
322322
..Default::default()
323323
};
324324

325-
node.with(Camera {
325+
node.insert(Camera {
326326
name: Some(base::camera::CAMERA_2D.to_owned()),
327327
projection_matrix: orthographic_projection.get_projection_matrix(),
328328
..Default::default()
329329
});
330-
node.with(orthographic_projection);
330+
node.insert(orthographic_projection);
331331
}
332332
gltf::camera::Projection::Perspective(perspective) => {
333333
let mut perspective_projection: PerspectiveProjection = PerspectiveProjection {
@@ -341,12 +341,12 @@ fn load_node(
341341
if let Some(aspect_ratio) = perspective.aspect_ratio() {
342342
perspective_projection.aspect_ratio = aspect_ratio;
343343
}
344-
node.with(Camera {
344+
node.insert(Camera {
345345
name: Some(base::camera::CAMERA_3D.to_owned()),
346346
projection_matrix: perspective_projection.get_projection_matrix(),
347347
..Default::default()
348348
});
349-
node.with(perspective_projection);
349+
node.insert(perspective_projection);
350350
}
351351
}
352352
}
@@ -371,7 +371,7 @@ fn load_node(
371371
let material_asset_path =
372372
AssetPath::new_ref(load_context.path(), Some(&material_label));
373373

374-
parent.spawn(PbrBundle {
374+
parent.spawn_bundle(PbrBundle {
375375
mesh: load_context.get_handle(mesh_asset_path),
376376
material: load_context.get_handle(material_asset_path),
377377
..Default::default()

crates/bevy_scene/src/command.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,12 +20,12 @@ impl Command for SpawnScene {
2020
}
2121

2222
pub trait SpawnSceneCommands {
23-
fn spawn_scene(&mut self, scene: Handle<Scene>) -> &mut Self;
23+
fn spawn_scene(&mut self, scene: Handle<Scene>);
2424
}
2525

2626
impl<'a> SpawnSceneCommands for Commands<'a> {
27-
fn spawn_scene(&mut self, scene_handle: Handle<Scene>) -> &mut Self {
28-
self.add_command(SpawnScene { scene_handle })
27+
fn spawn_scene(&mut self, scene_handle: Handle<Scene>) {
28+
self.add(SpawnScene { scene_handle });
2929
}
3030
}
3131

0 commit comments

Comments
 (0)