summaryrefslogtreecommitdiff
path: root/ecs/src/query
diff options
context:
space:
mode:
Diffstat (limited to 'ecs/src/query')
-rw-r--r--ecs/src/query/options.rs66
1 files changed, 66 insertions, 0 deletions
diff --git a/ecs/src/query/options.rs b/ecs/src/query/options.rs
new file mode 100644
index 0000000..d895073
--- /dev/null
+++ b/ecs/src/query/options.rs
@@ -0,0 +1,66 @@
+use std::collections::HashSet;
+use std::marker::PhantomData;
+
+use crate::component::{Component, Id as ComponentId};
+use crate::EntityComponent;
+
+/// Query options.
+pub trait Options
+{
+ fn entity_filter<'component>(
+ components: impl IntoIterator<Item = &'component EntityComponent>,
+ ) -> bool;
+}
+
+impl Options for ()
+{
+ fn entity_filter<'component>(
+ _: impl IntoIterator<Item = &'component EntityComponent>,
+ ) -> bool
+ {
+ true
+ }
+}
+
+pub struct With<ComponentT>
+where
+ ComponentT: Component,
+{
+ _pd: PhantomData<ComponentT>,
+}
+
+impl<ComponentT> Options for With<ComponentT>
+where
+ ComponentT: Component,
+{
+ fn entity_filter<'component>(
+ components: impl IntoIterator<Item = &'component EntityComponent>,
+ ) -> bool
+ {
+ let ids_set = components
+ .into_iter()
+ .map(|component| component.id)
+ .collect::<HashSet<_>>();
+
+ ids_set.contains(&ComponentId::of::<ComponentT>())
+ }
+}
+
+pub struct Not<OptionsT>
+where
+ OptionsT: Options,
+{
+ _pd: PhantomData<OptionsT>,
+}
+
+impl<OptionsT> Options for Not<OptionsT>
+where
+ OptionsT: Options,
+{
+ fn entity_filter<'component>(
+ components: impl IntoIterator<Item = &'component EntityComponent>,
+ ) -> bool
+ {
+ !OptionsT::entity_filter(components)
+ }
+}