mirror of
https://github.com/lisk77/comet.git
synced 2025-10-23 21:38:50 +00:00
fix(ecs): bug concerning adding entities to archetypes that already existed
This commit is contained in:
parent
ff475f1775
commit
7760baeab5
1 changed files with 66 additions and 20 deletions
86
crates/comet_ecs/src/scene.rs
Normal file → Executable file
86
crates/comet_ecs/src/scene.rs
Normal file → Executable file
|
@ -84,7 +84,25 @@ impl Scene {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn create_archetype(&mut self, components: ComponentSet) {
|
fn create_archetype(&mut self, components: ComponentSet) {
|
||||||
self.archetypes.create_archetype(components);
|
self.archetypes.create_archetype(components.clone());
|
||||||
|
|
||||||
|
// Collect entities that match the component set first to avoid borrow checker issues
|
||||||
|
let mut matching_entities = Vec::new();
|
||||||
|
for (entity_id, entity_option) in self.entities.iter().enumerate() {
|
||||||
|
if let Some(_entity) = entity_option {
|
||||||
|
let entity_component_set = self.get_component_set(entity_id);
|
||||||
|
|
||||||
|
// If the entity has all the required components (components is subset of entity's components)
|
||||||
|
if components.is_subset(&entity_component_set) {
|
||||||
|
matching_entities.push(entity_id as u32);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add all matching entities to the archetype
|
||||||
|
for entity_id in matching_entities {
|
||||||
|
self.add_entity_to_archetype(entity_id, components.clone());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn remove_archetype(&mut self, components: ComponentSet) {
|
fn remove_archetype(&mut self, components: ComponentSet) {
|
||||||
|
@ -173,36 +191,64 @@ impl Scene {
|
||||||
/// Adds a component to an entity by its ID and an instance of the component.
|
/// Adds a component to an entity by its ID and an instance of the component.
|
||||||
/// Overwrites the previous component if another component of the same type is added.
|
/// Overwrites the previous component if another component of the same type is added.
|
||||||
pub fn add_component<C: Component + 'static>(&mut self, entity_id: usize, component: C) {
|
pub fn add_component<C: Component + 'static>(&mut self, entity_id: usize, component: C) {
|
||||||
|
let old_component_set = self.get_component_set(entity_id);
|
||||||
|
if !old_component_set.to_vec().is_empty() {
|
||||||
|
self.remove_entity_from_archetype_subsets(entity_id as u32, old_component_set);
|
||||||
|
}
|
||||||
|
|
||||||
self.components.set_component(entity_id, component);
|
self.components.set_component(entity_id, component);
|
||||||
let component_index = self.components.keys().iter_mut().position(|x| *x == C::type_id()).unwrap();
|
let component_index = self.components.keys().iter_mut().position(|x| *x == C::type_id()).unwrap();
|
||||||
|
|
||||||
self.get_entity_mut(entity_id).unwrap().add_component(component_index);
|
self.get_entity_mut(entity_id).unwrap().add_component(component_index);
|
||||||
|
|
||||||
if !self.archetypes.contains_archetype(&self.get_component_set(entity_id)) {
|
let new_component_set = self.get_component_set(entity_id);
|
||||||
self.create_archetype(self.get_component_set(entity_id));
|
|
||||||
let powerset = ComponentSet::powerset(self.get_component_set(entity_id).to_vec());
|
if !self.archetypes.contains_archetype(&new_component_set) {
|
||||||
for set in powerset {
|
self.create_archetype(new_component_set.clone());
|
||||||
let component_set = ComponentSet::from_ids(set.iter().cloned().collect());
|
}
|
||||||
if !self.archetypes.contains_archetype(&component_set) {
|
|
||||||
self.create_archetype(component_set.clone());
|
let powerset = ComponentSet::powerset(new_component_set.to_vec());
|
||||||
self.add_entity_to_archetype(entity_id as u32, component_set);
|
|
||||||
}
|
for subset in powerset {
|
||||||
else if !self.archetypes.archetype_contains_entity(entity_id as u32, &component_set) {
|
let component_set = ComponentSet::from_ids(subset.iter().cloned().collect());
|
||||||
self.add_entity_to_archetype(entity_id as u32, component_set);
|
|
||||||
}
|
if !self.archetypes.contains_archetype(&component_set) {
|
||||||
|
self.create_archetype(component_set.clone());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
self.add_entity_to_archetype(entity_id as u32, component_set);
|
||||||
}
|
}
|
||||||
self.add_entity_to_archetype(entity_id as u32, ComponentSet::from_ids(vec![C::type_id()]));
|
|
||||||
if self.get_component_set(entity_id) != ComponentSet::from_ids(vec![C::type_id()]) {
|
|
||||||
self.add_entity_to_archetype(entity_id as u32, self.get_component_set(entity_id));
|
|
||||||
}
|
|
||||||
info!("Added component {} to entity {}!", C::type_name(), entity_id);
|
info!("Added component {} to entity {}!", C::type_name(), entity_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Removes a component from an entity by its ID.
|
|
||||||
pub fn remove_component<C: Component + 'static>(&mut self, entity_id: usize) {
|
pub fn remove_component<C: Component + 'static>(&mut self, entity_id: usize) {
|
||||||
|
let old_component_set = self.get_component_set(entity_id);
|
||||||
|
self.remove_entity_from_archetype_subsets(entity_id as u32, old_component_set);
|
||||||
|
|
||||||
self.components.remove_component::<C>(entity_id);
|
self.components.remove_component::<C>(entity_id);
|
||||||
self.remove_entity_from_archetype_subsets(entity_id as u32, self.get_component_set(entity_id));
|
let component_index = self.components.keys().iter().position(|x| *x == C::type_id()).unwrap();
|
||||||
|
self.get_entity_mut(entity_id).unwrap().remove_component(component_index);
|
||||||
|
|
||||||
|
let new_component_set = self.get_component_set(entity_id);
|
||||||
|
|
||||||
|
if !new_component_set.to_vec().is_empty() {
|
||||||
|
if !self.archetypes.contains_archetype(&new_component_set) {
|
||||||
|
self.create_archetype(new_component_set.clone());
|
||||||
|
}
|
||||||
|
|
||||||
|
let powerset = ComponentSet::powerset(new_component_set.to_vec());
|
||||||
|
|
||||||
|
for subset in powerset {
|
||||||
|
let component_set = ComponentSet::from_ids(subset.iter().cloned().collect());
|
||||||
|
|
||||||
|
if !self.archetypes.contains_archetype(&component_set) {
|
||||||
|
self.create_archetype(component_set.clone());
|
||||||
|
}
|
||||||
|
|
||||||
|
self.add_entity_to_archetype(entity_id as u32, component_set);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
info!("Removed component {} from entity {}!", C::type_name(), entity_id);
|
info!("Removed component {} from entity {}!", C::type_name(), entity_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue