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
9struct 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#[derive(Eq, PartialEq, Default)]
47pub struct Access {
48 component_read_and_writes: FixedBitSet,
51 component_writes: FixedBitSet,
54 resource_read_and_writes: FixedBitSet,
56 resource_writes: FixedBitSet,
58 component_read_and_writes_inverted: bool,
61 component_writes_inverted: bool,
64 reads_all_resources: bool,
67 writes_all_resources: bool,
70 archetypal: FixedBitSet,
72}
73
74impl 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 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 pub(crate) const fn new_read_all() -> Self {
156 let mut access = Self::new();
157 access.reads_all_resources = true;
158 access.component_read_and_writes_inverted = true;
161 access
162 }
163
164 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 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 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 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 pub fn add_resource_read(&mut self, index: ComponentId) {
209 self.resource_read_and_writes.grow_and_insert(index.index());
210 }
211
212 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 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 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 pub fn add_archetypal(&mut self, index: ComponentId) {
271 self.archetypal.grow_and_insert(index.index());
272 }
273
274 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 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 pub fn has_component_write(&self, index: ComponentId) -> bool {
287 self.component_writes_inverted ^ self.component_writes.contains(index.index())
288 }
289
290 pub fn has_any_component_write(&self) -> bool {
292 self.component_writes_inverted || !self.component_writes.is_clear()
293 }
294
295 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 pub fn has_any_resource_read(&self) -> bool {
302 self.reads_all_resources || !self.resource_read_and_writes.is_clear()
303 }
304
305 pub fn has_resource_write(&self, index: ComponentId) -> bool {
307 self.writes_all_resources || self.resource_writes.contains(index.index())
308 }
309
310 pub fn has_any_resource_write(&self) -> bool {
312 self.writes_all_resources || !self.resource_writes.is_clear()
313 }
314
315 pub fn has_any_read(&self) -> bool {
317 self.has_any_component_read() || self.has_any_resource_read()
318 }
319
320 pub fn has_any_write(&self) -> bool {
322 self.has_any_component_write() || self.has_any_resource_write()
323 }
324
325 pub fn has_archetypal(&self, index: ComponentId) -> bool {
334 self.archetypal.contains(index.index())
335 }
336
337 #[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 #[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 #[inline]
354 pub const fn read_all_resources(&mut self) {
355 self.reads_all_resources = true;
356 }
357
358 #[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 #[inline]
367 pub fn read_all(&mut self) {
368 self.read_all_components();
369 self.read_all_resources();
370 }
371
372 #[inline]
374 pub fn write_all(&mut self) {
375 self.write_all_components();
376 self.write_all_resources();
377 }
378
379 #[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 #[inline]
387 pub fn has_write_all_components(&self) -> bool {
388 self.component_writes_inverted && self.component_writes.is_clear()
389 }
390
391 #[inline]
393 pub fn has_read_all_resources(&self) -> bool {
394 self.reads_all_resources
395 }
396
397 #[inline]
399 pub fn has_write_all_resources(&self) -> bool {
400 self.writes_all_resources
401 }
402
403 pub fn has_read_all(&self) -> bool {
405 self.has_read_all_components() && self.has_read_all_resources()
406 }
407
408 pub fn has_write_all(&self) -> bool {
410 self.has_write_all_components() && self.has_write_all_resources()
411 }
412
413 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 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 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 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 pub fn is_components_compatible(&self, other: &Access) -> bool {
493 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 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 pub fn is_compatible(&self, other: &Access) -> bool {
571 self.is_components_compatible(other) && self.is_resources_compatible(other)
572 }
573
574 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 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 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 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 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 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 pub fn resource_reads_and_writes(&self) -> impl Iterator<Item = ComponentId> + '_ {
731 self.resource_read_and_writes.ones().map(ComponentId::new)
732 }
733
734 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 pub fn resource_writes(&self) -> impl Iterator<Item = ComponentId> + '_ {
743 self.resource_writes.ones().map(ComponentId::new)
744 }
745
746 pub fn archetypal(&self) -> impl Iterator<Item = ComponentId> + '_ {
755 self.archetypal.ones().map(ComponentId::new)
756 }
757
758 pub fn try_iter_component_access(
789 &self,
790 ) -> Result<impl Iterator<Item = ComponentAccessKind> + '_, UnboundedAccessError> {
791 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
823fn 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 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
851fn invertible_difference_with(
860 self_set: &mut FixedBitSet,
861 self_inverted: &mut bool,
862 other_set: &FixedBitSet,
863 other_inverted: bool,
864) {
865 *self_inverted = !*self_inverted;
868 invertible_union_with(self_set, self_inverted, other_set, other_inverted);
869 *self_inverted = !*self_inverted;
870}
871
872#[derive(Clone, Copy, PartialEq, Eq, Debug, Error)]
875#[error("Access is unbounded")]
876pub struct UnboundedAccessError {
877 pub writes_inverted: bool,
880 pub read_and_writes_inverted: bool,
883}
884
885#[derive(PartialEq, Eq, Hash, Debug, Clone, Copy)]
887pub enum ComponentAccessKind {
888 Archetypal(ComponentId),
890 Shared(ComponentId),
892 Exclusive(ComponentId),
894}
895
896impl ComponentAccessKind {
897 pub fn index(&self) -> &ComponentId {
899 let (Self::Archetypal(value) | Self::Shared(value) | Self::Exclusive(value)) = self;
900 value
901 }
902}
903
904#[derive(Debug, Eq, PartialEq)]
925pub struct FilteredAccess {
926 pub(crate) access: Access,
927 pub(crate) required: FixedBitSet,
928 pub(crate) filter_sets: Vec<AccessFilters>,
931}
932
933impl 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#[derive(Debug, PartialEq, From)]
966pub enum AccessConflicts {
967 All,
969 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 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 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 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 pub fn matches_nothing() -> Self {
1040 Self {
1041 access: Access::default(),
1042 required: FixedBitSet::default(),
1043 filter_sets: Vec::new(),
1044 }
1045 }
1046
1047 #[inline]
1049 pub fn access(&self) -> &Access {
1050 &self.access
1051 }
1052
1053 #[inline]
1055 pub fn access_mut(&mut self) -> &mut Access {
1056 &mut self.access
1057 }
1058
1059 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 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 pub fn add_resource_read(&mut self, index: ComponentId) {
1075 self.access.add_resource_read(index);
1076 }
1077
1078 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 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 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 pub fn append_or(&mut self, other: &FilteredAccess) {
1113 self.filter_sets.append(&mut other.filter_sets.clone());
1114 }
1115
1116 pub fn extend_access(&mut self, other: &FilteredAccess) {
1118 self.access.extend(&other.access);
1119 }
1120
1121 pub fn is_compatible(&self, other: &FilteredAccess) -> bool {
1123 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 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 pub fn get_conflicts(&self, other: &FilteredAccess) -> AccessConflicts {
1150 if !self.is_compatible(other) {
1151 return self.access.get_conflicts(&other.access);
1153 }
1154 AccessConflicts::empty()
1155 }
1156
1157 pub fn extend(&mut self, other: &FilteredAccess) {
1164 self.access.extend(&other.access);
1165 self.required.union_with(&other.required);
1166
1167 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 pub fn read_all(&mut self) {
1191 self.access.read_all();
1192 }
1193
1194 pub fn write_all(&mut self) {
1196 self.access.write_all();
1197 }
1198
1199 pub fn read_all_components(&mut self) {
1201 self.access.read_all_components();
1202 }
1203
1204 pub fn write_all_components(&mut self) {
1206 self.access.write_all_components();
1207 }
1208
1209 pub fn is_subset(&self, other: &FilteredAccess) -> bool {
1212 self.required.is_subset(&other.required) && self.access().is_subset(other.access())
1213 }
1214
1215 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 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 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
1247impl 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 !self.with.is_disjoint(&other.without) || !self.without.is_disjoint(&other.with)
1279 }
1280}
1281
1282#[derive(Debug, PartialEq, Eq, Default)]
1290pub struct FilteredAccessSet {
1291 combined_access: Access,
1292 filtered_accesses: Vec<FilteredAccess>,
1293}
1294
1295impl 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 pub const fn new() -> Self {
1313 Self {
1314 combined_access: Access::new(),
1315 filtered_accesses: Vec::new(),
1316 }
1317 }
1318
1319 #[inline]
1321 pub fn combined_access(&self) -> &Access {
1322 &self.combined_access
1323 }
1324
1325 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 pub fn get_conflicts(&self, other: &FilteredAccessSet) -> AccessConflicts {
1353 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 pub fn get_conflicts_single(&self, filtered_access: &FilteredAccess) -> AccessConflicts {
1367 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 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 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 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 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 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 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 pub fn read_all(&mut self) {
1421 let mut filter = FilteredAccess::matches_everything();
1422 filter.read_all();
1423 self.add(filter);
1424 }
1425
1426 pub fn write_all(&mut self) {
1428 let mut filter = FilteredAccess::matches_everything();
1429 filter.write_all();
1430 self.add(filter);
1431 }
1432
1433 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 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 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 access_a.add_component_write(ComponentId::new(0));
1688 access_a.add_component_write(ComponentId::new(1));
1689
1690 let mut access_b = FilteredAccess::default();
1692 access_b.and_with(ComponentId::new(2));
1693
1694 let mut access_c = FilteredAccess::default();
1696 access_c.and_with(ComponentId::new(3));
1697 access_c.and_without(ComponentId::new(4));
1698
1699 access_b.append_or(&access_c);
1701 access_a.extend(&access_b);
1704
1705 let mut expected = FilteredAccess::default();
1709 expected.add_component_write(ComponentId::new(0));
1710 expected.add_component_write(ComponentId::new(1));
1711 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 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 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 let (s, i) = invertible_union(false, false);
1817 assert_eq!((s, i), (bit_set(4, [0, 1, 2]), false));
1819
1820 let (s, i) = invertible_union(false, true);
1821 assert_eq!((s, i), (bit_set(4, [2]), true));
1823
1824 let (s, i) = invertible_union(true, false);
1825 assert_eq!((s, i), (bit_set(4, [1]), true));
1827
1828 let (s, i) = invertible_union(true, true);
1829 assert_eq!((s, i), (bit_set(4, [0]), true));
1831 }
1832
1833 #[test]
1834 fn invertible_union_with_different_lengths() {
1835 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 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 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 let (s, i) = invertible_difference(false, false);
1871 assert_eq!((s, i), (bit_set(4, [1]), false));
1873
1874 let (s, i) = invertible_difference(false, true);
1875 assert_eq!((s, i), (bit_set(4, [0]), false));
1877
1878 let (s, i) = invertible_difference(true, false);
1879 assert_eq!((s, i), (bit_set(4, [0, 1, 2]), true));
1881
1882 let (s, i) = invertible_difference(true, true);
1883 assert_eq!((s, i), (bit_set(4, [2]), false));
1885 }
1886}