bevy_ecs/query/
access.rs

1use crate::component::ComponentId;
2use crate::storage::SparseSetIndex;
3use crate::world::World;
4use alloc::{format, string::String, vec, vec::Vec};
5use core::{fmt, fmt::Debug, marker::PhantomData};
6use derive_more::From;
7use disqualified::ShortName;
8use fixedbitset::FixedBitSet;
9use thiserror::Error;
10
11/// A wrapper struct to make Debug representations of [`FixedBitSet`] easier
12/// to read, when used to store [`SparseSetIndex`].
13///
14/// Instead of the raw integer representation of the `FixedBitSet`, the list of
15/// `T` valid for [`SparseSetIndex`] is shown.
16///
17/// Normal `FixedBitSet` `Debug` output:
18/// ```text
19/// read_and_writes: FixedBitSet { data: [ 160 ], length: 8 }
20/// ```
21///
22/// Which, unless you are a computer, doesn't help much understand what's in
23/// the set. With `FormattedBitSet`, we convert the present set entries into
24/// what they stand for, it is much clearer what is going on:
25/// ```text
26/// read_and_writes: [ ComponentId(5), ComponentId(7) ]
27/// ```
28struct FormattedBitSet<'a, T: SparseSetIndex> {
29    bit_set: &'a FixedBitSet,
30    _marker: PhantomData<T>,
31}
32
33impl<'a, T: SparseSetIndex> FormattedBitSet<'a, T> {
34    fn new(bit_set: &'a FixedBitSet) -> Self {
35        Self {
36            bit_set,
37            _marker: PhantomData,
38        }
39    }
40}
41
42impl<'a, T: SparseSetIndex + Debug> Debug for FormattedBitSet<'a, T> {
43    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
44        f.debug_list()
45            .entries(self.bit_set.ones().map(T::get_sparse_set_index))
46            .finish()
47    }
48}
49
50/// Tracks read and write access to specific elements in a collection.
51///
52/// Used internally to ensure soundness during system initialization and execution.
53/// See the [`is_compatible`](Access::is_compatible) and [`get_conflicts`](Access::get_conflicts) functions.
54#[derive(Eq, PartialEq)]
55pub struct Access<T: SparseSetIndex> {
56    /// All accessed components, or forbidden components if
57    /// `Self::component_read_and_writes_inverted` is set.
58    component_read_and_writes: FixedBitSet,
59    /// All exclusively-accessed components, or components that may not be
60    /// exclusively accessed if `Self::component_writes_inverted` is set.
61    component_writes: FixedBitSet,
62    /// All accessed resources.
63    resource_read_and_writes: FixedBitSet,
64    /// The exclusively-accessed resources.
65    resource_writes: FixedBitSet,
66    /// Is `true` if this component can read all components *except* those
67    /// present in `Self::component_read_and_writes`.
68    component_read_and_writes_inverted: bool,
69    /// Is `true` if this component can write to all components *except* those
70    /// present in `Self::component_writes`.
71    component_writes_inverted: bool,
72    /// Is `true` if this has access to all resources.
73    /// This field is a performance optimization for `&World` (also harder to mess up for soundness).
74    reads_all_resources: bool,
75    /// Is `true` if this has mutable access to all resources.
76    /// If this is true, then `reads_all` must also be true.
77    writes_all_resources: bool,
78    // Components that are not accessed, but whose presence in an archetype affect query results.
79    archetypal: FixedBitSet,
80    marker: PhantomData<T>,
81}
82
83// This is needed since `#[derive(Clone)]` does not generate optimized `clone_from`.
84impl<T: SparseSetIndex> Clone for Access<T> {
85    fn clone(&self) -> Self {
86        Self {
87            component_read_and_writes: self.component_read_and_writes.clone(),
88            component_writes: self.component_writes.clone(),
89            resource_read_and_writes: self.resource_read_and_writes.clone(),
90            resource_writes: self.resource_writes.clone(),
91            component_read_and_writes_inverted: self.component_read_and_writes_inverted,
92            component_writes_inverted: self.component_writes_inverted,
93            reads_all_resources: self.reads_all_resources,
94            writes_all_resources: self.writes_all_resources,
95            archetypal: self.archetypal.clone(),
96            marker: PhantomData,
97        }
98    }
99
100    fn clone_from(&mut self, source: &Self) {
101        self.component_read_and_writes
102            .clone_from(&source.component_read_and_writes);
103        self.component_writes.clone_from(&source.component_writes);
104        self.resource_read_and_writes
105            .clone_from(&source.resource_read_and_writes);
106        self.resource_writes.clone_from(&source.resource_writes);
107        self.component_read_and_writes_inverted = source.component_read_and_writes_inverted;
108        self.component_writes_inverted = source.component_writes_inverted;
109        self.reads_all_resources = source.reads_all_resources;
110        self.writes_all_resources = source.writes_all_resources;
111        self.archetypal.clone_from(&source.archetypal);
112    }
113}
114
115impl<T: SparseSetIndex + Debug> Debug for Access<T> {
116    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
117        f.debug_struct("Access")
118            .field(
119                "component_read_and_writes",
120                &FormattedBitSet::<T>::new(&self.component_read_and_writes),
121            )
122            .field(
123                "component_writes",
124                &FormattedBitSet::<T>::new(&self.component_writes),
125            )
126            .field(
127                "resource_read_and_writes",
128                &FormattedBitSet::<T>::new(&self.resource_read_and_writes),
129            )
130            .field(
131                "resource_writes",
132                &FormattedBitSet::<T>::new(&self.resource_writes),
133            )
134            .field(
135                "component_read_and_writes_inverted",
136                &self.component_read_and_writes_inverted,
137            )
138            .field("component_writes_inverted", &self.component_writes_inverted)
139            .field("reads_all_resources", &self.reads_all_resources)
140            .field("writes_all_resources", &self.writes_all_resources)
141            .field("archetypal", &FormattedBitSet::<T>::new(&self.archetypal))
142            .finish()
143    }
144}
145
146impl<T: SparseSetIndex> Default for Access<T> {
147    fn default() -> Self {
148        Self::new()
149    }
150}
151
152impl<T: SparseSetIndex> Access<T> {
153    /// Creates an empty [`Access`] collection.
154    pub const fn new() -> Self {
155        Self {
156            reads_all_resources: false,
157            writes_all_resources: false,
158            component_read_and_writes_inverted: false,
159            component_writes_inverted: false,
160            component_read_and_writes: FixedBitSet::new(),
161            component_writes: FixedBitSet::new(),
162            resource_read_and_writes: FixedBitSet::new(),
163            resource_writes: FixedBitSet::new(),
164            archetypal: FixedBitSet::new(),
165            marker: PhantomData,
166        }
167    }
168
169    fn add_component_sparse_set_index_read(&mut self, index: usize) {
170        if !self.component_read_and_writes_inverted {
171            self.component_read_and_writes.grow_and_insert(index);
172        } else if index < self.component_read_and_writes.len() {
173            self.component_read_and_writes.remove(index);
174        }
175    }
176
177    fn add_component_sparse_set_index_write(&mut self, index: usize) {
178        if !self.component_writes_inverted {
179            self.component_writes.grow_and_insert(index);
180        } else if index < self.component_writes.len() {
181            self.component_writes.remove(index);
182        }
183    }
184
185    /// Adds access to the component given by `index`.
186    pub fn add_component_read(&mut self, index: T) {
187        let sparse_set_index = index.sparse_set_index();
188        self.add_component_sparse_set_index_read(sparse_set_index);
189    }
190
191    /// Adds exclusive access to the component given by `index`.
192    pub fn add_component_write(&mut self, index: T) {
193        let sparse_set_index = index.sparse_set_index();
194        self.add_component_sparse_set_index_read(sparse_set_index);
195        self.add_component_sparse_set_index_write(sparse_set_index);
196    }
197
198    /// Adds access to the resource given by `index`.
199    pub fn add_resource_read(&mut self, index: T) {
200        self.resource_read_and_writes
201            .grow_and_insert(index.sparse_set_index());
202    }
203
204    /// Adds exclusive access to the resource given by `index`.
205    pub fn add_resource_write(&mut self, index: T) {
206        self.resource_read_and_writes
207            .grow_and_insert(index.sparse_set_index());
208        self.resource_writes
209            .grow_and_insert(index.sparse_set_index());
210    }
211
212    fn remove_component_sparse_set_index_read(&mut self, index: usize) {
213        if self.component_read_and_writes_inverted {
214            self.component_read_and_writes.grow_and_insert(index);
215        } else if index < self.component_read_and_writes.len() {
216            self.component_read_and_writes.remove(index);
217        }
218    }
219
220    fn remove_component_sparse_set_index_write(&mut self, index: usize) {
221        if self.component_writes_inverted {
222            self.component_writes.grow_and_insert(index);
223        } else if index < self.component_writes.len() {
224            self.component_writes.remove(index);
225        }
226    }
227
228    /// Removes both read and write access to the component given by `index`.
229    ///
230    /// Because this method corresponds to the set difference operator ∖, it can
231    /// create complicated logical formulas that you should verify correctness
232    /// of. For example, A ∪ (B ∖ A) isn't equivalent to (A ∪ B) ∖ A, so you
233    /// can't replace a call to `remove_component_read` followed by a call to
234    /// `extend` with a call to `extend` followed by a call to
235    /// `remove_component_read`.
236    pub fn remove_component_read(&mut self, index: T) {
237        let sparse_set_index = index.sparse_set_index();
238        self.remove_component_sparse_set_index_write(sparse_set_index);
239        self.remove_component_sparse_set_index_read(sparse_set_index);
240    }
241
242    /// Removes write access to the component given by `index`.
243    ///
244    /// Because this method corresponds to the set difference operator ∖, it can
245    /// create complicated logical formulas that you should verify correctness
246    /// of. For example, A ∪ (B ∖ A) isn't equivalent to (A ∪ B) ∖ A, so you
247    /// can't replace a call to `remove_component_write` followed by a call to
248    /// `extend` with a call to `extend` followed by a call to
249    /// `remove_component_write`.
250    pub fn remove_component_write(&mut self, index: T) {
251        let sparse_set_index = index.sparse_set_index();
252        self.remove_component_sparse_set_index_write(sparse_set_index);
253    }
254
255    /// Adds an archetypal (indirect) access to the component given by `index`.
256    ///
257    /// This is for components whose values are not accessed (and thus will never cause conflicts),
258    /// but whose presence in an archetype may affect query results.
259    ///
260    /// Currently, this is only used for [`Has<T>`].
261    ///
262    /// [`Has<T>`]: crate::query::Has
263    pub fn add_archetypal(&mut self, index: T) {
264        self.archetypal.grow_and_insert(index.sparse_set_index());
265    }
266
267    /// Returns `true` if this can access the component given by `index`.
268    pub fn has_component_read(&self, index: T) -> bool {
269        self.component_read_and_writes_inverted
270            ^ self
271                .component_read_and_writes
272                .contains(index.sparse_set_index())
273    }
274
275    /// Returns `true` if this can access any component.
276    pub fn has_any_component_read(&self) -> bool {
277        self.component_read_and_writes_inverted || !self.component_read_and_writes.is_clear()
278    }
279
280    /// Returns `true` if this can exclusively access the component given by `index`.
281    pub fn has_component_write(&self, index: T) -> bool {
282        self.component_writes_inverted ^ self.component_writes.contains(index.sparse_set_index())
283    }
284
285    /// Returns `true` if this accesses any component mutably.
286    pub fn has_any_component_write(&self) -> bool {
287        self.component_writes_inverted || !self.component_writes.is_clear()
288    }
289
290    /// Returns `true` if this can access the resource given by `index`.
291    pub fn has_resource_read(&self, index: T) -> bool {
292        self.reads_all_resources
293            || self
294                .resource_read_and_writes
295                .contains(index.sparse_set_index())
296    }
297
298    /// Returns `true` if this can access any resource.
299    pub fn has_any_resource_read(&self) -> bool {
300        self.reads_all_resources || !self.resource_read_and_writes.is_clear()
301    }
302
303    /// Returns `true` if this can exclusively access the resource given by `index`.
304    pub fn has_resource_write(&self, index: T) -> bool {
305        self.writes_all_resources || self.resource_writes.contains(index.sparse_set_index())
306    }
307
308    /// Returns `true` if this accesses any resource mutably.
309    pub fn has_any_resource_write(&self) -> bool {
310        self.writes_all_resources || !self.resource_writes.is_clear()
311    }
312
313    /// Returns `true` if this accesses any resources or components.
314    pub fn has_any_read(&self) -> bool {
315        self.has_any_component_read() || self.has_any_resource_read()
316    }
317
318    /// Returns `true` if this accesses any resources or components mutably.
319    pub fn has_any_write(&self) -> bool {
320        self.has_any_component_write() || self.has_any_resource_write()
321    }
322
323    /// Returns true if this has an archetypal (indirect) access to the component given by `index`.
324    ///
325    /// This is a component whose value is not accessed (and thus will never cause conflicts),
326    /// but whose presence in an archetype may affect query results.
327    ///
328    /// Currently, this is only used for [`Has<T>`].
329    ///
330    /// [`Has<T>`]: crate::query::Has
331    pub fn has_archetypal(&self, index: T) -> bool {
332        self.archetypal.contains(index.sparse_set_index())
333    }
334
335    /// Sets this as having access to all components (i.e. `EntityRef`).
336    #[inline]
337    pub fn read_all_components(&mut self) {
338        self.component_read_and_writes_inverted = true;
339        self.component_read_and_writes.clear();
340    }
341
342    /// Sets this as having mutable access to all components (i.e. `EntityMut`).
343    #[inline]
344    pub fn write_all_components(&mut self) {
345        self.read_all_components();
346        self.component_writes_inverted = true;
347        self.component_writes.clear();
348    }
349
350    /// Sets this as having access to all resources (i.e. `&World`).
351    #[inline]
352    pub const fn read_all_resources(&mut self) {
353        self.reads_all_resources = true;
354    }
355
356    /// Sets this as having mutable access to all resources (i.e. `&mut World`).
357    #[inline]
358    pub const fn write_all_resources(&mut self) {
359        self.reads_all_resources = true;
360        self.writes_all_resources = true;
361    }
362
363    /// Sets this as having access to all indexed elements (i.e. `&World`).
364    #[inline]
365    pub fn read_all(&mut self) {
366        self.read_all_components();
367        self.read_all_resources();
368    }
369
370    /// Sets this as having mutable access to all indexed elements (i.e. `&mut World`).
371    #[inline]
372    pub fn write_all(&mut self) {
373        self.write_all_components();
374        self.write_all_resources();
375    }
376
377    /// Returns `true` if this has access to all components (i.e. `EntityRef`).
378    #[inline]
379    pub fn has_read_all_components(&self) -> bool {
380        self.component_read_and_writes_inverted && self.component_read_and_writes.is_clear()
381    }
382
383    /// Returns `true` if this has write access to all components (i.e. `EntityMut`).
384    #[inline]
385    pub fn has_write_all_components(&self) -> bool {
386        self.component_writes_inverted && self.component_writes.is_clear()
387    }
388
389    /// Returns `true` if this has access to all resources (i.e. `EntityRef`).
390    #[inline]
391    pub fn has_read_all_resources(&self) -> bool {
392        self.reads_all_resources
393    }
394
395    /// Returns `true` if this has write access to all resources (i.e. `EntityMut`).
396    #[inline]
397    pub fn has_write_all_resources(&self) -> bool {
398        self.writes_all_resources
399    }
400
401    /// Returns `true` if this has access to all indexed elements (i.e. `&World`).
402    pub fn has_read_all(&self) -> bool {
403        self.has_read_all_components() && self.has_read_all_resources()
404    }
405
406    /// Returns `true` if this has write access to all indexed elements (i.e. `&mut World`).
407    pub fn has_write_all(&self) -> bool {
408        self.has_write_all_components() && self.has_write_all_resources()
409    }
410
411    /// Removes all writes.
412    pub fn clear_writes(&mut self) {
413        self.writes_all_resources = false;
414        self.component_writes_inverted = false;
415        self.component_writes.clear();
416        self.resource_writes.clear();
417    }
418
419    /// Removes all accesses.
420    pub fn clear(&mut self) {
421        self.reads_all_resources = false;
422        self.writes_all_resources = false;
423        self.component_read_and_writes_inverted = false;
424        self.component_writes_inverted = false;
425        self.component_read_and_writes.clear();
426        self.component_writes.clear();
427        self.resource_read_and_writes.clear();
428        self.resource_writes.clear();
429    }
430
431    /// Adds all access from `other`.
432    pub fn extend(&mut self, other: &Access<T>) {
433        let component_read_and_writes_inverted =
434            self.component_read_and_writes_inverted || other.component_read_and_writes_inverted;
435        let component_writes_inverted =
436            self.component_writes_inverted || other.component_writes_inverted;
437
438        match (
439            self.component_read_and_writes_inverted,
440            other.component_read_and_writes_inverted,
441        ) {
442            (true, true) => {
443                self.component_read_and_writes
444                    .intersect_with(&other.component_read_and_writes);
445            }
446            (true, false) => {
447                self.component_read_and_writes
448                    .difference_with(&other.component_read_and_writes);
449            }
450            (false, true) => {
451                // We have to grow here because the new bits are going to get flipped to 1.
452                self.component_read_and_writes.grow(
453                    self.component_read_and_writes
454                        .len()
455                        .max(other.component_read_and_writes.len()),
456                );
457                self.component_read_and_writes.toggle_range(..);
458                self.component_read_and_writes
459                    .intersect_with(&other.component_read_and_writes);
460            }
461            (false, false) => {
462                self.component_read_and_writes
463                    .union_with(&other.component_read_and_writes);
464            }
465        }
466
467        match (
468            self.component_writes_inverted,
469            other.component_writes_inverted,
470        ) {
471            (true, true) => {
472                self.component_writes
473                    .intersect_with(&other.component_writes);
474            }
475            (true, false) => {
476                self.component_writes
477                    .difference_with(&other.component_writes);
478            }
479            (false, true) => {
480                // We have to grow here because the new bits are going to get flipped to 1.
481                self.component_writes.grow(
482                    self.component_writes
483                        .len()
484                        .max(other.component_writes.len()),
485                );
486                self.component_writes.toggle_range(..);
487                self.component_writes
488                    .intersect_with(&other.component_writes);
489            }
490            (false, false) => {
491                self.component_writes.union_with(&other.component_writes);
492            }
493        }
494
495        self.reads_all_resources = self.reads_all_resources || other.reads_all_resources;
496        self.writes_all_resources = self.writes_all_resources || other.writes_all_resources;
497        self.component_read_and_writes_inverted = component_read_and_writes_inverted;
498        self.component_writes_inverted = component_writes_inverted;
499        self.resource_read_and_writes
500            .union_with(&other.resource_read_and_writes);
501        self.resource_writes.union_with(&other.resource_writes);
502    }
503
504    /// Returns `true` if the access and `other` can be active at the same time,
505    /// only looking at their component access.
506    ///
507    /// [`Access`] instances are incompatible if one can write
508    /// an element that the other can read or write.
509    pub fn is_components_compatible(&self, other: &Access<T>) -> bool {
510        // We have a conflict if we write and they read or write, or if they
511        // write and we read or write.
512        for (
513            lhs_writes,
514            rhs_reads_and_writes,
515            lhs_writes_inverted,
516            rhs_reads_and_writes_inverted,
517        ) in [
518            (
519                &self.component_writes,
520                &other.component_read_and_writes,
521                self.component_writes_inverted,
522                other.component_read_and_writes_inverted,
523            ),
524            (
525                &other.component_writes,
526                &self.component_read_and_writes,
527                other.component_writes_inverted,
528                self.component_read_and_writes_inverted,
529            ),
530        ] {
531            match (lhs_writes_inverted, rhs_reads_and_writes_inverted) {
532                (true, true) => return false,
533                (false, true) => {
534                    if !lhs_writes.is_subset(rhs_reads_and_writes) {
535                        return false;
536                    }
537                }
538                (true, false) => {
539                    if !rhs_reads_and_writes.is_subset(lhs_writes) {
540                        return false;
541                    }
542                }
543                (false, false) => {
544                    if !lhs_writes.is_disjoint(rhs_reads_and_writes) {
545                        return false;
546                    }
547                }
548            }
549        }
550
551        true
552    }
553
554    /// Returns `true` if the access and `other` can be active at the same time,
555    /// only looking at their resource access.
556    ///
557    /// [`Access`] instances are incompatible if one can write
558    /// an element that the other can read or write.
559    pub fn is_resources_compatible(&self, other: &Access<T>) -> bool {
560        if self.writes_all_resources {
561            return !other.has_any_resource_read();
562        }
563
564        if other.writes_all_resources {
565            return !self.has_any_resource_read();
566        }
567
568        if self.reads_all_resources {
569            return !other.has_any_resource_write();
570        }
571
572        if other.reads_all_resources {
573            return !self.has_any_resource_write();
574        }
575
576        self.resource_writes
577            .is_disjoint(&other.resource_read_and_writes)
578            && other
579                .resource_writes
580                .is_disjoint(&self.resource_read_and_writes)
581    }
582
583    /// Returns `true` if the access and `other` can be active at the same time.
584    ///
585    /// [`Access`] instances are incompatible if one can write
586    /// an element that the other can read or write.
587    pub fn is_compatible(&self, other: &Access<T>) -> bool {
588        self.is_components_compatible(other) && self.is_resources_compatible(other)
589    }
590
591    /// Returns `true` if the set's component access is a subset of another, i.e. `other`'s component access
592    /// contains at least all the values in `self`.
593    pub fn is_subset_components(&self, other: &Access<T>) -> bool {
594        for (
595            our_components,
596            their_components,
597            our_components_inverted,
598            their_components_inverted,
599        ) in [
600            (
601                &self.component_read_and_writes,
602                &other.component_read_and_writes,
603                self.component_read_and_writes_inverted,
604                other.component_read_and_writes_inverted,
605            ),
606            (
607                &self.component_writes,
608                &other.component_writes,
609                self.component_writes_inverted,
610                other.component_writes_inverted,
611            ),
612        ] {
613            match (our_components_inverted, their_components_inverted) {
614                (true, true) => {
615                    if !their_components.is_subset(our_components) {
616                        return false;
617                    }
618                }
619                (true, false) => {
620                    return false;
621                }
622                (false, true) => {
623                    if !our_components.is_disjoint(their_components) {
624                        return false;
625                    }
626                }
627                (false, false) => {
628                    if !our_components.is_subset(their_components) {
629                        return false;
630                    }
631                }
632            }
633        }
634
635        true
636    }
637
638    /// Returns `true` if the set's resource access is a subset of another, i.e. `other`'s resource access
639    /// contains at least all the values in `self`.
640    pub fn is_subset_resources(&self, other: &Access<T>) -> bool {
641        if self.writes_all_resources {
642            return other.writes_all_resources;
643        }
644
645        if other.writes_all_resources {
646            return true;
647        }
648
649        if self.reads_all_resources {
650            return other.reads_all_resources;
651        }
652
653        if other.reads_all_resources {
654            return self.resource_writes.is_subset(&other.resource_writes);
655        }
656
657        self.resource_read_and_writes
658            .is_subset(&other.resource_read_and_writes)
659            && self.resource_writes.is_subset(&other.resource_writes)
660    }
661
662    /// Returns `true` if the set is a subset of another, i.e. `other` contains
663    /// at least all the values in `self`.
664    pub fn is_subset(&self, other: &Access<T>) -> bool {
665        self.is_subset_components(other) && self.is_subset_resources(other)
666    }
667
668    fn get_component_conflicts(&self, other: &Access<T>) -> AccessConflicts {
669        let mut conflicts = FixedBitSet::new();
670
671        // We have a conflict if we write and they read or write, or if they
672        // write and we read or write.
673        for (
674            lhs_writes,
675            rhs_reads_and_writes,
676            lhs_writes_inverted,
677            rhs_reads_and_writes_inverted,
678        ) in [
679            (
680                &self.component_writes,
681                &other.component_read_and_writes,
682                self.component_writes_inverted,
683                other.component_read_and_writes_inverted,
684            ),
685            (
686                &other.component_writes,
687                &self.component_read_and_writes,
688                other.component_writes_inverted,
689                self.component_read_and_writes_inverted,
690            ),
691        ] {
692            // There's no way that I can see to do this without a temporary.
693            // Neither CNF nor DNF allows us to avoid one.
694            let temp_conflicts: FixedBitSet =
695                match (lhs_writes_inverted, rhs_reads_and_writes_inverted) {
696                    (true, true) => return AccessConflicts::All,
697                    (false, true) => lhs_writes.difference(rhs_reads_and_writes).collect(),
698                    (true, false) => rhs_reads_and_writes.difference(lhs_writes).collect(),
699                    (false, false) => lhs_writes.intersection(rhs_reads_and_writes).collect(),
700                };
701            conflicts.union_with(&temp_conflicts);
702        }
703
704        AccessConflicts::Individual(conflicts)
705    }
706
707    /// Returns a vector of elements that the access and `other` cannot access at the same time.
708    pub fn get_conflicts(&self, other: &Access<T>) -> AccessConflicts {
709        let mut conflicts = match self.get_component_conflicts(other) {
710            AccessConflicts::All => return AccessConflicts::All,
711            AccessConflicts::Individual(conflicts) => conflicts,
712        };
713
714        if self.reads_all_resources {
715            if other.writes_all_resources {
716                return AccessConflicts::All;
717            }
718            conflicts.extend(other.resource_writes.ones());
719        }
720
721        if other.reads_all_resources {
722            if self.writes_all_resources {
723                return AccessConflicts::All;
724            }
725            conflicts.extend(self.resource_writes.ones());
726        }
727        if self.writes_all_resources {
728            conflicts.extend(other.resource_read_and_writes.ones());
729        }
730
731        if other.writes_all_resources {
732            conflicts.extend(self.resource_read_and_writes.ones());
733        }
734
735        conflicts.extend(
736            self.resource_writes
737                .intersection(&other.resource_read_and_writes),
738        );
739        conflicts.extend(
740            self.resource_read_and_writes
741                .intersection(&other.resource_writes),
742        );
743        AccessConflicts::Individual(conflicts)
744    }
745
746    /// Returns the indices of the resources this has access to.
747    pub fn resource_reads_and_writes(&self) -> impl Iterator<Item = T> + '_ {
748        self.resource_read_and_writes
749            .ones()
750            .map(T::get_sparse_set_index)
751    }
752
753    /// Returns the indices of the resources this has non-exclusive access to.
754    pub fn resource_reads(&self) -> impl Iterator<Item = T> + '_ {
755        self.resource_read_and_writes
756            .difference(&self.resource_writes)
757            .map(T::get_sparse_set_index)
758    }
759
760    /// Returns the indices of the resources this has exclusive access to.
761    pub fn resource_writes(&self) -> impl Iterator<Item = T> + '_ {
762        self.resource_writes.ones().map(T::get_sparse_set_index)
763    }
764
765    /// Returns the indices of the components that this has an archetypal access to.
766    ///
767    /// These are components whose values are not accessed (and thus will never cause conflicts),
768    /// but whose presence in an archetype may affect query results.
769    ///
770    /// Currently, this is only used for [`Has<T>`].
771    ///
772    /// [`Has<T>`]: crate::query::Has
773    pub fn archetypal(&self) -> impl Iterator<Item = T> + '_ {
774        self.archetypal.ones().map(T::get_sparse_set_index)
775    }
776
777    /// Returns an iterator over the component IDs and their [`ComponentAccessKind`].
778    ///
779    /// Returns `Err(UnboundedAccess)` if the access is unbounded.
780    /// This typically occurs when an [`Access`] is marked as accessing all
781    /// components, and then adding exceptions.
782    ///
783    /// # Examples
784    ///
785    /// ```rust
786    /// # use bevy_ecs::query::{Access, ComponentAccessKind};
787    /// let mut access = Access::<usize>::default();
788    ///
789    /// access.add_component_read(1);
790    /// access.add_component_write(2);
791    /// access.add_archetypal(3);
792    ///
793    /// let result = access
794    ///     .try_iter_component_access()
795    ///     .map(Iterator::collect::<Vec<_>>);
796    ///
797    /// assert_eq!(
798    ///     result,
799    ///     Ok(vec![
800    ///         ComponentAccessKind::Shared(1),
801    ///         ComponentAccessKind::Exclusive(2),
802    ///         ComponentAccessKind::Archetypal(3),
803    ///     ]),
804    /// );
805    /// ```
806    pub fn try_iter_component_access(
807        &self,
808    ) -> Result<impl Iterator<Item = ComponentAccessKind<T>> + '_, UnboundedAccessError> {
809        // component_writes_inverted is only ever true when component_read_and_writes_inverted is
810        // also true. Therefore it is sufficient to check just component_read_and_writes_inverted.
811        if self.component_read_and_writes_inverted {
812            return Err(UnboundedAccessError {
813                writes_inverted: self.component_writes_inverted,
814                read_and_writes_inverted: self.component_read_and_writes_inverted,
815            });
816        }
817
818        let reads_and_writes = self.component_read_and_writes.ones().map(|index| {
819            let sparse_index = T::get_sparse_set_index(index);
820
821            if self.component_writes.contains(index) {
822                ComponentAccessKind::Exclusive(sparse_index)
823            } else {
824                ComponentAccessKind::Shared(sparse_index)
825            }
826        });
827
828        let archetypal = self
829            .archetypal
830            .ones()
831            .filter(|&index| {
832                !self.component_writes.contains(index)
833                    && !self.component_read_and_writes.contains(index)
834            })
835            .map(|index| ComponentAccessKind::Archetypal(T::get_sparse_set_index(index)));
836
837        Ok(reads_and_writes.chain(archetypal))
838    }
839}
840
841/// Error returned when attempting to iterate over items included in an [`Access`]
842/// if the access excludes items rather than including them.
843#[derive(Clone, Copy, PartialEq, Eq, Debug, Error)]
844#[error("Access is unbounded")]
845pub struct UnboundedAccessError {
846    /// [`Access`] is defined in terms of _excluding_ [exclusive](ComponentAccessKind::Exclusive)
847    /// access.
848    pub writes_inverted: bool,
849    /// [`Access`] is defined in terms of _excluding_ [shared](ComponentAccessKind::Shared) and
850    /// [exclusive](ComponentAccessKind::Exclusive) access.
851    pub read_and_writes_inverted: bool,
852}
853
854/// Describes the level of access for a particular component as defined in an [`Access`].
855#[derive(PartialEq, Eq, Hash, Debug, Clone, Copy)]
856pub enum ComponentAccessKind<T> {
857    /// Archetypical access, such as `Has<Foo>`.
858    Archetypal(T),
859    /// Shared access, such as `&Foo`.
860    Shared(T),
861    /// Exclusive access, such as `&mut Foo`.
862    Exclusive(T),
863}
864
865impl<T> ComponentAccessKind<T> {
866    /// Gets the index of this `ComponentAccessKind`.
867    pub fn index(&self) -> &T {
868        let (Self::Archetypal(value) | Self::Shared(value) | Self::Exclusive(value)) = self;
869        value
870    }
871}
872
873/// An [`Access`] that has been filtered to include and exclude certain combinations of elements.
874///
875/// Used internally to statically check if queries are disjoint.
876///
877/// Subtle: a `read` or `write` in `access` should not be considered to imply a
878/// `with` access.
879///
880/// For example consider `Query<Option<&T>>` this only has a `read` of `T` as doing
881/// otherwise would allow for queries to be considered disjoint when they shouldn't:
882/// - `Query<(&mut T, Option<&U>)>` read/write `T`, read `U`, with `U`
883/// - `Query<&mut T, Without<U>>` read/write `T`, without `U`
884///   from this we could reasonably conclude that the queries are disjoint but they aren't.
885///
886/// In order to solve this the actual access that `Query<(&mut T, Option<&U>)>` has
887/// is read/write `T`, read `U`. It must still have a read `U` access otherwise the following
888/// queries would be incorrectly considered disjoint:
889/// - `Query<&mut T>`  read/write `T`
890/// - `Query<Option<&T>>` accesses nothing
891///
892/// See comments the [`WorldQuery`](super::WorldQuery) impls of [`AnyOf`](super::AnyOf)/`Option`/[`Or`](super::Or) for more information.
893#[derive(Debug, Eq, PartialEq)]
894pub struct FilteredAccess<T: SparseSetIndex> {
895    pub(crate) access: Access<T>,
896    pub(crate) required: FixedBitSet,
897    // An array of filter sets to express `With` or `Without` clauses in disjunctive normal form, for example: `Or<(With<A>, With<B>)>`.
898    // Filters like `(With<A>, Or<(With<B>, Without<C>)>` are expanded into `Or<((With<A>, With<B>), (With<A>, Without<C>))>`.
899    pub(crate) filter_sets: Vec<AccessFilters<T>>,
900}
901
902// This is needed since `#[derive(Clone)]` does not generate optimized `clone_from`.
903impl<T: SparseSetIndex> Clone for FilteredAccess<T> {
904    fn clone(&self) -> Self {
905        Self {
906            access: self.access.clone(),
907            required: self.required.clone(),
908            filter_sets: self.filter_sets.clone(),
909        }
910    }
911
912    fn clone_from(&mut self, source: &Self) {
913        self.access.clone_from(&source.access);
914        self.required.clone_from(&source.required);
915        self.filter_sets.clone_from(&source.filter_sets);
916    }
917}
918
919impl<T: SparseSetIndex> Default for FilteredAccess<T> {
920    fn default() -> Self {
921        Self::matches_everything()
922    }
923}
924
925impl<T: SparseSetIndex> From<FilteredAccess<T>> for FilteredAccessSet<T> {
926    fn from(filtered_access: FilteredAccess<T>) -> Self {
927        let mut base = FilteredAccessSet::<T>::default();
928        base.add(filtered_access);
929        base
930    }
931}
932
933/// Records how two accesses conflict with each other
934#[derive(Debug, PartialEq, From)]
935pub enum AccessConflicts {
936    /// Conflict is for all indices
937    All,
938    /// There is a conflict for a subset of indices
939    Individual(FixedBitSet),
940}
941
942impl AccessConflicts {
943    fn add(&mut self, other: &Self) {
944        match (self, other) {
945            (s, AccessConflicts::All) => {
946                *s = AccessConflicts::All;
947            }
948            (AccessConflicts::Individual(this), AccessConflicts::Individual(other)) => {
949                this.extend(other.ones());
950            }
951            _ => {}
952        }
953    }
954
955    pub(crate) fn is_empty(&self) -> bool {
956        match self {
957            Self::All => false,
958            Self::Individual(set) => set.is_empty(),
959        }
960    }
961
962    pub(crate) fn format_conflict_list(&self, world: &World) -> String {
963        match self {
964            AccessConflicts::All => String::new(),
965            AccessConflicts::Individual(indices) => indices
966                .ones()
967                .map(|index| {
968                    format!(
969                        "{}",
970                        ShortName(
971                            &world
972                                .components
973                                .get_name(ComponentId::get_sparse_set_index(index))
974                                .unwrap()
975                        )
976                    )
977                })
978                .collect::<Vec<_>>()
979                .join(", "),
980        }
981    }
982
983    /// An [`AccessConflicts`] which represents the absence of any conflict
984    pub(crate) fn empty() -> Self {
985        Self::Individual(FixedBitSet::new())
986    }
987}
988
989impl<T: SparseSetIndex> From<Vec<T>> for AccessConflicts {
990    fn from(value: Vec<T>) -> Self {
991        Self::Individual(value.iter().map(T::sparse_set_index).collect())
992    }
993}
994
995impl<T: SparseSetIndex> FilteredAccess<T> {
996    /// Returns a `FilteredAccess` which has no access and matches everything.
997    /// This is the equivalent of a `TRUE` logic atom.
998    pub fn matches_everything() -> Self {
999        Self {
1000            access: Access::default(),
1001            required: FixedBitSet::default(),
1002            filter_sets: vec![AccessFilters::default()],
1003        }
1004    }
1005
1006    /// Returns a `FilteredAccess` which has no access and matches nothing.
1007    /// This is the equivalent of a `FALSE` logic atom.
1008    pub fn matches_nothing() -> Self {
1009        Self {
1010            access: Access::default(),
1011            required: FixedBitSet::default(),
1012            filter_sets: Vec::new(),
1013        }
1014    }
1015
1016    /// Returns a reference to the underlying unfiltered access.
1017    #[inline]
1018    pub fn access(&self) -> &Access<T> {
1019        &self.access
1020    }
1021
1022    /// Returns a mutable reference to the underlying unfiltered access.
1023    #[inline]
1024    pub fn access_mut(&mut self) -> &mut Access<T> {
1025        &mut self.access
1026    }
1027
1028    /// Adds access to the component given by `index`.
1029    pub fn add_component_read(&mut self, index: T) {
1030        self.access.add_component_read(index.clone());
1031        self.add_required(index.clone());
1032        self.and_with(index);
1033    }
1034
1035    /// Adds exclusive access to the component given by `index`.
1036    pub fn add_component_write(&mut self, index: T) {
1037        self.access.add_component_write(index.clone());
1038        self.add_required(index.clone());
1039        self.and_with(index);
1040    }
1041
1042    /// Adds access to the resource given by `index`.
1043    pub fn add_resource_read(&mut self, index: T) {
1044        self.access.add_resource_read(index.clone());
1045    }
1046
1047    /// Adds exclusive access to the resource given by `index`.
1048    pub fn add_resource_write(&mut self, index: T) {
1049        self.access.add_resource_write(index.clone());
1050    }
1051
1052    fn add_required(&mut self, index: T) {
1053        self.required.grow_and_insert(index.sparse_set_index());
1054    }
1055
1056    /// Adds a `With` filter: corresponds to a conjunction (AND) operation.
1057    ///
1058    /// Suppose we begin with `Or<(With<A>, With<B>)>`, which is represented by an array of two `AccessFilter` instances.
1059    /// Adding `AND With<C>` via this method transforms it into the equivalent of  `Or<((With<A>, With<C>), (With<B>, With<C>))>`.
1060    pub fn and_with(&mut self, index: T) {
1061        for filter in &mut self.filter_sets {
1062            filter.with.grow_and_insert(index.sparse_set_index());
1063        }
1064    }
1065
1066    /// Adds a `Without` filter: corresponds to a conjunction (AND) operation.
1067    ///
1068    /// Suppose we begin with `Or<(With<A>, With<B>)>`, which is represented by an array of two `AccessFilter` instances.
1069    /// Adding `AND Without<C>` via this method transforms it into the equivalent of  `Or<((With<A>, Without<C>), (With<B>, Without<C>))>`.
1070    pub fn and_without(&mut self, index: T) {
1071        for filter in &mut self.filter_sets {
1072            filter.without.grow_and_insert(index.sparse_set_index());
1073        }
1074    }
1075
1076    /// Appends an array of filters: corresponds to a disjunction (OR) operation.
1077    ///
1078    /// As the underlying array of filters represents a disjunction,
1079    /// where each element (`AccessFilters`) represents a conjunction,
1080    /// we can simply append to the array.
1081    pub fn append_or(&mut self, other: &FilteredAccess<T>) {
1082        self.filter_sets.append(&mut other.filter_sets.clone());
1083    }
1084
1085    /// Adds all of the accesses from `other` to `self`.
1086    pub fn extend_access(&mut self, other: &FilteredAccess<T>) {
1087        self.access.extend(&other.access);
1088    }
1089
1090    /// Returns `true` if this and `other` can be active at the same time.
1091    pub fn is_compatible(&self, other: &FilteredAccess<T>) -> bool {
1092        // Resources are read from the world rather than the filtered archetypes,
1093        // so they must be compatible even if the filters are disjoint.
1094        if !self.access.is_resources_compatible(&other.access) {
1095            return false;
1096        }
1097
1098        if self.access.is_components_compatible(&other.access) {
1099            return true;
1100        }
1101
1102        // If the access instances are incompatible, we want to check that whether filters can
1103        // guarantee that queries are disjoint.
1104        // Since the `filter_sets` array represents a Disjunctive Normal Form formula ("ORs of ANDs"),
1105        // we need to make sure that each filter set (ANDs) rule out every filter set from the `other` instance.
1106        //
1107        // For example, `Query<&mut C, Or<(With<A>, Without<B>)>>` is compatible `Query<&mut C, (With<B>, Without<A>)>`,
1108        // but `Query<&mut C, Or<(Without<A>, Without<B>)>>` isn't compatible with `Query<&mut C, Or<(With<A>, With<B>)>>`.
1109        self.filter_sets.iter().all(|filter| {
1110            other
1111                .filter_sets
1112                .iter()
1113                .all(|other_filter| filter.is_ruled_out_by(other_filter))
1114        })
1115    }
1116
1117    /// Returns a vector of elements that this and `other` cannot access at the same time.
1118    pub fn get_conflicts(&self, other: &FilteredAccess<T>) -> AccessConflicts {
1119        if !self.is_compatible(other) {
1120            // filters are disjoint, so we can just look at the unfiltered intersection
1121            return self.access.get_conflicts(&other.access);
1122        }
1123        AccessConflicts::empty()
1124    }
1125
1126    /// Adds all access and filters from `other`.
1127    ///
1128    /// Corresponds to a conjunction operation (AND) for filters.
1129    ///
1130    /// Extending `Or<(With<A>, Without<B>)>` with `Or<(With<C>, Without<D>)>` will result in
1131    /// `Or<((With<A>, With<C>), (With<A>, Without<D>), (Without<B>, With<C>), (Without<B>, Without<D>))>`.
1132    pub fn extend(&mut self, other: &FilteredAccess<T>) {
1133        self.access.extend(&other.access);
1134        self.required.union_with(&other.required);
1135
1136        // We can avoid allocating a new array of bitsets if `other` contains just a single set of filters:
1137        // in this case we can short-circuit by performing an in-place union for each bitset.
1138        if other.filter_sets.len() == 1 {
1139            for filter in &mut self.filter_sets {
1140                filter.with.union_with(&other.filter_sets[0].with);
1141                filter.without.union_with(&other.filter_sets[0].without);
1142            }
1143            return;
1144        }
1145
1146        let mut new_filters = Vec::with_capacity(self.filter_sets.len() * other.filter_sets.len());
1147        for filter in &self.filter_sets {
1148            for other_filter in &other.filter_sets {
1149                let mut new_filter = filter.clone();
1150                new_filter.with.union_with(&other_filter.with);
1151                new_filter.without.union_with(&other_filter.without);
1152                new_filters.push(new_filter);
1153            }
1154        }
1155        self.filter_sets = new_filters;
1156    }
1157
1158    /// Sets the underlying unfiltered access as having access to all indexed elements.
1159    pub fn read_all(&mut self) {
1160        self.access.read_all();
1161    }
1162
1163    /// Sets the underlying unfiltered access as having mutable access to all indexed elements.
1164    pub fn write_all(&mut self) {
1165        self.access.write_all();
1166    }
1167
1168    /// Sets the underlying unfiltered access as having access to all components.
1169    pub fn read_all_components(&mut self) {
1170        self.access.read_all_components();
1171    }
1172
1173    /// Sets the underlying unfiltered access as having mutable access to all components.
1174    pub fn write_all_components(&mut self) {
1175        self.access.write_all_components();
1176    }
1177
1178    /// Returns `true` if the set is a subset of another, i.e. `other` contains
1179    /// at least all the values in `self`.
1180    pub fn is_subset(&self, other: &FilteredAccess<T>) -> bool {
1181        self.required.is_subset(&other.required) && self.access().is_subset(other.access())
1182    }
1183
1184    /// Returns the indices of the elements that this access filters for.
1185    pub fn with_filters(&self) -> impl Iterator<Item = T> + '_ {
1186        self.filter_sets
1187            .iter()
1188            .flat_map(|f| f.with.ones().map(T::get_sparse_set_index))
1189    }
1190
1191    /// Returns the indices of the elements that this access filters out.
1192    pub fn without_filters(&self) -> impl Iterator<Item = T> + '_ {
1193        self.filter_sets
1194            .iter()
1195            .flat_map(|f| f.without.ones().map(T::get_sparse_set_index))
1196    }
1197
1198    /// Returns true if the index is used by this `FilteredAccess` in any way
1199    pub fn contains(&self, index: T) -> bool {
1200        self.access().has_component_read(index.clone())
1201            || self.access().has_archetypal(index.clone())
1202            || self.filter_sets.iter().any(|f| {
1203                f.with.contains(index.sparse_set_index())
1204                    || f.without.contains(index.sparse_set_index())
1205            })
1206    }
1207}
1208
1209#[derive(Eq, PartialEq)]
1210pub(crate) struct AccessFilters<T> {
1211    pub(crate) with: FixedBitSet,
1212    pub(crate) without: FixedBitSet,
1213    _index_type: PhantomData<T>,
1214}
1215
1216// This is needed since `#[derive(Clone)]` does not generate optimized `clone_from`.
1217impl<T: SparseSetIndex> Clone for AccessFilters<T> {
1218    fn clone(&self) -> Self {
1219        Self {
1220            with: self.with.clone(),
1221            without: self.without.clone(),
1222            _index_type: PhantomData,
1223        }
1224    }
1225
1226    fn clone_from(&mut self, source: &Self) {
1227        self.with.clone_from(&source.with);
1228        self.without.clone_from(&source.without);
1229    }
1230}
1231
1232impl<T: SparseSetIndex + Debug> Debug for AccessFilters<T> {
1233    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1234        f.debug_struct("AccessFilters")
1235            .field("with", &FormattedBitSet::<T>::new(&self.with))
1236            .field("without", &FormattedBitSet::<T>::new(&self.without))
1237            .finish()
1238    }
1239}
1240
1241impl<T: SparseSetIndex> Default for AccessFilters<T> {
1242    fn default() -> Self {
1243        Self {
1244            with: FixedBitSet::default(),
1245            without: FixedBitSet::default(),
1246            _index_type: PhantomData,
1247        }
1248    }
1249}
1250
1251impl<T: SparseSetIndex> AccessFilters<T> {
1252    fn is_ruled_out_by(&self, other: &Self) -> bool {
1253        // Although not technically complete, we don't consider the case when `AccessFilters`'s
1254        // `without` bitset contradicts its own `with` bitset (e.g. `(With<A>, Without<A>)`).
1255        // Such query would be considered compatible with any other query, but as it's almost
1256        // always an error, we ignore this case instead of treating such query as compatible
1257        // with others.
1258        !self.with.is_disjoint(&other.without) || !self.without.is_disjoint(&other.with)
1259    }
1260}
1261
1262/// A collection of [`FilteredAccess`] instances.
1263///
1264/// Used internally to statically check if systems have conflicting access.
1265///
1266/// It stores multiple sets of accesses.
1267/// - A "combined" set, which is the access of all filters in this set combined.
1268/// - The set of access of each individual filters in this set.
1269#[derive(Debug, PartialEq, Eq)]
1270pub struct FilteredAccessSet<T: SparseSetIndex> {
1271    combined_access: Access<T>,
1272    filtered_accesses: Vec<FilteredAccess<T>>,
1273}
1274
1275// This is needed since `#[derive(Clone)]` does not generate optimized `clone_from`.
1276impl<T: SparseSetIndex> Clone for FilteredAccessSet<T> {
1277    fn clone(&self) -> Self {
1278        Self {
1279            combined_access: self.combined_access.clone(),
1280            filtered_accesses: self.filtered_accesses.clone(),
1281        }
1282    }
1283
1284    fn clone_from(&mut self, source: &Self) {
1285        self.combined_access.clone_from(&source.combined_access);
1286        self.filtered_accesses.clone_from(&source.filtered_accesses);
1287    }
1288}
1289
1290impl<T: SparseSetIndex> FilteredAccessSet<T> {
1291    /// Returns a reference to the unfiltered access of the entire set.
1292    #[inline]
1293    pub fn combined_access(&self) -> &Access<T> {
1294        &self.combined_access
1295    }
1296
1297    /// Returns `true` if this and `other` can be active at the same time.
1298    ///
1299    /// Access conflict resolution happen in two steps:
1300    /// 1. A "coarse" check, if there is no mutual unfiltered conflict between
1301    ///    `self` and `other`, we already know that the two access sets are
1302    ///    compatible.
1303    /// 2. A "fine grained" check, it kicks in when the "coarse" check fails.
1304    ///    the two access sets might still be compatible if some of the accesses
1305    ///    are restricted with the [`With`](super::With) or [`Without`](super::Without) filters so that access is
1306    ///    mutually exclusive. The fine grained phase iterates over all filters in
1307    ///    the `self` set and compares it to all the filters in the `other` set,
1308    ///    making sure they are all mutually compatible.
1309    pub fn is_compatible(&self, other: &FilteredAccessSet<T>) -> bool {
1310        if self.combined_access.is_compatible(other.combined_access()) {
1311            return true;
1312        }
1313        for filtered in &self.filtered_accesses {
1314            for other_filtered in &other.filtered_accesses {
1315                if !filtered.is_compatible(other_filtered) {
1316                    return false;
1317                }
1318            }
1319        }
1320        true
1321    }
1322
1323    /// Returns a vector of elements that this set and `other` cannot access at the same time.
1324    pub fn get_conflicts(&self, other: &FilteredAccessSet<T>) -> AccessConflicts {
1325        // if the unfiltered access is incompatible, must check each pair
1326        let mut conflicts = AccessConflicts::empty();
1327        if !self.combined_access.is_compatible(other.combined_access()) {
1328            for filtered in &self.filtered_accesses {
1329                for other_filtered in &other.filtered_accesses {
1330                    conflicts.add(&filtered.get_conflicts(other_filtered));
1331                }
1332            }
1333        }
1334        conflicts
1335    }
1336
1337    /// Returns a vector of elements that this set and `other` cannot access at the same time.
1338    pub fn get_conflicts_single(&self, filtered_access: &FilteredAccess<T>) -> AccessConflicts {
1339        // if the unfiltered access is incompatible, must check each pair
1340        let mut conflicts = AccessConflicts::empty();
1341        if !self.combined_access.is_compatible(filtered_access.access()) {
1342            for filtered in &self.filtered_accesses {
1343                conflicts.add(&filtered.get_conflicts(filtered_access));
1344            }
1345        }
1346        conflicts
1347    }
1348
1349    /// Adds the filtered access to the set.
1350    pub fn add(&mut self, filtered_access: FilteredAccess<T>) {
1351        self.combined_access.extend(&filtered_access.access);
1352        self.filtered_accesses.push(filtered_access);
1353    }
1354
1355    /// Adds a read access to a resource to the set.
1356    pub fn add_unfiltered_resource_read(&mut self, index: T) {
1357        let mut filter = FilteredAccess::default();
1358        filter.add_resource_read(index);
1359        self.add(filter);
1360    }
1361
1362    /// Adds a write access to a resource to the set.
1363    pub fn add_unfiltered_resource_write(&mut self, index: T) {
1364        let mut filter = FilteredAccess::default();
1365        filter.add_resource_write(index);
1366        self.add(filter);
1367    }
1368
1369    /// Adds read access to all resources to the set.
1370    pub fn add_unfiltered_read_all_resources(&mut self) {
1371        let mut filter = FilteredAccess::default();
1372        filter.access.read_all_resources();
1373        self.add(filter);
1374    }
1375
1376    /// Adds write access to all resources to the set.
1377    pub fn add_unfiltered_write_all_resources(&mut self) {
1378        let mut filter = FilteredAccess::default();
1379        filter.access.write_all_resources();
1380        self.add(filter);
1381    }
1382
1383    /// Adds all of the accesses from the passed set to `self`.
1384    pub fn extend(&mut self, filtered_access_set: FilteredAccessSet<T>) {
1385        self.combined_access
1386            .extend(&filtered_access_set.combined_access);
1387        self.filtered_accesses
1388            .extend(filtered_access_set.filtered_accesses);
1389    }
1390
1391    /// Marks the set as reading all possible indices of type T.
1392    pub fn read_all(&mut self) {
1393        let mut filter = FilteredAccess::matches_everything();
1394        filter.read_all();
1395        self.add(filter);
1396    }
1397
1398    /// Marks the set as writing all T.
1399    pub fn write_all(&mut self) {
1400        let mut filter = FilteredAccess::matches_everything();
1401        filter.write_all();
1402        self.add(filter);
1403    }
1404
1405    /// Removes all accesses stored in this set.
1406    pub fn clear(&mut self) {
1407        self.combined_access.clear();
1408        self.filtered_accesses.clear();
1409    }
1410}
1411
1412impl<T: SparseSetIndex> Default for FilteredAccessSet<T> {
1413    fn default() -> Self {
1414        Self {
1415            combined_access: Default::default(),
1416            filtered_accesses: Vec::new(),
1417        }
1418    }
1419}
1420
1421#[cfg(test)]
1422mod tests {
1423    use crate::query::{
1424        access::AccessFilters, Access, AccessConflicts, ComponentAccessKind, FilteredAccess,
1425        FilteredAccessSet, UnboundedAccessError,
1426    };
1427    use alloc::{vec, vec::Vec};
1428    use core::marker::PhantomData;
1429    use fixedbitset::FixedBitSet;
1430
1431    fn create_sample_access() -> Access<usize> {
1432        let mut access = Access::<usize>::default();
1433
1434        access.add_component_read(1);
1435        access.add_component_read(2);
1436        access.add_component_write(3);
1437        access.add_archetypal(5);
1438        access.read_all();
1439
1440        access
1441    }
1442
1443    fn create_sample_filtered_access() -> FilteredAccess<usize> {
1444        let mut filtered_access = FilteredAccess::<usize>::default();
1445
1446        filtered_access.add_component_write(1);
1447        filtered_access.add_component_read(2);
1448        filtered_access.add_required(3);
1449        filtered_access.and_with(4);
1450
1451        filtered_access
1452    }
1453
1454    fn create_sample_access_filters() -> AccessFilters<usize> {
1455        let mut access_filters = AccessFilters::<usize>::default();
1456
1457        access_filters.with.grow_and_insert(3);
1458        access_filters.without.grow_and_insert(5);
1459
1460        access_filters
1461    }
1462
1463    fn create_sample_filtered_access_set() -> FilteredAccessSet<usize> {
1464        let mut filtered_access_set = FilteredAccessSet::<usize>::default();
1465
1466        filtered_access_set.add_unfiltered_resource_read(2);
1467        filtered_access_set.add_unfiltered_resource_write(4);
1468        filtered_access_set.read_all();
1469
1470        filtered_access_set
1471    }
1472
1473    #[test]
1474    fn test_access_clone() {
1475        let original: Access<usize> = create_sample_access();
1476        let cloned = original.clone();
1477
1478        assert_eq!(original, cloned);
1479    }
1480
1481    #[test]
1482    fn test_access_clone_from() {
1483        let original: Access<usize> = create_sample_access();
1484        let mut cloned = Access::<usize>::default();
1485
1486        cloned.add_component_write(7);
1487        cloned.add_component_read(4);
1488        cloned.add_archetypal(8);
1489        cloned.write_all();
1490
1491        cloned.clone_from(&original);
1492
1493        assert_eq!(original, cloned);
1494    }
1495
1496    #[test]
1497    fn test_filtered_access_clone() {
1498        let original: FilteredAccess<usize> = create_sample_filtered_access();
1499        let cloned = original.clone();
1500
1501        assert_eq!(original, cloned);
1502    }
1503
1504    #[test]
1505    fn test_filtered_access_clone_from() {
1506        let original: FilteredAccess<usize> = create_sample_filtered_access();
1507        let mut cloned = FilteredAccess::<usize>::default();
1508
1509        cloned.add_component_write(7);
1510        cloned.add_component_read(4);
1511        cloned.append_or(&FilteredAccess::default());
1512
1513        cloned.clone_from(&original);
1514
1515        assert_eq!(original, cloned);
1516    }
1517
1518    #[test]
1519    fn test_access_filters_clone() {
1520        let original: AccessFilters<usize> = create_sample_access_filters();
1521        let cloned = original.clone();
1522
1523        assert_eq!(original, cloned);
1524    }
1525
1526    #[test]
1527    fn test_access_filters_clone_from() {
1528        let original: AccessFilters<usize> = create_sample_access_filters();
1529        let mut cloned = AccessFilters::<usize>::default();
1530
1531        cloned.with.grow_and_insert(1);
1532        cloned.without.grow_and_insert(2);
1533
1534        cloned.clone_from(&original);
1535
1536        assert_eq!(original, cloned);
1537    }
1538
1539    #[test]
1540    fn test_filtered_access_set_clone() {
1541        let original: FilteredAccessSet<usize> = create_sample_filtered_access_set();
1542        let cloned = original.clone();
1543
1544        assert_eq!(original, cloned);
1545    }
1546
1547    #[test]
1548    fn test_filtered_access_set_from() {
1549        let original: FilteredAccessSet<usize> = create_sample_filtered_access_set();
1550        let mut cloned = FilteredAccessSet::<usize>::default();
1551
1552        cloned.add_unfiltered_resource_read(7);
1553        cloned.add_unfiltered_resource_write(9);
1554        cloned.write_all();
1555
1556        cloned.clone_from(&original);
1557
1558        assert_eq!(original, cloned);
1559    }
1560
1561    #[test]
1562    fn read_all_access_conflicts() {
1563        // read_all / single write
1564        let mut access_a = Access::<usize>::default();
1565        access_a.add_component_write(0);
1566
1567        let mut access_b = Access::<usize>::default();
1568        access_b.read_all();
1569
1570        assert!(!access_b.is_compatible(&access_a));
1571
1572        // read_all / read_all
1573        let mut access_a = Access::<usize>::default();
1574        access_a.read_all();
1575
1576        let mut access_b = Access::<usize>::default();
1577        access_b.read_all();
1578
1579        assert!(access_b.is_compatible(&access_a));
1580    }
1581
1582    #[test]
1583    fn access_get_conflicts() {
1584        let mut access_a = Access::<usize>::default();
1585        access_a.add_component_read(0);
1586        access_a.add_component_read(1);
1587
1588        let mut access_b = Access::<usize>::default();
1589        access_b.add_component_read(0);
1590        access_b.add_component_write(1);
1591
1592        assert_eq!(access_a.get_conflicts(&access_b), vec![1_usize].into());
1593
1594        let mut access_c = Access::<usize>::default();
1595        access_c.add_component_write(0);
1596        access_c.add_component_write(1);
1597
1598        assert_eq!(
1599            access_a.get_conflicts(&access_c),
1600            vec![0_usize, 1_usize].into()
1601        );
1602        assert_eq!(
1603            access_b.get_conflicts(&access_c),
1604            vec![0_usize, 1_usize].into()
1605        );
1606
1607        let mut access_d = Access::<usize>::default();
1608        access_d.add_component_read(0);
1609
1610        assert_eq!(access_d.get_conflicts(&access_a), AccessConflicts::empty());
1611        assert_eq!(access_d.get_conflicts(&access_b), AccessConflicts::empty());
1612        assert_eq!(access_d.get_conflicts(&access_c), vec![0_usize].into());
1613    }
1614
1615    #[test]
1616    fn filtered_combined_access() {
1617        let mut access_a = FilteredAccessSet::<usize>::default();
1618        access_a.add_unfiltered_resource_read(1);
1619
1620        let mut filter_b = FilteredAccess::<usize>::default();
1621        filter_b.add_resource_write(1);
1622
1623        let conflicts = access_a.get_conflicts_single(&filter_b);
1624        assert_eq!(
1625            &conflicts,
1626            &AccessConflicts::from(vec![1_usize]),
1627            "access_a: {access_a:?}, filter_b: {filter_b:?}"
1628        );
1629    }
1630
1631    #[test]
1632    fn filtered_access_extend() {
1633        let mut access_a = FilteredAccess::<usize>::default();
1634        access_a.add_component_read(0);
1635        access_a.add_component_read(1);
1636        access_a.and_with(2);
1637
1638        let mut access_b = FilteredAccess::<usize>::default();
1639        access_b.add_component_read(0);
1640        access_b.add_component_write(3);
1641        access_b.and_without(4);
1642
1643        access_a.extend(&access_b);
1644
1645        let mut expected = FilteredAccess::<usize>::default();
1646        expected.add_component_read(0);
1647        expected.add_component_read(1);
1648        expected.and_with(2);
1649        expected.add_component_write(3);
1650        expected.and_without(4);
1651
1652        assert!(access_a.eq(&expected));
1653    }
1654
1655    #[test]
1656    fn filtered_access_extend_or() {
1657        let mut access_a = FilteredAccess::<usize>::default();
1658        // Exclusive access to `(&mut A, &mut B)`.
1659        access_a.add_component_write(0);
1660        access_a.add_component_write(1);
1661
1662        // Filter by `With<C>`.
1663        let mut access_b = FilteredAccess::<usize>::default();
1664        access_b.and_with(2);
1665
1666        // Filter by `(With<D>, Without<E>)`.
1667        let mut access_c = FilteredAccess::<usize>::default();
1668        access_c.and_with(3);
1669        access_c.and_without(4);
1670
1671        // Turns `access_b` into `Or<(With<C>, (With<D>, Without<D>))>`.
1672        access_b.append_or(&access_c);
1673        // Applies the filters to the initial query, which corresponds to the FilteredAccess'
1674        // representation of `Query<(&mut A, &mut B), Or<(With<C>, (With<D>, Without<E>))>>`.
1675        access_a.extend(&access_b);
1676
1677        // Construct the expected `FilteredAccess` struct.
1678        // The intention here is to test that exclusive access implied by `add_write`
1679        // forms correct normalized access structs when extended with `Or` filters.
1680        let mut expected = FilteredAccess::<usize>::default();
1681        expected.add_component_write(0);
1682        expected.add_component_write(1);
1683        // The resulted access is expected to represent `Or<((With<A>, With<B>, With<C>), (With<A>, With<B>, With<D>, Without<E>))>`.
1684        expected.filter_sets = vec![
1685            AccessFilters {
1686                with: FixedBitSet::with_capacity_and_blocks(3, [0b111]),
1687                without: FixedBitSet::default(),
1688                _index_type: PhantomData,
1689            },
1690            AccessFilters {
1691                with: FixedBitSet::with_capacity_and_blocks(4, [0b1011]),
1692                without: FixedBitSet::with_capacity_and_blocks(5, [0b10000]),
1693                _index_type: PhantomData,
1694            },
1695        ];
1696
1697        assert_eq!(access_a, expected);
1698    }
1699
1700    #[test]
1701    fn try_iter_component_access_simple() {
1702        let mut access = Access::<usize>::default();
1703
1704        access.add_component_read(1);
1705        access.add_component_read(2);
1706        access.add_component_write(3);
1707        access.add_archetypal(5);
1708
1709        let result = access
1710            .try_iter_component_access()
1711            .map(Iterator::collect::<Vec<_>>);
1712
1713        assert_eq!(
1714            result,
1715            Ok(vec![
1716                ComponentAccessKind::Shared(1),
1717                ComponentAccessKind::Shared(2),
1718                ComponentAccessKind::Exclusive(3),
1719                ComponentAccessKind::Archetypal(5),
1720            ]),
1721        );
1722    }
1723
1724    #[test]
1725    fn try_iter_component_access_unbounded_write_all() {
1726        let mut access = Access::<usize>::default();
1727
1728        access.add_component_read(1);
1729        access.add_component_read(2);
1730        access.write_all();
1731
1732        let result = access
1733            .try_iter_component_access()
1734            .map(Iterator::collect::<Vec<_>>);
1735
1736        assert_eq!(
1737            result,
1738            Err(UnboundedAccessError {
1739                writes_inverted: true,
1740                read_and_writes_inverted: true
1741            }),
1742        );
1743    }
1744
1745    #[test]
1746    fn try_iter_component_access_unbounded_read_all() {
1747        let mut access = Access::<usize>::default();
1748
1749        access.add_component_read(1);
1750        access.add_component_read(2);
1751        access.read_all();
1752
1753        let result = access
1754            .try_iter_component_access()
1755            .map(Iterator::collect::<Vec<_>>);
1756
1757        assert_eq!(
1758            result,
1759            Err(UnboundedAccessError {
1760                writes_inverted: false,
1761                read_and_writes_inverted: true
1762            }),
1763        );
1764    }
1765}