Change with_related to work with a Bundle and added with_relationships method (#18699)
# Objective Fixes #18678 ## Solution Moved the current `with_related` method to `with_relationships` and added a new `with_related` that uses a bundle. I'm not entirely sold on the name just yet, if anyone has any ideas let me know. ## Testing I wasn't able to test these changes because it crashed my computer every time I tried (fun). But there don't seem to be any tests that use the old `with_related` method so it should be fine, hopefully ## Showcase ```rust commands.spawn_empty() .with_related::<Relationship>(Name::new("Related thingy")) .with_relationships(|rel| { rel.spawn(Name::new("Second related thingy")); }); ``` --------- Co-authored-by: Carter Anderson <mcanders1@gmail.com>
This commit is contained in:
parent
83a78d8583
commit
772524b3a6
@ -268,7 +268,7 @@ impl<'w> EntityWorldMut<'w> {
|
||||
/// Spawns children of this entity (with a [`ChildOf`] relationship) by taking a function that operates on a [`ChildSpawner`].
|
||||
/// See also [`with_related`](Self::with_related).
|
||||
pub fn with_children(&mut self, func: impl FnOnce(&mut ChildSpawner)) -> &mut Self {
|
||||
self.with_related(func);
|
||||
self.with_related_entities(func);
|
||||
self
|
||||
}
|
||||
|
||||
@ -352,7 +352,7 @@ impl<'a> EntityCommands<'a> {
|
||||
&mut self,
|
||||
func: impl FnOnce(&mut RelatedSpawnerCommands<ChildOf>),
|
||||
) -> &mut Self {
|
||||
self.with_related(func);
|
||||
self.with_related_entities(func);
|
||||
self
|
||||
}
|
||||
|
||||
@ -406,8 +406,7 @@ impl<'a> EntityCommands<'a> {
|
||||
///
|
||||
/// [`with_children`]: EntityCommands::with_children
|
||||
pub fn with_child(&mut self, bundle: impl Bundle) -> &mut Self {
|
||||
let parent = self.id();
|
||||
self.commands.spawn((bundle, ChildOf(parent)));
|
||||
self.with_related::<ChildOf>(bundle);
|
||||
self
|
||||
}
|
||||
|
||||
|
@ -1654,7 +1654,7 @@ mod tests {
|
||||
fn on_add(trigger: Trigger<OnAdd, A>, mut commands: Commands) {
|
||||
commands
|
||||
.entity(trigger.target())
|
||||
.with_related::<crate::hierarchy::ChildOf>(|rsc| {
|
||||
.with_related_entities::<crate::hierarchy::ChildOf>(|rsc| {
|
||||
rsc.spawn_empty();
|
||||
});
|
||||
}
|
||||
|
@ -13,8 +13,17 @@ use core::{marker::PhantomData, mem};
|
||||
use super::OrderedRelationshipSourceCollection;
|
||||
|
||||
impl<'w> EntityWorldMut<'w> {
|
||||
/// Spawns a entity related to this entity (with the `R` relationship) by taking a bundle
|
||||
pub fn with_related<R: Relationship>(&mut self, bundle: impl Bundle) -> &mut Self {
|
||||
let parent = self.id();
|
||||
self.world_scope(|world| {
|
||||
world.spawn((bundle, R::from(parent)));
|
||||
});
|
||||
self
|
||||
}
|
||||
|
||||
/// Spawns entities related to this entity (with the `R` relationship) by taking a function that operates on a [`RelatedSpawner`].
|
||||
pub fn with_related<R: Relationship>(
|
||||
pub fn with_related_entities<R: Relationship>(
|
||||
&mut self,
|
||||
func: impl FnOnce(&mut RelatedSpawner<R>),
|
||||
) -> &mut Self {
|
||||
@ -322,8 +331,15 @@ impl<'w> EntityWorldMut<'w> {
|
||||
}
|
||||
|
||||
impl<'a> EntityCommands<'a> {
|
||||
/// Spawns a entity related to this entity (with the `R` relationship) by taking a bundle
|
||||
pub fn with_related<R: Relationship>(&mut self, bundle: impl Bundle) -> &mut Self {
|
||||
let parent = self.id();
|
||||
self.commands.spawn((bundle, R::from(parent)));
|
||||
self
|
||||
}
|
||||
|
||||
/// Spawns entities related to this entity (with the `R` relationship) by taking a function that operates on a [`RelatedSpawner`].
|
||||
pub fn with_related<R: Relationship>(
|
||||
pub fn with_related_entities<R: Relationship>(
|
||||
&mut self,
|
||||
func: impl FnOnce(&mut RelatedSpawnerCommands<R>),
|
||||
) -> &mut Self {
|
||||
|
@ -125,7 +125,7 @@ impl<R: Relationship, F: FnOnce(&mut RelatedSpawner<R>) + Send + Sync + 'static>
|
||||
for SpawnWith<F>
|
||||
{
|
||||
fn spawn(self, world: &mut World, entity: Entity) {
|
||||
world.entity_mut(entity).with_related(self.0);
|
||||
world.entity_mut(entity).with_related_entities(self.0);
|
||||
}
|
||||
|
||||
fn size_hint(&self) -> usize {
|
||||
@ -235,9 +235,7 @@ pub struct SpawnOneRelated<R: Relationship, B: Bundle> {
|
||||
|
||||
impl<R: Relationship, B: Bundle> BundleEffect for SpawnOneRelated<R, B> {
|
||||
fn apply(self, entity: &mut EntityWorldMut) {
|
||||
entity.with_related::<R>(|s| {
|
||||
s.spawn(self.bundle);
|
||||
});
|
||||
entity.with_related::<R>(self.bundle);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -53,12 +53,14 @@ fn main() {
|
||||
// Relations are just components, so we can add them into the bundle that we're spawning.
|
||||
let bob = commands.spawn((Name::new("Bob"), Targeting(alice))).id();
|
||||
|
||||
// The `with_related` helper method on `EntityCommands` can be used to add relations in a more ergonomic way.
|
||||
// The `with_related` and `with_relationships` helper methods on `EntityCommands` can be used to add relations in a more ergonomic way.
|
||||
let charlie = commands
|
||||
.spawn((Name::new("Charlie"), Targeting(bob)))
|
||||
// The `with_related` method will automatically add the `Targeting` component to any entities spawned within the closure,
|
||||
// The `with_related` method will spawn a bundle with `Targeting` relationship
|
||||
.with_related::<Targeting>(Name::new("James"))
|
||||
// The `with_relationships` method will automatically add the `Targeting` component to any entities spawned within the closure,
|
||||
// targeting the entity that we're calling `with_related` on.
|
||||
.with_related::<Targeting>(|related_spawner_commands| {
|
||||
.with_related_entities::<Targeting>(|related_spawner_commands| {
|
||||
// We could spawn multiple entities here, and they would all target `charlie`.
|
||||
related_spawner_commands.spawn(Name::new("Devon"));
|
||||
})
|
||||
|
Loading…
Reference in New Issue
Block a user