bevy_ecs/query/
access.rs

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