diff options
| author | HampusM <hampus@hampusmat.com> | 2026-09-20 20:40:00 +0200 |
|---|---|---|
| committer | HampusM <hampus@hampusmat.com> | 2026-09-20 20:40:00 +0200 |
| commit | f954bee2a90de66c138ae1168e4e32ef0df1b2eb (patch) | |
| tree | 277dd9bfdc947c54a8220ee04f4eeadf4483340b | |
| parent | a228e48b345d142fdb0c17b5c39ea7685dd4c67b (diff) | |
| -rw-r--r-- | engine-ecs/src/actions.rs | 47 | ||||
| -rw-r--r-- | engine-ecs/src/bundle.rs | 38 | ||||
| -rw-r--r-- | engine-ecs/src/lib.rs | 58 |
3 files changed, 67 insertions, 76 deletions
diff --git a/engine-ecs/src/actions.rs b/engine-ecs/src/actions.rs index c367f6e..5eaa24e 100644 --- a/engine-ecs/src/actions.rs +++ b/engine-ecs/src/actions.rs @@ -25,21 +25,17 @@ impl Actions<'_> { let new_entity_uid = Uid::new_unique(); - let components_parts = bundle.into_parts_array(); + let components_parts = bundle.iter_component_parts().collect::<Vec<_>>(); - if let Some(comp_parts) = components_parts - .as_ref() + if let Some(ComponentParts { name: sole_name, .. }) = components_parts .iter() .find(|comp_parts| comp_parts.is_sole) { - panic!( - "Cannot spawn entity with sole component {}", - comp_parts.name - ); + panic!("Cannot spawn entity with sole component '{sole_name}'"); } self.action_queue - .push(Action::Spawn(new_entity_uid, components_parts.into())); + .push(Action::Spawn(new_entity_uid, components_parts)); new_entity_uid } @@ -57,26 +53,20 @@ impl Actions<'_> { let new_entity_uid = Uid::new_unique(); - let components_parts = bundle.into_parts_array(); + let components_parts = bundle + .iter_component_parts() + .chain([EntityName { name: name.into() }.into_parts()]) + .collect::<Vec<_>>(); - if let Some(comp_parts) = components_parts - .as_ref() + if let Some(ComponentParts { name: sole_name, .. }) = components_parts .iter() .find(|comp_parts| comp_parts.is_sole) { - panic!( - "Cannot spawn entity with sole component {}", - comp_parts.name - ); + panic!("Cannot spawn entity with sole component '{sole_name}'"); } - self.action_queue.push(Action::Spawn( - new_entity_uid, - components_parts - .into_iter() - .chain([EntityName { name: name.into() }.into_parts()]) - .collect(), - )); + self.action_queue + .push(Action::Spawn(new_entity_uid, components_parts)); new_entity_uid } @@ -119,22 +109,21 @@ impl Actions<'_> { debug_assert!(!entity_uid.is_pair()); - if bundle.cnt() == 0 { + let components_parts = bundle.iter_component_parts().collect::<Vec<_>>(); + + if components_parts.is_empty() { return; } - let components_parts = bundle.into_parts_array(); - - if let Some(comp_parts) = components_parts - .as_ref() + if let Some(ComponentParts { name: sole_name, .. }) = components_parts .iter() .find(|comp_parts| comp_parts.is_sole) { - panic!("Cannot add sole component {} to an entity", comp_parts.name); + panic!("Cannot spawn entity with sole component '{sole_name}'"); } self.action_queue - .push(Action::AddComponents(entity_uid, components_parts.into())); + .push(Action::AddComponents(entity_uid, components_parts)); } /// Queues up removing component(s) from a entity at the end of the current tick. diff --git a/engine-ecs/src/bundle.rs b/engine-ecs/src/bundle.rs index 89e0cc4..4c13599 100644 --- a/engine-ecs/src/bundle.rs +++ b/engine-ecs/src/bundle.rs @@ -1,34 +1,26 @@ use seq_macro::seq; -use crate::component::{IntoParts, Parts}; -use crate::util::Array; +use crate::component::{IntoParts as IntoComponentParts, Parts as ComponentParts}; -pub trait Bundle +pub trait Bundle: 'static { - type PartsArray: Array<Parts>; - - fn cnt(&self) -> usize; - - fn into_parts_array(self) -> Self::PartsArray; + fn iter_component_parts(self) -> impl Iterator<Item = ComponentParts>; } macro_rules! gen_tuple_impls { ($c: tt) => { seq!(I in 0..$c { - impl<#(IntoCompParts~I: IntoParts,)*> Bundle for (#(IntoCompParts~I,)*) + impl<#(Bundle~I: Bundle,)*> Bundle for (#(Bundle~I,)*) { - type PartsArray = [Parts; $c]; - - fn cnt(&self) -> usize + fn iter_component_parts(self) -> impl Iterator<Item = ComponentParts> { - $c - } + let parts = [].into_iter(); - fn into_parts_array(self) -> Self::PartsArray - { - [#({ - self.I.into_parts() - },)*] + #( + let parts = parts.chain(self.I.iter_component_parts()); + )* + + parts } } }); @@ -38,3 +30,11 @@ macro_rules! gen_tuple_impls { seq!(C in 0..17 { gen_tuple_impls!(C); }); + +impl<T: IntoComponentParts + 'static> Bundle for T +{ + fn iter_component_parts(self) -> impl Iterator<Item = ComponentParts> + { + [self.into_parts()].into_iter() + } +} diff --git a/engine-ecs/src/lib.rs b/engine-ecs/src/lib.rs index 53e49df..aef374c 100644 --- a/engine-ecs/src/lib.rs +++ b/engine-ecs/src/lib.rs @@ -170,20 +170,13 @@ impl World #[tracing::instrument(skip_all)] pub fn spawn_with_uid<BundleT: Bundle>(&mut self, entity_uid: Uid, bundle: BundleT) { - let components_parts = bundle.into_parts_array(); + let components_parts = bundle.iter_component_parts(); - if let Some(comp_parts) = components_parts - .as_ref() - .iter() - .find(|comp_parts| comp_parts.is_sole) - { - panic!( - "Cannot spawn entity with sole component {}", - comp_parts.name - ); - } - - self.create_ent(entity_uid, components_parts); + self.create_ent( + entity_uid, + components_parts, + ComponentAddingFlags { allow_soles: false }, + ); } /// Creates a entity with the given components. The entity will have the specified @@ -199,24 +192,12 @@ impl World bundle: BundleT, ) { - let components_parts = bundle.into_parts_array(); - - if let Some(comp_parts) = components_parts - .as_ref() - .iter() - .find(|comp_parts| comp_parts.is_sole) - { - panic!( - "Cannot spawn entity with sole component {}", - comp_parts.name - ); - } + let components_parts = bundle.iter_component_parts(); self.create_ent( entity_uid, - components_parts - .into_iter() - .chain([EntityName { name: name.into() }.into_parts()]), + components_parts.chain([EntityName { name: name.into() }.into_parts()]), + ComponentAddingFlags { allow_soles: false }, ); } @@ -233,6 +214,7 @@ impl World [component_parts], &mut self.data.component_storage, &EventSubmitter::new(&self.data.new_events), + ComponentAddingFlags { allow_soles: false }, ); } @@ -266,6 +248,7 @@ impl World sole.into_parts(), EntityName { name: name.into() }.into_parts(), ], + ComponentAddingFlags { allow_soles: true }, ); Ok(()) @@ -288,6 +271,7 @@ impl World .into_iter() .map(IntoComponentParts::into_parts), ), + ComponentAddingFlags { allow_soles: false }, ); system_callbacks.on_created(self, SystemMetadata { ent_id }); @@ -471,6 +455,7 @@ impl World &mut self, entity_uid: Uid, components: impl IntoIterator<Item = ComponentParts>, + flags: ComponentAddingFlags, ) { debug_assert!(!entity_uid.is_pair()); @@ -486,6 +471,7 @@ impl World components, &mut self.data.component_storage, &EventSubmitter::new(&self.data.new_events), + flags, ); } @@ -623,6 +609,7 @@ impl World components, &mut self.data.component_storage, &EventSubmitter::new(&self.data.new_events), + ComponentAddingFlags { allow_soles: false }, ); } Action::Despawn(entity_id) => { @@ -640,6 +627,7 @@ impl World components, &mut self.data.component_storage, &EventSubmitter::new(&self.data.new_events), + ComponentAddingFlags { allow_soles: false }, ); } Action::RemoveComponents(entity_uid, component_ids) => { @@ -670,6 +658,7 @@ impl World [new_pair], &mut self.data.component_storage, &EventSubmitter::new(&self.data.new_events), + ComponentAddingFlags { allow_soles: false }, ); } Action::Stop => { @@ -684,11 +673,18 @@ impl World components: impl IntoIterator<Item = ComponentParts>, component_storage: &mut ComponentStorage, event_submitter: &EventSubmitter<'_>, + flags: ComponentAddingFlags, ) { let component_iter = components.into_iter(); for component_parts in component_iter { + assert!( + flags.allow_soles || !component_parts.is_sole, + "Cannot add sole component '{}' to an entity", + component_parts.name + ); + let comp_id = component_parts.id; let comp_name = component_parts.name; let comp_type_id = (&*component_parts.data).type_id(); @@ -999,3 +995,9 @@ impl ActionQueue #[derive(Debug, thiserror::Error)] #[error("Sole already exists")] pub struct SoleAlreadyExistsError; + +#[derive(Debug)] +struct ComponentAddingFlags +{ + allow_soles: bool, +} |
