feat(ecs): limited the creation of archetypes to three unique components to lower the creation to polynomial complexity

This commit is contained in:
lisk77 2025-07-26 01:13:23 +02:00
parent 0da5200916
commit d04c706a94
5 changed files with 409 additions and 421 deletions

View file

@ -1,142 +1,109 @@
use crate::Column;
use std::hash::{
Hash,
};
#[derive(Debug, Clone)]
pub struct SparseSet {
sparse: Vec<Option<Vec<Option<usize>>>>,
dense: Column,
page_size: usize
sparse: Vec<Option<Vec<Option<usize>>>>,
dense: Column,
page_size: usize,
}
impl SparseSet {
pub fn new<T: 'static>(capacity: usize, page_size: usize) -> Self {
Self {
sparse: Vec::new(),
dense: Column::new::<T>(capacity),
page_size
}
}
pub fn new<T: 'static>(capacity: usize, page_size: usize) -> Self {
Self {
sparse: Vec::new(),
dense: Column::new::<T>(capacity),
page_size,
}
}
pub fn insert<T: 'static>(&mut self, index: usize, value: T) {
let page = index / self.page_size;
pub fn insert<T: 'static>(&mut self, index: usize, value: T) {
let page = index / self.page_size;
if page >= self.sparse.len() {
self.sparse.resize(page + 1, None);
}
if page >= self.sparse.len() {
self.sparse.resize(page + 1, None);
}
if self.sparse[page].is_none() {
self.sparse[page] = Some(vec![None; self.page_size]);
}
if self.sparse[page].is_none() {
self.sparse[page] = Some(vec![None; self.page_size]);
}
if let Some(page_vec) = &mut self.sparse[page] {
page_vec[index % self.page_size] = Some(self.dense.data.len());
}
if let Some(page_vec) = &mut self.sparse[page] {
page_vec[index % self.page_size] = Some(self.dense.data.len());
}
self.dense.push(value);
}
self.dense.push(value);
}
pub fn remove<T: 'static>(&mut self, index: usize) -> Option<T> {
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_index = self.dense.data.len() - 1;
if dense_index != last_index {
self.dense.swap(dense_index, last_index);
if let Some(page_vec) = self.sparse.get_mut(last_index / self.page_size).and_then(|x| x.as_mut()) {
page_vec[last_index % self.page_size] = Some(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;
}
return self.dense.remove::<T>(last_index);
}
}
None
}
pub fn remove<T: 'static>(&mut self, index: usize) -> Option<T> {
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_index = self.dense.data.len() - 1;
if dense_index != last_index {
self.dense.swap(dense_index, last_index);
if let Some(page_vec) = self
.sparse
.get_mut(last_index / self.page_size)
.and_then(|x| x.as_mut())
{
page_vec[last_index % self.page_size] = Some(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;
}
return self.dense.remove::<T>(last_index);
}
}
None
}
pub fn get<T: 'static>(&self, index: usize) -> Option<&T> {
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()) {
self.dense.get::<T>(*sparse_index)
}
else {
None
}
}
else {
None
}
}
pub fn get<T: 'static>(&self, index: usize) -> Option<&T> {
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())
{
self.dense.get::<T>(*sparse_index)
} else {
None
}
} else {
None
}
}
pub fn get_mut<T: 'static>(&mut self, index: usize) -> Option<&mut T> {
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()) {
self.dense.get_mut::<T>(*sparse_index)
}
else {
None
}
}
else {
None
}
}
pub fn get_mut<T: 'static>(&mut self, index: usize) -> Option<&mut T> {
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())
{
self.dense.get_mut::<T>(*sparse_index)
} else {
None
}
} else {
None
}
}
}
/*#[derive(Debug, Clone)]
pub struct SparseSet {
sparse: Vec<Option<usize>>,
dense: Column,
}
impl SparseSet {
pub fn new<T: 'static>(capacity: usize) -> Self {
Self {
sparse: Vec::new(),
dense: Column::new::<T>(capacity),
}
}
pub fn insert<T: 'static>(&mut self, index: usize, value: T) {
if index >= self.sparse.len() {
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 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
}
}
pub fn get<T: 'static>(&self, index: usize) -> Option<&T> {
match self.sparse.get(index).and_then(|x| x.as_ref()) {
Some(sparse_index) => self.dense.get::<T>(*sparse_index),
None => None,
}
}
pub fn get_mut<T: 'static>(&mut self, index: usize) -> Option<&mut T> {
match self.sparse.get(index).and_then(|x| x.as_ref()) {
Some(sparse_index) => self.dense.get_mut::<T>(*sparse_index),
None => None,
}
}
}*/