diff --git a/crates/comet_app/src/app.rs b/crates/comet_app/src/app.rs index b998b7b..083aa48 100755 --- a/crates/comet_app/src/app.rs +++ b/crates/comet_app/src/app.rs @@ -1,7 +1,5 @@ use comet_colors::{Color as ColorTrait, LinearRgba}; -use comet_ecs::{ - Camera2D, Component, Entity, EntityId, Render2D, Scene, Text, Transform2D, Transform3D, -}; +use comet_ecs::{Camera2D, Component, Entity, Render2D, Scene, Text, Transform2D, Transform3D}; use comet_input::keyboard::Key; use comet_log::*; use comet_renderer::renderer::Renderer; @@ -165,22 +163,22 @@ impl App { } /// Creates a new entity and returns its ID. - pub fn new_entity(&mut self) -> EntityId { - self.scene.new_entity() + pub fn new_entity(&mut self) -> usize { + self.scene.new_entity() as usize } /// Deletes an entity by its ID. - pub fn delete_entity(&mut self, entity_id: EntityId) { + pub fn delete_entity(&mut self, entity_id: usize) { self.scene.delete_entity(entity_id) } /// Gets an immutable reference to an entity by its ID. - pub fn get_entity(&self, entity_id: EntityId) -> Option<&Entity> { + pub fn get_entity(&self, entity_id: usize) -> Option<&Entity> { self.scene.get_entity(entity_id) } /// Gets a mutable reference to an entity by its ID. - pub fn get_entity_mut(&mut self, entity_id: EntityId) -> Option<&mut Entity> { + pub fn get_entity_mut(&mut self, entity_id: usize) -> Option<&mut Entity> { self.scene.get_entity_mut(entity_id) } @@ -196,29 +194,29 @@ impl App { /// 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(&mut self, entity_id: EntityId, component: C) { + pub fn add_component(&mut self, entity_id: usize, component: C) { self.scene.add_component(entity_id, component) } /// Removes a component from an entity by its ID. - pub fn remove_component(&mut self, entity_id: EntityId) { + pub fn remove_component(&mut self, entity_id: usize) { self.scene.remove_component::(entity_id) } /// Returns a reference to a component of an entity by its ID. - pub fn get_component(&self, entity_id: EntityId) -> Option<&C> { + pub fn get_component(&self, entity_id: usize) -> Option<&C> { self.scene.get_component::(entity_id) } /// Returns a mutable reference to a component of an entity by its ID. - pub fn get_component_mut(&mut self, entity_id: EntityId) -> Option<&mut C> { + pub fn get_component_mut(&mut self, entity_id: usize) -> Option<&mut C> { self.scene.get_component_mut::(entity_id) } /// Returns a list of entities that have the given components. /// The amount of queriable components is limited to 3 such that the `Archetype` creation is more efficient. /// Otherwise it would be a factorial complexity chaos. - pub fn get_entities_with(&self, components: Vec) -> Vec { + pub fn get_entities_with(&self, components: Vec) -> Vec { self.scene.get_entities_with(components) } @@ -235,7 +233,7 @@ impl App { } /// Returns whether an entity has the given component. - pub fn has(&self, entity_id: EntityId) -> bool { + pub fn has(&self, entity_id: usize) -> bool { self.scene.has::(entity_id) } @@ -245,7 +243,7 @@ impl App { } /// Spawns a prefab with the given name. - pub fn spawn_prefab(&mut self, name: &str) -> Option { + pub fn spawn_prefab(&mut self, name: &str) -> Option { self.scene.spawn_prefab(name) } diff --git a/crates/comet_ecs/component_derive/src/lib.rs b/crates/comet_ecs/component_derive/src/lib.rs index 44e6d6d..79355e9 100755 --- a/crates/comet_ecs/component_derive/src/lib.rs +++ b/crates/comet_ecs/component_derive/src/lib.rs @@ -27,13 +27,6 @@ pub fn component_derive(input: TokenStream) -> TokenStream { } }); - let clone_fields = fields.iter().map(|field| { - let field_name = &field.ident; - quote! { - #field_name: self.#field_name.clone() - } - }); - let default_fields = if let Data::Struct(data) = &input.data { match &data.fields { Fields::Named(fields) => fields @@ -90,11 +83,13 @@ pub fn component_derive(input: TokenStream) -> TokenStream { impl Clone for #name { fn clone(&self) -> Self { Self { - #(#clone_fields),* + ..*self } } } + impl Copy for #name {} + impl std::fmt::Debug for #name { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { f.debug_struct(stringify!(#name)) diff --git a/crates/comet_ecs/src/archetypes.rs b/crates/comet_ecs/src/archetypes.rs index 7736ac7..c6ccd11 100755 --- a/crates/comet_ecs/src/archetypes.rs +++ b/crates/comet_ecs/src/archetypes.rs @@ -1,9 +1,9 @@ use comet_structs::ComponentSet; -use std::collections::HashMap; +use std::collections::{HashMap, HashSet}; #[derive(Debug, Clone)] pub struct Archetypes { - archetypes: HashMap>, + archetypes: HashMap>, } impl Archetypes { @@ -13,31 +13,27 @@ impl Archetypes { } } - pub fn component_sets(&self) -> impl Iterator { - self.archetypes.keys() + pub fn component_sets(&self) -> Vec { + self.archetypes.keys().cloned().collect() } pub fn create_archetype(&mut self, components: ComponentSet) { - self.archetypes.entry(components).or_insert_with(Vec::new); + self.archetypes.insert(components, HashSet::new()); } - pub fn get_archetype(&self, components: &ComponentSet) -> Option<&Vec> { + pub fn get_archetype(&self, components: &ComponentSet) -> Option<&HashSet> { self.archetypes.get(components) } pub fn add_entity_to_archetype(&mut self, components: &ComponentSet, entity: u32) { if let Some(archetype) = self.archetypes.get_mut(components) { - if !archetype.iter().any(|&e| e == entity) { - archetype.push(entity); - } + archetype.insert(entity); } } pub fn remove_entity_from_archetype(&mut self, components: &ComponentSet, entity: u32) { if let Some(archetype) = self.archetypes.get_mut(components) { - if let Some(pos) = archetype.iter().position(|&id| id == entity) { - archetype.swap_remove(pos); - } + archetype.retain(|&id| id != entity); } } diff --git a/crates/comet_ecs/src/component.rs b/crates/comet_ecs/src/component.rs index 177f31e..ab17c9b 100755 --- a/crates/comet_ecs/src/component.rs +++ b/crates/comet_ecs/src/component.rs @@ -5,7 +5,6 @@ // They are intended to work with the base suite of systems provided by the engine. use crate::math::{v2, v3}; use crate::{Entity, Scene}; -use comet_log::*; use comet_colors::Color as ColorTrait; use comet_math::m4; use component_derive::Component; @@ -111,13 +110,10 @@ pub struct Transform3D { // # TRAITS # // ################################################## -pub trait Component: Send + Sync + 'static { +pub trait Component: Send + Sync + PartialEq + Default + 'static { fn new() -> Self where - Self: Sized + Default, - { - Default::default() - } + Self: Sized; fn type_id() -> std::any::TypeId { std::any::TypeId::of::() @@ -140,7 +136,7 @@ pub trait Render { } pub trait Camera { - fn get_visible_entities(&self, camera_position: &Position2D, scene: &Scene) -> Vec; + fn get_visible_entities(&self, camera_position: Position2D, scene: Scene) -> Vec; fn get_projection_matrix(&self) -> m4; } @@ -250,8 +246,8 @@ impl Rectangle2D { } } - pub fn position(&self) -> &Position2D { - &self.position + pub fn position(&self) -> Position2D { + self.position } pub fn set_position(&mut self, position: Position2D) { @@ -421,7 +417,7 @@ impl Camera2D { self.priority = priority; } - pub fn in_view_frustum(&self, camera_pos: &Position2D, entity: &Position2D) -> bool { + pub fn in_view_frustum(&self, camera_pos: Position2D, entity: Position2D) -> bool { let left = camera_pos.x() - self.zoom; let right = camera_pos.x() + self.zoom; let bottom = camera_pos.y() - self.zoom; @@ -432,19 +428,18 @@ impl Camera2D { } impl Camera for Camera2D { - fn get_visible_entities(&self, camera_position: &Position2D, scene: &Scene) -> Vec { + fn get_visible_entities(&self, camera_position: Position2D, scene: Scene) -> Vec { let entities = scene.entities(); let mut visible_entities = Vec::new(); for entity in entities { - if let Some(ent) = entity.clone() { - let id = ent.id(); - if let Some(transform) = scene.get_component::(id) { - if self.in_view_frustum(camera_position, transform.position()) { - visible_entities.push(ent); - } - } else { - error!("Entity {} missing Transform2D", id.index); - } + if self.in_view_frustum( + camera_position, + *scene + .get_component::(*entity.clone().unwrap().id() as usize) + .unwrap() + .position(), + ) { + visible_entities.push(entity.clone().unwrap()); } } visible_entities @@ -503,7 +498,7 @@ impl Text { } pub fn color(&self) -> Color { - self.color.clone() + self.color } pub fn set_visibility(&mut self, visibility: bool) { diff --git a/crates/comet_ecs/src/entity.rs b/crates/comet_ecs/src/entity.rs index f74cb58..e906d90 100755 --- a/crates/comet_ecs/src/entity.rs +++ b/crates/comet_ecs/src/entity.rs @@ -1,46 +1,32 @@ use bit_set::BitSet; -/// Handle used to reference entities safely. Contains an index into the entity -/// storage and a generation counter to detect stale handles. -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)] -pub struct EntityId { - pub index: u32, - pub gen: u32, -} - -impl Default for EntityId { - fn default() -> Self { - Self { index: 0, gen: 0 } - } -} - #[derive(Debug, Clone, PartialEq)] pub struct Entity { - id: EntityId, - components: BitSet, + id: u32, + components: BitSet } impl Entity { - pub(crate) fn new(index: u32, gen: u32) -> Self { - Self { - id: EntityId { index, gen }, - components: BitSet::new(), - } - } + pub(crate) fn new(id: u32) -> Self { + Self { + id, + components: BitSet::new() + } + } - pub fn id(&self) -> EntityId { - self.id - } + pub fn id(&self) -> &u32 { + &self.id + } - pub(crate) fn add_component(&mut self, component_index: usize) { - self.components.insert(component_index); - } + pub(crate) fn add_component(&mut self, component_index: usize) { + self.components.insert(component_index); + } - pub(crate) fn remove_component(&mut self, component_index: usize) { - self.components.remove(component_index); - } + pub(crate) fn remove_component(&mut self, component_index: usize) { + self.components.remove(component_index); + } - pub(crate) fn get_components(&self) -> &BitSet { - &self.components - } + pub(crate) fn get_components(&self) -> &BitSet { + &self.components + } } diff --git a/crates/comet_ecs/src/prefabs.rs b/crates/comet_ecs/src/prefabs.rs index b6f1e48..5fe8698 100644 --- a/crates/comet_ecs/src/prefabs.rs +++ b/crates/comet_ecs/src/prefabs.rs @@ -1,6 +1,6 @@ use comet_structs::FlatMap; -pub type PrefabFactory = fn(&mut crate::Scene) -> crate::EntityId; +pub type PrefabFactory = fn(&mut crate::Scene) -> usize; pub(crate) struct PrefabManager { pub(crate) prefabs: FlatMap, @@ -26,8 +26,8 @@ impl PrefabManager { macro_rules! register_prefab { ($scene:expr, $name:expr, $($component:expr),* $(,)?) => { { - fn prefab_factory(scene: &mut $crate::Scene) -> $crate::EntityId { - let entity = scene.new_entity(); + fn prefab_factory(scene: &mut $crate::Scene) -> usize { + let entity = scene.new_entity() as usize; $( scene.add_component(entity, $component); )* diff --git a/crates/comet_ecs/src/scene.rs b/crates/comet_ecs/src/scene.rs index 4d76542..25c3c40 100755 --- a/crates/comet_ecs/src/scene.rs +++ b/crates/comet_ecs/src/scene.rs @@ -1,6 +1,6 @@ use crate::archetypes::Archetypes; use crate::prefabs::PrefabManager; -use crate::{Component, Entity, EntityId, IdQueue}; +use crate::{Component, Entity, IdQueue}; use comet_log::*; use comet_structs::*; use std::any::TypeId; @@ -8,7 +8,6 @@ use std::any::TypeId; pub struct Scene { id_queue: IdQueue, next_id: u32, - generations: Vec, entities: Vec>, components: ComponentStorage, archetypes: Archetypes, @@ -20,7 +19,6 @@ impl Scene { Self { id_queue: IdQueue::new(), next_id: 0, - generations: Vec::new(), entities: Vec::new(), components: ComponentStorage::new(), archetypes: Archetypes::new(), @@ -45,78 +43,48 @@ impl Scene { } } - fn is_alive(&self, id: EntityId) -> bool { - self.generations - .get(id.index as usize) - .is_some_and(|g| *g == id.gen) - && self - .entities - .get(id.index as usize) - .is_some_and(|e| e.is_some()) - } - /// Retuns the `Vec` of `Option` which contains all the entities in the current Scene. pub fn entities(&self) -> &Vec> { &self.entities } /// Creates a new entity and returns its ID. - pub fn new_entity(&mut self) -> EntityId { - let index = self.next_id; - let gen = if (index as usize) >= self.generations.len() { - self.generations.push(0); - 0 - } else { - self.generations[index as usize] - }; - - if (index as usize) >= self.entities.len() { - self.entities.push(Some(Entity::new(index, gen))); - } else { - self.entities[index as usize] = Some(Entity::new(index, gen)); + pub fn new_entity(&mut self) -> u32 { + let id = self.next_id; + if (self.next_id as usize) >= self.entities.len() { + self.entities.push(Some(Entity::new(self.next_id))); + self.get_next_id(); + info!("Created entity! ID: {}", id); + return id; } - - let id = EntityId { index, gen }; + self.entities[self.next_id as usize] = Some(Entity::new(self.next_id)); self.get_next_id(); - info!("Created entity! ID: {} (gen {})", id.index, id.gen); + info!("Created entity! ID: {}", id); id } /// Gets an immutable reference to an entity by its ID. - pub fn get_entity(&self, entity_id: EntityId) -> Option<&Entity> { - if !self.is_alive(entity_id) { - return None; - } - self.entities - .get(entity_id.index as usize) - .and_then(|e| e.as_ref()) + pub fn get_entity(&self, entity_id: usize) -> Option<&Entity> { + self.entities.get(entity_id).unwrap().as_ref() } /// Gets a mutable reference to an entity by its ID. - pub fn get_entity_mut(&mut self, entity_id: EntityId) -> Option<&mut Entity> { - if !self.is_alive(entity_id) { - return None; - } - self.entities - .get_mut(entity_id.index as usize) - .and_then(|e| e.as_mut()) + pub fn get_entity_mut(&mut self, entity_id: usize) -> Option<&mut Entity> { + self.entities.get_mut(entity_id).unwrap().as_mut() } /// Deletes an entity by its ID. - pub fn delete_entity(&mut self, entity_id: EntityId) { - if !self.is_alive(entity_id) { - return; + pub fn delete_entity(&mut self, entity_id: usize) { + self.remove_entity_from_archetype_subsets( + entity_id as u32, + self.get_component_set(entity_id), + ); + self.entities[entity_id] = None; + info!("Deleted entity! ID: {}", entity_id); + for (_, value) in self.components.iter_mut() { + value.remove::(entity_id); } - - let idx = entity_id.index as usize; - self.remove_entity_from_archetype(entity_id.index, self.get_component_set(idx)); - self.entities[idx] = None; - info!("Deleted entity! ID: {}", entity_id.index); - self.components.remove_entity(idx); - if let Some(gen) = self.generations.get_mut(idx) { - *gen = gen.wrapping_add(1); - } - self.id_queue.sorted_enqueue(entity_id.index); + self.id_queue.sorted_enqueue(entity_id as u32); self.get_next_id(); } @@ -139,6 +107,24 @@ impl Scene { } } + fn get_keys(&self, components: ComponentSet) -> Vec { + let component_sets = self.archetypes.component_sets(); + component_sets + .iter() + .enumerate() + .filter_map(|(i, &ref elem)| { + if elem.is_subset(&components) { + Some(i) + } else { + None + } + }) + .collect::>() + .iter() + .map(|index| component_sets[*index].clone()) + .collect::>() + } + fn add_entity_to_archetype(&mut self, entity_id: u32, components: ComponentSet) { self.archetypes .add_entity_to_archetype(&components, entity_id); @@ -149,6 +135,18 @@ impl Scene { .remove_entity_from_archetype(&components, entity_id); } + fn remove_entity_from_archetype_subsets(&mut self, entity_id: u32, components: ComponentSet) { + let keys = self.get_keys(components); + + for key in keys { + self.remove_entity_from_archetype(entity_id, key.clone()); + if self.archetypes.get_archetype(&key).unwrap().len() == 0 { + self.archetypes.remove_archetype(&key); + } + } + info!("Removed entity {} from all archetypes!", entity_id); + } + fn get_component_set(&self, entity_id: usize) -> ComponentSet { let components = match self.entities.get(entity_id) { Some(cmp) => match cmp.as_ref() { @@ -194,152 +192,120 @@ impl Scene { /// 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(&mut self, entity_id: EntityId, component: C) { - if !self.is_alive(entity_id) { - error!( - "Attempted to add component {} to dead entity {}", - C::type_name(), - entity_id.index - ); - return; - } - - let old_component_set = self.get_component_set(entity_id.index as usize); + pub fn add_component(&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(entity_id.index, old_component_set); + self.remove_entity_from_archetype_subsets(entity_id as u32, old_component_set); } - self.components - .set_component(entity_id.index as usize, component); - if let Some(component_index) = self + self.components.set_component(entity_id, component); + let component_index = self .components .keys() - .iter() + .iter_mut() .position(|x| *x == C::type_id()) - { - if let Some(entity) = self.get_entity_mut(entity_id) { - entity.add_component(component_index); - } else { - error!( - "Attempted to add component to non-existent entity {}", - entity_id.index - ); - } - } else { - error!( - "Component {} not registered, cannot add to entity {}", - C::type_name(), - entity_id.index - ); - } + .unwrap(); + self.get_entity_mut(entity_id) + .unwrap() + .add_component(component_index); - let new_component_set = self.get_component_set(entity_id.index as usize); + let new_component_set = self.get_component_set(entity_id); if !self.archetypes.contains_archetype(&new_component_set) { self.create_archetype(new_component_set.clone()); } - self.add_entity_to_archetype(entity_id.index, new_component_set); + let subsets = ComponentSet::compute_subsets_up_to_size_3(new_component_set.to_vec()); + + for subset in subsets { + if !self.archetypes.contains_archetype(&subset) { + self.create_archetype(subset.clone()); + } + + self.add_entity_to_archetype(entity_id as u32, subset); + } info!( "Added component {} to entity {}!", C::type_name(), - entity_id.index + entity_id ); } - pub fn remove_component(&mut self, entity_id: EntityId) { - if !self.is_alive(entity_id) { - return; - } - let old_component_set = self.get_component_set(entity_id.index as usize); - self.remove_entity_from_archetype(entity_id.index, old_component_set); + pub fn remove_component(&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::(entity_id.index as usize); - if let Some(component_index) = self + self.components.remove_component::(entity_id); + let component_index = self .components .keys() .iter() .position(|x| *x == C::type_id()) - { - if let Some(entity) = self.get_entity_mut(entity_id) { - entity.remove_component(component_index); - } - } + .unwrap(); + self.get_entity_mut(entity_id) + .unwrap() + .remove_component(component_index); - let new_component_set = self.get_component_set(entity_id.index as usize); + 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()); } - self.add_entity_to_archetype(entity_id.index, new_component_set); + let subsets = ComponentSet::compute_subsets_up_to_size_3(new_component_set.to_vec()); + + for subset in subsets { + if !self.archetypes.contains_archetype(&subset) { + self.create_archetype(subset.clone()); + } + + self.add_entity_to_archetype(entity_id as u32, subset); + } } info!( "Removed component {} from entity {}!", C::type_name(), - entity_id.index + entity_id ); } /// Returns a reference to a component of an entity by its ID. - pub fn get_component(&self, entity_id: EntityId) -> Option<&C> { - if !self.is_alive(entity_id) { - return None; - } - self.components - .get_component::(entity_id.index as usize) + pub fn get_component(&self, entity_id: usize) -> Option<&C> { + self.components.get_component::(entity_id) } pub fn get_component_mut( &mut self, - entity_id: EntityId, + entity_id: usize, ) -> Option<&mut C> { - if !self.is_alive(entity_id) { - return None; - } - self.components - .get_component_mut::(entity_id.index as usize) + self.components.get_component_mut::(entity_id) } - pub fn has(&self, entity_id: EntityId) -> bool { - self.is_alive(entity_id) - && self - .components - .get_component::(entity_id.index as usize) - .is_some() + pub fn has(&self, entity_id: usize) -> bool { + self.components.get_component::(entity_id).is_some() } /// Returns a list of entities that have the given components. - pub fn get_entities_with(&self, components: Vec) -> Vec { + pub fn get_entities_with(&self, components: Vec) -> Vec { let component_set = ComponentSet::from_ids(components); - let mut result = Vec::new(); - - for archetype_set in self.archetypes.component_sets() { - if component_set.is_subset(archetype_set) { - if let Some(entities) = self.archetypes.get_archetype(archetype_set) { - for index in entities.iter() { - if let Some(gen) = self.generations.get(*index as usize) { - if self - .entities - .get(*index as usize) - .is_some_and(|e| e.is_some()) - { - result.push(EntityId { - index: *index, - gen: *gen, - }); - } - } - } - } - } + if component_set.size() > 3 { + error!("An entity query should only contain at most 3 different components!"); + return Vec::new(); } - - result + if self.archetypes.contains_archetype(&component_set) { + return self + .archetypes + .get_archetype(&component_set) + .unwrap() + .clone() + .iter() + .map(|x| *x as usize) + .collect(); + } + Vec::new() } /// Deletes all entities that have the given components. @@ -351,31 +317,14 @@ impl Scene { } /// Iterates over all entities that have the two given components and calls the given function. - pub fn foreach(&mut self, mut func: impl FnMut(&mut C, &mut K)) { - if std::any::TypeId::of::() == std::any::TypeId::of::() { - error!("foreach called with identical component types"); - return; - } + pub fn foreach(&mut self, func: fn(&mut C, &mut K)) { + let entities = self.get_entities_with(vec![C::type_id(), K::type_id()]); + for entity in entities { + let c_ptr = self.get_component_mut::(entity).unwrap() as *mut C; + let k_ptr = self.get_component_mut::(entity).unwrap() as *mut K; - let required = ComponentSet::from_ids(vec![C::type_id(), K::type_id()]); - let (c_set, k_set) = self - .components - .get_two_mut(&C::type_id(), &K::type_id()); - - if let (Some(c_store), Some(k_store)) = (c_set, k_set) { - for archetype_set in self.archetypes.component_sets() { - if required.is_subset(archetype_set) { - if let Some(entities) = self.archetypes.get_archetype(archetype_set) { - for &idx in entities { - let idx = idx as usize; - if let (Some(c), Some(k)) = - (c_store.get_mut::(idx), k_store.get_mut::(idx)) - { - func(c, k); - } - } - } - } + unsafe { + func(&mut *c_ptr, &mut *k_ptr); } } } @@ -386,7 +335,7 @@ impl Scene { } /// Spawns a prefab with the given name. - pub fn spawn_prefab(&mut self, name: &str) -> Option { + pub fn spawn_prefab(&mut self, name: &str) -> Option { if self.prefabs.has_prefab(name) { if let Some(factory) = self.prefabs.prefabs.get(&name.to_string()) { let factory = *factory; // Copy the function pointer diff --git a/crates/comet_renderer/src/camera.rs b/crates/comet_renderer/src/camera.rs index 77f3045..2e70adf 100644 --- a/crates/comet_renderer/src/camera.rs +++ b/crates/comet_renderer/src/camera.rs @@ -18,11 +18,7 @@ impl CameraManager { self.cameras.get(self.active_camera).unwrap() } - pub fn update_from_scene( - &mut self, - scene: &comet_ecs::Scene, - camera_entities: Vec, - ) { + pub fn update_from_scene(&mut self, scene: &comet_ecs::Scene, camera_entities: Vec) { self.cameras.clear(); let mut cameras_with_priority: Vec<(RenderCamera, u8)> = Vec::new(); diff --git a/crates/comet_renderer/src/renderer2d.rs b/crates/comet_renderer/src/renderer2d.rs index 91ffe06..1601295 100644 --- a/crates/comet_renderer/src/renderer2d.rs +++ b/crates/comet_renderer/src/renderer2d.rs @@ -11,7 +11,6 @@ use comet_math::{m4, v2}; use comet_resources::{ font::Font, graphic_resource_manager::GraphicResourceManager, texture_atlas::*, Texture, Vertex, }; -use std::collections::HashSet; use std::sync::Arc; use wgpu::util::DeviceExt; use winit::{dpi::PhysicalSize, window::Window}; @@ -62,7 +61,6 @@ pub struct Renderer2D<'a> { resource_manager: GraphicResourceManager, camera_manager: CameraManager, render_passes: Vec, - cached_render_entities: Vec, last_frame_time: std::time::Instant, delta_time: f32, } @@ -746,45 +744,16 @@ impl<'a> Renderer2D<'a> { return; } - let unsorted_entities = scene.get_entities_with(vec![ + let mut entities = scene.get_entities_with(vec![ comet_ecs::Transform2D::type_id(), comet_ecs::Render2D::type_id(), ]); - let mut dirty_sort = self.cached_render_entities.len() != unsorted_entities.len(); - - if !dirty_sort { - let unsorted_set: HashSet = - unsorted_entities.iter().copied().collect(); - dirty_sort = self - .cached_render_entities - .iter() - .any(|e| !unsorted_set.contains(e)); - } - - if !dirty_sort { - dirty_sort = !self.cached_render_entities.windows(2).all(|w| { - let a = scene - .get_component::(w[0]) - .map(|r| r.draw_index()); - let b = scene - .get_component::(w[1]) - .map(|r| r.draw_index()); - matches!((a, b), (Some(da), Some(db)) if da <= db) - }); - } - - if dirty_sort { - let mut entities = unsorted_entities; - entities.sort_by(|&a, &b| { - let ra = scene.get_component::(a).unwrap(); - let rb = scene.get_component::(b).unwrap(); - ra.draw_index().cmp(&rb.draw_index()) - }); - self.cached_render_entities = entities; - } - - let entities = self.cached_render_entities.clone(); + entities.sort_by(|&a, &b| { + let ra = scene.get_component::(a).unwrap(); + let rb = scene.get_component::(b).unwrap(); + ra.draw_index().cmp(&rb.draw_index()) + }); let texts = scene.get_entities_with(vec![ comet_ecs::Transform2D::type_id(), @@ -953,7 +922,7 @@ impl<'a> Renderer2D<'a> { } } - fn setup_camera(&mut self, scene: &comet_ecs::Scene, cameras: Vec) { + fn setup_camera(&mut self, scene: &comet_ecs::Scene, cameras: Vec) { if cameras.is_empty() { return; } @@ -1043,7 +1012,6 @@ impl<'a> Renderer for Renderer2D<'a> { resource_manager: GraphicResourceManager::new(), camera_manager: CameraManager::new(), render_passes: Vec::new(), - cached_render_entities: Vec::new(), last_frame_time: std::time::Instant::now(), delta_time: 0.0, } diff --git a/crates/comet_structs/src/column.rs b/crates/comet_structs/src/column.rs index 6b8ee1a..b6969b2 100644 --- a/crates/comet_structs/src/column.rs +++ b/crates/comet_structs/src/column.rs @@ -272,33 +272,6 @@ impl Column { } } - /// Remove an element without knowing its concrete type. Drops in place. - pub fn remove_any(&mut self, index: usize) { - if index >= self.data.len() { - return; - } - unsafe { - let ptr = self.data.swap_remove_and_forget_unchecked(index); - (self.data.drop)(ptr); - } - } - - /// Overwrites an existing element in place, dropping the previous value. - pub fn set(&mut self, index: usize, item: T) -> Option<()> { - assert_eq!(TypeId::of::(), TypeId::of::(), "Type mismatch"); - if index >= self.data.len() { - return None; - } - - unsafe { - let ptr = self.data.get_unchecked_mut(index) as *mut T; - ptr::drop_in_place(ptr); - ptr::write(ptr, item); - } - - Some(()) - } - pub fn swap(&mut self, index1: usize, index2: usize) { assert!( index1 < self.data.len() && index2 < self.data.len(), diff --git a/crates/comet_structs/src/component_storage.rs b/crates/comet_structs/src/component_storage.rs index 017a776..3216bda 100644 --- a/crates/comet_structs/src/component_storage.rs +++ b/crates/comet_structs/src/component_storage.rs @@ -55,11 +55,4 @@ impl ComponentStorage { None } } - - /// Removes all components belonging to the given entity index. - pub fn remove_entity(&mut self, index: usize) { - for (_, value) in self.iter_mut() { - value.remove_any(index); - } - } } diff --git a/crates/comet_structs/src/componet_set.rs b/crates/comet_structs/src/componet_set.rs index e37cf1f..0d2a816 100644 --- a/crates/comet_structs/src/componet_set.rs +++ b/crates/comet_structs/src/componet_set.rs @@ -67,10 +67,6 @@ impl ComponentSet { self.set.is_subset(&other.set) } - pub fn is_superset(&self, other: &ComponentSet) -> bool { - self.set.is_superset(&other.set) - } - pub fn to_vec(&self) -> Vec { self.set.iter().cloned().collect() } diff --git a/crates/comet_structs/src/flat_map.rs b/crates/comet_structs/src/flat_map.rs index 49524c8..1b0edef 100644 --- a/crates/comet_structs/src/flat_map.rs +++ b/crates/comet_structs/src/flat_map.rs @@ -44,39 +44,6 @@ impl FlatMap { } } - pub fn get_two_mut(&mut self, a: &K, b: &K) -> (Option<&mut V>, Option<&mut V>) { - if a == b { - let first = self.get_mut(a); - return (first, None); - } - - let mut first_index = None; - let mut second_index = None; - - for (idx, (key, _)) in self.map.iter().enumerate() { - if key == a { - first_index = Some(idx); - } else if key == b { - second_index = Some(idx); - } - } - - match (first_index, second_index) { - (Some(i), Some(j)) => { - if i < j { - let (left, right) = self.map.split_at_mut(j); - (Some(&mut left[i].1), Some(&mut right[0].1)) - } else { - let (left, right) = self.map.split_at_mut(i); - (Some(&mut right[0].1), Some(&mut left[j].1)) - } - } - (Some(i), None) => (self.map.get_mut(i).map(|pair| &mut pair.1), None), - (None, Some(j)) => (None, self.map.get_mut(j).map(|pair| &mut pair.1)), - _ => (None, None), - } - } - pub fn contains(&self, key: &K) -> bool { self.map.iter().any(|node| node.0 == *key) } @@ -84,4 +51,4 @@ impl FlatMap { pub fn iter_mut(&mut self) -> impl Iterator { self.map.iter_mut() } -} +} \ No newline at end of file diff --git a/crates/comet_structs/src/sparse_set.rs b/crates/comet_structs/src/sparse_set.rs index d5bbcb1..bd8527d 100644 --- a/crates/comet_structs/src/sparse_set.rs +++ b/crates/comet_structs/src/sparse_set.rs @@ -28,12 +28,6 @@ impl SparseSet { } if let Some(page_vec) = &mut self.sparse[page] { - // If there is already a mapping, overwrite the existing dense value instead of pushing. - if let Some(sparse_index) = page_vec[index % self.page_size] { - let _ = self.dense.set::(sparse_index, value); - return; - } - page_vec[index % self.page_size] = Some(self.dense.data.len()); } @@ -75,64 +69,6 @@ impl SparseSet { None } - /// Removes an element by external index without knowing its type. Returns true if something was removed. - pub fn remove_any(&mut self, index: usize) -> bool { - 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_dense_index = self.dense.data.len() - 1; - - if dense_index != last_dense_index { - if let Some(ext_index) = self.find_external_index(last_dense_index) { - if let Some(page_vec) = self - .sparse - .get_mut(ext_index / self.page_size) - .and_then(|x| x.as_mut()) - { - page_vec[ext_index % self.page_size] = Some(dense_index); - } - } - self.dense.swap(dense_index, last_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; - } - - self.dense.remove_any(dense_index); - return true; - } - } - false - } - - /// Finds the external index that maps to a given dense index. - fn find_external_index(&self, dense_index: usize) -> Option { - for (page_idx, page_opt) in self.sparse.iter().enumerate() { - if let Some(page) = page_opt { - for (offset, entry) in page.iter().enumerate() { - if let Some(idx) = entry { - if *idx == dense_index { - return Some(page_idx * self.page_size + offset); - } - } - } - } - } - None - } - pub fn get(&self, index: usize) -> Option<&T> { if let Some(page_vec) = self .sparse