brood/query/view/contains/
filter.rs

1//! Denotes that a filter can be applied upon a set of views.
2
3use crate::{
4    archetype,
5    component,
6    entity,
7    query::{
8        filter::{
9            And,
10            Has,
11            None,
12            Not,
13            Or,
14        },
15        view,
16    },
17    registry,
18};
19
20mod index {
21    pub enum Index {}
22}
23
24/// Denotes that a filter can be applied upon views.
25///
26/// This means that any components viewed can also be filtered on, treating the views as a
27/// sub-registry.
28pub trait ContainsFilter<'a, Filter, Index>: Sealed<'a, Filter, Index> {}
29
30impl<'a, Views, Filter, Index> ContainsFilter<'a, Filter, Index> for Views where
31    Views: Sealed<'a, Filter, Index>
32{
33}
34
35pub trait Sealed<'a, Filter, Index>: view::Views<'a> + Sized {
36    /// # Safety
37    /// `indices` must contain valid indices into `Registry` (and therefore valid indices into
38    /// `identifier`).
39    unsafe fn filter<Registry>(
40        indices: &Self::Indices,
41        identifier: archetype::IdentifierRef<Registry>,
42    ) -> bool
43    where
44        Registry: registry::Registry;
45}
46
47impl<'a, Component, Views> Sealed<'a, Has<Component>, index::Index> for (&'a Component, Views)
48where
49    Component: component::Component,
50    Views: view::Views<'a>,
51    Self: view::Views<'a, Indices = (usize, Views::Indices)>,
52{
53    unsafe fn filter<Registry>(
54        indices: &Self::Indices,
55        identifier: archetype::IdentifierRef<Registry>,
56    ) -> bool
57    where
58        Registry: registry::Registry,
59    {
60        let index = indices.0;
61        // SAFETY: `index` is guaranteed to be a valid index into the `Registry`.
62        unsafe { identifier.get_unchecked(index) }
63    }
64}
65
66impl<'a, Component, Views> Sealed<'a, Has<Component>, index::Index> for (&'a mut Component, Views)
67where
68    Component: component::Component,
69    Views: view::Views<'a>,
70    Self: view::Views<'a, Indices = (usize, Views::Indices)>,
71{
72    unsafe fn filter<Registry>(
73        indices: &Self::Indices,
74        identifier: archetype::IdentifierRef<Registry>,
75    ) -> bool
76    where
77        Registry: registry::Registry,
78    {
79        let index = indices.0;
80        // SAFETY: `index` is guaranteed to be a valid index into the `Registry`.
81        unsafe { identifier.get_unchecked(index) }
82    }
83}
84
85impl<'a, Component, Views> Sealed<'a, Has<Component>, index::Index>
86    for (Option<&'a Component>, Views)
87where
88    Component: component::Component,
89    Views: view::Views<'a>,
90    Self: view::Views<'a, Indices = (usize, Views::Indices)>,
91{
92    unsafe fn filter<Registry>(
93        indices: &Self::Indices,
94        identifier: archetype::IdentifierRef<Registry>,
95    ) -> bool
96    where
97        Registry: registry::Registry,
98    {
99        let index = indices.0;
100        // SAFETY: `index` is guaranteed to be a valid index into the `Registry`.
101        unsafe { identifier.get_unchecked(index) }
102    }
103}
104
105impl<'a, Component, Views> Sealed<'a, Has<Component>, index::Index>
106    for (Option<&'a mut Component>, Views)
107where
108    Component: component::Component,
109    Views: view::Views<'a>,
110    Self: view::Views<'a, Indices = (usize, Views::Indices)>,
111{
112    unsafe fn filter<Registry>(
113        indices: &Self::Indices,
114        identifier: archetype::IdentifierRef<Registry>,
115    ) -> bool
116    where
117        Registry: registry::Registry,
118    {
119        let index = indices.0;
120        // SAFETY: `index` is guaranteed to be a valid index into the `Registry`.
121        unsafe { identifier.get_unchecked(index) }
122    }
123}
124
125impl<'a, Component, View, Views, Index> Sealed<'a, Has<Component>, (Index,)> for (View, Views)
126where
127    Component: component::Component,
128    View: view::View<'a>,
129    Views: Sealed<'a, Has<Component>, Index>,
130    Self: view::Views<'a, Indices = (View::Index, Views::Indices)>,
131{
132    unsafe fn filter<Registry>(
133        indices: &Self::Indices,
134        identifier: archetype::IdentifierRef<Registry>,
135    ) -> bool
136    where
137        Registry: registry::Registry,
138    {
139        // SAFETY: `indices.1` is guaranteed to contain valid indices into `Registry`.
140        unsafe { Views::filter(&indices.1, identifier) }
141    }
142}
143
144impl<'a, FilterA, FilterB, Views, IndexA, IndexB>
145    Sealed<'a, And<FilterA, FilterB>, And<IndexA, IndexB>> for Views
146where
147    Views: Sealed<'a, FilterA, IndexA> + Sealed<'a, FilterB, IndexB>,
148    Self: view::Views<'a>,
149{
150    unsafe fn filter<Registry>(
151        indices: &Self::Indices,
152        identifier: archetype::IdentifierRef<Registry>,
153    ) -> bool
154    where
155        Registry: registry::Registry,
156    {
157        // SAFETY: `indices` is guaranteed to contain valid indices into `Registry`.
158        unsafe {
159            <Views as Sealed<'a, FilterA, IndexA>>::filter(indices, identifier)
160                && <Views as Sealed<'a, FilterB, IndexB>>::filter(indices, identifier)
161        }
162    }
163}
164
165impl<'a, FilterA, FilterB, Views, IndexA, IndexB>
166    Sealed<'a, Or<FilterA, FilterB>, Or<IndexA, IndexB>> for Views
167where
168    Views: Sealed<'a, FilterA, IndexA> + Sealed<'a, FilterB, IndexB>,
169    Self: view::Views<'a>,
170{
171    unsafe fn filter<Registry>(
172        indices: &Self::Indices,
173        identifier: archetype::IdentifierRef<Registry>,
174    ) -> bool
175    where
176        Registry: registry::Registry,
177    {
178        // SAFETY: `indices` is guaranteed to contain valid indices into `Registry`.
179        unsafe {
180            <Views as Sealed<'a, FilterA, IndexA>>::filter(indices, identifier)
181                || <Views as Sealed<'a, FilterB, IndexB>>::filter(indices, identifier)
182        }
183    }
184}
185
186impl<'a, Filter, Views, Index> Sealed<'a, Not<Filter>, Index> for Views
187where
188    Views: Sealed<'a, Filter, Index>,
189{
190    unsafe fn filter<Registry>(
191        indices: &Self::Indices,
192        identifier: archetype::IdentifierRef<Registry>,
193    ) -> bool
194    where
195        Registry: registry::Registry,
196    {
197        // SAFETY: `indices` is guaranteed to contain valid indices into `Registry`.
198        !unsafe { Views::filter(indices, identifier) }
199    }
200}
201
202impl<'a, Views> Sealed<'a, None, index::Index> for Views
203where
204    Self: view::Views<'a>,
205{
206    unsafe fn filter<Registry>(
207        _indices: &Self::Indices,
208        _identifier: archetype::IdentifierRef<Registry>,
209    ) -> bool
210    where
211        Registry: registry::Registry,
212    {
213        true
214    }
215}
216
217impl<'a, Component, Views> Sealed<'a, &'a Component, index::Index> for (&'a Component, Views)
218where
219    Views: view::Views<'a>,
220    Self: view::Views<'a, Indices = (usize, Views::Indices)>,
221{
222    unsafe fn filter<Registry>(
223        indices: &Self::Indices,
224        identifier: archetype::IdentifierRef<Registry>,
225    ) -> bool
226    where
227        Registry: registry::Registry,
228    {
229        let index = indices.0;
230        // SAFETY: `index` is guaranteed to be a valid index into the `Registry`.
231        unsafe { identifier.get_unchecked(index) }
232    }
233}
234
235impl<'a, Component, Views> Sealed<'a, Option<&'a Component>, index::Index> for Views
236where
237    Self: view::Views<'a>,
238{
239    unsafe fn filter<Registry>(
240        _indices: &Self::Indices,
241        _identifier: archetype::IdentifierRef<Registry>,
242    ) -> bool
243    where
244        Registry: registry::Registry,
245    {
246        true
247    }
248}
249
250impl<'a, Component, Views> Sealed<'a, &'a Component, index::Index> for (&'a mut Component, Views)
251where
252    Views: view::Views<'a>,
253    Self: view::Views<'a, Indices = (usize, Views::Indices)>,
254{
255    unsafe fn filter<Registry>(
256        indices: &Self::Indices,
257        identifier: archetype::IdentifierRef<Registry>,
258    ) -> bool
259    where
260        Registry: registry::Registry,
261    {
262        let index = indices.0;
263        // SAFETY: `index` is guaranteed to be a valid index into the `Registry`.
264        unsafe { identifier.get_unchecked(index) }
265    }
266}
267
268impl<'a, Component, Views> Sealed<'a, &'a mut Component, index::Index>
269    for (&'a mut Component, Views)
270where
271    Views: view::Views<'a>,
272    Self: view::Views<'a, Indices = (usize, Views::Indices)>,
273{
274    unsafe fn filter<Registry>(
275        indices: &Self::Indices,
276        identifier: archetype::IdentifierRef<Registry>,
277    ) -> bool
278    where
279        Registry: registry::Registry,
280    {
281        let index = indices.0;
282        // SAFETY: `index` is guaranteed to be a valid index into the `Registry`.
283        unsafe { identifier.get_unchecked(index) }
284    }
285}
286
287impl<'a, Component, Views> Sealed<'a, Option<&'a mut Component>, index::Index> for Views
288where
289    Self: view::Views<'a>,
290{
291    unsafe fn filter<Registry>(
292        _indices: &Self::Indices,
293        _identifier: archetype::IdentifierRef<Registry>,
294    ) -> bool
295    where
296        Registry: registry::Registry,
297    {
298        true
299    }
300}
301
302impl<'a, Component, Views> Sealed<'a, &'a Component, index::Index>
303    for (Option<&'a Component>, Views)
304where
305    Views: view::Views<'a>,
306    Self: view::Views<'a, Indices = (usize, Views::Indices)>,
307{
308    unsafe fn filter<Registry>(
309        indices: &Self::Indices,
310        identifier: archetype::IdentifierRef<Registry>,
311    ) -> bool
312    where
313        Registry: registry::Registry,
314    {
315        let index = indices.0;
316        // SAFETY: `index` is guaranteed to be a valid index into the `Registry`.
317        unsafe { identifier.get_unchecked(index) }
318    }
319}
320
321impl<'a, Component, Views> Sealed<'a, &'a Component, index::Index>
322    for (Option<&'a mut Component>, Views)
323where
324    Views: view::Views<'a>,
325    Self: view::Views<'a, Indices = (usize, Views::Indices)>,
326{
327    unsafe fn filter<Registry>(
328        indices: &Self::Indices,
329        identifier: archetype::IdentifierRef<Registry>,
330    ) -> bool
331    where
332        Registry: registry::Registry,
333    {
334        let index = indices.0;
335        // SAFETY: `index` is guaranteed to be a valid index into the `Registry`.
336        unsafe { identifier.get_unchecked(index) }
337    }
338}
339
340impl<'a, Component, Views> Sealed<'a, &'a mut Component, index::Index>
341    for (Option<&'a mut Component>, Views)
342where
343    Views: view::Views<'a>,
344    Self: view::Views<'a, Indices = (usize, Views::Indices)>,
345{
346    unsafe fn filter<Registry>(
347        indices: &Self::Indices,
348        identifier: archetype::IdentifierRef<Registry>,
349    ) -> bool
350    where
351        Registry: registry::Registry,
352    {
353        let index = indices.0;
354        // SAFETY: `index` is guaranteed to be a valid index into the `Registry`.
355        unsafe { identifier.get_unchecked(index) }
356    }
357}
358
359impl<'a, Component, View, Views, Index> Sealed<'a, &'a Component, (Index,)> for (View, Views)
360where
361    Component: component::Component,
362    View: view::View<'a>,
363    Views: Sealed<'a, &'a Component, Index>,
364    Self: view::Views<'a, Indices = (View::Index, Views::Indices)>,
365{
366    unsafe fn filter<Registry>(
367        indices: &Self::Indices,
368        identifier: archetype::IdentifierRef<Registry>,
369    ) -> bool
370    where
371        Registry: registry::Registry,
372    {
373        // SAFETY: `indices.1` is guaranteed to contain valid indices into `Registry`.
374        unsafe { Views::filter(&indices.1, identifier) }
375    }
376}
377
378impl<'a, Component, View, Views, Index> Sealed<'a, &'a mut Component, (Index,)> for (View, Views)
379where
380    Component: component::Component,
381    View: view::View<'a>,
382    Views: Sealed<'a, &'a mut Component, Index>,
383    Self: view::Views<'a, Indices = (View::Index, Views::Indices)>,
384{
385    unsafe fn filter<Registry>(
386        indices: &Self::Indices,
387        identifier: archetype::IdentifierRef<Registry>,
388    ) -> bool
389    where
390        Registry: registry::Registry,
391    {
392        // SAFETY: `indices.1` is guaranteed to contain valid indices into `Registry`.
393        unsafe { Views::filter(&indices.1, identifier) }
394    }
395}
396
397impl<'a, Views> Sealed<'a, entity::Identifier, index::Index> for Views
398where
399    Self: view::Views<'a>,
400{
401    unsafe fn filter<Registry>(
402        _indices: &Self::Indices,
403        _identifier: archetype::IdentifierRef<Registry>,
404    ) -> bool
405    where
406        Registry: registry::Registry,
407    {
408        true
409    }
410}
411
412impl<'a, Views> Sealed<'a, view::Null, index::Index> for Views
413where
414    Self: view::Views<'a>,
415{
416    unsafe fn filter<Registry>(
417        _indices: &Self::Indices,
418        _identifier: archetype::IdentifierRef<Registry>,
419    ) -> bool
420    where
421        Registry: registry::Registry,
422    {
423        true
424    }
425}
426
427impl<'a, Views, Filter, Filters, Index, Indices> Sealed<'a, (Filter, Filters), (Index, Indices)>
428    for Views
429where
430    Self: view::Views<'a>,
431    Views: Sealed<'a, Filter, Index> + Sealed<'a, Filters, Indices>,
432{
433    unsafe fn filter<Registry>(
434        indices: &Self::Indices,
435        identifier: archetype::IdentifierRef<Registry>,
436    ) -> bool
437    where
438        Registry: registry::Registry,
439    {
440        // SAFETY: `indices` is guaranteed to contain valid indices into `Registry`.
441        unsafe {
442            <Views as Sealed<'a, Filter, Index>>::filter(indices, identifier)
443                && <Views as Sealed<'a, Filters, Indices>>::filter(indices, identifier)
444        }
445    }
446}