mirror of
https://github.com/lisk77/comet.git
synced 2025-12-12 17:18:50 +00:00
fix(ecs): entity deletion is now type correct
This commit is contained in:
parent
607bf94f1e
commit
2a37205c22
4 changed files with 77 additions and 3 deletions
|
|
@ -272,6 +272,17 @@ impl Column {
|
|||
}
|
||||
}
|
||||
|
||||
/// Remove an element without knowing its concrete type. Drops in place.
|
||||
pub fn remove_any(&mut self, index: usize) {
|
||||
if index >= self.data.len() {
|
||||
return;
|
||||
}
|
||||
unsafe {
|
||||
let ptr = self.data.swap_remove_and_forget_unchecked(index);
|
||||
(self.data.drop)(ptr);
|
||||
}
|
||||
}
|
||||
|
||||
/// Overwrites an existing element in place, dropping the previous value.
|
||||
pub fn set<T: 'static>(&mut self, index: usize, item: T) -> Option<()> {
|
||||
assert_eq!(TypeId::of::<T>(), TypeId::of::<T>(), "Type mismatch");
|
||||
|
|
|
|||
|
|
@ -55,4 +55,11 @@ impl ComponentStorage {
|
|||
None
|
||||
}
|
||||
}
|
||||
|
||||
/// Removes all components belonging to the given entity index.
|
||||
pub fn remove_entity(&mut self, index: usize) {
|
||||
for (_, value) in self.iter_mut() {
|
||||
value.remove_any(index);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -75,6 +75,64 @@ impl SparseSet {
|
|||
None
|
||||
}
|
||||
|
||||
/// Removes an element by external index without knowing its type. Returns true if something was removed.
|
||||
pub fn remove_any(&mut self, index: usize) -> bool {
|
||||
if let Some(page_vec) = self
|
||||
.sparse
|
||||
.get(index / self.page_size)
|
||||
.and_then(|x| x.as_ref())
|
||||
{
|
||||
if let Some(sparse_index) = page_vec
|
||||
.get(index % self.page_size)
|
||||
.and_then(|x| x.as_ref())
|
||||
{
|
||||
let dense_index = *sparse_index;
|
||||
let last_dense_index = self.dense.data.len() - 1;
|
||||
|
||||
if dense_index != last_dense_index {
|
||||
if let Some(ext_index) = self.find_external_index(last_dense_index) {
|
||||
if let Some(page_vec) = self
|
||||
.sparse
|
||||
.get_mut(ext_index / self.page_size)
|
||||
.and_then(|x| x.as_mut())
|
||||
{
|
||||
page_vec[ext_index % self.page_size] = Some(dense_index);
|
||||
}
|
||||
}
|
||||
self.dense.swap(dense_index, last_dense_index);
|
||||
}
|
||||
|
||||
if let Some(page_vec) = self
|
||||
.sparse
|
||||
.get_mut(index / self.page_size)
|
||||
.and_then(|x| x.as_mut())
|
||||
{
|
||||
page_vec[index % self.page_size] = None;
|
||||
}
|
||||
|
||||
self.dense.remove_any(dense_index);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
false
|
||||
}
|
||||
|
||||
/// Finds the external index that maps to a given dense index.
|
||||
fn find_external_index(&self, dense_index: usize) -> Option<usize> {
|
||||
for (page_idx, page_opt) in self.sparse.iter().enumerate() {
|
||||
if let Some(page) = page_opt {
|
||||
for (offset, entry) in page.iter().enumerate() {
|
||||
if let Some(idx) = entry {
|
||||
if *idx == dense_index {
|
||||
return Some(page_idx * self.page_size + offset);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
None
|
||||
}
|
||||
|
||||
pub fn get<T: 'static>(&self, index: usize) -> Option<&T> {
|
||||
if let Some(page_vec) = self
|
||||
.sparse
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue