diff --git a/engine/src/core/ecs/mod.rs b/engine/src/core/ecs/mod.rs index 37b0ab7..e69de29 100644 --- a/engine/src/core/ecs/mod.rs +++ b/engine/src/core/ecs/mod.rs @@ -1,170 +0,0 @@ -use std::any::{Any, TypeId}; -use std::collections::HashMap; -use std::sync::Mutex; - -pub trait Component: Sized + 'static { - fn update(&mut self, delta_time: f32); - fn serialize(&self) -> Vec; - fn deserialize(data: &[u8; 6]) -> Self; -} - -pub trait Entity: Sized { - fn add_component(&mut self, component: C); - fn remove_component(&mut self); - fn get_component(&self) -> Option<&C>; - fn serialize(&self) -> Vec; - fn deserialize(data: &[u8; 6]) -> Self; -} -lazy_static::lazy_static! { - // Global registry mapping component TypeId to a unique bit flag. - static ref COMPONENT_REGISTRY: Mutex> = Mutex::new(HashMap::new()); - static ref NEXT_COMPONENT_BIT: Mutex = Mutex::new(1); -} - -// To allow dynamic dispatch on components (even though Component itself is not object‐safe) -// we wrap them in an object–safe trait. -pub trait ComponentObject: Any { - fn update_obj(&mut self, delta_time: f32); - fn serialize_obj(&self) -> Vec; - fn as_any(&self) -> &dyn Any; -} -impl ComponentObject for T { - fn update_obj(&mut self, delta_time: f32) { - T::update(self, delta_time) - } - fn serialize_obj(&self) -> Vec { - T::serialize(self) - } - fn as_any(&self) -> &dyn Any { - self - } -} - -pub struct EntityImpl { - id: usize, - bitmask: u64, - // The key is the unique bit flag for the component type. - components: HashMap>, -} - -impl EntityImpl { - pub fn new(id: usize) -> Self { - EntityImpl { - id, - bitmask: 0, - components: HashMap::new(), - } - } -} - -impl Entity for EntityImpl { - fn add_component(&mut self, component: C) { - let type_id = TypeId::of::(); - let mut registry = COMPONENT_REGISTRY.lock().unwrap(); - let bit = registry.entry(type_id).or_insert_with(|| { - let mut next_bit = NEXT_COMPONENT_BIT.lock().unwrap(); - let current = *next_bit; - *next_bit *= 2; - current - }); - self.bitmask |= *bit; - self.components.insert(*bit, Box::new(component)); - } - - fn remove_component(&mut self) { - let type_id = TypeId::of::(); - if let Some(&bit) = COMPONENT_REGISTRY.lock().unwrap().get(&type_id) { - self.bitmask &= !bit; - } - } - - fn get_component(&self) -> Option<&C> { - let type_id = TypeId::of::(); - if let Some(&bit) = COMPONENT_REGISTRY.lock().unwrap().get(&type_id) { - self.components - .get(&bit) - .and_then(|boxed| boxed.as_any().downcast_ref::()) - } else { - None - } - } - - fn serialize(&self) -> Vec { - // Serialize the entity's bitmask into 6 bytes (lowest 48 bits). - let mut bytes = self.bitmask.to_le_bytes().to_vec(); - bytes.truncate(6); - bytes - } - - fn deserialize(data: &[u8; 6]) -> Self { - let mut full = [0u8; 8]; - full[..6].copy_from_slice(data); - let bitmask = u64::from_le_bytes(full); - // When deserializing, we recreate an entity with the restored bitmask. - // Note: The individual component data are not restored here. - Self { - id: 0, - bitmask, - components: HashMap::new(), - } - } -} - -pub struct ECS { - next_entity_id: usize, - pub entities: HashMap, -} - -impl ECS { - pub fn new() -> Self { - ECS { - next_entity_id: 0, - entities: HashMap::new(), - } - } - - pub fn create_entity(&mut self) -> &mut EntityImpl { - let entity = EntityImpl::new(self.next_entity_id); - self.entities.insert(self.next_entity_id, entity); - self.next_entity_id += 1; - self.entities.get_mut(&(self.next_entity_id - 1)).unwrap() - } - - pub fn update(&mut self, delta_time: f32) { - for entity in self.entities.values_mut() { - // Update each component attached to the entity. - for comp in entity.components.values_mut() { - comp.update_obj(delta_time); - } - } - } - - pub fn serialize(&self) -> Vec { - let mut data = Vec::new(); - // For each entity, store its id (8 bytes) and its 6-byte bitmask. - for (id, entity) in &self.entities { - data.extend_from_slice(&id.to_le_bytes()); - data.extend_from_slice(&entity.serialize()); - } - data - } - - pub fn deserialize(&mut self, data: &[u8]) { - self.entities.clear(); - // Each serialized entity uses 8 (id) + 6 (bitmask) = 14 bytes. - let entity_size = 14; - let count = data.len() / entity_size; - for i in 0..count { - let offset = i * entity_size; - let mut id_bytes = [0u8; 8]; - id_bytes.copy_from_slice(&data[offset..offset + 8]); - let id = usize::from_le_bytes(id_bytes); - - let mut mask_bytes = [0u8; 6]; - mask_bytes.copy_from_slice(&data[offset + 8..offset + 14]); - let entity = EntityImpl::deserialize(&mask_bytes); - self.entities.insert(id, entity); - } - self.next_entity_id = count; - } -} diff --git a/engine/src/main.rs b/engine/src/main.rs index 00ad1d7..070d3f6 100644 --- a/engine/src/main.rs +++ b/engine/src/main.rs @@ -35,7 +35,6 @@ async fn main() { - let event_loop = EventLoop::new().unwrap(); splash::print_splash(); if !cfg!(debug_assertions) { info!("{}", "Debug mode disabled".bright_blue());