ecs: rename Changed<T> to Mutated<T>
This commit is contained in:
parent
19d24e92aa
commit
e673faab7c
@ -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<T: Component>(&self) -> Option<NonNull<T>> {
|
||||
@ -111,27 +110,25 @@ impl Archetype {
|
||||
})
|
||||
}
|
||||
|
||||
// TODO: this should be unsafe i think
|
||||
#[allow(missing_docs)]
|
||||
#[inline]
|
||||
pub fn get_with_modified<T: Component>(&self) -> Option<(NonNull<T>, NonNull<bool>)> {
|
||||
pub fn get_with_mutated<T: Component>(&self) -> Option<(NonNull<T>, NonNull<bool>)> {
|
||||
let state = self.state.get(&TypeId::of::<T>())?;
|
||||
Some(unsafe {
|
||||
(
|
||||
NonNull::new_unchecked(
|
||||
(*self.data.get()).as_ptr().add(state.offset).cast::<T>() 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<T: Component>(&self) -> Option<NonNull<bool>> {
|
||||
pub fn get_mutated<T: Component>(&self) -> Option<NonNull<bool>> {
|
||||
let state = self.state.get(&TypeId::of::<T>())?;
|
||||
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<bool>,
|
||||
pub mutated_entities: Vec<bool>,
|
||||
pub added_entities: Vec<bool>,
|
||||
}
|
||||
|
||||
@ -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() {
|
||||
|
@ -126,7 +126,7 @@ impl<'a, T: Component> RefMut<'a, T> {
|
||||
);
|
||||
archetype.borrow_mut::<T>();
|
||||
let modified = archetype
|
||||
.get_modified::<T>()
|
||||
.get_mutated::<T>()
|
||||
.unwrap()
|
||||
.as_ptr()
|
||||
.add(index as usize);
|
||||
|
@ -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};
|
||||
|
||||
|
@ -153,7 +153,7 @@ impl<T: Query> Query for Option<T> {
|
||||
/// 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<T: Component> 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<T> {
|
||||
}
|
||||
unsafe fn get(archetype: &'a Archetype, offset: usize) -> Option<Self> {
|
||||
archetype
|
||||
.get_with_modified::<T>()
|
||||
.map(|(components, modified)| {
|
||||
.get_with_mutated::<T>()
|
||||
.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<T> {
|
||||
#[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<T>;
|
||||
impl<'a, T: Component> Query for Mutated<'a, T> {
|
||||
type Fetch = FetchMutated<T>;
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
pub struct FetchChanged<T>(NonNull<T>, NonNull<bool>);
|
||||
pub struct FetchMutated<T>(NonNull<T>, NonNull<bool>);
|
||||
|
||||
impl<'a, T: Component> Fetch<'a> for FetchChanged<T> {
|
||||
type Item = Changed<'a, T>;
|
||||
impl<'a, T: Component> Fetch<'a> for FetchMutated<T> {
|
||||
type Item = Mutated<'a, T>;
|
||||
|
||||
fn access(archetype: &Archetype) -> Option<Access> {
|
||||
if archetype.has::<T>() {
|
||||
@ -256,16 +256,21 @@ impl<'a, T: Component> Fetch<'a> for FetchChanged<T> {
|
||||
archetype.borrow::<T>();
|
||||
}
|
||||
unsafe fn get(archetype: &'a Archetype, offset: usize) -> Option<Self> {
|
||||
let components = NonNull::new_unchecked(archetype.get::<T>()?.as_ptr().add(offset));
|
||||
let modified = NonNull::new_unchecked(archetype.get_modified::<T>()?.as_ptr().add(offset));
|
||||
Some(Self(components, modified))
|
||||
archetype
|
||||
.get_with_mutated::<T>()
|
||||
.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::<T>();
|
||||
}
|
||||
|
||||
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<T> {
|
||||
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<T> {
|
||||
}
|
||||
unsafe fn get(archetype: &'a Archetype, offset: usize) -> Option<Self> {
|
||||
let components = NonNull::new_unchecked(archetype.get::<T>()?.as_ptr().add(offset));
|
||||
let modified = NonNull::new_unchecked(archetype.get_added::<T>()?.as_ptr().add(offset));
|
||||
Some(Self(components, modified))
|
||||
let added = NonNull::new_unchecked(archetype.get_added::<T>()?.as_ptr().add(offset));
|
||||
Some(Self(components, added))
|
||||
}
|
||||
fn release(archetype: &Archetype) {
|
||||
archetype.release::<T>();
|
||||
@ -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<Entity> {
|
||||
world
|
||||
.query::<(Changed<A>, Entity)>()
|
||||
.query::<(Mutated<A>, Entity)>()
|
||||
.iter()
|
||||
.map(|(_a, e)| e)
|
||||
.collect::<Vec<Entity>>()
|
||||
@ -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<A>, Entity)>()
|
||||
.query::<(Mutated<A>, Entity)>()
|
||||
.iter()
|
||||
.map(|(_a, e)| e)
|
||||
.collect::<Vec<Entity>>()
|
||||
@ -947,10 +952,26 @@ mod tests {
|
||||
}
|
||||
|
||||
let a_b_changed = world
|
||||
.query::<(Changed<A>, Changed<B>, Entity)>()
|
||||
.query::<(Mutated<A>, Mutated<B>, Entity)>()
|
||||
.iter()
|
||||
.map(|(_a, _b, e)| e)
|
||||
.collect::<Vec<Entity>>();
|
||||
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<Entity> {
|
||||
world
|
||||
.query::<(Mutated<A>, Added<A>, Entity)>()
|
||||
.iter()
|
||||
.map(|(_a, _b, e)| e)
|
||||
.collect::<Vec<Entity>>()
|
||||
};
|
||||
assert_eq!(get_changed_or_added(&world), vec![e1]);
|
||||
world.clear_trackers();
|
||||
}
|
||||
}
|
||||
|
@ -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();
|
||||
|
@ -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,
|
||||
};
|
||||
}
|
||||
|
@ -30,14 +30,14 @@ fn button_system(
|
||||
button_materials: Res<ButtonMaterials>,
|
||||
mut click_query: Query<(
|
||||
&Button,
|
||||
Changed<Click>,
|
||||
Mutated<Click>,
|
||||
Option<&Hover>,
|
||||
&mut Handle<ColorMaterial>,
|
||||
&Children,
|
||||
)>,
|
||||
mut hover_query: Query<(
|
||||
&Button,
|
||||
Changed<Hover>,
|
||||
Mutated<Hover>,
|
||||
Option<&Click>,
|
||||
&mut Handle<ColorMaterial>,
|
||||
&Children,
|
||||
|
Loading…
Reference in New Issue
Block a user