summaryrefslogtreecommitdiff
path: root/ecs/src/component/storage.rs
diff options
context:
space:
mode:
Diffstat (limited to 'ecs/src/component/storage.rs')
-rw-r--r--ecs/src/component/storage.rs63
1 files changed, 46 insertions, 17 deletions
diff --git a/ecs/src/component/storage.rs b/ecs/src/component/storage.rs
index 53f51f2..9cf4433 100644
--- a/ecs/src/component/storage.rs
+++ b/ecs/src/component/storage.rs
@@ -33,14 +33,43 @@ pub struct ArchetypeSearchTerms<'a>
impl ArchetypeSearchTerms<'_>
{
- fn excluded_contains(&self, uid: Uid) -> bool
+ fn excluded_contains(&self, comp_id: Uid) -> bool
{
- self.excluded_components.binary_search(&uid).is_ok()
+ let comp_id_kind = comp_id.kind();
+
+ debug_assert!(
+ comp_id_kind == UidKind::Component
+ || (comp_id_kind == UidKind::Pair
+ && comp_id.target_component() != Uid::wildcard())
+ );
+
+ let is_found = self.excluded_components.binary_search(&comp_id).is_ok();
+
+ if !is_found && comp_id_kind == UidKind::Pair {
+ return self.excluded_components.iter().any(|excluded_comp_id| {
+ excluded_comp_id.kind() == UidKind::Pair
+ && excluded_comp_id.has_same_relation_as(comp_id)
+ && excluded_comp_id.target_component() == Uid::wildcard()
+ });
+ }
+
+ is_found
}
- fn required_contains(&self, uid: Uid) -> bool
+ fn contains_conflicting(&self) -> bool
{
- self.required_components.binary_search(&uid).is_ok()
+ self.excluded_components.iter().any(|excluded_comp_id| {
+ self.required_components
+ .binary_search(excluded_comp_id)
+ .is_ok()
+ })
+ }
+
+ fn archetype_contains_all_required(&self, archetype: &Archetype) -> bool
+ {
+ self.required_components
+ .iter()
+ .all(|comp_id| archetype.contains_matching_component(*comp_id))
}
}
@@ -61,11 +90,7 @@ impl Storage
{
let archetype_id = ArchetypeId::new(&search_terms.required_components);
- if search_terms
- .excluded_components
- .iter()
- .any(|excluded_comp_id| search_terms.required_contains(*excluded_comp_id))
- {
+ if search_terms.contains_conflicting() {
return ArchetypeRefIter {
storage: self,
pre_iter: Either::B(Vec::new().into_iter()),
@@ -81,7 +106,15 @@ impl Storage
.borrow_mut()
.push(ImaginaryArchetype {
id: archetype_id,
- component_ids: search_terms.required_components.to_vec(),
+ component_ids: search_terms
+ .required_components
+ .iter()
+ .copied()
+ .filter(|required_comp_id| {
+ required_comp_id.kind() != UidKind::Pair
+ || required_comp_id.target_component() != Uid::wildcard()
+ })
+ .collect(),
});
let found_archetypes = self.find_all_archetype_with_comps(&search_terms);
@@ -175,7 +208,7 @@ impl Storage
if archetype_node
.archetype()
- .has_component_with_id(component_id)
+ .contains_component_with_exact_id(component_id)
{
return Err(Error::ComponentAlreadyInEntity {
entity: entity_uid,
@@ -266,7 +299,7 @@ impl Storage
if !archetype_node
.archetype()
- .has_component_with_id(component_id)
+ .contains_component_with_exact_id(component_id)
{
return Err(Error::ComponentNotFoundInEntity {
entity: entity_uid,
@@ -367,11 +400,7 @@ impl Storage
continue;
}
- if !search_terms
- .required_components
- .iter()
- .all(|comp_id| node.archetype().has_component_with_id(*comp_id))
- {
+ if !search_terms.archetype_contains_all_required(node.archetype()) {
continue;
}