1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199
//! Filters for entities.
//!
//! `Filter`s are used to filter results when querying entities. Along with [`Views`], they are
//! what make up a query over a [`World`]. They provide the ability to query based on a
//! [`Component`] without actually having to borrow the `Component`'s value.
//!
//! Note that some `Views` provide implicit `Filter`s. Specifically, non-optional views over a
//! `Component` `C` (`&C` and `&mut C`) both implicitly [`And`] a [`Has<C>`] `Filter` with other
//! `Filter`s.
//!
//! [`And`]: crate::query::filter::And
//! [`Component`]: crate::component::Component
//! [`Has<C>`]: crate::query::filter::Has
//! [`Views`]: crate::query::view::Views
//! [`World`]: crate::world::World
mod sealed;
pub(crate) use sealed::Sealed;
use crate::{
component::Component,
entity,
query::view,
};
use core::marker::PhantomData;
/// A filter for entities.
///
/// `Filter`s are used to filter results when querying entities. Along with [`Views`], they are
/// what make up a query over a [`World`]. They provide the ability to query based on a
/// [`Component`] without actually having to borrow the `Component`'s value.
///
/// Note that some `Views` provide implicit `Filter`s. Specifically, non-optional views over a
/// `Component` `C` (`&C` and `&mut C`) both implicitly [`And`] a [`Has<C>`] `Filter` with other
/// `Filter`s.
///
/// [`And`]: crate::query::filter::And
/// [`Component`]: crate::component::Component
/// [`Has<C>`]: crate::query::filter::Has
/// [`Views`]: crate::query::view::Views
/// [`World`]: crate::world::World
pub trait Filter: Sealed {}
/// An empty filter.
///
/// This filter is used when a filter is required but nothing is needed to be filtered. For
/// example, some queries don't need any additional filtering beyond the filtering already provided
/// by their [`Views`]. This filter can be provided in those cases.
///
/// # Example
/// ``` rust
/// use brood::query::filter;
///
/// type NoFilter = filter::None;
/// ```
///
/// [`Views`]: crate::query::view::Views
pub enum None {}
impl Filter for None {}
/// Filter based on whether a [`Component`] is present in an entity.
///
/// This filters out any entities which do not have the `Component` `C`. No borrow of the value `C`
/// from the entity is required.
///
/// # Example'
/// ``` rust
/// use brood::query::filter;
///
/// // Define a component.
/// struct Foo(usize);
///
/// // Define a filter for the component above.
/// type HasFoo = filter::Has<Foo>;
/// ```
///
/// [`Component`]: crate::component::Component
pub struct Has<C>
where
C: Component,
{
component: PhantomData<C>,
}
impl<C> Filter for Has<C> where C: Component {}
/// Filter using the logical inverse of another [`Filter`].
///
/// This filters out any entities which would not have been filtered by the `Filter` `F`.
///
/// # Example
/// ``` rust
/// use brood::query::filter;
///
/// // Define a component.
/// struct Foo(usize);
///
/// // Define a filter for the component above.
/// type HasFoo = filter::Has<Foo>;
///
/// // Define a component that is the inverse of the filter above.
/// type DoesNotHaveFoo = filter::Not<HasFoo>;
/// ```
///
/// [`Filter`]: crate::query::filter::Filter
pub struct Not<F> {
filter: PhantomData<F>,
}
impl<F> Filter for Not<F> where F: Filter {}
/// Filter entities which are filtered by two [`Filter`]s.
///
/// This filter is a logical `and` between two `Filter`s `F1` and `F2`. Any entity filtered out by
/// either `Filter` will be filtered out by the `And` filter.
///
/// # Example
/// ``` rust
/// use brood::query::filter;
///
/// // Define components.
/// struct Foo(usize);
/// struct Bar(bool);
///
/// // Define filters based on the above components.
/// type HasFoo = filter::Has<Foo>;
/// type HasBar = filter::Has<Bar>;
///
/// // Define a filter using a combination of the above filters.
/// type HasFooAndBar = filter::And<HasFoo, HasBar>;
/// ```
///
/// [`Filter`]: crate::query::filter::Filter
pub struct And<F1, F2> {
filter_1: PhantomData<F1>,
filter_2: PhantomData<F2>,
}
impl<F1, F2> Filter for And<F1, F2>
where
F1: Filter,
F2: Filter,
{
}
/// Filter entities which are filtered by one of two [`Filter`]s.
///
/// This filter is a logical `or` between two `Filter`s `F1` and `F2`. Any entity filtered out by
/// both `Filter`s will be filtered out by the `Or` filter.
///
/// # Example
/// ``` rust
/// use brood::query::filter;
///
/// // Define components.
/// struct Foo(usize);
/// struct Bar(bool);
///
/// // Define filters based on the above components.
/// type HasFoo = filter::Has<Foo>;
/// type HasBar = filter::Has<Bar>;
///
/// // Define a filter using a combination of the above filters.
/// type HasFooOrBar = filter::Or<HasFoo, HasBar>;
/// ```
///
/// [`Filter`]: crate::query::filter::Filter
pub struct Or<F1, F2> {
filter_1: PhantomData<F1>,
filter_2: PhantomData<F2>,
}
impl<F1, F2> Filter for Or<F1, F2>
where
F1: Filter,
F2: Filter,
{
}
impl<C> Filter for &C where C: Component {}
impl<C> Filter for &mut C where C: Component {}
impl<C> Filter for Option<&C> where C: Component {}
impl<C> Filter for Option<&mut C> where C: Component {}
impl Filter for entity::Identifier {}
impl Filter for view::Null {}
impl<V, W> Filter for (V, W)
where
V: Filter,
W: Filter,
{
}