summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--engine-ecs/src/actions.rs47
-rw-r--r--engine-ecs/src/bundle.rs38
-rw-r--r--engine-ecs/src/lib.rs58
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,
+}