use crate::prelude::{GlobalTransform, Transform};
use bevy_ecs::{prelude::Entity, system::EntityCommands, world::Command, world::World};
use bevy_hierarchy::{PushChild, RemoveParent};
pub struct PushChildInPlace {
pub parent: Entity,
pub child: Entity,
}
impl Command for PushChildInPlace {
fn apply(self, world: &mut World) {
let hierarchy_command = PushChild {
child: self.child,
parent: self.parent,
};
hierarchy_command.apply(world);
let mut update_transform = || {
let parent = *world.get_entity(self.parent)?.get::<GlobalTransform>()?;
let child_global = *world.get_entity(self.child)?.get::<GlobalTransform>()?;
let mut child_entity = world.get_entity_mut(self.child)?;
let mut child = child_entity.get_mut::<Transform>()?;
*child = child_global.reparented_to(&parent);
Some(())
};
update_transform();
}
}
pub struct RemoveParentInPlace {
pub child: Entity,
}
impl Command for RemoveParentInPlace {
fn apply(self, world: &mut World) {
let hierarchy_command = RemoveParent { child: self.child };
hierarchy_command.apply(world);
let mut update_transform = || {
let child_global = *world.get_entity(self.child)?.get::<GlobalTransform>()?;
let mut child_entity = world.get_entity_mut(self.child)?;
let mut child = child_entity.get_mut::<Transform>()?;
*child = child_global.compute_transform();
Some(())
};
update_transform();
}
}
pub trait BuildChildrenTransformExt {
fn set_parent_in_place(&mut self, parent: Entity) -> &mut Self;
fn remove_parent_in_place(&mut self) -> &mut Self;
}
impl BuildChildrenTransformExt for EntityCommands<'_> {
fn set_parent_in_place(&mut self, parent: Entity) -> &mut Self {
let child = self.id();
self.commands().add(PushChildInPlace { child, parent });
self
}
fn remove_parent_in_place(&mut self) -> &mut Self {
let child = self.id();
self.commands().add(RemoveParentInPlace { child });
self
}
}