mirror of
https://github.com/lisk77/comet.git
synced 2025-10-23 13:38:48 +00:00
fix: the ecs will now create all the archetypes for any combination of components that entities have on them
This commit is contained in:
parent
7d351ced62
commit
c1d41323f9
4 changed files with 55 additions and 12 deletions
|
@ -48,4 +48,12 @@ impl Archetypes {
|
|||
pub fn contains_archetype(&self, components: &ComponentSet) -> bool {
|
||||
self.archetypes.contains_key(components)
|
||||
}
|
||||
|
||||
pub fn archetype_contains_entity(&self, entity_id: u32, components: &ComponentSet) -> bool {
|
||||
if self.contains_archetype(components) {
|
||||
let archetype = self.get_archetype(components).unwrap();
|
||||
return archetype.contains(&entity_id);
|
||||
}
|
||||
false
|
||||
}
|
||||
}
|
|
@ -8,11 +8,9 @@ pub struct Entity {
|
|||
|
||||
impl Entity {
|
||||
pub(crate) fn new(id: u32) -> Self {
|
||||
let mut components = BitSet::new();
|
||||
components.insert(0);
|
||||
Self {
|
||||
id,
|
||||
components
|
||||
components: BitSet::new()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -31,4 +29,4 @@ impl Entity {
|
|||
pub(crate) fn get_components(&self) -> &BitSet {
|
||||
&self.components
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,8 +1,6 @@
|
|||
use std::any::TypeId;
|
||||
use crate::{
|
||||
Entity,
|
||||
Component,
|
||||
IdQueue,
|
||||
entity, Component, Entity, IdQueue
|
||||
};
|
||||
use comet_log::*;
|
||||
use comet_structs::*;
|
||||
|
@ -153,18 +151,27 @@ impl Scene {
|
|||
|
||||
/// Registers a new component in the scene.
|
||||
pub fn register_component<C: Component + 'static>(&mut self) {
|
||||
self.components.register_component::<C>(self.entities.len());
|
||||
self.create_archetype(ComponentSet::from_ids(vec![C::type_id()]));
|
||||
info!("Registered component: {}", C::type_name());
|
||||
if !self.components.contains(&C::type_id()) {
|
||||
self.components.register_component::<C>(self.entities.len());
|
||||
self.create_archetype(ComponentSet::from_ids(vec![C::type_id()]));
|
||||
info!("Registered component: {}", C::type_name());
|
||||
return;
|
||||
}
|
||||
warn!("Component {} is already registered!", C::type_name());
|
||||
}
|
||||
|
||||
/// Deregisters a component from the scene.
|
||||
pub fn deregister_component<C: Component + 'static>(&mut self) {
|
||||
self.components.deregister_component::<C>();
|
||||
info!("Deregistered component: {}", C::type_name());
|
||||
if self.components.contains(&C::type_id()) {
|
||||
self.components.deregister_component::<C>();
|
||||
info!("Deregistered component: {}", C::type_name());
|
||||
return;
|
||||
}
|
||||
warn!("Component {} was not registered!", C::type_name());
|
||||
}
|
||||
|
||||
/// 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.
|
||||
pub fn add_component<C: Component + 'static>(&mut self, entity_id: usize, component: C) {
|
||||
self.components.set_component(entity_id, component);
|
||||
let component_index = self.components.keys().iter_mut().position(|x| *x == C::type_id()).unwrap();
|
||||
|
@ -173,11 +180,23 @@ impl Scene {
|
|||
|
||||
if !self.archetypes.contains_archetype(&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());
|
||||
for set in powerset {
|
||||
let component_set = ComponentSet::from_ids(set.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);
|
||||
}
|
||||
else if !self.archetypes.archetype_contains_entity(entity_id as u32, &component_set) {
|
||||
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));
|
||||
}
|
||||
debug!("{:?}", self.archetypes);
|
||||
info!("Added component {} to entity {}!", C::type_name(), entity_id);
|
||||
}
|
||||
|
||||
|
|
|
@ -20,6 +20,24 @@ impl ComponentSet {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn powerset(ids: Vec<TypeId>) -> Vec<HashSet<TypeId>> {
|
||||
let n = ids.len();
|
||||
let mut subsets: Vec<HashSet<TypeId>> = Vec::with_capacity(1 << n);
|
||||
|
||||
for mask in 0..(1 << n) {
|
||||
let mut subset = HashSet::new();
|
||||
for i in 0..n {
|
||||
if (mask & (1 << i)) != 0 {
|
||||
subset.insert(ids[i].clone());
|
||||
}
|
||||
}
|
||||
subsets.push(subset);
|
||||
}
|
||||
subsets.remove(0);
|
||||
|
||||
subsets
|
||||
}
|
||||
|
||||
pub fn is_subset(&self, other: &ComponentSet) -> bool {
|
||||
self.set.is_subset(&other.set)
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue