legion/internals/query/filter/
not.rs1use 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#[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}