Skip to content

Commit ff12f69

Browse files
authored
Document part of bevy_ecs::Commands (#976)
Document part of bevy_ecs::Commands
1 parent 71e2c7f commit ff12f69

File tree

3 files changed

+118
-28
lines changed

3 files changed

+118
-28
lines changed

crates/bevy_ecs/src/core/bundle.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@ use std::{
2222
};
2323

2424
/// A dynamically typed collection of components
25+
///
26+
/// See [Bundle]
2527
pub trait DynamicBundle {
2628
/// Invoke a callback on the fields' type IDs, sorted by descending alignment then id
2729
#[doc(hidden)]
@@ -38,6 +40,8 @@ pub trait DynamicBundle {
3840
}
3941

4042
/// A statically typed collection of components
43+
///
44+
/// See [DynamicBundle]
4145
pub trait Bundle: DynamicBundle {
4246
#[doc(hidden)]
4347
fn with_static_ids<T>(f: impl FnOnce(&[TypeId]) -> T) -> T;

crates/bevy_ecs/src/core/world.rs

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -76,16 +76,16 @@ impl World {
7676
/// let a = world.spawn((123, "abc"));
7777
/// let b = world.spawn((456, true));
7878
/// ```
79-
pub fn spawn(&mut self, components: impl DynamicBundle) -> Entity {
79+
pub fn spawn(&mut self, bundle: impl DynamicBundle) -> Entity {
8080
// Ensure all entity allocations are accounted for so `self.entities` can realloc if
8181
// necessary
8282
self.flush();
8383

8484
let entity = self.entities.alloc();
85-
let archetype_id = components.with_ids(|ids| {
85+
let archetype_id = bundle.with_ids(|ids| {
8686
self.index.get(ids).copied().unwrap_or_else(|| {
8787
let x = self.archetypes.len() as u32;
88-
self.archetypes.push(Archetype::new(components.type_info()));
88+
self.archetypes.push(Archetype::new(bundle.type_info()));
8989
self.index.insert(ids.to_vec(), x);
9090
self.archetype_generation += 1;
9191
x
@@ -95,7 +95,7 @@ impl World {
9595
let archetype = &mut self.archetypes[archetype_id as usize];
9696
unsafe {
9797
let index = archetype.allocate(entity);
98-
components.put(|ptr, ty, size| {
98+
bundle.put(|ptr, ty, size| {
9999
archetype.put_dynamic(ptr, ty, size, index, ComponentFlags::ADDED);
100100
true
101101
});
@@ -566,7 +566,7 @@ impl World {
566566
pub fn insert(
567567
&mut self,
568568
entity: Entity,
569-
components: impl DynamicBundle,
569+
bundle: impl DynamicBundle,
570570
) -> Result<(), NoSuchEntity> {
571571
use std::collections::hash_map::Entry;
572572

@@ -576,7 +576,7 @@ impl World {
576576
// Assemble Vec<TypeInfo> for the final entity
577577
let arch = &mut self.archetypes[loc.archetype as usize];
578578
let mut info = arch.types().to_vec();
579-
for ty in components.type_info() {
579+
for ty in bundle.type_info() {
580580
if let Some(ptr) = arch.get_dynamic(ty.id(), ty.layout().size(), loc.index) {
581581
ty.drop(ptr.as_ptr());
582582
} else {
@@ -601,7 +601,7 @@ impl World {
601601
if target == loc.archetype {
602602
// Update components in the current archetype
603603
let arch = &mut self.archetypes[loc.archetype as usize];
604-
components.put(|ptr, ty, size| {
604+
bundle.put(|ptr, ty, size| {
605605
arch.put_dynamic(ptr, ty, size, loc.index, ComponentFlags::MUTATED);
606606
true
607607
});
@@ -625,7 +625,7 @@ impl World {
625625
self.entities.get_mut(moved).unwrap().index = old_index;
626626
}
627627

628-
components.put(|ptr, ty, size| {
628+
bundle.put(|ptr, ty, size| {
629629
let had_component = source_arch.has_dynamic(ty);
630630
let flags = if had_component {
631631
ComponentFlags::MUTATED

crates/bevy_ecs/src/system/commands.rs

Lines changed: 106 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -16,15 +16,15 @@ pub(crate) struct Spawn<T>
1616
where
1717
T: DynamicBundle + Send + Sync + 'static,
1818
{
19-
components: T,
19+
bundle: T,
2020
}
2121

2222
impl<T> Command for Spawn<T>
2323
where
2424
T: DynamicBundle + Send + Sync + 'static,
2525
{
2626
fn write(self: Box<Self>, world: &mut World, _resources: &mut Resources) {
27-
world.spawn(self.components);
27+
world.spawn(self.bundle);
2828
}
2929
}
3030

@@ -33,7 +33,7 @@ where
3333
I: IntoIterator,
3434
I::Item: Bundle,
3535
{
36-
components_iter: I,
36+
bundles_iter: I,
3737
}
3838

3939
impl<I> Command for SpawnBatch<I>
@@ -42,7 +42,7 @@ where
4242
I::Item: Bundle,
4343
{
4444
fn write(self: Box<Self>, world: &mut World, _resources: &mut Resources) {
45-
world.spawn_batch(self.components_iter);
45+
world.spawn_batch(self.bundles_iter);
4646
}
4747
}
4848

@@ -64,15 +64,15 @@ where
6464
T: DynamicBundle + Send + Sync + 'static,
6565
{
6666
entity: Entity,
67-
components: T,
67+
bundle: T,
6868
}
6969

7070
impl<T> Command for Insert<T>
7171
where
7272
T: DynamicBundle + Send + Sync + 'static,
7373
{
7474
fn write(self: Box<Self>, world: &mut World, _resources: &mut Resources) {
75-
world.insert(self.entity, self.components).unwrap();
75+
world.insert(self.entity, self.bundle).unwrap();
7676
}
7777
}
7878

@@ -181,6 +181,7 @@ impl<T: Resource> Command for InsertLocalResource<T> {
181181
}
182182
}
183183

184+
/// A list of commands that will be run to populate a `World` and `Resources`.
184185
#[derive(Default)]
185186
pub struct Commands {
186187
commands: Vec<Box<dyn Command>>,
@@ -189,38 +190,78 @@ pub struct Commands {
189190
}
190191

191192
impl Commands {
192-
pub fn spawn(&mut self, components: impl DynamicBundle + Send + Sync + 'static) -> &mut Self {
193+
/// Creates a new entity with the components contained in `bundle`.
194+
///
195+
/// Note that `bundle` is a [DynamicBundle], which is a collection of components. [DynamicBundle] is automatically implemented for tuples of components. You can also create your own bundle types by deriving [`derive@Bundle`]. If you would like to spawn an entity with a single component, consider wrapping the component in a tuple (which [DynamicBundle] is implemented for).
196+
///
197+
/// See [`Self::set_current_entity`], [`Self::insert`].
198+
///
199+
/// # Example
200+
///
201+
/// ```
202+
/// use bevy_ecs::prelude::*;
203+
///
204+
/// struct Component1;
205+
/// struct Component2;
206+
///
207+
/// #[derive(Bundle)]
208+
/// struct ExampleBundle {
209+
/// a: Component1,
210+
/// b: Component2,
211+
/// }
212+
///
213+
/// fn example_system(mut commands: Commands) {
214+
/// // Create a new entity with a component bundle.
215+
/// commands.spawn(ExampleBundle {
216+
/// a: Component1,
217+
/// b: Component2,
218+
/// });
219+
///
220+
/// // Create a new entity with a single component.
221+
/// commands.spawn((Component1,));
222+
/// // Create a new entity with two components.
223+
/// commands.spawn((Component1, Component2));
224+
/// }
225+
/// ```
226+
pub fn spawn(&mut self, bundle: impl DynamicBundle + Send + Sync + 'static) -> &mut Self {
193227
let entity = self
194228
.entity_reserver
195229
.as_ref()
196230
.expect("Entity reserver has not been set.")
197231
.reserve_entity();
198-
self.current_entity = Some(entity);
199-
self.commands.push(Box::new(Insert { entity, components }));
232+
self.set_current_entity(entity);
233+
self.insert(entity, bundle);
200234
self
201235
}
202236

203-
pub fn spawn_batch<I>(&mut self, components_iter: I) -> &mut Self
237+
/// Equivalent to iterating `bundles_iter` and calling [`Self::spawn`] on each bundle, but slightly more performant.
238+
pub fn spawn_batch<I>(&mut self, bundles_iter: I) -> &mut Self
204239
where
205240
I: IntoIterator + Send + Sync + 'static,
206241
I::Item: Bundle,
207242
{
208-
self.add_command(SpawnBatch { components_iter })
243+
self.add_command(SpawnBatch { bundles_iter })
209244
}
210245

211-
/// Despawns only the specified entity, ignoring any other consideration.
246+
/// Despawns only the specified entity, not including its children.
212247
pub fn despawn(&mut self, entity: Entity) -> &mut Self {
213248
self.add_command(Despawn { entity })
214249
}
215250

251+
/// Inserts a bundle of components into `entity`.
252+
///
253+
/// See [`World::insert`].
216254
pub fn insert(
217255
&mut self,
218256
entity: Entity,
219-
components: impl DynamicBundle + Send + Sync + 'static,
257+
bundle: impl DynamicBundle + Send + Sync + 'static,
220258
) -> &mut Self {
221-
self.add_command(Insert { entity, components })
259+
self.add_command(Insert { entity, bundle })
222260
}
223261

262+
/// Inserts a single component into `entity`.
263+
///
264+
/// See [`World::insert_one`].
224265
pub fn insert_one(&mut self, entity: Entity, component: impl Component) -> &mut Self {
225266
self.add_command(InsertOne { entity, component })
226267
}
@@ -229,6 +270,9 @@ impl Commands {
229270
self.add_command(InsertResource { resource })
230271
}
231272

273+
/// Insert a resource that is local to a specific system.
274+
///
275+
/// See [`crate::System::id`].
232276
pub fn insert_local_resource<T: Resource>(
233277
&mut self,
234278
system_id: SystemId,
@@ -240,6 +284,7 @@ impl Commands {
240284
})
241285
}
242286

287+
/// See [`World::remove_one`].
243288
pub fn remove_one<T>(&mut self, entity: Entity) -> &mut Self
244289
where
245290
T: Component,
@@ -250,6 +295,7 @@ impl Commands {
250295
})
251296
}
252297

298+
/// See [`World::remove`].
253299
pub fn remove<T>(&mut self, entity: Entity) -> &mut Self
254300
where
255301
T: Bundle + Send + Sync + 'static,
@@ -260,18 +306,54 @@ impl Commands {
260306
})
261307
}
262308

263-
pub fn with_bundle(
264-
&mut self,
265-
components: impl DynamicBundle + Send + Sync + 'static,
266-
) -> &mut Self {
267-
let current_entity = self.current_entity.expect("Cannot add components because the 'current entity' is not set. You should spawn an entity first.");
309+
/// Adds a bundle of components to the current entity.
310+
///
311+
/// See [`Self::with`], [`Self::current_entity`].
312+
pub fn with_bundle(&mut self, bundle: impl DynamicBundle + Send + Sync + 'static) -> &mut Self {
313+
let current_entity = self.current_entity.expect("Cannot add bundle because the 'current entity' is not set. You should spawn an entity first.");
268314
self.commands.push(Box::new(Insert {
269315
entity: current_entity,
270-
components,
316+
bundle,
271317
}));
272318
self
273319
}
274320

321+
/// Adds a single component to the current entity.
322+
///
323+
/// See [`Self::with_bundle`], [`Self::current_entity`].
324+
///
325+
/// # Warning
326+
///
327+
/// It's possible to call this with a bundle, but this is likely not intended and [`Self::with_bundle`] should be used instead. If `with` is called with a bundle, the bundle itself will be added as a component instead of the bundles' inner components each being added.
328+
///
329+
/// # Example
330+
///
331+
/// `with` can be chained with [`Self::spawn`].
332+
///
333+
/// ```
334+
/// use bevy_ecs::prelude::*;
335+
///
336+
/// struct Component1;
337+
/// struct Component2;
338+
///
339+
/// fn example_system(mut commands: Commands) {
340+
/// // Create a new entity with a `Component1` and `Component2`.
341+
/// commands.spawn((Component1,)).with(Component2);
342+
///
343+
/// // Psst! These are also equivalent to the line above!
344+
/// commands.spawn((Component1, Component2));
345+
/// commands.spawn(()).with(Component1).with(Component2);
346+
/// #[derive(Bundle)]
347+
/// struct ExampleBundle {
348+
/// a: Component1,
349+
/// b: Component2,
350+
/// }
351+
/// commands.spawn(()).with_bundle(ExampleBundle {
352+
/// a: Component1,
353+
/// b: Component2,
354+
/// });
355+
/// }
356+
/// ```
275357
pub fn with(&mut self, component: impl Component) -> &mut Self {
276358
let current_entity = self.current_entity.expect("Cannot add component because the 'current entity' is not set. You should spawn an entity first.");
277359
self.commands.push(Box::new(InsertOne {
@@ -281,22 +363,26 @@ impl Commands {
281363
self
282364
}
283365

366+
/// Adds a command directly to the command list. Prefer this to [`Self::add_command_boxed`] if the type of `command` is statically known.
284367
pub fn add_command<C: Command + 'static>(&mut self, command: C) -> &mut Self {
285368
self.commands.push(Box::new(command));
286369
self
287370
}
288371

372+
/// See [`Self::add_command`].
289373
pub fn add_command_boxed(&mut self, command: Box<dyn Command>) -> &mut Self {
290374
self.commands.push(command);
291375
self
292376
}
293377

378+
/// Runs all the stored commands on `world` and `resources`. The command buffer is emptied as a part of this call.
294379
pub fn apply(&mut self, world: &mut World, resources: &mut Resources) {
295380
for command in self.commands.drain(..) {
296381
command.write(world, resources);
297382
}
298383
}
299384

385+
/// Returns the current entity, set by [`Self::spawn`] or with [`Self::set_current_entity`].
300386
pub fn current_entity(&self) -> Option<Entity> {
301387
self.current_entity
302388
}

0 commit comments

Comments
 (0)