mirror of
https://github.com/lisk77/comet.git
synced 2025-10-23 21:38:50 +00:00
fix: weird bug in the ComponentStorage
where due to the implementation of the SparseSet
, components weren't correctly managed
This commit is contained in:
parent
cae678747f
commit
fae4e852fd
4 changed files with 33 additions and 51 deletions
|
@ -147,8 +147,8 @@ impl App {
|
|||
self.input_manager.key_released(key)
|
||||
}
|
||||
|
||||
pub fn new_entity(&mut self) -> u32 {
|
||||
self.world.new_entity()
|
||||
pub fn new_entity(&mut self) -> usize{
|
||||
self.world.new_entity() as usize
|
||||
}
|
||||
|
||||
pub fn delete_entity(&mut self, entity_id: usize) {
|
||||
|
|
|
@ -281,7 +281,7 @@ impl Column {
|
|||
}
|
||||
}
|
||||
|
||||
fn swap(&mut self, index1: usize, index2: usize) {
|
||||
pub fn swap(&mut self, index1: usize, index2: usize) {
|
||||
assert!(index1 < self.data.len() && index2 < self.data.len(), "Index out of bounds");
|
||||
|
||||
unsafe {
|
||||
|
|
|
@ -26,7 +26,7 @@ impl ComponentStorage {
|
|||
|
||||
pub fn set_component<T: 'static>(&mut self, index: usize, element: T) {
|
||||
if let Some(sparse_set) = self.get_mut(&TypeId::of::<T>()) {
|
||||
sparse_set.set(index, element);
|
||||
sparse_set.insert(index, element);
|
||||
}
|
||||
else {
|
||||
error!("Component {:?} is not registered", TypeId::of::<T>());
|
||||
|
|
|
@ -1,77 +1,59 @@
|
|||
use crate::Column;
|
||||
use std::hash::{
|
||||
Hash,
|
||||
Hasher
|
||||
};
|
||||
use std::ptr;
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct SparseSet {
|
||||
sparse: Vec<Option<usize>>,
|
||||
dense: Column,
|
||||
len: usize
|
||||
pub sparse: Vec<Option<usize>>,
|
||||
pub dense: Column,
|
||||
}
|
||||
|
||||
impl SparseSet {
|
||||
pub fn new<T: 'static>(capacity: usize) -> Self {
|
||||
Self {
|
||||
sparse: Vec::with_capacity(capacity),
|
||||
sparse: Vec::new(),
|
||||
dense: Column::new::<T>(capacity),
|
||||
len: 0
|
||||
}
|
||||
}
|
||||
|
||||
pub fn set<T: 'static>(&mut self, index: usize, element: T) {
|
||||
pub fn insert<T: 'static>(&mut self, index: usize, value: T) {
|
||||
if index >= self.sparse.len() {
|
||||
self.sparse.resize_with(index + 1, || None);
|
||||
}
|
||||
|
||||
if let Some(column_index) = self.sparse[index] {
|
||||
// Explicitly drop the existing component before replacing it
|
||||
unsafe {
|
||||
let existing_ptr = self.dense.data.get_unchecked_mut(column_index) as *mut T;
|
||||
ptr::drop_in_place(existing_ptr);
|
||||
ptr::write(existing_ptr, element);
|
||||
}
|
||||
} else {
|
||||
let column_index = unsafe { self.dense.data.push_uninit() };
|
||||
unsafe {
|
||||
self.dense.data.initialize_unchecked(column_index, &element as *const T as *mut u8);
|
||||
}
|
||||
self.sparse[index] = Some(column_index);
|
||||
self.len += 1;
|
||||
self.sparse.resize(index + 1, None);
|
||||
}
|
||||
self.sparse[index] = Some(self.dense.data.len());
|
||||
self.dense.push(value);
|
||||
}
|
||||
|
||||
pub fn remove<T: 'static>(&mut self, index: usize) -> Option<T> {
|
||||
if index >= self.sparse.len() || self.sparse[index] == None {
|
||||
return None;
|
||||
pub fn remove<T: 'static>(&mut self, index: usize) -> Option<T>{
|
||||
if let Some(sparse_index) = self.sparse.get(index).and_then(|x| x.as_ref()) {
|
||||
let dense_index = *sparse_index;
|
||||
let last_index = self.dense.data.len() - 1;
|
||||
if dense_index != last_index {
|
||||
self.dense.swap(dense_index, last_index);
|
||||
if let Some(sparse) = self.sparse.get_mut(last_index) {
|
||||
*sparse = Some(dense_index);
|
||||
}
|
||||
}
|
||||
self.sparse[index] = None;
|
||||
self.dense.remove::<T>(last_index)
|
||||
}
|
||||
else {
|
||||
None
|
||||
}
|
||||
|
||||
let column_index = self.sparse[index];
|
||||
let element = unsafe {
|
||||
self.dense.data.swap_remove_and_forget_unchecked(column_index.unwrap())
|
||||
};
|
||||
|
||||
self.sparse[index] = None;
|
||||
self.len -= 1;
|
||||
|
||||
Some(unsafe { ptr::read(element as *const T) })
|
||||
}
|
||||
|
||||
pub fn get<T: 'static>(&self, index: usize) -> Option<&T> {
|
||||
if index >= self.sparse.len() || self.sparse[index] == None {
|
||||
return None;
|
||||
match self.sparse.get(index).and_then(|x| x.as_ref()) {
|
||||
Some(sparse_index) => self.dense.get::<T>(*sparse_index),
|
||||
None => None,
|
||||
}
|
||||
|
||||
self.dense.get::<T>(index)
|
||||
}
|
||||
|
||||
pub fn get_mut<T: 'static>(&mut self, index: usize) -> Option<&mut T> {
|
||||
if index >= self.sparse.len() || self.sparse[index] == None {
|
||||
return None;
|
||||
match self.sparse.get(index).and_then(|x| x.as_ref()) {
|
||||
Some(sparse_index) => self.dense.get_mut::<T>(*sparse_index),
|
||||
None => None,
|
||||
}
|
||||
|
||||
self.dense.get_mut::<T>(index)
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue