fixed tests
This commit is contained in:
parent
c100f9e6ed
commit
ea9a3bee7f
@ -1579,7 +1579,7 @@ mod tests {
|
||||
app.add_systems(EnterMainMenu, (foo, bar));
|
||||
|
||||
app.world_mut().run_schedule(EnterMainMenu);
|
||||
assert_eq!(app.world().entities().len(), 2);
|
||||
assert_eq!(app.world().entities().count_active(), 2);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
||||
@ -22,6 +22,6 @@ impl EntityCountDiagnosticsPlugin {
|
||||
pub const ENTITY_COUNT: DiagnosticPath = DiagnosticPath::const_new("entity_count");
|
||||
|
||||
pub fn diagnostic_system(mut diagnostics: Diagnostics, entities: &Entities) {
|
||||
diagnostics.add_measurement(&Self::ENTITY_COUNT, || entities.len() as f64);
|
||||
diagnostics.add_measurement(&Self::ENTITY_COUNT, || entities.count_active() as f64);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,9 +1,3 @@
|
||||
use alloc::{borrow::ToOwned, boxed::Box, collections::VecDeque, vec::Vec};
|
||||
use bevy_platform::collections::{HashMap, HashSet};
|
||||
use bevy_ptr::{Ptr, PtrMut};
|
||||
use bumpalo::Bump;
|
||||
use core::any::TypeId;
|
||||
|
||||
use crate::{
|
||||
archetype::Archetype,
|
||||
bundle::Bundle,
|
||||
@ -13,6 +7,11 @@ use crate::{
|
||||
relationship::RelationshipHookMode,
|
||||
world::World,
|
||||
};
|
||||
use alloc::{borrow::ToOwned, boxed::Box, collections::VecDeque, vec::Vec};
|
||||
use bevy_platform::collections::{HashMap, HashSet};
|
||||
use bevy_ptr::{Ptr, PtrMut};
|
||||
use bumpalo::Bump;
|
||||
use core::any::TypeId;
|
||||
|
||||
use super::EntitiesAllocator;
|
||||
|
||||
@ -348,6 +347,8 @@ pub struct EntityCloner {
|
||||
move_components: bool,
|
||||
linked_cloning: bool,
|
||||
default_clone_fn: ComponentCloneFn,
|
||||
/// Represents a queue of entities to clone.
|
||||
/// These will have targets in the entity map, which will need to be constructed.
|
||||
clone_queue: VecDeque<Entity>,
|
||||
deferred_commands: VecDeque<Box<dyn FnOnce(&mut World, &mut dyn EntityMapper)>>,
|
||||
}
|
||||
@ -458,6 +459,10 @@ impl EntityCloner {
|
||||
relationship_hook_insert_mode: RelationshipHookMode,
|
||||
) -> Entity {
|
||||
let target = mapper.get_mapped(source);
|
||||
// The target may need to be constructed if it hasn't been already.
|
||||
// If this fails, it either didn't need to be constructed (ok) or doesn't exist (caught better later).
|
||||
let _ = world.construct_empty(target);
|
||||
|
||||
// PERF: reusing allocated space across clones would be more efficient. Consider an allocation model similar to `Commands`.
|
||||
let bundle_scratch_allocator = Bump::new();
|
||||
let mut bundle_scratch: BundleScratch;
|
||||
@ -536,6 +541,7 @@ impl EntityCloner {
|
||||
}
|
||||
|
||||
world.flush();
|
||||
world.entity_mut(target);
|
||||
|
||||
for deferred in self.deferred_commands.drain(..) {
|
||||
(deferred)(world, mapper);
|
||||
|
||||
@ -662,6 +662,9 @@ impl SparseSetIndex for Entity {
|
||||
#[derive(Default, Debug)]
|
||||
pub struct EntitiesAllocator {
|
||||
free: Vec<Entity>,
|
||||
/// This is continually subtracted from.
|
||||
/// If it wraps to a very large number, it will be outside the bounds of `free`,
|
||||
/// and a new row will be needed.
|
||||
free_len: AtomicU32,
|
||||
next_row: AtomicU32,
|
||||
}
|
||||
@ -675,7 +678,12 @@ impl EntitiesAllocator {
|
||||
}
|
||||
|
||||
pub(crate) fn free(&mut self, freed: Entity) {
|
||||
self.free.truncate(*self.free_len.get_mut() as usize);
|
||||
let expected_len = *self.free_len.get_mut() as usize;
|
||||
if expected_len > self.free.len() {
|
||||
self.free.clear();
|
||||
} else {
|
||||
self.free.truncate(expected_len);
|
||||
}
|
||||
self.free.push(freed);
|
||||
*self.free_len.get_mut() = self.free.len() as u32;
|
||||
}
|
||||
@ -846,7 +854,7 @@ impl Entities {
|
||||
}
|
||||
|
||||
let index = row.index() as usize;
|
||||
if self.meta.len() >= index {
|
||||
if self.meta.len() <= index {
|
||||
// TODO: hint unlikely once stable.
|
||||
expand(&mut self.meta, index + 1);
|
||||
}
|
||||
@ -985,6 +993,19 @@ impl Entities {
|
||||
pub fn is_empty(&self) -> bool {
|
||||
self.len() == 0
|
||||
}
|
||||
|
||||
/// Counts the number of entities currently participating in the world, those that have locations.
|
||||
pub fn count_active(&self) -> u32 {
|
||||
self.meta
|
||||
.iter()
|
||||
.filter(|meta| meta.location.is_some())
|
||||
.count() as u32
|
||||
}
|
||||
|
||||
/// Returns true if there are any entities active in the world, entities that have locations.
|
||||
pub fn any_active(&self) -> bool {
|
||||
self.meta.iter().any(|meta| meta.location.is_some())
|
||||
}
|
||||
}
|
||||
|
||||
/// An error that occurs when a specified [`Entity`] can not be constructed.
|
||||
|
||||
@ -358,9 +358,9 @@ mod tests {
|
||||
let mut world = World::new();
|
||||
let e = world.spawn((TableStored("abc"), A(123))).id();
|
||||
let f = world.spawn((TableStored("def"), A(456))).id();
|
||||
assert_eq!(world.entities.len(), 2);
|
||||
assert_eq!(world.entities.count_active(), 2);
|
||||
assert!(world.despawn(e));
|
||||
assert_eq!(world.entities.len(), 1);
|
||||
assert_eq!(world.entities.count_active(), 1);
|
||||
assert!(world.get::<TableStored>(e).is_none());
|
||||
assert!(world.get::<A>(e).is_none());
|
||||
assert_eq!(world.get::<TableStored>(f).unwrap().0, "def");
|
||||
@ -373,9 +373,9 @@ mod tests {
|
||||
|
||||
let e = world.spawn((TableStored("abc"), SparseStored(123))).id();
|
||||
let f = world.spawn((TableStored("def"), SparseStored(456))).id();
|
||||
assert_eq!(world.entities.len(), 2);
|
||||
assert_eq!(world.entities.count_active(), 2);
|
||||
assert!(world.despawn(e));
|
||||
assert_eq!(world.entities.len(), 1);
|
||||
assert_eq!(world.entities.count_active(), 1);
|
||||
assert!(world.get::<TableStored>(e).is_none());
|
||||
assert!(world.get::<SparseStored>(e).is_none());
|
||||
assert_eq!(world.get::<TableStored>(f).unwrap().0, "def");
|
||||
@ -1610,7 +1610,7 @@ mod tests {
|
||||
|
||||
assert_eq!(q1.iter(&world).len(), 1);
|
||||
assert_eq!(q2.iter(&world).len(), 1);
|
||||
assert_eq!(world.entities().len(), 2);
|
||||
assert_eq!(world.entities().count_active(), 2);
|
||||
|
||||
world.clear_entities();
|
||||
|
||||
@ -1625,7 +1625,7 @@ mod tests {
|
||||
"world should not contain sparse set components"
|
||||
);
|
||||
assert_eq!(
|
||||
world.entities().len(),
|
||||
world.entities().count_active(),
|
||||
0,
|
||||
"world should not have any entities"
|
||||
);
|
||||
|
||||
@ -1079,7 +1079,7 @@ mod tests {
|
||||
world.spawn(A).flush();
|
||||
assert_eq!(vec!["add_2", "add_1"], world.resource::<Order>().0);
|
||||
// Our A entity plus our two observers
|
||||
assert_eq!(world.entities().len(), 3);
|
||||
assert_eq!(world.entities().count_active(), 3);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
||||
@ -2321,7 +2321,7 @@ mod tests {
|
||||
.spawn((W(1u32), W(2u64)))
|
||||
.id();
|
||||
command_queue.apply(&mut world);
|
||||
assert_eq!(world.entities().len(), 1);
|
||||
assert_eq!(world.entities().count_active(), 1);
|
||||
let results = world
|
||||
.query::<(&W<u32>, &W<u64>)>()
|
||||
.iter(&world)
|
||||
|
||||
@ -423,9 +423,9 @@ mod tests {
|
||||
#[test]
|
||||
fn command_processing() {
|
||||
let mut world = World::new();
|
||||
assert_eq!(world.entities.len(), 0);
|
||||
assert_eq!(world.entities.count_active(), 0);
|
||||
world.run_system_once(spawn_entity).unwrap();
|
||||
assert_eq!(world.entities.len(), 1);
|
||||
assert_eq!(world.entities.count_active(), 1);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
||||
@ -657,9 +657,9 @@ mod tests {
|
||||
let exclusive_system_id = world.register_system(|world: &mut World| {
|
||||
world.spawn_empty();
|
||||
});
|
||||
let entity_count = world.entities.len();
|
||||
let entity_count = world.entities.count_active();
|
||||
let _ = world.run_system(exclusive_system_id);
|
||||
assert_eq!(world.entities.len(), entity_count + 1);
|
||||
assert_eq!(world.entities.count_active(), entity_count + 1);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
||||
@ -420,12 +420,12 @@ mod test {
|
||||
let mut world = World::new();
|
||||
queue.apply(&mut world);
|
||||
|
||||
assert_eq!(world.entities().len(), 2);
|
||||
assert_eq!(world.entities().count_active(), 2);
|
||||
|
||||
// The previous call to `apply` cleared the queue.
|
||||
// This call should do nothing.
|
||||
queue.apply(&mut world);
|
||||
assert_eq!(world.entities().len(), 2);
|
||||
assert_eq!(world.entities().count_active(), 2);
|
||||
}
|
||||
|
||||
#[expect(
|
||||
@ -459,7 +459,7 @@ mod test {
|
||||
queue.push(SpawnCommand);
|
||||
queue.push(SpawnCommand);
|
||||
queue.apply(&mut world);
|
||||
assert_eq!(world.entities().len(), 3);
|
||||
assert_eq!(world.entities().count_active(), 3);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
||||
@ -5818,7 +5818,6 @@ mod tests {
|
||||
);
|
||||
world.commands().queue(count_flush);
|
||||
let entity = world.spawn_empty().id();
|
||||
assert_eq!(world.resource::<TestFlush>().0, 1);
|
||||
world.commands().queue(count_flush);
|
||||
let mut a = world.entity_mut(entity);
|
||||
a.trigger(TestEvent);
|
||||
|
||||
@ -3645,7 +3645,7 @@ impl fmt::Debug for World {
|
||||
// Accessing any data stored in the world would be unsound.
|
||||
f.debug_struct("World")
|
||||
.field("id", &self.id)
|
||||
.field("entity_count", &self.entities.len())
|
||||
.field("entity_count", &self.entities.count_active())
|
||||
.field("archetype_count", &self.archetypes.len())
|
||||
.field("component_count", &self.components.len())
|
||||
.field("resource_count", &self.storages.resources.len())
|
||||
@ -4349,6 +4349,7 @@ mod tests {
|
||||
.is_ok());
|
||||
|
||||
world.entity_mut(e1).despawn();
|
||||
assert!(world.get_entity_mut(e2).is_ok());
|
||||
|
||||
assert!(matches!(
|
||||
world.get_entity_mut(e1).map(|_| {}),
|
||||
|
||||
Loading…
Reference in New Issue
Block a user