From d6d96277436ddaf670bbbc52992c95ad60858a7d Mon Sep 17 00:00:00 2001 From: james7132 Date: Sun, 13 Mar 2022 17:46:49 -0700 Subject: [PATCH 01/13] Iterative Transform Propagation --- .../src/transform_propagate_system.rs | 96 ++++++++++--------- 1 file changed, 50 insertions(+), 46 deletions(-) diff --git a/crates/bevy_transform/src/transform_propagate_system.rs b/crates/bevy_transform/src/transform_propagate_system.rs index fb6ef6b1db7f8..8a5ff95423221 100644 --- a/crates/bevy_transform/src/transform_propagate_system.rs +++ b/crates/bevy_transform/src/transform_propagate_system.rs @@ -4,71 +4,75 @@ use bevy_ecs::{ query::{Changed, With, Without}, system::Query, }; +use smallvec::SmallVec; +use std::ptr::NonNull; + +struct Pending { + parent: NonNull, + changed: bool, + child: Entity, +} /// Update [`GlobalTransform`] component of entities based on entity hierarchy and /// [`Transform`] component. pub fn transform_propagate_system( mut root_query: Query< - (Entity, Option<&Children>, &Transform, &mut GlobalTransform), + ( + Option<&Children>, + &Transform, + Changed, + &mut GlobalTransform, + ), Without, >, - mut transform_query: Query<(&Transform, &mut GlobalTransform), With>, - changed_transform_query: Query>, - children_query: Query, (With, With)>, + mut transform_query: Query< + ( + &Transform, + Changed, + Option<&Children>, + &mut GlobalTransform, + ), + With, + >, ) { - for (entity, children, transform, mut global_transform) in root_query.iter_mut() { + let mut pending = SmallVec::<[Pending; 128]>::new(); + for (children, transform, is_changed, mut global_transform) in root_query.iter_mut() { + debug_assert!(pending.is_empty()); let mut changed = false; - if changed_transform_query.get(entity).is_ok() { + if is_changed { *global_transform = GlobalTransform::from(*transform); changed = true; } if let Some(children) = children { - for child in children.0.iter() { - propagate_recursive( - &global_transform, - &changed_transform_query, - &mut transform_query, - &children_query, - *child, + unsafe { + pending.extend(children.0.iter().map(|child| Pending { + parent: NonNull::new_unchecked(&mut *global_transform as *mut GlobalTransform), changed, - ); + child: *child, + })); } } - } -} -fn propagate_recursive( - parent: &GlobalTransform, - changed_transform_query: &Query>, - transform_query: &mut Query<(&Transform, &mut GlobalTransform), With>, - children_query: &Query, (With, With)>, - entity: Entity, - mut changed: bool, -) { - changed |= changed_transform_query.get(entity).is_ok(); - - let global_matrix = { - if let Ok((transform, mut global_transform)) = transform_query.get_mut(entity) { - if changed { - *global_transform = parent.mul_transform(*transform); + while let Some(mut current) = pending.pop() { + if let Ok((transform, changed, children, mut global_transform)) = + transform_query.get_mut(current.child) + { + current.changed |= changed; + let global_matrix = unsafe { + if current.changed { + *global_transform = current.parent.as_ref().mul_transform(*transform); + } + NonNull::new_unchecked(&mut *global_transform as *mut GlobalTransform) + }; + if let Some(children) = children { + pending.extend(children.0.iter().map(|child| Pending { + parent: global_matrix, + changed: current.changed, + child: *child, + })); + } } - *global_transform - } else { - return; - } - }; - - if let Ok(Some(children)) = children_query.get(entity) { - for child in children.0.iter() { - propagate_recursive( - &global_matrix, - changed_transform_query, - transform_query, - children_query, - *child, - changed, - ); } } } From 83ee6b55a8d42797971e51c60aad600670565a8d Mon Sep 17 00:00:00 2001 From: james7132 Date: Sun, 13 Mar 2022 18:04:40 -0700 Subject: [PATCH 02/13] Fix change detection --- .../src/transform_propagate_system.rs | 24 +++++++++---------- 1 file changed, 11 insertions(+), 13 deletions(-) diff --git a/crates/bevy_transform/src/transform_propagate_system.rs b/crates/bevy_transform/src/transform_propagate_system.rs index 8a5ff95423221..82f310e0236b6 100644 --- a/crates/bevy_transform/src/transform_propagate_system.rs +++ b/crates/bevy_transform/src/transform_propagate_system.rs @@ -5,10 +5,9 @@ use bevy_ecs::{ system::Query, }; use smallvec::SmallVec; -use std::ptr::NonNull; struct Pending { - parent: NonNull, + parent: *const GlobalTransform, changed: bool, child: Entity, } @@ -18,9 +17,9 @@ struct Pending { pub fn transform_propagate_system( mut root_query: Query< ( - Option<&Children>, &Transform, Changed, + Option<&Children>, &mut GlobalTransform, ), Without, @@ -36,7 +35,7 @@ pub fn transform_propagate_system( >, ) { let mut pending = SmallVec::<[Pending; 128]>::new(); - for (children, transform, is_changed, mut global_transform) in root_query.iter_mut() { + for (transform, is_changed, children, mut global_transform) in root_query.iter_mut() { debug_assert!(pending.is_empty()); let mut changed = false; if is_changed { @@ -45,13 +44,11 @@ pub fn transform_propagate_system( } if let Some(children) = children { - unsafe { - pending.extend(children.0.iter().map(|child| Pending { - parent: NonNull::new_unchecked(&mut *global_transform as *mut GlobalTransform), - changed, - child: *child, - })); - } + pending.extend(children.0.iter().map(|child| Pending { + parent: &*global_transform as *const GlobalTransform, + changed, + child: *child, + })); } while let Some(mut current) = pending.pop() { @@ -60,10 +57,11 @@ pub fn transform_propagate_system( { current.changed |= changed; let global_matrix = unsafe { + let parent = current.parent.as_ref().unwrap(); if current.changed { - *global_transform = current.parent.as_ref().mul_transform(*transform); + *global_transform = parent.mul_transform(*transform); } - NonNull::new_unchecked(&mut *global_transform as *mut GlobalTransform) + &*global_transform as *const GlobalTransform }; if let Some(children) = children { pending.extend(children.0.iter().map(|child| Pending { From 20897097c55c5dbc61a36a156a8559db80f8df41 Mon Sep 17 00:00:00 2001 From: james7132 Date: Sun, 13 Mar 2022 18:11:24 -0700 Subject: [PATCH 03/13] Use a local instead of potentially reallocating every tick --- .../src/transform_propagate_system.rs | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/crates/bevy_transform/src/transform_propagate_system.rs b/crates/bevy_transform/src/transform_propagate_system.rs index 82f310e0236b6..4c3ff1df459fd 100644 --- a/crates/bevy_transform/src/transform_propagate_system.rs +++ b/crates/bevy_transform/src/transform_propagate_system.rs @@ -2,16 +2,23 @@ use crate::components::{Children, GlobalTransform, Parent, Transform}; use bevy_ecs::{ entity::Entity, query::{Changed, With, Without}, - system::Query, + system::{Local, Query}, }; -use smallvec::SmallVec; -struct Pending { +/// Used for [`transform_propagate_system`]. Ignore otherwise. +pub struct Pending { parent: *const GlobalTransform, changed: bool, child: Entity, } +// SAFE: Values are cleared after every frame and cannot otherwise be +// constructed without transmute. +unsafe impl Send for Pending {} +// SAFE: Values are cleared after every frame and cannot otherwise be +// constructed without transmute. +unsafe impl Sync for Pending {} + /// Update [`GlobalTransform`] component of entities based on entity hierarchy and /// [`Transform`] component. pub fn transform_propagate_system( @@ -33,10 +40,9 @@ pub fn transform_propagate_system( ), With, >, + mut pending: Local>, ) { - let mut pending = SmallVec::<[Pending; 128]>::new(); for (transform, is_changed, children, mut global_transform) in root_query.iter_mut() { - debug_assert!(pending.is_empty()); let mut changed = false; if is_changed { *global_transform = GlobalTransform::from(*transform); @@ -56,6 +62,8 @@ pub fn transform_propagate_system( transform_query.get_mut(current.child) { current.changed |= changed; + // SAFE: The pointers here are generated only during this one traversal + // from one given run of the system. let global_matrix = unsafe { let parent = current.parent.as_ref().unwrap(); if current.changed { @@ -73,6 +81,7 @@ pub fn transform_propagate_system( } } } + debug_assert!(pending.is_empty()); } #[cfg(test)] From 3adc342ff148b99a6ff945ef00e6f201402c272e Mon Sep 17 00:00:00 2001 From: james7132 Date: Sun, 13 Mar 2022 20:51:53 -0700 Subject: [PATCH 04/13] Split out a parallel system for handling entirely flat entities --- crates/bevy_transform/src/lib.rs | 12 +++++++ .../src/transform_propagate_system.rs | 31 +++++++++++++------ 2 files changed, 33 insertions(+), 10 deletions(-) diff --git a/crates/bevy_transform/src/lib.rs b/crates/bevy_transform/src/lib.rs index 45ab1f2ab7988..1aab6596699b7 100644 --- a/crates/bevy_transform/src/lib.rs +++ b/crates/bevy_transform/src/lib.rs @@ -112,6 +112,12 @@ impl Plugin for TransformPlugin { .label(TransformSystem::TransformPropagate) .after(TransformSystem::ParentUpdate), ) + .add_startup_system_to_stage( + StartupStage::PostStartup, + transform_propagate_system::transform_propagate_flat_system + .label(TransformSystem::TransformPropagate) + .after(TransformSystem::ParentUpdate), + ) .add_system_to_stage( CoreStage::PostUpdate, parent_update_system.label(TransformSystem::ParentUpdate), @@ -121,6 +127,12 @@ impl Plugin for TransformPlugin { transform_propagate_system::transform_propagate_system .label(TransformSystem::TransformPropagate) .after(TransformSystem::ParentUpdate), + ) + .add_startup_system_to_stage( + StartupStage::PostStartup, + transform_propagate_system::transform_propagate_flat_system + .label(TransformSystem::TransformPropagate) + .after(TransformSystem::ParentUpdate), ); } } diff --git a/crates/bevy_transform/src/transform_propagate_system.rs b/crates/bevy_transform/src/transform_propagate_system.rs index 4c3ff1df459fd..a135938381902 100644 --- a/crates/bevy_transform/src/transform_propagate_system.rs +++ b/crates/bevy_transform/src/transform_propagate_system.rs @@ -6,7 +6,7 @@ use bevy_ecs::{ }; /// Used for [`transform_propagate_system`]. Ignore otherwise. -pub struct Pending { +pub(crate) struct Pending { parent: *const GlobalTransform, changed: bool, child: Entity, @@ -21,12 +21,25 @@ unsafe impl Sync for Pending {} /// Update [`GlobalTransform`] component of entities based on entity hierarchy and /// [`Transform`] component. -pub fn transform_propagate_system( +pub(crate) fn transform_propagate_flat_system( + mut root_query: Query< + (&Transform, &mut GlobalTransform), + (Without, Without, Changed), + >, +) { + for (transform, mut global_transform) in root_query.iter_mut() { + *global_transform = GlobalTransform::from(*transform); + } +} + +/// Update [`GlobalTransform`] component of entities based on entity hierarchy and +/// [`Transform`] component. +pub(crate) fn transform_propagate_system( mut root_query: Query< ( &Transform, Changed, - Option<&Children>, + &Children, &mut GlobalTransform, ), Without, @@ -49,13 +62,11 @@ pub fn transform_propagate_system( changed = true; } - if let Some(children) = children { - pending.extend(children.0.iter().map(|child| Pending { - parent: &*global_transform as *const GlobalTransform, - changed, - child: *child, - })); - } + pending.extend(children.0.iter().map(|child| Pending { + parent: &*global_transform as *const GlobalTransform, + changed, + child: *child, + })); while let Some(mut current) = pending.pop() { if let Ok((transform, changed, children, mut global_transform)) = From ae68c7e2d5624885b6633d8458fcf700aa980eb6 Mon Sep 17 00:00:00 2001 From: james7132 Date: Sun, 13 Mar 2022 20:58:54 -0700 Subject: [PATCH 05/13] Use correct stage for flat hierarchy system --- crates/bevy_transform/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/bevy_transform/src/lib.rs b/crates/bevy_transform/src/lib.rs index 1aab6596699b7..694abc60c4630 100644 --- a/crates/bevy_transform/src/lib.rs +++ b/crates/bevy_transform/src/lib.rs @@ -129,7 +129,7 @@ impl Plugin for TransformPlugin { .after(TransformSystem::ParentUpdate), ) .add_startup_system_to_stage( - StartupStage::PostStartup, + CoreStage::PostUpdate, transform_propagate_system::transform_propagate_flat_system .label(TransformSystem::TransformPropagate) .after(TransformSystem::ParentUpdate), From 706e92e4f82e698f015267eb764ef541ae568b40 Mon Sep 17 00:00:00 2001 From: james7132 Date: Sun, 13 Mar 2022 21:13:53 -0700 Subject: [PATCH 06/13] fix up docs --- crates/bevy_transform/src/components/global_transform.rs | 4 ++-- crates/bevy_transform/src/components/transform.rs | 4 ++-- crates/bevy_transform/src/lib.rs | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/crates/bevy_transform/src/components/global_transform.rs b/crates/bevy_transform/src/components/global_transform.rs index 68664507d4455..aafac41c69859 100644 --- a/crates/bevy_transform/src/components/global_transform.rs +++ b/crates/bevy_transform/src/components/global_transform.rs @@ -18,8 +18,8 @@ use std::ops::Mul; /// /// [`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). +/// [`GlobalTransform`] is updated from [`Transform`] in the systems labelled +/// [`TransformSystem::TransformPropagate`](crate::TransformSystem::TransformPropagate). /// /// 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/transform.rs b/crates/bevy_transform/src/components/transform.rs index f0c6d536f3982..1bd0d41f1f630 100644 --- a/crates/bevy_transform/src/components/transform.rs +++ b/crates/bevy_transform/src/components/transform.rs @@ -19,8 +19,8 @@ use std::ops::Mul; /// /// [`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). +/// [`GlobalTransform`] is updated from [`Transform`] in the systems labelled +/// [`TransformSystem::TransformPropagate`](crate::TransformSystem::TransformPropagate). /// /// 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/lib.rs b/crates/bevy_transform/src/lib.rs index 694abc60c4630..588dd6d5ac8a3 100644 --- a/crates/bevy_transform/src/lib.rs +++ b/crates/bevy_transform/src/lib.rs @@ -36,8 +36,8 @@ use prelude::{parent_update_system, Children, GlobalTransform, Parent, PreviousP /// /// [`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). +/// [`GlobalTransform`] is updated from [`Transform`] in the systems labelled +/// [`TransformSystem::TransformPropagate`](crate::TransformSystem::TransformPropagate). /// /// 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 From 89067204650060f8dd61e18e978d1600ffbe62f8 Mon Sep 17 00:00:00 2001 From: james7132 Date: Sun, 13 Mar 2022 22:39:22 -0700 Subject: [PATCH 07/13] CoreStage::PostUpdate isn't startup --- crates/bevy_transform/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/bevy_transform/src/lib.rs b/crates/bevy_transform/src/lib.rs index 588dd6d5ac8a3..95a7ac6a74a15 100644 --- a/crates/bevy_transform/src/lib.rs +++ b/crates/bevy_transform/src/lib.rs @@ -128,7 +128,7 @@ impl Plugin for TransformPlugin { .label(TransformSystem::TransformPropagate) .after(TransformSystem::ParentUpdate), ) - .add_startup_system_to_stage( + .add_system_to_stage( CoreStage::PostUpdate, transform_propagate_system::transform_propagate_flat_system .label(TransformSystem::TransformPropagate) From bcc1ac0b5a67c57548b7875d80d92b13ffcb51cb Mon Sep 17 00:00:00 2001 From: james7132 Date: Mon, 14 Mar 2022 01:38:16 -0700 Subject: [PATCH 08/13] Use read instead of as_ref().unwrap() --- crates/bevy_transform/src/transform_propagate_system.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/crates/bevy_transform/src/transform_propagate_system.rs b/crates/bevy_transform/src/transform_propagate_system.rs index a135938381902..00e8fa4830871 100644 --- a/crates/bevy_transform/src/transform_propagate_system.rs +++ b/crates/bevy_transform/src/transform_propagate_system.rs @@ -76,9 +76,8 @@ pub(crate) fn transform_propagate_system( // SAFE: The pointers here are generated only during this one traversal // from one given run of the system. let global_matrix = unsafe { - let parent = current.parent.as_ref().unwrap(); if current.changed { - *global_transform = parent.mul_transform(*transform); + *global_transform = current.parent.read().mul_transform(*transform); } &*global_transform as *const GlobalTransform }; From 7354e68a7949b04f5f8c7a939ed3bddcc468c69e Mon Sep 17 00:00:00 2001 From: james7132 Date: Mon, 14 Mar 2022 01:45:54 -0700 Subject: [PATCH 09/13] Add comment about Local optimization --- crates/bevy_transform/src/transform_propagate_system.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/crates/bevy_transform/src/transform_propagate_system.rs b/crates/bevy_transform/src/transform_propagate_system.rs index 00e8fa4830871..03745c5237075 100644 --- a/crates/bevy_transform/src/transform_propagate_system.rs +++ b/crates/bevy_transform/src/transform_propagate_system.rs @@ -53,6 +53,8 @@ pub(crate) fn transform_propagate_system( ), With, >, + // Stack space for the depth-first search of a given hierarchy. Used as a Local to + // avoid reallocating the stack space used here. mut pending: Local>, ) { for (transform, is_changed, children, mut global_transform) in root_query.iter_mut() { From a25b8d5c7847374fb5f25f977d37114c8a78165d Mon Sep 17 00:00:00 2001 From: james7132 Date: Tue, 15 Mar 2022 05:53:25 -0700 Subject: [PATCH 10/13] Code cleanup and fix build --- crates/bevy_transform/src/lib.rs | 17 ++++++--------- crates/bevy_transform/src/systems.rs | 31 +++++++++++++--------------- 2 files changed, 20 insertions(+), 28 deletions(-) diff --git a/crates/bevy_transform/src/lib.rs b/crates/bevy_transform/src/lib.rs index 535892ec1d75e..fa8005298cad4 100644 --- a/crates/bevy_transform/src/lib.rs +++ b/crates/bevy_transform/src/lib.rs @@ -4,7 +4,6 @@ /// The basic components of the transform crate pub mod components; mod systems; -pub use crate::systems::transform_propagate_system; #[doc(hidden)] pub mod prelude { @@ -97,29 +96,25 @@ impl Plugin for TransformPlugin { StartupStage::PostStartup, systems::transform_propagate_system .label(TransformSystem::TransformPropagate) - .after(TransformSystem::ParentUpdate), + .after(HierarchySystem::ParentUpdate), ) .add_startup_system_to_stage( StartupStage::PostStartup, - transform_propagate_system::transform_propagate_flat_system + systems::transform_propagate_flat_system .label(TransformSystem::TransformPropagate) - .after(TransformSystem::ParentUpdate), - ) - .add_system_to_stage( - CoreStage::PostUpdate, - parent_update_system.label(TransformSystem::ParentUpdate), + .after(HierarchySystem::ParentUpdate), ) .add_system_to_stage( CoreStage::PostUpdate, systems::transform_propagate_system .label(TransformSystem::TransformPropagate) - .after(TransformSystem::ParentUpdate), + .after(HierarchySystem::ParentUpdate), ) .add_system_to_stage( CoreStage::PostUpdate, - transform_propagate_system::transform_propagate_flat_system + systems::transform_propagate_flat_system .label(TransformSystem::TransformPropagate) - .after(TransformSystem::ParentUpdate), + .after(HierarchySystem::ParentUpdate), ); } } diff --git a/crates/bevy_transform/src/systems.rs b/crates/bevy_transform/src/systems.rs index 614379199d62e..a630700dae1a7 100644 --- a/crates/bevy_transform/src/systems.rs +++ b/crates/bevy_transform/src/systems.rs @@ -58,35 +58,32 @@ pub(crate) fn transform_propagate_system( // avoid reallocating the stack space used here. mut pending: Local>, ) { - for (transform, is_changed, children, mut global_transform) in root_query.iter_mut() { - let mut changed = false; - if is_changed { + for (transform, changed, children, mut global_transform) in root_query.iter_mut() { + if changed { *global_transform = GlobalTransform::from(*transform); - changed = true; } - pending.extend(children.0.iter().map(|child| Pending { + pending.extend(children.iter().map(|child| Pending { parent: &*global_transform as *const GlobalTransform, changed, child: *child, })); - while let Some(mut current) = pending.pop() { - if let Ok((transform, changed, children, mut global_transform)) = + while let Some(current) = pending.pop() { + if let Ok((transform, mut changed, children, mut global_transform)) = transform_query.get_mut(current.child) { - current.changed |= changed; - // SAFE: The pointers here are generated only during this one traversal - // from one given run of the system. - let global_matrix = unsafe { - if current.changed { + changed |= current.changed; + if changed { + // SAFE: The pointers here are generated only during this one traversal + // from one given run of the system. + unsafe { *global_transform = current.parent.read().mul_transform(*transform); - } - &*global_transform as *const GlobalTransform - }; + }; + } if let Some(children) = children { - pending.extend(children.0.iter().map(|child| Pending { - parent: global_matrix, + pending.extend(children.iter().map(|child| Pending { + parent: &*global_transform as *const GlobalTransform, changed: current.changed, child: *child, })); From 484c2d753555b260cba6dac925530f9aef7cb144 Mon Sep 17 00:00:00 2001 From: james7132 Date: Tue, 15 Mar 2022 22:11:39 -0700 Subject: [PATCH 11/13] Use for_each_mut --- crates/bevy_transform/src/systems.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/crates/bevy_transform/src/systems.rs b/crates/bevy_transform/src/systems.rs index a630700dae1a7..4e5e80f85dadb 100644 --- a/crates/bevy_transform/src/systems.rs +++ b/crates/bevy_transform/src/systems.rs @@ -28,9 +28,9 @@ pub(crate) fn transform_propagate_flat_system( (Without, Without, Changed), >, ) { - for (transform, mut global_transform) in root_query.iter_mut() { + root_query.for_each_mut(|(transform, mut global_transform)| { *global_transform = GlobalTransform::from(*transform); - } + }); } /// Update [`GlobalTransform`] component of entities based on entity hierarchy and @@ -58,7 +58,7 @@ pub(crate) fn transform_propagate_system( // avoid reallocating the stack space used here. mut pending: Local>, ) { - for (transform, changed, children, mut global_transform) in root_query.iter_mut() { + root_query.for_each_mut(|(transform, changed, children, mut global_transform)| { if changed { *global_transform = GlobalTransform::from(*transform); } @@ -90,7 +90,7 @@ pub(crate) fn transform_propagate_system( } } } - } + }); debug_assert!(pending.is_empty()); } From c464e4688e0a5910681f9c2f63ee13944b106a8a Mon Sep 17 00:00:00 2001 From: james7132 Date: Thu, 17 Mar 2022 20:33:34 -0700 Subject: [PATCH 12/13] Fix safety comments --- crates/bevy_transform/src/systems.rs | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/crates/bevy_transform/src/systems.rs b/crates/bevy_transform/src/systems.rs index 4e5e80f85dadb..55a9d6a6cb708 100644 --- a/crates/bevy_transform/src/systems.rs +++ b/crates/bevy_transform/src/systems.rs @@ -6,22 +6,23 @@ use bevy_ecs::{ }; use bevy_hierarchy::{Children, Parent}; -/// Used for [`transform_propagate_system`]. Ignore otherwise. pub(crate) struct Pending { parent: *const GlobalTransform, changed: bool, child: Entity, } -// SAFE: Values are cleared after every frame and cannot otherwise be -// constructed without transmute. +// SAFE: Access to the parent pointer is only usable in this module, the values +// are cleared after every system execution, and the system only uses one +// thread. There is no way to move this type across multiple threads. unsafe impl Send for Pending {} -// SAFE: Values are cleared after every frame and cannot otherwise be -// constructed without transmute. +// SAFE: Access to the parent pointer is only usable in this module, the values +// are cleared after every system execution, and the system only uses one +// thread. There is no way to access this type across multiple threads. unsafe impl Sync for Pending {} -/// Update [`GlobalTransform`] component of entities based on entity hierarchy and -/// [`Transform`] component. +/// Update [`GlobalTransform`] component of entities without children or parents +/// based on the [`Transform`] component. pub(crate) fn transform_propagate_flat_system( mut root_query: Query< (&Transform, &mut GlobalTransform), From f10f76c8c25fad65f8f4dd53477efec8370ed48a Mon Sep 17 00:00:00 2001 From: james7132 Date: Thu, 17 Mar 2022 20:35:25 -0700 Subject: [PATCH 13/13] fix formatting --- crates/bevy_transform/src/systems.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/crates/bevy_transform/src/systems.rs b/crates/bevy_transform/src/systems.rs index 55a9d6a6cb708..61477de8476ff 100644 --- a/crates/bevy_transform/src/systems.rs +++ b/crates/bevy_transform/src/systems.rs @@ -13,11 +13,11 @@ pub(crate) struct Pending { } // SAFE: Access to the parent pointer is only usable in this module, the values -// are cleared after every system execution, and the system only uses one +// are cleared after every system execution, and the system only uses one // thread. There is no way to move this type across multiple threads. unsafe impl Send for Pending {} // SAFE: Access to the parent pointer is only usable in this module, the values -// are cleared after every system execution, and the system only uses one +// are cleared after every system execution, and the system only uses one // thread. There is no way to access this type across multiple threads. unsafe impl Sync for Pending {}