Skip to content

Commit

Permalink
Delete components after killing entities to avoid clearing components…
Browse files Browse the repository at this point in the history
… on an

entity with the wrong generation.

Also removed some spots that redudantly try to ensure that `MetaTable<dyn
AnyStorage>>` is available since it is always inserted in `WorldExt::new`.
  • Loading branch information
Imberflur committed Jun 6, 2023
1 parent 7b03fca commit 635ee21
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 16 deletions.
18 changes: 11 additions & 7 deletions src/world/entity.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,12 +60,16 @@ pub(crate) struct Allocator {

impl Allocator {
/// Kills a list of entities immediately.
pub fn kill(&mut self, delete: &[Entity]) -> Result<(), WrongGeneration> {
for &entity in delete {
///
/// If an entity with an outdated generation is encountered, the index of
/// that entity within the provided slice is returned (entities after this
/// index are not killed).
pub fn kill(&mut self, delete: &[Entity]) -> Result<(), (WrongGeneration, usize)> {
for (index, &entity) in delete.iter().enumerate() {
let id = entity.id() as usize;

if !self.is_alive(entity) {
return self.del_err(entity);
return Err((self.del_err(entity), index));
}

self.alive.remove(entity.id());
Expand All @@ -89,22 +93,22 @@ impl Allocator {
/// maintained).
pub fn kill_atomic(&self, e: Entity) -> Result<(), WrongGeneration> {
if !self.is_alive(e) {
return self.del_err(e);
return Err(self.del_err(e));
}

self.killed.add_atomic(e.id());

Ok(())
}

pub(crate) fn del_err(&self, e: Entity) -> Result<(), WrongGeneration> {
Err(WrongGeneration {
pub(crate) fn del_err(&self, e: Entity) -> WrongGeneration {
WrongGeneration {
action: "delete",
actual_gen: self.generations[e.id() as usize]
.0
.unwrap_or_else(Generation::one),
entity: e,
})
}
}

/// Return `true` if the entity is alive.
Expand Down
24 changes: 15 additions & 9 deletions src/world/world_ext.rs
Original file line number Diff line number Diff line change
Expand Up @@ -259,7 +259,11 @@ pub trait WorldExt {
fn delete_entity(&mut self, entity: Entity) -> Result<(), WrongGeneration>;

/// Deletes the specified entities and their components.
fn delete_entities(&mut self, delete: &[Entity]) -> Result<(), WrongGeneration>;
///
/// If an entity with an outdated generation is encountered, the index of
/// that entity within the provided slice is returned (entities after this
/// index are not deleted).
fn delete_entities(&mut self, delete: &[Entity]) -> Result<(), (WrongGeneration, usize)>;

/// Deletes all entities and their components.
fn delete_all(&mut self);
Expand Down Expand Up @@ -315,8 +319,6 @@ impl WorldExt for World {
{
self.entry()
.or_insert_with(move || MaskedStorage::<T>::new(storage()));
self.entry::<MetaTable<dyn AnyStorage>>()
.or_insert_with(Default::default);
self.fetch_mut::<MetaTable<dyn AnyStorage>>()
.register(&*self.fetch::<MaskedStorage<T>>());
}
Expand Down Expand Up @@ -369,12 +371,18 @@ impl WorldExt for World {

fn delete_entity(&mut self, entity: Entity) -> Result<(), WrongGeneration> {
self.delete_entities(&[entity])
.map_err(|(wrong_gen, _)| wrong_gen)
}

fn delete_entities(&mut self, delete: &[Entity]) -> Result<(), WrongGeneration> {
self.delete_components(delete);

self.entities_mut().alloc.kill(delete)
fn delete_entities(&mut self, delete: &[Entity]) -> Result<(), (WrongGeneration, usize)> {
let res = self.entities_mut().alloc.kill(delete);
if let Err((wrong_gen, failed_index)) = res {
self.delete_components(&delete[..failed_index]);
Err((wrong_gen, failed_index))
} else {
self.delete_components(delete);
Ok(())
}
}

fn delete_all(&mut self) {
Expand Down Expand Up @@ -406,8 +414,6 @@ impl WorldExt for World {
}

fn delete_components(&mut self, delete: &[Entity]) {
self.entry::<MetaTable<dyn AnyStorage>>()
.or_insert_with(Default::default);
for storage in self.fetch_mut::<MetaTable<dyn AnyStorage>>().iter_mut(self) {
storage.drop(delete);
}
Expand Down

0 comments on commit 635ee21

Please sign in to comment.