summaryrefslogtreecommitdiff
path: root/engine-ecs/src/component
diff options
context:
space:
mode:
authorHampusM <hampus@hampusmat.com>2026-08-17 14:46:14 +0200
committerHampusM <hampus@hampusmat.com>2026-08-17 14:46:14 +0200
commit4c4dd2b8bfa4655acbf03967f274e76440ec9530 (patch)
treeec635a0d2dce3d49d4564f21cb2a9058190e88f4 /engine-ecs/src/component
parent11efaee7b80c5c9b8227d265874842da9a5f85fd (diff)
feat(engine-ecs): add query traversal kind SelfOrUp
Diffstat (limited to 'engine-ecs/src/component')
-rw-r--r--engine-ecs/src/component/storage.rs70
1 files changed, 57 insertions, 13 deletions
diff --git a/engine-ecs/src/component/storage.rs b/engine-ecs/src/component/storage.rs
index f6ab309..5746bea 100644
--- a/engine-ecs/src/component/storage.rs
+++ b/engine-ecs/src/component/storage.rs
@@ -80,6 +80,7 @@ impl<const TERM_CAP: usize> Traversal<TERM_CAP>
pub enum TraversalKind
{
Up,
+ SelfOrUp,
}
#[derive(Debug)]
@@ -87,7 +88,15 @@ pub struct TraversalResult
{
pub relation: Uid,
pub term_metadata: TermMetadata,
- pub found_ent: Uid,
+ pub found: FoundByTraversal,
+}
+
+#[derive(Debug)]
+#[non_exhaustive]
+pub enum FoundByTraversal
+{
+ SelfEntity,
+ OtherEntity(Uid),
}
impl<const TERM_CAP: usize> SearchTerms<TERM_CAP>
@@ -869,20 +878,55 @@ fn do_traversals<const TERM_CAP: usize>(
// TODO: Optimize traversals. Caching is needed especially
for traversal in traversals {
- if traversal.kind == TraversalKind::Up {
- archetype
- .get_matching_component_ids(traversal.relationship())
- .find_map(|relationship| {
- traverse_dfs(
+ let traversal_terms = (traversal.terms)(traversal);
+
+ match traversal.kind {
+ TraversalKind::Up => {
+ archetype
+ .get_matching_component_ids(traversal.relationship())
+ .find_map(|relationship| {
+ traverse_dfs(
+ storage,
+ relationship.target(),
+ traversal,
+ &traversal_terms,
+ results,
+ )
+ })?;
+ }
+ TraversalKind::SelfOrUp => {
+ if traversal_terms.absent.iter().all(|absent_comp_id| {
+ !archetype.contains_matching_component(*absent_comp_id)
+ }) && traversal_terms.archetype_contains_all_required(archetype)
+ && do_traversals(
storage,
- relationship.target(),
- traversal,
- &(traversal.terms)(traversal),
+ archetype,
+ &traversal_terms.traverse,
results,
)
- })?;
- } else {
- unimplemented!();
+ .is_some()
+ {
+ results.push(TraversalResult {
+ relation: traversal.relation,
+ term_metadata: traversal.term_metadata,
+ found: FoundByTraversal::SelfEntity,
+ });
+
+ return Some(());
+ }
+
+ archetype
+ .get_matching_component_ids(traversal.relationship())
+ .find_map(|relationship| {
+ traverse_dfs(
+ storage,
+ relationship.target(),
+ traversal,
+ &traversal_terms,
+ results,
+ )
+ })?;
+ }
}
}
@@ -909,7 +953,7 @@ fn traverse_dfs<const TERM_CAP: usize>(
results.push(TraversalResult {
relation: traversal.relation,
term_metadata: traversal.term_metadata,
- found_ent: ent_id,
+ found: FoundByTraversal::OtherEntity(ent_id),
});
return Some(());