diff options
Diffstat (limited to 'engine-ecs')
| -rw-r--r-- | engine-ecs/src/actions.rs | 51 | ||||
| -rw-r--r-- | engine-ecs/src/component.rs | 36 | ||||
| -rw-r--r-- | engine-ecs/src/lib.rs | 99 | ||||
| -rw-r--r-- | engine-ecs/src/pair.rs | 5 |
4 files changed, 144 insertions, 47 deletions
diff --git a/engine-ecs/src/actions.rs b/engine-ecs/src/actions.rs index 8387acc..9ca9198 100644 --- a/engine-ecs/src/actions.rs +++ b/engine-ecs/src/actions.rs @@ -29,10 +29,21 @@ impl Actions<'_> { let new_entity_uid = Uid::new_unique(); - self.action_queue.push(Action::Spawn( - new_entity_uid, - components.into_parts_array().into(), - )); + let components_parts = components.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 + ); + } + + self.action_queue + .push(Action::Spawn(new_entity_uid, components_parts.into())); new_entity_uid } @@ -50,10 +61,22 @@ impl Actions<'_> { let new_entity_uid = Uid::new_unique(); + let components_parts = components.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 + ); + } + self.action_queue.push(Action::Spawn( new_entity_uid, - components - .into_parts_array() + components_parts .into_iter() .chain([EntityName { name: name.into() }.into_parts()]) .collect(), @@ -106,10 +129,18 @@ impl Actions<'_> return; } - self.action_queue.push(Action::AddComponents( - entity_uid, - components.into_parts_array().into(), - )); + let components_parts = components.into_parts_array(); + + if let Some(comp_parts) = components_parts + .as_ref() + .iter() + .find(|comp_parts| comp_parts.is_sole) + { + panic!("Cannot add sole component {} to an entity", comp_parts.name); + } + + self.action_queue + .push(Action::AddComponents(entity_uid, components_parts.into())); } /// Queues up removing component(s) from a entity at the end of the current tick. diff --git a/engine-ecs/src/component.rs b/engine-ecs/src/component.rs index 9220ffb..847ecbd 100644 --- a/engine-ecs/src/component.rs +++ b/engine-ecs/src/component.rs @@ -294,6 +294,7 @@ pub struct Parts { pub id: Uid, pub name: &'static str, + pub is_sole: bool, pub type_reflection: Option<&'static TypeReflection>, pub data: Box<dyn Any>, pub pair_relation_metadata: Option<PairMemberMetadata>, @@ -302,6 +303,18 @@ pub struct Parts impl Parts { + pub fn from_component_info(component_info: &Info, id: Uid, data: Box<dyn Any>) + -> Self + { + assert_eq!((*data).type_id(), component_info.ty_id); + + Self::builder() + .type_reflection(component_info.type_reflection) + .name(component_info.name) + .is_sole(component_info.is_sole) + .build_with_any_data(id, data) + } + #[must_use] pub fn builder() -> PartsBuilder { @@ -313,6 +326,7 @@ impl Parts pub struct PartsBuilder { name: &'static str, + is_sole: bool, type_reflection: Option<&'static TypeReflection>, pair_relation_metadata: Option<PairMemberMetadata>, pair_target_metadata: Option<PairMemberMetadata>, @@ -328,6 +342,13 @@ impl PartsBuilder } #[must_use] + pub fn is_sole(mut self, is_sole: bool) -> Self + { + self.is_sole = is_sole; + self + } + + #[must_use] pub fn type_reflection( mut self, type_reflection: Option<&'static TypeReflection>, @@ -338,20 +359,15 @@ impl PartsBuilder } #[must_use] - pub fn pair_relation_metadata( - mut self, - metadata: Option<PairMemberMetadata>, - ) -> Self + pub fn pair_relation_metadata(mut self, metadata: Option<PairMemberMetadata>) + -> Self { self.pair_relation_metadata = metadata; self } #[must_use] - pub fn pair_target_metadata( - mut self, - metadata: Option<PairMemberMetadata>, - ) -> Self + pub fn pair_target_metadata(mut self, metadata: Option<PairMemberMetadata>) -> Self { self.pair_target_metadata = metadata; self @@ -363,6 +379,7 @@ impl PartsBuilder Parts { id, name: self.name, + is_sole: self.is_sole, type_reflection: self.type_reflection, data: Box::new(data), pair_relation_metadata: self.pair_relation_metadata, @@ -376,6 +393,7 @@ impl PartsBuilder Parts { id, name: self.name, + is_sole: self.is_sole, type_reflection: self.type_reflection, data, pair_relation_metadata: self.pair_relation_metadata, @@ -390,6 +408,7 @@ impl Default for PartsBuilder { Self { name: "(unspecified)", + is_sole: false, type_reflection: None, pair_relation_metadata: None, pair_target_metadata: None, @@ -404,4 +423,5 @@ pub struct Info pub type_reflection: Option<&'static TypeReflection>, pub ty_id: TypeId, pub name: &'static str, + pub is_sole: bool, } diff --git a/engine-ecs/src/lib.rs b/engine-ecs/src/lib.rs index b987f65..450940a 100644 --- a/engine-ecs/src/lib.rs +++ b/engine-ecs/src/lib.rs @@ -1,6 +1,6 @@ #![deny(clippy::all, clippy::pedantic)] -use std::any::{Any, TypeId}; +use std::any::Any; use std::borrow::Cow; use std::fmt::Debug; use std::hint::cold_path; @@ -54,7 +54,6 @@ use crate::query::{ TermsBuilderInterface, MAX_TERM_CNT as QUERY_MAX_TERM_CNT, }; -use crate::reflection::Type as TypeReflection; use crate::sole::{Single, Sole}; use crate::system::observer::Observer; use crate::system::{ @@ -176,7 +175,20 @@ impl World where Comps: ComponentSequence, { - self.create_ent(entity_uid, components.into_parts_array()); + let components_parts = components.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 + ); + } + + self.create_ent(entity_uid, components_parts); } /// Creates a entity with the given components. The entity will have the specified @@ -193,10 +205,22 @@ impl World ) where Comps: ComponentSequence, { + let components_parts = components.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 + ); + } + self.create_ent( entity_uid, - components - .into_parts_array() + components_parts .into_iter() .chain([EntityName { name: name.into() }.into_parts()]), ); @@ -204,6 +228,12 @@ impl World pub fn add_component(&mut self, entity_id: Uid, component_parts: ComponentParts) { + assert!( + !component_parts.is_sole, + "Cannot add sole component {} to an entity", + component_parts.name + ); + Self::add_entity_components( entity_id, [component_parts], @@ -225,6 +255,15 @@ impl World where SoleT: Sole, { + if self + .data + .component_storage + .get_entity_archetype(SoleT::id()) + .is_some() + { + return Err(SoleAlreadyExistsError); + } + let name = sole.name(); self.create_ent( @@ -685,22 +724,28 @@ impl World &component_parts.pair_relation_metadata { Self::create_component_info_entity_if_missing( - comp_id.relation(), - pair_relation_metadata.name, - pair_relation_metadata.ty, - pair_relation_metadata.ty_id, component_storage, + comp_id.relation(), + ComponentInfo { + type_reflection: pair_relation_metadata.ty, + ty_id: pair_relation_metadata.ty_id, + name: pair_relation_metadata.name, + is_sole: pair_relation_metadata.is_sole, + }, ); } if let Some(pair_target_metadata) = &component_parts.pair_target_metadata { Self::create_component_info_entity_if_missing( - comp_id.target(), - pair_target_metadata.name, - pair_target_metadata.ty, - pair_target_metadata.ty_id, component_storage, + comp_id.target(), + ComponentInfo { + type_reflection: pair_target_metadata.ty, + ty_id: pair_target_metadata.ty_id, + name: pair_target_metadata.name, + is_sole: pair_target_metadata.is_sole, + }, ); } @@ -708,11 +753,14 @@ impl World } Self::create_component_info_entity_if_missing( - comp_id, - comp_name, - component_parts.type_reflection, - comp_type_id, component_storage, + comp_id, + ComponentInfo { + type_reflection: component_parts.type_reflection, + ty_id: comp_type_id, + name: comp_name, + is_sole: component_parts.is_sole, + }, ); event_submitter.submit_event( @@ -726,11 +774,9 @@ impl World } fn create_component_info_entity_if_missing( - comp_id: Uid, - comp_name: &'static str, - type_reflection: Option<&'static TypeReflection>, - type_id: TypeId, component_storage: &mut ComponentStorage, + comp_id: Uid, + comp_info: ComponentInfo, ) { if let Some(comp_ent_archetype) = component_storage.get_entity_archetype(comp_id) @@ -746,12 +792,7 @@ impl World } } - let comp_info_parts = ComponentInfo { - type_reflection, - name: comp_name, - ty_id: type_id, - } - .into_parts(); + let comp_info_parts = comp_info.into_parts(); match component_storage.add_entity_component( comp_id, @@ -962,5 +1003,5 @@ impl ActionQueue } #[derive(Debug, thiserror::Error)] -#[error("Sole {0} already exists")] -pub struct SoleAlreadyExistsError(pub &'static str); +#[error("Sole already exists")] +pub struct SoleAlreadyExistsError; diff --git a/engine-ecs/src/pair.rs b/engine-ecs/src/pair.rs index 98f0257..834077c 100644 --- a/engine-ecs/src/pair.rs +++ b/engine-ecs/src/pair.rs @@ -46,6 +46,7 @@ impl<Relation, Target> Builder<Relation, Target> ty: NewRelation::type_reflection(), ty_id: TypeId::of::<NewRelation>(), name: type_name::<NewRelation>(), + is_sole: false, }), target_metadata: self.target_metadata, } @@ -71,6 +72,7 @@ impl<Relation, Target> Builder<Relation, Target> ty: NewTarget::type_reflection(), ty_id: TypeId::of::<NewTarget>(), name: type_name::<NewTarget>(), + is_sole: false, }), } } @@ -103,6 +105,7 @@ impl_multiple!( ty: NewTarget::type_reflection(), ty_id: TypeId::of::<NewTarget>(), name: type_name::<NewTarget>(), + is_sole: false, }), } } @@ -125,6 +128,7 @@ impl_multiple!( ty: NewRelation::type_reflection(), ty_id: TypeId::of::<NewRelation>(), name: type_name::<NewRelation>(), + is_sole: false, }), target_metadata: self.target_metadata, } @@ -770,6 +774,7 @@ pub struct MemberMetadata pub ty: Option<&'static TypeReflection>, pub ty_id: TypeId, pub name: &'static str, + pub is_sole: bool, } #[macro_export] |
