Skip to content

Commit dc7cd92

Browse files
tim-blackbirdalradish
authored andcommitted
Remove EntityCommands::add_children (bevyengine#6942)
# Objective Remove a method with an unfortunate name and questionable usefulness. Added in bevyengine#4708 It doesn't make sense to me for us to provide a method to work around a limitation of closures when we can simply, *not* use a closure. The limitation in this case is not being able to initialize a variable from inside a closure: ```rust let child_id; commands.spawn_empty().with_children(|parent| { // Error: passing uninitalized variable to a closure. child_id = parent.spawn_empty().id(); }); // Do something with child_id ``` The docs for `add_children` suggest the following: ```rust let child_id = commands .spawn_empty() .add_children(|parent| parent.spawn_empty().id()); ``` I would instead suggest using the following snippet. ```rust let parent_id = commands.spawn_empty().id(); let child_id = commands.spawn_empty().set_parent(parent_id).id(); // To be fair, at the time of bevyengine#4708 this would have been a bit more cumbersome since `set_parent` did not exist. ``` Using `add_children` gets more unwieldy when you also want the `parent_id`. ```rust let parent_commands = commands.spawn_empty(); let parent_id = parent_commands.id(); let child_id = parent_commands.add_children(|parent| parent.spawn_empty().id()); ``` ### The name I see why `add_children` is named that way, it's the non-builder variant of `with_children` so it kinda makes sense, but now the method name situation for `add_child`, `add_children` and `push_children` is *rather* unfortunate. Removing `add_children` and renaming `push_children` to `add_children` in one go is kinda bleh, but that way we end up with the matching methods `add_child` and `add_children`. Another reason to rename `push_children` is that it's trying to mimick the `Vec` api naming but fails because `push` is for single elements. I guess it should have been `extend_children_from_slice`, but lets not name it that :) ### Questions ~~Should `push_children` be renamed in this PR? This would make the migration guide easier to deal with.~~ Let's do that later. Does anyone know of a way to do a simple text/regex search through all the github repos for usage of `add_children`? That way we can have a better idea of how this will affect users. My guess is that usage of `add_children` is quite rare. ## Migration Guide The method `add_children` on `EntityCommands` was removed. If you were using `add_children` over `with_children` to return data out of the closure you can use `set_parent` or `add_child` to avoid the closure instead. Co-authored-by: devil-ira <[email protected]>
1 parent 0d7736a commit dc7cd92

File tree

1 file changed

+6
-44
lines changed

1 file changed

+6
-44
lines changed

crates/bevy_hierarchy/src/child_builder.rs

Lines changed: 6 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -248,40 +248,7 @@ impl<'w, 's, 'a> ChildBuilder<'w, 's, 'a> {
248248
/// Trait defining how to build children
249249
pub trait BuildChildren {
250250
/// Creates a [`ChildBuilder`] with the given children built in the given closure
251-
///
252-
/// Compared to [`add_children`][BuildChildren::add_children], this method returns self
253-
/// to allow chaining.
254251
fn with_children(&mut self, f: impl FnOnce(&mut ChildBuilder)) -> &mut Self;
255-
/// Creates a [`ChildBuilder`] with the given children built in the given closure
256-
///
257-
/// Compared to [`with_children`][BuildChildren::with_children], this method returns the
258-
/// the value returned from the closure, but doesn't allow chaining.
259-
///
260-
/// ## Example
261-
///
262-
/// ```no_run
263-
/// # use bevy_ecs::prelude::*;
264-
/// # use bevy_hierarchy::*;
265-
/// #
266-
/// # #[derive(Component)]
267-
/// # struct SomethingElse;
268-
/// #
269-
/// # #[derive(Component)]
270-
/// # struct MoreStuff;
271-
/// #
272-
/// # fn foo(mut commands: Commands) {
273-
/// let mut parent_commands = commands.spawn_empty();
274-
/// let child_id = parent_commands.add_children(|parent| {
275-
/// parent.spawn_empty().id()
276-
/// });
277-
///
278-
/// parent_commands.insert(SomethingElse);
279-
/// commands.entity(child_id).with_children(|parent| {
280-
/// parent.spawn(MoreStuff);
281-
/// });
282-
/// # }
283-
/// ```
284-
fn add_children<T>(&mut self, f: impl FnOnce(&mut ChildBuilder) -> T) -> T;
285252
/// Pushes children to the back of the builder's children. For any entities that are
286253
/// already a child of this one, this method does nothing.
287254
///
@@ -313,11 +280,6 @@ pub trait BuildChildren {
313280

314281
impl<'w, 's, 'a> BuildChildren for EntityCommands<'w, 's, 'a> {
315282
fn with_children(&mut self, spawn_children: impl FnOnce(&mut ChildBuilder)) -> &mut Self {
316-
self.add_children(spawn_children);
317-
self
318-
}
319-
320-
fn add_children<T>(&mut self, spawn_children: impl FnOnce(&mut ChildBuilder) -> T) -> T {
321283
let parent = self.id();
322284
let mut builder = ChildBuilder {
323285
commands: self.commands(),
@@ -327,11 +289,10 @@ impl<'w, 's, 'a> BuildChildren for EntityCommands<'w, 's, 'a> {
327289
},
328290
};
329291

330-
let result = spawn_children(&mut builder);
292+
spawn_children(&mut builder);
331293
let children = builder.push_children;
332294
self.commands().add(children);
333-
334-
result
295+
self
335296
}
336297

337298
fn push_children(&mut self, children: &[Entity]) -> &mut Self {
@@ -506,12 +467,13 @@ mod tests {
506467
let mut commands = Commands::new(&mut queue, &world);
507468

508469
let parent = commands.spawn(C(1)).id();
509-
let children = commands.entity(parent).add_children(|parent| {
510-
[
470+
let mut children = Vec::new();
471+
commands.entity(parent).with_children(|parent| {
472+
children.extend([
511473
parent.spawn(C(2)).id(),
512474
parent.spawn(C(3)).id(),
513475
parent.spawn(C(4)).id(),
514-
]
476+
]);
515477
});
516478

517479
queue.apply(&mut world);

0 commit comments

Comments
 (0)