summaryrefslogtreecommitdiff
path: root/engine-ecs
diff options
context:
space:
mode:
Diffstat (limited to 'engine-ecs')
-rw-r--r--engine-ecs/src/actions.rs51
-rw-r--r--engine-ecs/src/component.rs36
-rw-r--r--engine-ecs/src/lib.rs99
-rw-r--r--engine-ecs/src/pair.rs5
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]