Thanks to visit codestin.com
Credit goes to docs.rs

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 `true` if this and `other` can be active at the same time.
1326    ///
1327    /// Access conflict resolution happen in two steps:
1328    /// 1. A "coarse" check, if there is no mutual unfiltered conflict between
1329    ///    `self` and `other`, we already know that the two access sets are
1330    ///    compatible.
1331    /// 2. A "fine grained" check, it kicks in when the "coarse" check fails.
1332    ///    the two access sets might still be compatible if some of the accesses
1333    ///    are restricted with the [`With`](super::With) or [`Without`](super::Without) filters so that access is
1334    ///    mutually exclusive. The fine grained phase iterates over all filters in
1335    ///    the `self` set and compares it to all the filters in the `other` set,
1336    ///    making sure they are all mutually compatible.
1337    pub fn is_compatible(&self, other: &FilteredAccessSet) -> bool {
1338        if self.combined_access.is_compatible(other.combined_access()) {
1339            return true;
1340        }
1341        for filtered in &self.filtered_accesses {
1342            for other_filtered in &other.filtered_accesses {
1343                if !filtered.is_compatible(other_filtered) {
1344                    return false;
1345                }
1346            }
1347        }
1348        true
1349    }
1350
1351    /// Returns a vector of elements that this set and `other` cannot access at the same time.
1352    pub fn get_conflicts(&self, other: &FilteredAccessSet) -> AccessConflicts {
1353        // if the unfiltered access is incompatible, must check each pair
1354        let mut conflicts = AccessConflicts::empty();
1355        if !self.combined_access.is_compatible(other.combined_access()) {
1356            for filtered in &self.filtered_accesses {
1357                for other_filtered in &other.filtered_accesses {
1358                    conflicts.add(&filtered.get_conflicts(other_filtered));
1359                }
1360            }
1361        }
1362        conflicts
1363    }
1364
1365    /// Returns a vector of elements that this set and `other` cannot access at the same time.
1366    pub fn get_conflicts_single(&self, filtered_access: &FilteredAccess) -> AccessConflicts {
1367        // if the unfiltered access is incompatible, must check each pair
1368        let mut conflicts = AccessConflicts::empty();
1369        if !self.combined_access.is_compatible(filtered_access.access()) {
1370            for filtered in &self.filtered_accesses {
1371                conflicts.add(&filtered.get_conflicts(filtered_access));
1372            }
1373        }
1374        conflicts
1375    }
1376
1377    /// Adds the filtered access to the set.
1378    pub fn add(&mut self, filtered_access: FilteredAccess) {
1379        self.combined_access.extend(&filtered_access.access);
1380        self.filtered_accesses.push(filtered_access);
1381    }
1382
1383    /// Adds a read access to a resource to the set.
1384    pub fn add_unfiltered_resource_read(&mut self, index: ComponentId) {
1385        let mut filter = FilteredAccess::default();
1386        filter.add_resource_read(index);
1387        self.add(filter);
1388    }
1389
1390    /// Adds a write access to a resource to the set.
1391    pub fn add_unfiltered_resource_write(&mut self, index: ComponentId) {
1392        let mut filter = FilteredAccess::default();
1393        filter.add_resource_write(index);
1394        self.add(filter);
1395    }
1396
1397    /// Adds read access to all resources to the set.
1398    pub fn add_unfiltered_read_all_resources(&mut self) {
1399        let mut filter = FilteredAccess::default();
1400        filter.access.read_all_resources();
1401        self.add(filter);
1402    }
1403
1404    /// Adds write access to all resources to the set.
1405    pub fn add_unfiltered_write_all_resources(&mut self) {
1406        let mut filter = FilteredAccess::default();
1407        filter.access.write_all_resources();
1408        self.add(filter);
1409    }
1410
1411    /// Adds all of the accesses from the passed set to `self`.
1412    pub fn extend(&mut self, filtered_access_set: FilteredAccessSet) {
1413        self.combined_access
1414            .extend(&filtered_access_set.combined_access);
1415        self.filtered_accesses
1416            .extend(filtered_access_set.filtered_accesses);
1417    }
1418
1419    /// Marks the set as reading all possible indices of type T.
1420    pub fn read_all(&mut self) {
1421        let mut filter = FilteredAccess::matches_everything();
1422        filter.read_all();
1423        self.add(filter);
1424    }
1425
1426    /// Marks the set as writing all T.
1427    pub fn write_all(&mut self) {
1428        let mut filter = FilteredAccess::matches_everything();
1429        filter.write_all();
1430        self.add(filter);
1431    }
1432
1433    /// Removes all accesses stored in this set.
1434    pub fn clear(&mut self) {
1435        self.combined_access.clear();
1436        self.filtered_accesses.clear();
1437    }
1438}
1439
1440#[cfg(test)]
1441mod tests {
1442    use super::{invertible_difference_with, invertible_union_with};
1443    use crate::{
1444        component::ComponentId,
1445        query::{
1446            access::AccessFilters, Access, AccessConflicts, ComponentAccessKind, FilteredAccess,
1447            FilteredAccessSet, UnboundedAccessError,
1448        },
1449    };
1450    use alloc::{vec, vec::Vec};
1451    use fixedbitset::FixedBitSet;
1452
1453    fn create_sample_access() -> Access {
1454        let mut access = Access::default();
1455
1456        access.add_component_read(ComponentId::new(1));
1457        access.add_component_read(ComponentId::new(2));
1458        access.add_component_write(ComponentId::new(3));
1459        access.add_archetypal(ComponentId::new(5));
1460        access.read_all();
1461
1462        access
1463    }
1464
1465    fn create_sample_filtered_access() -> FilteredAccess {
1466        let mut filtered_access = FilteredAccess::default();
1467
1468        filtered_access.add_component_write(ComponentId::new(1));
1469        filtered_access.add_component_read(ComponentId::new(2));
1470        filtered_access.add_required(ComponentId::new(3));
1471        filtered_access.and_with(ComponentId::new(4));
1472
1473        filtered_access
1474    }
1475
1476    fn create_sample_access_filters() -> AccessFilters {
1477        let mut access_filters = AccessFilters::default();
1478
1479        access_filters.with.grow_and_insert(3);
1480        access_filters.without.grow_and_insert(5);
1481
1482        access_filters
1483    }
1484
1485    fn create_sample_filtered_access_set() -> FilteredAccessSet {
1486        let mut filtered_access_set = FilteredAccessSet::default();
1487
1488        filtered_access_set.add_unfiltered_resource_read(ComponentId::new(2));
1489        filtered_access_set.add_unfiltered_resource_write(ComponentId::new(4));
1490        filtered_access_set.read_all();
1491
1492        filtered_access_set
1493    }
1494
1495    #[test]
1496    fn test_access_clone() {
1497        let original = create_sample_access();
1498        let cloned = original.clone();
1499
1500        assert_eq!(original, cloned);
1501    }
1502
1503    #[test]
1504    fn test_access_clone_from() {
1505        let original = create_sample_access();
1506        let mut cloned = Access::default();
1507
1508        cloned.add_component_write(ComponentId::new(7));
1509        cloned.add_component_read(ComponentId::new(4));
1510        cloned.add_archetypal(ComponentId::new(8));
1511        cloned.write_all();
1512
1513        cloned.clone_from(&original);
1514
1515        assert_eq!(original, cloned);
1516    }
1517
1518    #[test]
1519    fn test_filtered_access_clone() {
1520        let original = create_sample_filtered_access();
1521        let cloned = original.clone();
1522
1523        assert_eq!(original, cloned);
1524    }
1525
1526    #[test]
1527    fn test_filtered_access_clone_from() {
1528        let original = create_sample_filtered_access();
1529        let mut cloned = FilteredAccess::default();
1530
1531        cloned.add_component_write(ComponentId::new(7));
1532        cloned.add_component_read(ComponentId::new(4));
1533        cloned.append_or(&FilteredAccess::default());
1534
1535        cloned.clone_from(&original);
1536
1537        assert_eq!(original, cloned);
1538    }
1539
1540    #[test]
1541    fn test_access_filters_clone() {
1542        let original = create_sample_access_filters();
1543        let cloned = original.clone();
1544
1545        assert_eq!(original, cloned);
1546    }
1547
1548    #[test]
1549    fn test_access_filters_clone_from() {
1550        let original = create_sample_access_filters();
1551        let mut cloned = AccessFilters::default();
1552
1553        cloned.with.grow_and_insert(1);
1554        cloned.without.grow_and_insert(2);
1555
1556        cloned.clone_from(&original);
1557
1558        assert_eq!(original, cloned);
1559    }
1560
1561    #[test]
1562    fn test_filtered_access_set_clone() {
1563        let original = create_sample_filtered_access_set();
1564        let cloned = original.clone();
1565
1566        assert_eq!(original, cloned);
1567    }
1568
1569    #[test]
1570    fn test_filtered_access_set_from() {
1571        let original = create_sample_filtered_access_set();
1572        let mut cloned = FilteredAccessSet::default();
1573
1574        cloned.add_unfiltered_resource_read(ComponentId::new(7));
1575        cloned.add_unfiltered_resource_write(ComponentId::new(9));
1576        cloned.write_all();
1577
1578        cloned.clone_from(&original);
1579
1580        assert_eq!(original, cloned);
1581    }
1582
1583    #[test]
1584    fn read_all_access_conflicts() {
1585        // read_all / single write
1586        let mut access_a = Access::default();
1587        access_a.add_component_write(ComponentId::new(0));
1588
1589        let mut access_b = Access::default();
1590        access_b.read_all();
1591
1592        assert!(!access_b.is_compatible(&access_a));
1593
1594        // read_all / read_all
1595        let mut access_a = Access::default();
1596        access_a.read_all();
1597
1598        let mut access_b = Access::default();
1599        access_b.read_all();
1600
1601        assert!(access_b.is_compatible(&access_a));
1602    }
1603
1604    #[test]
1605    fn access_get_conflicts() {
1606        let mut access_a = Access::default();
1607        access_a.add_component_read(ComponentId::new(0));
1608        access_a.add_component_read(ComponentId::new(1));
1609
1610        let mut access_b = Access::default();
1611        access_b.add_component_read(ComponentId::new(0));
1612        access_b.add_component_write(ComponentId::new(1));
1613
1614        assert_eq!(
1615            access_a.get_conflicts(&access_b),
1616            vec![ComponentId::new(1)].into()
1617        );
1618
1619        let mut access_c = Access::default();
1620        access_c.add_component_write(ComponentId::new(0));
1621        access_c.add_component_write(ComponentId::new(1));
1622
1623        assert_eq!(
1624            access_a.get_conflicts(&access_c),
1625            vec![ComponentId::new(0), ComponentId::new(1)].into()
1626        );
1627        assert_eq!(
1628            access_b.get_conflicts(&access_c),
1629            vec![ComponentId::new(0), ComponentId::new(1)].into()
1630        );
1631
1632        let mut access_d = Access::default();
1633        access_d.add_component_read(ComponentId::new(0));
1634
1635        assert_eq!(access_d.get_conflicts(&access_a), AccessConflicts::empty());
1636        assert_eq!(access_d.get_conflicts(&access_b), AccessConflicts::empty());
1637        assert_eq!(
1638            access_d.get_conflicts(&access_c),
1639            vec![ComponentId::new(0)].into()
1640        );
1641    }
1642
1643    #[test]
1644    fn filtered_combined_access() {
1645        let mut access_a = FilteredAccessSet::default();
1646        access_a.add_unfiltered_resource_read(ComponentId::new(1));
1647
1648        let mut filter_b = FilteredAccess::default();
1649        filter_b.add_resource_write(ComponentId::new(1));
1650
1651        let conflicts = access_a.get_conflicts_single(&filter_b);
1652        assert_eq!(
1653            &conflicts,
1654            &AccessConflicts::from(vec![ComponentId::new(1)]),
1655            "access_a: {access_a:?}, filter_b: {filter_b:?}"
1656        );
1657    }
1658
1659    #[test]
1660    fn filtered_access_extend() {
1661        let mut access_a = FilteredAccess::default();
1662        access_a.add_component_read(ComponentId::new(0));
1663        access_a.add_component_read(ComponentId::new(1));
1664        access_a.and_with(ComponentId::new(2));
1665
1666        let mut access_b = FilteredAccess::default();
1667        access_b.add_component_read(ComponentId::new(0));
1668        access_b.add_component_write(ComponentId::new(3));
1669        access_b.and_without(ComponentId::new(4));
1670
1671        access_a.extend(&access_b);
1672
1673        let mut expected = FilteredAccess::default();
1674        expected.add_component_read(ComponentId::new(0));
1675        expected.add_component_read(ComponentId::new(1));
1676        expected.and_with(ComponentId::new(2));
1677        expected.add_component_write(ComponentId::new(3));
1678        expected.and_without(ComponentId::new(4));
1679
1680        assert!(access_a.eq(&expected));
1681    }
1682
1683    #[test]
1684    fn filtered_access_extend_or() {
1685        let mut access_a = FilteredAccess::default();
1686        // Exclusive access to `(&mut A, &mut B)`.
1687        access_a.add_component_write(ComponentId::new(0));
1688        access_a.add_component_write(ComponentId::new(1));
1689
1690        // Filter by `With<C>`.
1691        let mut access_b = FilteredAccess::default();
1692        access_b.and_with(ComponentId::new(2));
1693
1694        // Filter by `(With<D>, Without<E>)`.
1695        let mut access_c = FilteredAccess::default();
1696        access_c.and_with(ComponentId::new(3));
1697        access_c.and_without(ComponentId::new(4));
1698
1699        // Turns `access_b` into `Or<(With<C>, (With<D>, Without<D>))>`.
1700        access_b.append_or(&access_c);
1701        // Applies the filters to the initial query, which corresponds to the FilteredAccess'
1702        // representation of `Query<(&mut A, &mut B), Or<(With<C>, (With<D>, Without<E>))>>`.
1703        access_a.extend(&access_b);
1704
1705        // Construct the expected `FilteredAccess` struct.
1706        // The intention here is to test that exclusive access implied by `add_write`
1707        // forms correct normalized access structs when extended with `Or` filters.
1708        let mut expected = FilteredAccess::default();
1709        expected.add_component_write(ComponentId::new(0));
1710        expected.add_component_write(ComponentId::new(1));
1711        // The resulted access is expected to represent `Or<((With<A>, With<B>, With<C>), (With<A>, With<B>, With<D>, Without<E>))>`.
1712        expected.filter_sets = vec![
1713            AccessFilters {
1714                with: FixedBitSet::with_capacity_and_blocks(3, [0b111]),
1715                without: FixedBitSet::default(),
1716            },
1717            AccessFilters {
1718                with: FixedBitSet::with_capacity_and_blocks(4, [0b1011]),
1719                without: FixedBitSet::with_capacity_and_blocks(5, [0b10000]),
1720            },
1721        ];
1722
1723        assert_eq!(access_a, expected);
1724    }
1725
1726    #[test]
1727    fn try_iter_component_access_simple() {
1728        let mut access = Access::default();
1729
1730        access.add_component_read(ComponentId::new(1));
1731        access.add_component_read(ComponentId::new(2));
1732        access.add_component_write(ComponentId::new(3));
1733        access.add_archetypal(ComponentId::new(5));
1734
1735        let result = access
1736            .try_iter_component_access()
1737            .map(Iterator::collect::<Vec<_>>);
1738
1739        assert_eq!(
1740            result,
1741            Ok(vec![
1742                ComponentAccessKind::Shared(ComponentId::new(1)),
1743                ComponentAccessKind::Shared(ComponentId::new(2)),
1744                ComponentAccessKind::Exclusive(ComponentId::new(3)),
1745                ComponentAccessKind::Archetypal(ComponentId::new(5)),
1746            ]),
1747        );
1748    }
1749
1750    #[test]
1751    fn try_iter_component_access_unbounded_write_all() {
1752        let mut access = Access::default();
1753
1754        access.add_component_read(ComponentId::new(1));
1755        access.add_component_read(ComponentId::new(2));
1756        access.write_all();
1757
1758        let result = access
1759            .try_iter_component_access()
1760            .map(Iterator::collect::<Vec<_>>);
1761
1762        assert_eq!(
1763            result,
1764            Err(UnboundedAccessError {
1765                writes_inverted: true,
1766                read_and_writes_inverted: true
1767            }),
1768        );
1769    }
1770
1771    #[test]
1772    fn try_iter_component_access_unbounded_read_all() {
1773        let mut access = Access::default();
1774
1775        access.add_component_read(ComponentId::new(1));
1776        access.add_component_read(ComponentId::new(2));
1777        access.read_all();
1778
1779        let result = access
1780            .try_iter_component_access()
1781            .map(Iterator::collect::<Vec<_>>);
1782
1783        assert_eq!(
1784            result,
1785            Err(UnboundedAccessError {
1786                writes_inverted: false,
1787                read_and_writes_inverted: true
1788            }),
1789        );
1790    }
1791
1792    /// Create a `FixedBitSet` with a given number of total bits and a given list of bits to set.
1793    /// Setting the number of bits is important in tests since the `PartialEq` impl checks that the length matches.
1794    fn bit_set(bits: usize, iter: impl IntoIterator<Item = usize>) -> FixedBitSet {
1795        let mut result = FixedBitSet::with_capacity(bits);
1796        result.extend(iter);
1797        result
1798    }
1799
1800    #[test]
1801    fn invertible_union_with_tests() {
1802        let invertible_union = |mut self_inverted: bool, other_inverted: bool| {
1803            // Check all four possible bit states: In both sets, the first, the second, or neither
1804            let mut self_set = bit_set(4, [0, 1]);
1805            let other_set = bit_set(4, [0, 2]);
1806            invertible_union_with(
1807                &mut self_set,
1808                &mut self_inverted,
1809                &other_set,
1810                other_inverted,
1811            );
1812            (self_set, self_inverted)
1813        };
1814
1815        // Check each combination of `inverted` flags
1816        let (s, i) = invertible_union(false, false);
1817        // [0, 1] | [0, 2] = [0, 1, 2]
1818        assert_eq!((s, i), (bit_set(4, [0, 1, 2]), false));
1819
1820        let (s, i) = invertible_union(false, true);
1821        // [0, 1] | [1, 3, ...] = [0, 1, 3, ...]
1822        assert_eq!((s, i), (bit_set(4, [2]), true));
1823
1824        let (s, i) = invertible_union(true, false);
1825        // [2, 3, ...] | [0, 2] = [0, 2, 3, ...]
1826        assert_eq!((s, i), (bit_set(4, [1]), true));
1827
1828        let (s, i) = invertible_union(true, true);
1829        // [2, 3, ...] | [1, 3, ...] = [1, 2, 3, ...]
1830        assert_eq!((s, i), (bit_set(4, [0]), true));
1831    }
1832
1833    #[test]
1834    fn invertible_union_with_different_lengths() {
1835        // When adding a large inverted set to a small normal set,
1836        // make sure we invert the bits beyond the original length.
1837        // Failing to call `grow` before `toggle_range` would cause bit 1 to be zero,
1838        // which would incorrectly treat it as included in the output set.
1839        let mut self_set = bit_set(1, [0]);
1840        let mut self_inverted = false;
1841        let other_set = bit_set(3, [0, 1]);
1842        let other_inverted = true;
1843        invertible_union_with(
1844            &mut self_set,
1845            &mut self_inverted,
1846            &other_set,
1847            other_inverted,
1848        );
1849
1850        // [0] | [2, ...] = [0, 2, ...]
1851        assert_eq!((self_set, self_inverted), (bit_set(3, [1]), true));
1852    }
1853
1854    #[test]
1855    fn invertible_difference_with_tests() {
1856        let invertible_difference = |mut self_inverted: bool, other_inverted: bool| {
1857            // Check all four possible bit states: In both sets, the first, the second, or neither
1858            let mut self_set = bit_set(4, [0, 1]);
1859            let other_set = bit_set(4, [0, 2]);
1860            invertible_difference_with(
1861                &mut self_set,
1862                &mut self_inverted,
1863                &other_set,
1864                other_inverted,
1865            );
1866            (self_set, self_inverted)
1867        };
1868
1869        // Check each combination of `inverted` flags
1870        let (s, i) = invertible_difference(false, false);
1871        // [0, 1] - [0, 2] = [1]
1872        assert_eq!((s, i), (bit_set(4, [1]), false));
1873
1874        let (s, i) = invertible_difference(false, true);
1875        // [0, 1] - [1, 3, ...] = [0]
1876        assert_eq!((s, i), (bit_set(4, [0]), false));
1877
1878        let (s, i) = invertible_difference(true, false);
1879        // [2, 3, ...] - [0, 2] = [3, ...]
1880        assert_eq!((s, i), (bit_set(4, [0, 1, 2]), true));
1881
1882        let (s, i) = invertible_difference(true, true);
1883        // [2, 3, ...] - [1, 3, ...] = [2]
1884        assert_eq!((s, i), (bit_set(4, [2]), false));
1885    }
1886}