mirror of
https://github.com/bevyengine/bevy
synced 2024-11-22 20:53:53 +00:00
Add mutated state when inserting an already existing component (#404)
Add mutated state when inserting an already existing component
This commit is contained in:
parent
0db9e9494d
commit
5bd6deb974
4 changed files with 62 additions and 17 deletions
|
@ -406,11 +406,15 @@ impl Archetype {
|
|||
size: usize,
|
||||
index: usize,
|
||||
added: bool,
|
||||
mutated: bool,
|
||||
) {
|
||||
let state = self.state.get_mut(&ty).unwrap();
|
||||
if added {
|
||||
state.added_entities[index] = true;
|
||||
}
|
||||
if mutated {
|
||||
state.mutated_entities[index] = true;
|
||||
}
|
||||
let ptr = (*self.data.get())
|
||||
.as_ptr()
|
||||
.add(state.offset + size * index)
|
||||
|
|
|
@ -900,24 +900,24 @@ mod tests {
|
|||
}
|
||||
}
|
||||
|
||||
fn get_changed_a(world: &mut World) -> Vec<Entity> {
|
||||
fn get_mutated_a(world: &mut World) -> Vec<Entity> {
|
||||
world
|
||||
.query_mut::<(Mutated<A>, Entity)>()
|
||||
.map(|(_a, e)| e)
|
||||
.collect::<Vec<Entity>>()
|
||||
};
|
||||
|
||||
assert_eq!(get_changed_a(&mut world), vec![e1, e3]);
|
||||
assert_eq!(get_mutated_a(&mut world), vec![e1, e3]);
|
||||
|
||||
// ensure changing an entity's archetypes also moves its mutated state
|
||||
world.insert(e1, (C,)).unwrap();
|
||||
|
||||
assert_eq!(get_changed_a(&mut world), vec![e3, e1], "changed entities list should not change (although the order will due to archetype moves)");
|
||||
assert_eq!(get_mutated_a(&mut 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 mutated state
|
||||
world.insert(e1, (A(0), B)).unwrap();
|
||||
assert_eq!(
|
||||
get_changed_a(&mut world),
|
||||
get_mutated_a(&mut world),
|
||||
vec![e3, e1],
|
||||
"changed entities list should not change"
|
||||
);
|
||||
|
@ -925,7 +925,7 @@ mod tests {
|
|||
// removing an unchanged entity should not change mutated state
|
||||
world.despawn(e2).unwrap();
|
||||
assert_eq!(
|
||||
get_changed_a(&mut world),
|
||||
get_mutated_a(&mut world),
|
||||
vec![e3, e1],
|
||||
"changed entities list should not change"
|
||||
);
|
||||
|
@ -933,7 +933,7 @@ mod tests {
|
|||
// removing a changed entity should remove it from enumeration
|
||||
world.despawn(e1).unwrap();
|
||||
assert_eq!(
|
||||
get_changed_a(&mut world),
|
||||
get_mutated_a(&mut world),
|
||||
vec![e3],
|
||||
"e1 should no longer be returned"
|
||||
);
|
||||
|
@ -943,8 +943,46 @@ mod tests {
|
|||
assert!(world
|
||||
.query_mut::<(Mutated<A>, Entity)>()
|
||||
.map(|(_a, e)| e)
|
||||
.collect::<Vec<Entity>>()
|
||||
.is_empty());
|
||||
.next()
|
||||
.is_none());
|
||||
|
||||
let e4 = world.spawn(());
|
||||
|
||||
world.insert_one(e4, A(0)).unwrap();
|
||||
assert!(get_mutated_a(&mut world).is_empty());
|
||||
|
||||
world.insert_one(e4, A(1)).unwrap();
|
||||
assert_eq!(get_mutated_a(&mut world), vec![e4]);
|
||||
|
||||
world.clear_trackers();
|
||||
|
||||
// ensure inserting multiple components set mutated state for
|
||||
// already existing components and set added state for
|
||||
// non existing components even when changing archetype.
|
||||
world.insert(e4, (A(0), B(0))).unwrap();
|
||||
|
||||
let added_a = world
|
||||
.query::<(Added<A>, Entity)>()
|
||||
.iter()
|
||||
.map(|(_, e)| e)
|
||||
.next();
|
||||
assert!(added_a.is_none());
|
||||
|
||||
assert_eq!(get_mutated_a(&mut world), vec![e4]);
|
||||
|
||||
let added_b = world
|
||||
.query::<(Added<B>, Entity)>()
|
||||
.iter()
|
||||
.map(|(_, e)| e)
|
||||
.next();
|
||||
assert!(added_b.is_some());
|
||||
|
||||
let mutated_b = world
|
||||
.query_mut::<(Mutated<B>, Entity)>()
|
||||
.iter()
|
||||
.map(|(_, e)| e)
|
||||
.next();
|
||||
assert!(mutated_b.is_none());
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -962,11 +1000,11 @@ mod tests {
|
|||
b.0 += 1;
|
||||
}
|
||||
|
||||
let a_b_changed = world
|
||||
let a_b_mutated = world
|
||||
.query_mut::<(Mutated<A>, Mutated<B>, Entity)>()
|
||||
.map(|(_a, _b, e)| e)
|
||||
.collect::<Vec<Entity>>();
|
||||
assert_eq!(a_b_changed, vec![e2]);
|
||||
assert_eq!(a_b_mutated, vec![e2]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -986,12 +1024,12 @@ mod tests {
|
|||
b.0 += 1;
|
||||
}
|
||||
|
||||
let a_b_changed = world
|
||||
let a_b_mutated = world
|
||||
.query_mut::<(Or<(Mutated<A>, Mutated<B>)>, Entity)>()
|
||||
.map(|((_a, _b), e)| e)
|
||||
.collect::<Vec<Entity>>();
|
||||
// e1 has mutated A, e3 has mutated B, e2 has mutated A and B, _e4 has no mutated component
|
||||
assert_eq!(a_b_changed, vec![e1, e2, e3]);
|
||||
assert_eq!(a_b_mutated, vec![e1, e2, e3]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
|
@ -102,7 +102,7 @@ impl World {
|
|||
unsafe {
|
||||
let index = archetype.allocate(entity);
|
||||
components.put(|ptr, ty, size| {
|
||||
archetype.put_dynamic(ptr, ty, size, index, true);
|
||||
archetype.put_dynamic(ptr, ty, size, index, true, false);
|
||||
true
|
||||
});
|
||||
self.entities.meta[entity.id as usize].location = Location {
|
||||
|
@ -530,7 +530,7 @@ impl World {
|
|||
// Update components in the current archetype
|
||||
let arch = &mut self.archetypes[loc.archetype as usize];
|
||||
components.put(|ptr, ty, size| {
|
||||
arch.put_dynamic(ptr, ty, size, loc.index, false);
|
||||
arch.put_dynamic(ptr, ty, size, loc.index, false, true);
|
||||
true
|
||||
});
|
||||
return Ok(());
|
||||
|
@ -547,7 +547,7 @@ impl World {
|
|||
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_mutated| {
|
||||
target_arch.put_dynamic(ptr, ty, size, target_index, false);
|
||||
target_arch.put_dynamic(ptr, ty, size, target_index, false, false);
|
||||
let type_state = target_arch.get_type_state_mut(ty).unwrap();
|
||||
*type_state.added().as_ptr().add(target_index) = is_added;
|
||||
*type_state.mutated().as_ptr().add(target_index) = is_mutated;
|
||||
|
@ -557,7 +557,8 @@ impl World {
|
|||
}
|
||||
|
||||
components.put(|ptr, ty, size| {
|
||||
target_arch.put_dynamic(ptr, ty, size, target_index, true);
|
||||
let had_component = source_arch.has_dynamic(ty);
|
||||
target_arch.put_dynamic(ptr, ty, size, target_index, !had_component, had_component);
|
||||
true
|
||||
});
|
||||
}
|
||||
|
@ -1003,7 +1004,8 @@ where
|
|||
unsafe {
|
||||
let index = self.archetype.allocate(entity);
|
||||
components.put(|ptr, ty, size| {
|
||||
self.archetype.put_dynamic(ptr, ty, size, index, true);
|
||||
self.archetype
|
||||
.put_dynamic(ptr, ty, size, index, true, false);
|
||||
true
|
||||
});
|
||||
self.entities.meta[entity.id as usize].location = Location {
|
||||
|
|
|
@ -231,6 +231,7 @@ impl Resources {
|
|||
core::mem::size_of::<T>(),
|
||||
index,
|
||||
added,
|
||||
!added,
|
||||
);
|
||||
std::mem::forget(resource);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue