refactor(ecs): speedup for archetypes

This commit is contained in:
lisk77 2025-11-25 23:40:26 +01:00
parent 2a37205c22
commit 64bf88c229
2 changed files with 14 additions and 10 deletions

View file

@ -1,9 +1,9 @@
use comet_structs::ComponentSet; use comet_structs::ComponentSet;
use std::collections::{HashMap, HashSet}; use std::collections::HashMap;
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct Archetypes { pub struct Archetypes {
archetypes: HashMap<ComponentSet, HashSet<u32>>, archetypes: HashMap<ComponentSet, Vec<u32>>,
} }
impl Archetypes { impl Archetypes {
@ -13,27 +13,31 @@ impl Archetypes {
} }
} }
pub fn component_sets(&self) -> Vec<ComponentSet> { pub fn component_sets(&self) -> impl Iterator<Item = &ComponentSet> {
self.archetypes.keys().cloned().collect() self.archetypes.keys()
} }
pub fn create_archetype(&mut self, components: ComponentSet) { pub fn create_archetype(&mut self, components: ComponentSet) {
self.archetypes.insert(components, HashSet::new()); self.archetypes.entry(components).or_insert_with(Vec::new);
} }
pub fn get_archetype(&self, components: &ComponentSet) -> Option<&HashSet<u32>> { pub fn get_archetype(&self, components: &ComponentSet) -> Option<&Vec<u32>> {
self.archetypes.get(components) self.archetypes.get(components)
} }
pub fn add_entity_to_archetype(&mut self, components: &ComponentSet, entity: u32) { pub fn add_entity_to_archetype(&mut self, components: &ComponentSet, entity: u32) {
if let Some(archetype) = self.archetypes.get_mut(components) { if let Some(archetype) = self.archetypes.get_mut(components) {
archetype.insert(entity); if !archetype.iter().any(|&e| e == entity) {
archetype.push(entity);
}
} }
} }
pub fn remove_entity_from_archetype(&mut self, components: &ComponentSet, entity: u32) { pub fn remove_entity_from_archetype(&mut self, components: &ComponentSet, entity: u32) {
if let Some(archetype) = self.archetypes.get_mut(components) { if let Some(archetype) = self.archetypes.get_mut(components) {
archetype.retain(|&id| id != entity); if let Some(pos) = archetype.iter().position(|&id| id == entity) {
archetype.swap_remove(pos);
}
} }
} }

View file

@ -319,8 +319,8 @@ impl Scene {
let mut result = Vec::new(); let mut result = Vec::new();
for archetype_set in self.archetypes.component_sets() { for archetype_set in self.archetypes.component_sets() {
if component_set.is_subset(&archetype_set) { if component_set.is_subset(archetype_set) {
if let Some(entities) = self.archetypes.get_archetype(&archetype_set) { if let Some(entities) = self.archetypes.get_archetype(archetype_set) {
for index in entities.iter() { for index in entities.iter() {
if let Some(gen) = self.generations.get(*index as usize) { if let Some(gen) = self.generations.get(*index as usize) {
if self if self