diff --git a/crates/bevy_gltf/Cargo.toml b/crates/bevy_gltf/Cargo.toml index 79d05e0708..4d9e96ab3c 100644 --- a/crates/bevy_gltf/Cargo.toml +++ b/crates/bevy_gltf/Cargo.toml @@ -14,6 +14,7 @@ bevy_app = { path = "../bevy_app", version = "0.6.0" } bevy_asset = { path = "../bevy_asset", version = "0.6.0" } bevy_core = { path = "../bevy_core", version = "0.6.0" } bevy_ecs = { path = "../bevy_ecs", version = "0.6.0" } +bevy_hierarchy = { path = "../bevy_hierarchy", version = "0.6.0" } bevy_pbr = { path = "../bevy_pbr", version = "0.6.0" } bevy_reflect = { path = "../bevy_reflect", version = "0.6.0", features = ["bevy"] } bevy_render = { path = "../bevy_render", version = "0.6.0" } diff --git a/crates/bevy_gltf/src/loader.rs b/crates/bevy_gltf/src/loader.rs index 293e4bece8..464f89c4a9 100644 --- a/crates/bevy_gltf/src/loader.rs +++ b/crates/bevy_gltf/src/loader.rs @@ -4,6 +4,7 @@ use bevy_asset::{ }; use bevy_core::Name; use bevy_ecs::world::World; +use bevy_hierarchy::{BuildWorldChildren, WorldChildBuilder}; use bevy_log::warn; use bevy_math::{Mat4, Vec3}; use bevy_pbr::{ @@ -24,11 +25,8 @@ use bevy_render::{ view::VisibleEntities, }; use bevy_scene::Scene; -use bevy_transform::{ - hierarchy::{BuildWorldChildren, WorldChildBuilder}, - prelude::Transform, - TransformBundle, -}; +use bevy_transform::{components::Transform, TransformBundle}; + use bevy_utils::{HashMap, HashSet}; use gltf::{ mesh::Mode, diff --git a/crates/bevy_hierarchy/Cargo.toml b/crates/bevy_hierarchy/Cargo.toml new file mode 100644 index 0000000000..69290ddd68 --- /dev/null +++ b/crates/bevy_hierarchy/Cargo.toml @@ -0,0 +1,19 @@ +[package] +name = "bevy_hierarchy" +version = "0.6.0" +edition = "2021" +description = "Provides hierarchy functionality for Bevy Engine" +homepage = "https://bevyengine.org" +repository = "https://github.com/bevyengine/bevy" +license = "MIT OR Apache-2.0" +keywords = ["bevy"] + +[dependencies] +# bevy +bevy_app = { path = "../bevy_app", version = "0.6.0" } +bevy_ecs = { path = "../bevy_ecs", version = "0.6.0", features = ["bevy_reflect"] } +bevy_reflect = { path = "../bevy_reflect", version = "0.6.0", features = ["bevy"] } +bevy_utils = { path = "../bevy_utils", version = "0.6.0" } + +# other +smallvec = { version = "1.6", features = ["serde", "union", "const_generics"] } diff --git a/crates/bevy_transform/src/hierarchy/child_builder.rs b/crates/bevy_hierarchy/src/child_builder.rs similarity index 100% rename from crates/bevy_transform/src/hierarchy/child_builder.rs rename to crates/bevy_hierarchy/src/child_builder.rs diff --git a/crates/bevy_transform/src/components/children.rs b/crates/bevy_hierarchy/src/components/children.rs similarity index 100% rename from crates/bevy_transform/src/components/children.rs rename to crates/bevy_hierarchy/src/components/children.rs diff --git a/crates/bevy_hierarchy/src/components/mod.rs b/crates/bevy_hierarchy/src/components/mod.rs new file mode 100644 index 0000000000..3d6928ea3f --- /dev/null +++ b/crates/bevy_hierarchy/src/components/mod.rs @@ -0,0 +1,5 @@ +mod children; +mod parent; + +pub use children::Children; +pub use parent::{Parent, PreviousParent}; diff --git a/crates/bevy_transform/src/components/parent.rs b/crates/bevy_hierarchy/src/components/parent.rs similarity index 100% rename from crates/bevy_transform/src/components/parent.rs rename to crates/bevy_hierarchy/src/components/parent.rs diff --git a/crates/bevy_transform/src/hierarchy/hierarchy.rs b/crates/bevy_hierarchy/src/hierarchy.rs similarity index 98% rename from crates/bevy_transform/src/hierarchy/hierarchy.rs rename to crates/bevy_hierarchy/src/hierarchy.rs index 0820742c34..56c9b0f8ad 100644 --- a/crates/bevy_transform/src/hierarchy/hierarchy.rs +++ b/crates/bevy_hierarchy/src/hierarchy.rs @@ -116,7 +116,7 @@ mod tests { }; use super::DespawnRecursiveExt; - use crate::{components::Children, hierarchy::BuildChildren}; + use crate::{child_builder::BuildChildren, components::Children}; #[derive(Component, Clone, Copy, PartialEq, Eq, Ord, PartialOrd, Debug)] struct Idx(u32); diff --git a/crates/bevy_hierarchy/src/lib.rs b/crates/bevy_hierarchy/src/lib.rs new file mode 100644 index 0000000000..60fa42f525 --- /dev/null +++ b/crates/bevy_hierarchy/src/lib.rs @@ -0,0 +1,53 @@ +#![warn(missing_docs)] +//! `bevy_hierarchy` can be used to define hierarchies of entities. +//! +//! Most commonly, these hierarchies are used for inheriting `Transform` values +//! from the [`Parent`] to its [`Children`]. + +mod components; +pub use components::*; + +mod hierarchy; +pub use hierarchy::*; + +mod child_builder; +pub use child_builder::*; + +mod systems; +pub use systems::*; + +#[doc(hidden)] +pub mod prelude { + #[doc(hidden)] + pub use crate::{child_builder::*, components::*, hierarchy::*, HierarchyPlugin}; +} + +use bevy_app::prelude::*; +use bevy_ecs::prelude::*; + +/// The base plugin for handling [`Parent`] and [`Children`] components +#[derive(Default)] +pub struct HierarchyPlugin; + +/// Label enum for the systems relating to hierarchy upkeep +#[derive(Debug, Hash, PartialEq, Eq, Clone, SystemLabel)] +pub enum HierarchySystem { + /// Updates [`Parent`] when changes in the hierarchy occur + ParentUpdate, +} + +impl Plugin for HierarchyPlugin { + fn build(&self, app: &mut App) { + app.register_type::() + .register_type::() + .register_type::() + .add_startup_system_to_stage( + StartupStage::PostStartup, + parent_update_system.label(HierarchySystem::ParentUpdate), + ) + .add_system_to_stage( + CoreStage::PostUpdate, + parent_update_system.label(HierarchySystem::ParentUpdate), + ); + } +} diff --git a/crates/bevy_transform/src/hierarchy/hierarchy_maintenance_system.rs b/crates/bevy_hierarchy/src/systems.rs similarity index 53% rename from crates/bevy_transform/src/hierarchy/hierarchy_maintenance_system.rs rename to crates/bevy_hierarchy/src/systems.rs index dbbeacab12..194f0da0c2 100644 --- a/crates/bevy_transform/src/hierarchy/hierarchy_maintenance_system.rs +++ b/crates/bevy_hierarchy/src/systems.rs @@ -70,101 +70,3 @@ pub fn parent_update_system( commands.entity(*e).insert(Children::with(v)); }); } -#[cfg(test)] -mod test { - use bevy_ecs::{ - schedule::{Schedule, Stage, SystemStage}, - system::CommandQueue, - world::World, - }; - - use super::*; - use crate::{hierarchy::BuildChildren, transform_propagate_system::transform_propagate_system}; - - #[test] - fn correct_children() { - let mut world = World::default(); - - let mut update_stage = SystemStage::parallel(); - update_stage.add_system(parent_update_system); - update_stage.add_system(transform_propagate_system); - - let mut schedule = Schedule::default(); - schedule.add_stage("update", update_stage); - - // Add parent entities - let mut command_queue = CommandQueue::default(); - let mut commands = Commands::new(&mut command_queue, &world); - let mut children = Vec::new(); - let parent = commands - .spawn() - .insert(Transform::from_xyz(1.0, 0.0, 0.0)) - .id(); - commands.entity(parent).with_children(|parent| { - children.push( - parent - .spawn() - .insert(Transform::from_xyz(0.0, 2.0, 0.0)) - .id(), - ); - children.push( - parent - .spawn() - .insert(Transform::from_xyz(0.0, 3.0, 0.0)) - .id(), - ); - }); - command_queue.apply(&mut world); - schedule.run(&mut world); - - assert_eq!( - world - .get::(parent) - .unwrap() - .0 - .iter() - .cloned() - .collect::>(), - children, - ); - - // Parent `e1` to `e2`. - (*world.get_mut::(children[0]).unwrap()).0 = children[1]; - - schedule.run(&mut world); - - assert_eq!( - world - .get::(parent) - .unwrap() - .iter() - .cloned() - .collect::>(), - vec![children[1]] - ); - - assert_eq!( - world - .get::(children[1]) - .unwrap() - .iter() - .cloned() - .collect::>(), - vec![children[0]] - ); - - assert!(world.despawn(children[0])); - - schedule.run(&mut world); - - assert_eq!( - world - .get::(parent) - .unwrap() - .iter() - .cloned() - .collect::>(), - vec![children[1]] - ); - } -} diff --git a/crates/bevy_internal/Cargo.toml b/crates/bevy_internal/Cargo.toml index 36642c9bc6..4b9891f3ff 100644 --- a/crates/bevy_internal/Cargo.toml +++ b/crates/bevy_internal/Cargo.toml @@ -56,6 +56,7 @@ bevy_core = { path = "../bevy_core", version = "0.6.0" } bevy_derive = { path = "../bevy_derive", version = "0.6.0" } bevy_diagnostic = { path = "../bevy_diagnostic", version = "0.6.0" } bevy_ecs = { path = "../bevy_ecs", version = "0.6.0" } +bevy_hierarchy = { path = "../bevy_hierarchy", version = "0.6.0" } bevy_input = { path = "../bevy_input", version = "0.6.0" } bevy_log = { path = "../bevy_log", version = "0.6.0" } bevy_math = { path = "../bevy_math", version = "0.6.0" } diff --git a/crates/bevy_internal/src/default_plugins.rs b/crates/bevy_internal/src/default_plugins.rs index 76ccb2954c..d4badf887d 100644 --- a/crates/bevy_internal/src/default_plugins.rs +++ b/crates/bevy_internal/src/default_plugins.rs @@ -4,6 +4,7 @@ use bevy_app::{PluginGroup, PluginGroupBuilder}; /// * [`LogPlugin`](bevy_log::LogPlugin) /// * [`CorePlugin`](bevy_core::CorePlugin) /// * [`TransformPlugin`](bevy_transform::TransformPlugin) +/// * [`HierarchyPlugin`](bevy_hierarchy::HierarchyPlugin) /// * [`DiagnosticsPlugin`](bevy_diagnostic::DiagnosticsPlugin) /// * [`InputPlugin`](bevy_input::InputPlugin) /// * [`WindowPlugin`](bevy_window::WindowPlugin) @@ -27,6 +28,7 @@ impl PluginGroup for DefaultPlugins { group.add(bevy_log::LogPlugin::default()); group.add(bevy_core::CorePlugin::default()); group.add(bevy_transform::TransformPlugin::default()); + group.add(bevy_hierarchy::HierarchyPlugin::default()); group.add(bevy_diagnostic::DiagnosticsPlugin::default()); group.add(bevy_input::InputPlugin::default()); group.add(bevy_window::WindowPlugin::default()); diff --git a/crates/bevy_internal/src/lib.rs b/crates/bevy_internal/src/lib.rs index 3df3d0c2c9..bf65182c7f 100644 --- a/crates/bevy_internal/src/lib.rs +++ b/crates/bevy_internal/src/lib.rs @@ -65,6 +65,11 @@ pub mod tasks { pub use bevy_tasks::*; } +pub mod hierarchy { + //! Entity hierarchies and property inheritance + pub use bevy_hierarchy::*; +} + pub mod transform { //! Local and global transforms (e.g. translation, scale, rotation). pub use bevy_transform::*; diff --git a/crates/bevy_internal/src/prelude.rs b/crates/bevy_internal/src/prelude.rs index 7bd1170c05..148d245bee 100644 --- a/crates/bevy_internal/src/prelude.rs +++ b/crates/bevy_internal/src/prelude.rs @@ -1,7 +1,7 @@ #[doc(hidden)] pub use crate::{ - app::prelude::*, asset::prelude::*, core::prelude::*, ecs::prelude::*, input::prelude::*, - log::prelude::*, math::prelude::*, reflect::prelude::*, scene::prelude::*, + app::prelude::*, asset::prelude::*, core::prelude::*, ecs::prelude::*, hierarchy::prelude::*, + input::prelude::*, log::prelude::*, math::prelude::*, reflect::prelude::*, scene::prelude::*, transform::prelude::*, utils::prelude::*, window::prelude::*, DefaultPlugins, MinimalPlugins, }; diff --git a/crates/bevy_render/src/view/visibility/mod.rs b/crates/bevy_render/src/view/visibility/mod.rs index cec6525d1a..860ebb2142 100644 --- a/crates/bevy_render/src/view/visibility/mod.rs +++ b/crates/bevy_render/src/view/visibility/mod.rs @@ -6,7 +6,8 @@ use bevy_app::{CoreStage, Plugin}; use bevy_asset::{Assets, Handle}; use bevy_ecs::prelude::*; use bevy_reflect::Reflect; -use bevy_transform::{components::GlobalTransform, TransformSystem}; +use bevy_transform::components::GlobalTransform; +use bevy_transform::TransformSystem; use crate::{ camera::{Camera, CameraProjection, OrthographicProjection, PerspectiveProjection}, diff --git a/crates/bevy_scene/Cargo.toml b/crates/bevy_scene/Cargo.toml index adecdd8f76..e63d7db638 100644 --- a/crates/bevy_scene/Cargo.toml +++ b/crates/bevy_scene/Cargo.toml @@ -14,7 +14,7 @@ bevy_app = { path = "../bevy_app", version = "0.6.0" } bevy_asset = { path = "../bevy_asset", version = "0.6.0" } bevy_ecs = { path = "../bevy_ecs", version = "0.6.0" } bevy_reflect = { path = "../bevy_reflect", version = "0.6.0", features = ["bevy"] } -bevy_transform = { path = "../bevy_transform", version = "0.6.0" } +bevy_hierarchy = { path = "../bevy_hierarchy", version = "0.6.0" } bevy_utils = { path = "../bevy_utils", version = "0.6.0" } # other diff --git a/crates/bevy_scene/src/command.rs b/crates/bevy_scene/src/command.rs index 0bed5edf17..55b8c4ec85 100644 --- a/crates/bevy_scene/src/command.rs +++ b/crates/bevy_scene/src/command.rs @@ -4,7 +4,7 @@ use bevy_ecs::{ system::{Command, Commands}, world::World, }; -use bevy_transform::hierarchy::ChildBuilder; +use bevy_hierarchy::ChildBuilder; use crate::{Scene, SceneSpawner}; diff --git a/crates/bevy_scene/src/scene_spawner.rs b/crates/bevy_scene/src/scene_spawner.rs index fdaedcead3..142d299743 100644 --- a/crates/bevy_scene/src/scene_spawner.rs +++ b/crates/bevy_scene/src/scene_spawner.rs @@ -7,8 +7,8 @@ use bevy_ecs::{ system::Command, world::{Mut, World}, }; +use bevy_hierarchy::{AddChild, Parent}; use bevy_reflect::TypeRegistryArc; -use bevy_transform::{hierarchy::AddChild, prelude::Parent}; use bevy_utils::{tracing::error, HashMap}; use thiserror::Error; use uuid::Uuid; diff --git a/crates/bevy_transform/.gitignore b/crates/bevy_transform/.gitignore deleted file mode 100644 index af368c3d50..0000000000 --- a/crates/bevy_transform/.gitignore +++ /dev/null @@ -1,24 +0,0 @@ -book/book -target -Cargo.lock -*.log - -# Backup files -.DS_Store -thumbs.db -*~ -*.rs.bk -*.swp - -# IDE / Editor files -*.iml -.idea -.vscode - - -#Added by cargo -# -#already existing elements are commented out - -/target -**/*.rs.bk diff --git a/crates/bevy_transform/Cargo.toml b/crates/bevy_transform/Cargo.toml index c09078e211..207a429187 100644 --- a/crates/bevy_transform/Cargo.toml +++ b/crates/bevy_transform/Cargo.toml @@ -2,7 +2,7 @@ name = "bevy_transform" version = "0.6.0" edition = "2021" -description = "Provides hierarchy and transform functionality for Bevy Engine" +description = "Provides transform functionality for Bevy Engine" homepage = "https://bevyengine.org" repository = "https://github.com/bevyengine/bevy" license = "MIT OR Apache-2.0" @@ -12,9 +12,6 @@ keywords = ["bevy"] # bevy bevy_app = { path = "../bevy_app", version = "0.6.0" } bevy_ecs = { path = "../bevy_ecs", version = "0.6.0", features = ["bevy_reflect"] } +bevy_hierarchy = { path = "../bevy_hierarchy", version = "0.6.0"} bevy_math = { path = "../bevy_math", version = "0.6.0" } bevy_reflect = { path = "../bevy_reflect", version = "0.6.0", features = ["bevy"] } -bevy_utils = { path = "../bevy_utils", version = "0.6.0" } - -# other -smallvec = { version = "1.6", features = ["serde", "union", "const_generics"] } diff --git a/crates/bevy_transform/src/components/global_transform.rs b/crates/bevy_transform/src/components/global_transform.rs index 68664507d4..f1bce51993 100644 --- a/crates/bevy_transform/src/components/global_transform.rs +++ b/crates/bevy_transform/src/components/global_transform.rs @@ -14,12 +14,12 @@ use std::ops::Mul; /// ## [`Transform`] and [`GlobalTransform`] /// /// [`Transform`] is the position of an entity relative to its parent position, or the reference -/// frame if it doesn't have a [`Parent`](super::Parent). +/// frame if it doesn't have a [`Parent`](bevy_hierarchy::Parent). /// /// [`GlobalTransform`] is the position of an entity relative to the reference frame. /// /// [`GlobalTransform`] is updated from [`Transform`] in the system -/// [`transform_propagate_system`](crate::transform_propagate_system::transform_propagate_system). +/// [`transform_propagate_system`](crate::transform_propagate_system). /// /// This system runs in stage [`CoreStage::PostUpdate`](crate::CoreStage::PostUpdate). If you /// update the[`Transform`] of an entity in this stage or after, you will notice a 1 frame lag diff --git a/crates/bevy_transform/src/components/mod.rs b/crates/bevy_transform/src/components/mod.rs index 67720a2b4e..10d3f72e3a 100644 --- a/crates/bevy_transform/src/components/mod.rs +++ b/crates/bevy_transform/src/components/mod.rs @@ -1,9 +1,5 @@ -mod children; mod global_transform; -mod parent; mod transform; -pub use children::Children; pub use global_transform::*; -pub use parent::{Parent, PreviousParent}; pub use transform::*; diff --git a/crates/bevy_transform/src/components/transform.rs b/crates/bevy_transform/src/components/transform.rs index f0c6d536f3..80c80c7f54 100644 --- a/crates/bevy_transform/src/components/transform.rs +++ b/crates/bevy_transform/src/components/transform.rs @@ -15,12 +15,12 @@ use std::ops::Mul; /// ## [`Transform`] and [`GlobalTransform`] /// /// [`Transform`] is the position of an entity relative to its parent position, or the reference -/// frame if it doesn't have a [`Parent`](super::Parent). +/// frame if it doesn't have a [`Parent`](bevy_hierarchy::Parent). /// /// [`GlobalTransform`] is the position of an entity relative to the reference frame. /// /// [`GlobalTransform`] is updated from [`Transform`] in the system -/// [`transform_propagate_system`](crate::transform_propagate_system::transform_propagate_system). +/// [`transform_propagate_system`](crate::transform_propagate_system). /// /// This system runs in stage [`CoreStage::PostUpdate`](crate::CoreStage::PostUpdate). If you /// update the[`Transform`] of an entity in this stage or after, you will notice a 1 frame lag diff --git a/crates/bevy_transform/src/hierarchy/mod.rs b/crates/bevy_transform/src/hierarchy/mod.rs deleted file mode 100644 index 23e9108e2d..0000000000 --- a/crates/bevy_transform/src/hierarchy/mod.rs +++ /dev/null @@ -1,8 +0,0 @@ -mod child_builder; -#[allow(clippy::module_inception)] -mod hierarchy; -mod hierarchy_maintenance_system; - -pub use child_builder::*; -pub use hierarchy::*; -pub use hierarchy_maintenance_system::*; diff --git a/crates/bevy_transform/src/lib.rs b/crates/bevy_transform/src/lib.rs index 45ab1f2ab7..a88017c7d7 100644 --- a/crates/bevy_transform/src/lib.rs +++ b/crates/bevy_transform/src/lib.rs @@ -3,23 +3,19 @@ /// The basic components of the transform crate pub mod components; -/// Establishing and updating the transform hierarchy -pub mod hierarchy; -/// Propagating transform changes down the transform hierarchy -pub mod transform_propagate_system; +mod systems; +pub use crate::systems::transform_propagate_system; #[doc(hidden)] pub mod prelude { #[doc(hidden)] - pub use crate::{components::*, hierarchy::*, TransformBundle, TransformPlugin}; + pub use crate::{components::*, TransformBundle, TransformPlugin}; } use bevy_app::prelude::*; -use bevy_ecs::{ - bundle::Bundle, - schedule::{ParallelSystemDescriptorCoercion, SystemLabel}, -}; -use prelude::{parent_update_system, Children, GlobalTransform, Parent, PreviousParent, Transform}; +use bevy_ecs::prelude::*; +use bevy_hierarchy::HierarchySystem; +use prelude::{GlobalTransform, Transform}; /// A [`Bundle`] of the [`Transform`] and [`GlobalTransform`] /// [`Component`](bevy_ecs::component::Component)s, which describe the position of an entity. @@ -32,12 +28,12 @@ use prelude::{parent_update_system, Children, GlobalTransform, Parent, PreviousP /// ## [`Transform`] and [`GlobalTransform`] /// /// [`Transform`] is the position of an entity relative to its parent position, or the reference -/// frame if it doesn't have a [`Parent`](Parent). +/// frame if it doesn't have a parent. /// /// [`GlobalTransform`] is the position of an entity relative to the reference frame. /// /// [`GlobalTransform`] is updated from [`Transform`] in the system -/// [`transform_propagate_system`](crate::transform_propagate_system::transform_propagate_system). +/// [`transform_propagate_system`]. /// /// This system runs in stage [`CoreStage::PostUpdate`](crate::CoreStage::PostUpdate). If you /// update the[`Transform`] of an entity in this stage or after, you will notice a 1 frame lag @@ -81,46 +77,33 @@ impl From for TransformBundle { Self::from_transform(transform) } } +/// Label enum for the systems relating to transform propagation +#[derive(Debug, Hash, PartialEq, Eq, Clone, SystemLabel)] +pub enum TransformSystem { + /// Propagates changes in transform to childrens' [`GlobalTransform`](crate::components::GlobalTransform) + TransformPropagate, +} + /// The base plugin for handling [`Transform`] components #[derive(Default)] pub struct TransformPlugin; -/// Label enum for the types of systems relating to transform -#[derive(Debug, Hash, PartialEq, Eq, Clone, SystemLabel)] -pub enum TransformSystem { - /// Propagates changes in transform to childrens' [`GlobalTransform`] - TransformPropagate, - /// Updates [`Parent`] when changes in the hierarchy occur - ParentUpdate, -} - impl Plugin for TransformPlugin { fn build(&self, app: &mut App) { - app.register_type::() - .register_type::() - .register_type::() - .register_type::() + app.register_type::() .register_type::() - // add transform systems to startup so the first update is "correct" + // Adding these to startup ensures the first update is "correct" .add_startup_system_to_stage( StartupStage::PostStartup, - parent_update_system.label(TransformSystem::ParentUpdate), - ) - .add_startup_system_to_stage( - StartupStage::PostStartup, - transform_propagate_system::transform_propagate_system + systems::transform_propagate_system .label(TransformSystem::TransformPropagate) - .after(TransformSystem::ParentUpdate), + .after(HierarchySystem::ParentUpdate), ) .add_system_to_stage( CoreStage::PostUpdate, - parent_update_system.label(TransformSystem::ParentUpdate), - ) - .add_system_to_stage( - CoreStage::PostUpdate, - transform_propagate_system::transform_propagate_system + systems::transform_propagate_system .label(TransformSystem::TransformPropagate) - .after(TransformSystem::ParentUpdate), + .after(HierarchySystem::ParentUpdate), ); } } diff --git a/crates/bevy_transform/src/transform_propagate_system.rs b/crates/bevy_transform/src/systems.rs similarity index 66% rename from crates/bevy_transform/src/transform_propagate_system.rs rename to crates/bevy_transform/src/systems.rs index fb6ef6b1db..9fb2e9a2d0 100644 --- a/crates/bevy_transform/src/transform_propagate_system.rs +++ b/crates/bevy_transform/src/systems.rs @@ -1,9 +1,10 @@ -use crate::components::{Children, GlobalTransform, Parent, Transform}; +use crate::components::{GlobalTransform, Transform}; use bevy_ecs::{ entity::Entity, query::{Changed, With, Without}, system::Query, }; +use bevy_hierarchy::{Children, Parent}; /// Update [`GlobalTransform`] component of entities based on entity hierarchy and /// [`Transform`] component. @@ -24,7 +25,7 @@ pub fn transform_propagate_system( } if let Some(children) = children { - for child in children.0.iter() { + for child in children.iter() { propagate_recursive( &global_transform, &changed_transform_query, @@ -60,7 +61,7 @@ fn propagate_recursive( }; if let Ok(Some(children)) = children_query.get(entity) { - for child in children.0.iter() { + for child in children.iter() { propagate_recursive( &global_matrix, changed_transform_query, @@ -81,10 +82,11 @@ mod test { world::World, }; - use super::*; - use crate::{ - hierarchy::{parent_update_system, BuildChildren, BuildWorldChildren}, - TransformBundle, + use crate::components::{GlobalTransform, Transform}; + use crate::systems::transform_propagate_system; + use crate::TransformBundle; + use bevy_hierarchy::{ + parent_update_system, BuildChildren, BuildWorldChildren, Children, Parent, }; #[test] @@ -174,4 +176,90 @@ mod test { GlobalTransform::from_xyz(1.0, 0.0, 0.0) * Transform::from_xyz(0.0, 0.0, 3.0) ); } + + #[test] + fn correct_children() { + let mut world = World::default(); + + let mut update_stage = SystemStage::parallel(); + update_stage.add_system(parent_update_system); + update_stage.add_system(transform_propagate_system); + + let mut schedule = Schedule::default(); + schedule.add_stage("update", update_stage); + + // Add parent entities + let mut command_queue = CommandQueue::default(); + let mut commands = Commands::new(&mut command_queue, &world); + let mut children = Vec::new(); + let parent = commands + .spawn() + .insert(Transform::from_xyz(1.0, 0.0, 0.0)) + .id(); + commands.entity(parent).with_children(|parent| { + children.push( + parent + .spawn() + .insert(Transform::from_xyz(0.0, 2.0, 0.0)) + .id(), + ); + children.push( + parent + .spawn() + .insert(Transform::from_xyz(0.0, 3.0, 0.0)) + .id(), + ); + }); + command_queue.apply(&mut world); + schedule.run(&mut world); + + assert_eq!( + world + .get::(parent) + .unwrap() + .iter() + .cloned() + .collect::>(), + children, + ); + + // Parent `e1` to `e2`. + (*world.get_mut::(children[0]).unwrap()).0 = children[1]; + + schedule.run(&mut world); + + assert_eq!( + world + .get::(parent) + .unwrap() + .iter() + .cloned() + .collect::>(), + vec![children[1]] + ); + + assert_eq!( + world + .get::(children[1]) + .unwrap() + .iter() + .cloned() + .collect::>(), + vec![children[0]] + ); + + assert!(world.despawn(children[0])); + + schedule.run(&mut world); + + assert_eq!( + world + .get::(parent) + .unwrap() + .iter() + .cloned() + .collect::>(), + vec![children[1]] + ); + } } diff --git a/crates/bevy_ui/Cargo.toml b/crates/bevy_ui/Cargo.toml index 6954fa9d1b..4a7fce13a4 100644 --- a/crates/bevy_ui/Cargo.toml +++ b/crates/bevy_ui/Cargo.toml @@ -16,6 +16,7 @@ bevy_core = { path = "../bevy_core", version = "0.6.0" } bevy_core_pipeline = { path = "../bevy_core_pipeline", version = "0.6.0" } bevy_derive = { path = "../bevy_derive", version = "0.6.0" } bevy_ecs = { path = "../bevy_ecs", version = "0.6.0" } +bevy_hierarchy = { path = "../bevy_hierarchy", version = "0.6.0" } bevy_input = { path = "../bevy_input", version = "0.6.0" } bevy_log = { path = "../bevy_log", version = "0.6.0" } bevy_math = { path = "../bevy_math", version = "0.6.0" } diff --git a/crates/bevy_ui/src/flex/mod.rs b/crates/bevy_ui/src/flex/mod.rs index cda1167e74..63ccf94a2c 100644 --- a/crates/bevy_ui/src/flex/mod.rs +++ b/crates/bevy_ui/src/flex/mod.rs @@ -7,9 +7,10 @@ use bevy_ecs::{ query::{Changed, FilterFetch, With, Without, WorldQuery}, system::{Query, Res, ResMut}, }; +use bevy_hierarchy::{Children, Parent}; use bevy_log::warn; use bevy_math::Vec2; -use bevy_transform::prelude::{Children, Parent, Transform}; +use bevy_transform::components::Transform; use bevy_utils::HashMap; use bevy_window::{Window, WindowId, WindowScaleFactorChanged, Windows}; use std::fmt; diff --git a/crates/bevy_ui/src/update.rs b/crates/bevy_ui/src/update.rs index 9fe53009b9..8af7d72cac 100644 --- a/crates/bevy_ui/src/update.rs +++ b/crates/bevy_ui/src/update.rs @@ -8,12 +8,10 @@ use bevy_ecs::{ query::{With, Without}, system::{Commands, Query}, }; +use bevy_hierarchy::{Children, Parent}; use bevy_math::Vec2; use bevy_sprite::Rect; -use bevy_transform::{ - components::GlobalTransform, - prelude::{Children, Parent, Transform}, -}; +use bevy_transform::components::{GlobalTransform, Transform}; /// The resolution of Z values for UI pub const UI_Z_STEP: f32 = 0.001; @@ -141,7 +139,8 @@ mod tests { system::{CommandQueue, Commands}, world::World, }; - use bevy_transform::{components::Transform, hierarchy::BuildChildren}; + use bevy_hierarchy::BuildChildren; + use bevy_transform::components::Transform; use crate::Node;