From e673faab7ce9c2d7b47e57d6b5601a4bc3fbc269 Mon Sep 17 00:00:00 2001 From: Carter Anderson Date: Wed, 22 Jul 2020 12:42:12 -0700 Subject: [PATCH] ecs: rename Changed to Mutated --- crates/bevy_ecs/hecs/src/archetype.rs | 29 +++++----- crates/bevy_ecs/hecs/src/borrow.rs | 2 +- crates/bevy_ecs/hecs/src/lib.rs | 2 +- crates/bevy_ecs/hecs/src/query.rs | 81 +++++++++++++++++---------- crates/bevy_ecs/hecs/src/world.rs | 10 ++-- crates/bevy_ecs/src/lib.rs | 2 +- examples/ui/button.rs | 4 +- 7 files changed, 74 insertions(+), 56 deletions(-) diff --git a/crates/bevy_ecs/hecs/src/archetype.rs b/crates/bevy_ecs/hecs/src/archetype.rs index ce294b1253..8f597729b8 100644 --- a/crates/bevy_ecs/hecs/src/archetype.rs +++ b/crates/bevy_ecs/hecs/src/archetype.rs @@ -99,7 +99,6 @@ impl Archetype { self.state.contains_key(&id) } - // TODO: this should be unsafe i think #[allow(missing_docs)] #[inline] pub fn get(&self) -> Option> { @@ -111,27 +110,25 @@ impl Archetype { }) } - // TODO: this should be unsafe i think #[allow(missing_docs)] #[inline] - pub fn get_with_modified(&self) -> Option<(NonNull, NonNull)> { + pub fn get_with_mutated(&self) -> Option<(NonNull, NonNull)> { let state = self.state.get(&TypeId::of::())?; Some(unsafe { ( NonNull::new_unchecked( (*self.data.get()).as_ptr().add(state.offset).cast::() as *mut T ), - NonNull::new_unchecked(state.modified_entities.as_ptr() as *mut bool), + NonNull::new_unchecked(state.mutated_entities.as_ptr() as *mut bool), ) }) } - // TODO: this should be unsafe i think #[allow(missing_docs)] #[inline] - pub fn get_modified(&self) -> Option> { + pub fn get_mutated(&self) -> Option> { let state = self.state.get(&TypeId::of::())?; - Some(unsafe { NonNull::new_unchecked(state.modified_entities.as_ptr() as *mut bool) }) + Some(unsafe { NonNull::new_unchecked(state.mutated_entities.as_ptr() as *mut bool) }) } #[allow(missing_docs)] @@ -264,7 +261,7 @@ impl Archetype { self.entities = new_entities; for type_state in self.state.values_mut() { - type_state.modified_entities.resize_with(count, || false); + type_state.mutated_entities.resize_with(count, || false); type_state.added_entities.resize_with(count, || false); } @@ -325,7 +322,7 @@ impl Archetype { ); let type_state = self.state.get_mut(&ty.id).unwrap(); - type_state.modified_entities[index as usize] = type_state.modified_entities[last as usize]; + type_state.mutated_entities[index as usize] = type_state.mutated_entities[last as usize]; type_state.added_entities[index as usize] = type_state.added_entities[last as usize]; } } @@ -352,8 +349,8 @@ impl Archetype { .as_ptr(); let type_state = self.state.get(&ty.id).unwrap(); let is_added= type_state.added_entities[index as usize]; - let is_modified = type_state.modified_entities[index as usize]; - f(moved, ty.id(), ty.layout().size(), is_added, is_modified); + let is_mutated = type_state.mutated_entities[index as usize]; + f(moved, ty.id(), ty.layout().size(), is_added, is_mutated); if index != last { ptr::copy_nonoverlapping( self.get_dynamic(ty.id, ty.layout.size(), last) @@ -364,7 +361,7 @@ impl Archetype { ); let type_state = self.state.get_mut(&ty.id).unwrap(); type_state.added_entities[index as usize] = type_state.added_entities[last as usize]; - type_state.modified_entities[index as usize] = type_state.modified_entities[last as usize]; + type_state.mutated_entities[index as usize] = type_state.mutated_entities[last as usize]; } } self.len -= 1; @@ -415,7 +412,7 @@ impl Drop for Archetype { pub struct TypeState { offset: usize, borrow: AtomicBorrow, - pub modified_entities: Vec, + pub mutated_entities: Vec, pub added_entities: Vec, } @@ -424,14 +421,14 @@ impl TypeState { Self { offset: 0, borrow: AtomicBorrow::new(), - modified_entities: Vec::new(), + mutated_entities: Vec::new(), added_entities: Vec::new(), } } fn clear_trackers(&mut self) { - for modified in self.modified_entities.iter_mut() { - *modified = false; + for mutated in self.mutated_entities.iter_mut() { + *mutated = false; } for added in self.added_entities.iter_mut() { diff --git a/crates/bevy_ecs/hecs/src/borrow.rs b/crates/bevy_ecs/hecs/src/borrow.rs index 1d072a9692..5ad4bcc668 100644 --- a/crates/bevy_ecs/hecs/src/borrow.rs +++ b/crates/bevy_ecs/hecs/src/borrow.rs @@ -126,7 +126,7 @@ impl<'a, T: Component> RefMut<'a, T> { ); archetype.borrow_mut::(); let modified = archetype - .get_modified::() + .get_mutated::() .unwrap() .as_ptr() .add(index as usize); diff --git a/crates/bevy_ecs/hecs/src/lib.rs b/crates/bevy_ecs/hecs/src/lib.rs index a98f3b4c98..4bafd8f9c4 100644 --- a/crates/bevy_ecs/hecs/src/lib.rs +++ b/crates/bevy_ecs/hecs/src/lib.rs @@ -80,7 +80,7 @@ pub use borrow::{EntityRef, Ref, RefMut}; pub use bundle::{Bundle, DynamicBundle, MissingComponent}; pub use entities::{Entity, Location, NoSuchEntity}; pub use entity_builder::{BuiltEntity, EntityBuilder}; -pub use query::{Access, BatchedIter, Query, QueryBorrow, QueryIter, With, Without, Mut, Changed}; +pub use query::{Access, BatchedIter, Query, QueryBorrow, QueryIter, With, Without, Mut, Mutated}; pub use query_one::QueryOne; pub use world::{ArchetypesGeneration, Component, ComponentError, Iter, SpawnBatchIter, World}; diff --git a/crates/bevy_ecs/hecs/src/query.rs b/crates/bevy_ecs/hecs/src/query.rs index f86690acd0..722799bdbb 100644 --- a/crates/bevy_ecs/hecs/src/query.rs +++ b/crates/bevy_ecs/hecs/src/query.rs @@ -153,7 +153,7 @@ impl Query for Option { /// Unique borrow of an entity's component pub struct Mut<'a, T: Component> { value: &'a mut T, - modified: &'a mut bool, + mutated: &'a mut bool, } unsafe impl Send for Mut<'_, T> {} @@ -170,7 +170,7 @@ impl<'a, T: Component> Deref for Mut<'a, T> { impl<'a, T: Component> DerefMut for Mut<'a, T> { #[inline] fn deref_mut(&mut self) -> &mut T { - *self.modified = true; + *self.mutated = true; self.value } } @@ -197,11 +197,11 @@ impl<'a, T: Component> Fetch<'a> for FetchMut { } unsafe fn get(archetype: &'a Archetype, offset: usize) -> Option { archetype - .get_with_modified::() - .map(|(components, modified)| { + .get_with_mutated::() + .map(|(components, mutated)| { Self( NonNull::new_unchecked(components.as_ptr().add(offset)), - NonNull::new_unchecked(modified.as_ptr().add(offset)), + NonNull::new_unchecked(mutated.as_ptr().add(offset)), ) }) } @@ -212,37 +212,37 @@ impl<'a, T: Component> Fetch<'a> for FetchMut { #[inline] unsafe fn next(&mut self) -> Mut<'a, T> { let component = self.0.as_ptr(); - let modified = self.1.as_ptr(); + let mutated = self.1.as_ptr(); self.0 = NonNull::new_unchecked(component.add(1)); - self.1 = NonNull::new_unchecked(modified.add(1)); + self.1 = NonNull::new_unchecked(mutated.add(1)); Mut { value: &mut *component, - modified: &mut *modified, + mutated: &mut *mutated, } } } #[allow(missing_docs)] -pub struct Changed<'a, T> { +pub struct Mutated<'a, T> { value: &'a T, } -impl<'a, T: Component> Deref for Changed<'a, T> { +impl<'a, T: Component> Deref for Mutated<'a, T> { type Target = T; fn deref(&self) -> &T { self.value } } -impl<'a, T: Component> Query for Changed<'a, T> { - type Fetch = FetchChanged; +impl<'a, T: Component> Query for Mutated<'a, T> { + type Fetch = FetchMutated; } #[doc(hidden)] -pub struct FetchChanged(NonNull, NonNull); +pub struct FetchMutated(NonNull, NonNull); -impl<'a, T: Component> Fetch<'a> for FetchChanged { - type Item = Changed<'a, T>; +impl<'a, T: Component> Fetch<'a> for FetchMutated { + type Item = Mutated<'a, T>; fn access(archetype: &Archetype) -> Option { if archetype.has::() { @@ -256,16 +256,21 @@ impl<'a, T: Component> Fetch<'a> for FetchChanged { archetype.borrow::(); } unsafe fn get(archetype: &'a Archetype, offset: usize) -> Option { - let components = NonNull::new_unchecked(archetype.get::()?.as_ptr().add(offset)); - let modified = NonNull::new_unchecked(archetype.get_modified::()?.as_ptr().add(offset)); - Some(Self(components, modified)) + archetype + .get_with_mutated::() + .map(|(components, mutated)| { + Self( + NonNull::new_unchecked(components.as_ptr().add(offset)), + NonNull::new_unchecked(mutated.as_ptr().add(offset)), + ) + }) } fn release(archetype: &Archetype) { archetype.release::(); } unsafe fn should_skip(&self) -> bool { - // skip if the current item wasn't changed + // skip if the current item wasn't mutated !*self.1.as_ref() } @@ -274,7 +279,7 @@ impl<'a, T: Component> Fetch<'a> for FetchChanged { self.1 = NonNull::new_unchecked(self.1.as_ptr().add(1)); let value = self.0.as_ptr(); self.0 = NonNull::new_unchecked(value.add(1)); - Changed { value: &*value } + Mutated { value: &*value } } } @@ -313,8 +318,8 @@ impl<'a, T: Component> Fetch<'a> for FetchAdded { } unsafe fn get(archetype: &'a Archetype, offset: usize) -> Option { let components = NonNull::new_unchecked(archetype.get::()?.as_ptr().add(offset)); - let modified = NonNull::new_unchecked(archetype.get_added::()?.as_ptr().add(offset)); - Some(Self(components, modified)) + let added = NonNull::new_unchecked(archetype.get_added::()?.as_ptr().add(offset)); + Some(Self(components, added)) } fn release(archetype: &Archetype) { archetype.release::(); @@ -820,7 +825,7 @@ smaller_tuples_too!(tuple_impl, O, N, M, L, K, J, I, H, G, F, E, D, C, B, A); #[cfg(test)] mod tests { - use crate::{Changed, Entity, Mut, World}; + use crate::{Entity, Mut, Mutated, World}; use std::{vec, vec::Vec}; use super::*; @@ -869,7 +874,7 @@ mod tests { } #[test] - fn modified_trackers() { + fn mutated_trackers() { let mut world = World::default(); let e1 = world.spawn((A(0), B(0))); let e2 = world.spawn((A(0), B(0))); @@ -884,7 +889,7 @@ mod tests { fn get_changed_a(world: &World) -> Vec { world - .query::<(Changed, Entity)>() + .query::<(Mutated, Entity)>() .iter() .map(|(_a, e)| e) .collect::>() @@ -892,12 +897,12 @@ mod tests { assert_eq!(get_changed_a(&world), vec![e1, e3]); - // ensure changing an entity's archetypes also moves its modified state + // ensure changing an entity's archetypes also moves its mutated state world.insert(e1, (C,)).unwrap(); assert_eq!(get_changed_a(&world), vec![e3, e1], "changed entities list should not change (although the order will due to archetype moves)"); - // spawning a new A entity should not change existing modified state + // spawning a new A entity should not change existing mutated state world.insert(e1, (A(0), B)).unwrap(); assert_eq!( get_changed_a(&world), @@ -905,7 +910,7 @@ mod tests { "changed entities list should not change" ); - // removing an unchanged entity should not change modified state + // removing an unchanged entity should not change mutated state world.despawn(e2).unwrap(); assert_eq!( get_changed_a(&world), @@ -924,7 +929,7 @@ mod tests { world.clear_trackers(); assert!(world - .query::<(Changed, Entity)>() + .query::<(Mutated, Entity)>() .iter() .map(|(_a, e)| e) .collect::>() @@ -947,10 +952,26 @@ mod tests { } let a_b_changed = world - .query::<(Changed, Changed, Entity)>() + .query::<(Mutated, Mutated, Entity)>() .iter() .map(|(_a, _b, e)| e) .collect::>(); assert_eq!(a_b_changed, vec![e2]); } + + #[test] + fn changed_or_added_query() { + let mut world = World::default(); + let e1 = world.spawn((A(0), B(0))); + + fn get_changed_or_added(world: &World) -> Vec { + world + .query::<(Mutated, Added, Entity)>() + .iter() + .map(|(_a, _b, e)| e) + .collect::>() + }; + assert_eq!(get_changed_or_added(&world), vec![e1]); + world.clear_trackers(); + } } diff --git a/crates/bevy_ecs/hecs/src/world.rs b/crates/bevy_ecs/hecs/src/world.rs index 1f0e686196..8abdbe794f 100644 --- a/crates/bevy_ecs/hecs/src/world.rs +++ b/crates/bevy_ecs/hecs/src/world.rs @@ -386,11 +386,11 @@ impl World { let target_index = target_arch.allocate(entity.id()); loc.archetype = target; let old_index = mem::replace(&mut loc.index, target_index); - if let Some(moved) = source_arch.move_to(old_index, |ptr, ty, size, is_added, is_modified| { + if let Some(moved) = source_arch.move_to(old_index, |ptr, ty, size, is_added, is_mutated| { target_arch.put_dynamic(ptr, ty, size, target_index, false); let type_state = target_arch.get_type_state_mut(ty).unwrap(); type_state.added_entities[target_index as usize] = is_added; - type_state.modified_entities[target_index as usize] = is_modified; + type_state.mutated_entities[target_index as usize] = is_mutated; }) { self.entities.get_mut(Entity::with_id(moved)).unwrap().index = old_index; } @@ -467,13 +467,13 @@ impl World { let target_index = target_arch.allocate(entity.id()); loc.archetype = target; loc.index = target_index; - if let Some(moved) = source_arch.move_to(old_index, |src, ty, size, is_added, is_modified| { + if let Some(moved) = source_arch.move_to(old_index, |src, ty, size, is_added, is_mutated| { // Only move the components present in the target archetype, i.e. the non-removed ones. if let Some(dst) = target_arch.get_dynamic(ty, size, target_index) { ptr::copy_nonoverlapping(src, dst.as_ptr(), size); let state = target_arch.get_type_state_mut(ty).unwrap(); state.added_entities[target_index as usize] = is_added; - state.modified_entities[target_index as usize] = is_modified; + state.mutated_entities[target_index as usize] = is_mutated; } }) { self.entities.get_mut(Entity::with_id(moved)).unwrap().index = old_index; @@ -567,7 +567,7 @@ impl World { self.entities.get(entity).ok() } - /// Clears each entity's tracker state. For example, each entity's component "modified" state will be reset to `false`. + /// Clears each entity's tracker state. For example, each entity's component "mutated" state will be reset to `false`. pub fn clear_trackers(&mut self) { for archetype in self.archetypes.iter_mut() { archetype.clear_trackers(); diff --git a/crates/bevy_ecs/src/lib.rs b/crates/bevy_ecs/src/lib.rs index 19f000385b..72c66348ca 100644 --- a/crates/bevy_ecs/src/lib.rs +++ b/crates/bevy_ecs/src/lib.rs @@ -16,6 +16,6 @@ pub mod prelude { Commands, IntoForEachSystem, IntoQuerySystem, IntoThreadLocalSystem, Query, System, }, world::WorldBuilderSource, - Bundle, Changed, Component, Entity, Ref, RefMut, With, Without, World, + Bundle, Mutated, Component, Entity, Ref, RefMut, With, Without, World, }; } diff --git a/examples/ui/button.rs b/examples/ui/button.rs index 3feef9d5e9..451e14668e 100644 --- a/examples/ui/button.rs +++ b/examples/ui/button.rs @@ -30,14 +30,14 @@ fn button_system( button_materials: Res, mut click_query: Query<( &Button, - Changed, + Mutated, Option<&Hover>, &mut Handle, &Children, )>, mut hover_query: Query<( &Button, - Changed, + Mutated, Option<&Click>, &mut Handle, &Children,