legion/internals/query/filter/
not.rs

1use super::{
2    and::And, or::Or, passthrough::Passthrough, ActiveFilter, DynamicFilter, FilterResult,
3    GroupMatcher, LayoutFilter,
4};
5use crate::internals::{query::view::Fetch, storage::component::ComponentTypeId, world::WorldId};
6
7/// A filter which negates `F`.
8#[derive(Debug, Clone, Default)]
9pub struct Not<F> {
10    pub(super) filter: F,
11}
12
13impl<F> ActiveFilter for Not<F> {}
14
15impl<F> GroupMatcher for Not<F> {
16    fn can_match_group() -> bool {
17        false
18    }
19    fn group_components() -> Vec<ComponentTypeId> {
20        vec![]
21    }
22}
23
24impl<F: LayoutFilter> LayoutFilter for Not<F> {
25    fn matches_layout(&self, components: &[ComponentTypeId]) -> FilterResult {
26        match self.filter.matches_layout(components) {
27            FilterResult::Match(success) => FilterResult::Match(!success),
28            FilterResult::Defer => FilterResult::Defer,
29        }
30    }
31}
32
33impl<F: DynamicFilter> DynamicFilter for Not<F> {
34    fn prepare(&mut self, world: WorldId) {
35        self.filter.prepare(world);
36    }
37
38    fn matches_archetype<T: Fetch>(&mut self, fetch: &T) -> FilterResult {
39        match self.filter.matches_archetype(fetch) {
40            FilterResult::Match(success) => FilterResult::Match(!success),
41            FilterResult::Defer => FilterResult::Defer,
42        }
43    }
44}
45
46impl<'a, F, Rhs: ActiveFilter> std::ops::BitAnd<Rhs> for Not<F> {
47    type Output = And<(Self, Rhs)>;
48
49    #[inline]
50    fn bitand(self, rhs: Rhs) -> Self::Output {
51        And {
52            filters: (self, rhs),
53        }
54    }
55}
56
57impl<'a, F> std::ops::BitAnd<Passthrough> for Not<F> {
58    type Output = Self;
59
60    #[inline]
61    fn bitand(self, _: Passthrough) -> Self::Output {
62        self
63    }
64}
65
66impl<'a, F, Rhs: ActiveFilter> std::ops::BitOr<Rhs> for Not<F> {
67    type Output = Or<(Self, Rhs)>;
68
69    #[inline]
70    fn bitor(self, rhs: Rhs) -> Self::Output {
71        Or {
72            filters: (self, rhs),
73        }
74    }
75}
76
77impl<'a, F> std::ops::BitOr<Passthrough> for Not<F> {
78    type Output = Self;
79
80    #[inline]
81    fn bitor(self, _: Passthrough) -> Self::Output {
82        self
83    }
84}