From 35992d140bf347ee138ed78837e755d6ea060e69 Mon Sep 17 00:00:00 2001 From: hodasemi Date: Thu, 6 Mar 2025 09:01:09 +0100 Subject: [PATCH] Readd archetypes --- ecs/src/updates.rs | 61 ++++++++++++++++++++-------------------------- ecs/src/world.rs | 43 +++++++++++++++++++++++++++++++- 2 files changed, 69 insertions(+), 35 deletions(-) diff --git a/ecs/src/updates.rs b/ecs/src/updates.rs index 638b324..6a0e46d 100644 --- a/ecs/src/updates.rs +++ b/ecs/src/updates.rs @@ -2,6 +2,7 @@ use std::any::TypeId; +use std::collections::HashMap; use std::marker::PhantomData; #[cfg(feature = "timings")] use std::time::Instant; @@ -591,46 +592,38 @@ impl Updates { } } -// #[derive(Default)] -// pub struct Archetypes { -// archetypes: HashMap, -// } +#[derive(Default)] +pub struct Archetypes { + archetypes: HashMap, +} -// impl Archetypes { -// pub(crate) fn add_entity(&mut self, entity_object: &EntityObject) -> Result<()> { -// for archetype in self.archetypes.values_mut() { -// archetype.add_entity(entity_object)?; -// } +impl Archetypes { + pub(crate) fn add_entity(&mut self, entity_object: &EntityObject) -> Result<()> { + for archetype in self.archetypes.values_mut() { + archetype.add_entity(entity_object)?; + } -// Ok(()) -// } + Ok(()) + } -// pub(crate) fn remove_entity(&mut self, entity: Entity) { -// for archetype in self.archetypes.values_mut() { -// archetype.remove_entity(entity); -// } -// } + pub(crate) fn remove_entity(&mut self, entity: Entity) { + for archetype in self.archetypes.values_mut() { + archetype.remove_entity(entity); + } + } -// pub(crate) fn clear(&mut self) { -// self.archetypes.clear(); -// } + pub(crate) fn insert(&mut self, name: String, archetype: Archetype) { + assert!(self.archetypes.insert(name, archetype).is_none()); + } -// pub(crate) fn insert(&mut self, name: String, archetype: Archetype) { -// assert!(self.archetypes.insert(name, archetype).is_none()); -// } + pub(crate) fn get(&self, name: &String) -> Option<&Archetype> { + self.archetypes.get(name) + } -// pub(crate) fn get(&self, name: &String) -> Option<&Archetype> { -// self.archetypes.get(name) -// } - -// pub(crate) fn execute( -// &self, -// name: &String, -// scene_contents: &mut SceneContents<'_>, -// ) -> Result<()> { -// self.archetypes[name].execute(scene_contents) -// } -// } + pub(crate) fn execute(&self, name: &String, world: &mut World) -> Result<()> { + self.archetypes[name].execute(world) + } +} #[rustfmt::skip] impl_singleton_update!(single, [R]); diff --git a/ecs/src/world.rs b/ecs/src/world.rs index aa11188..de53e2e 100644 --- a/ecs/src/world.rs +++ b/ecs/src/world.rs @@ -4,7 +4,7 @@ use std::{ time::{Duration, Instant}, }; -use anyhow::{Result, bail}; +use anyhow::{Error, Result, bail}; use indexmap::IndexMap; use utilities::prelude::{remove_life_time, remove_life_time_mut}; @@ -14,6 +14,7 @@ pub struct WorldBuilder { pub(crate) updates: Updates, pub events: Events, pub resources: Resources, + archetypes: Archetypes, systems: Vec Result + Send + Sync + 'static>>, } @@ -24,6 +25,10 @@ impl WorldBuilder { { self.systems.push(Box::new(f)); } + + pub fn add_archetype(&mut self, name: impl ToString, archetype: Archetype) { + self.archetypes.insert(name.to_string(), archetype); + } } impl WorldBuilder { @@ -33,6 +38,7 @@ impl WorldBuilder { events: self.events, resources: self.resources, entities: Default::default(), + archetypes: self.archetypes, entities_to_remove: Default::default(), entities_to_add: Default::default(), @@ -57,6 +63,7 @@ pub struct World { pub events: Events, pub resources: Resources, pub(crate) entities: IndexMap, + archetypes: Archetypes, entities_to_remove: Vec, entities_to_add: Vec, @@ -76,6 +83,7 @@ impl World { events: Default::default(), resources: Default::default(), systems: Default::default(), + archetypes: Default::default(), } } @@ -197,6 +205,33 @@ impl World { Ok(None) } + + pub fn execute_archetype(&mut self, name: impl ToString) -> Result<()> { + let archetypes = unsafe { remove_life_time_mut(&mut self.archetypes) }; + archetypes.execute(&name.to_string(), self) + } + + pub fn archetype_info(&self, name: impl ToString) -> Result { + let name = name.to_string(); + let archetype = self + .archetypes + .get(&name) + .ok_or_else(|| Error::msg(format!("requested archetype ({}) not found", name)))?; + + let mut entities = Vec::new(); + + for entity in archetype.entities().keys() { + #[cfg(debug_assertions)] + let debug_name = self.entity(*entity)?.debug_name.clone(); + + #[cfg(not(debug_assertions))] + let debug_name = None; + + entities.push((*entity, debug_name)); + } + + Ok(ArchetypeInfo::new(entities)) + } } // async application of changes @@ -212,6 +247,7 @@ impl World { let e = entity.as_entity(); self.updates.add_entity(&mut entity, &self.entities)?; + self.archetypes.add_entity(&entity)?; assert!(self.entities.insert(e, entity).is_none()); Ok(e) @@ -225,6 +261,7 @@ impl World { entity_object.activation_state.apply_change(); self.updates.remove_entity(entity); + self.archetypes.remove_entity(entity); return Ok(Some(entity_object)); } @@ -244,6 +281,7 @@ impl World { .ok_or_else(|| EntityNotFoundError::new(entity))?; self.updates.remove_entity(entity); + self.archetypes.remove_entity(entity); entity_object.activation_state.apply_change(); @@ -255,6 +293,7 @@ impl World { entity_object.activation_state.apply_change(); self.updates.add_entity(entity_object, &self.entities)?; + self.archetypes.add_entity(entity_object)?; Ok(()) } @@ -270,6 +309,7 @@ impl World { .ok_or_else(|| EntityNotFoundError::new(entity))?; self.updates.remove_entity(entity); + self.archetypes.remove_entity(entity); entity_object.activation_state.apply_change(); @@ -280,6 +320,7 @@ impl World { entity_object.activation_state.apply_change(); self.updates.add_entity(entity_object, &self.entities)?; + self.archetypes.add_entity(entity_object)?; Ok(()) }