Skip to content

Commit c4e8261

Browse files
committed
Absorbed AccessSet implementation into TypeAccess.
1 parent 8fbe2a7 commit c4e8261

File tree

1 file changed

+68
-109
lines changed

1 file changed

+68
-109
lines changed

crates/bevy_ecs/src/core/access.rs

Lines changed: 68 additions & 109 deletions
Original file line numberDiff line numberDiff line change
@@ -196,87 +196,6 @@ impl QueryAccess {
196196
}
197197
}
198198

199-
// TODO consider ditching, see CondensedTypeAccess for comparison
200-
#[derive(Debug, Eq, PartialEq, Clone)]
201-
enum AccessSet<T: Hash + Eq + PartialEq> {
202-
All,
203-
Some(HashSet<T>),
204-
}
205-
206-
impl<T: Hash + Eq + PartialEq> Default for AccessSet<T> {
207-
fn default() -> Self {
208-
Self::Some(Default::default())
209-
}
210-
}
211-
212-
impl<T: Hash + Eq + PartialEq + Copy> AccessSet<T> {
213-
fn is_disjoint(&self, other: &AccessSet<T>) -> bool {
214-
if let (AccessSet::Some(set), AccessSet::Some(other)) = (self, other) {
215-
set.is_disjoint(other)
216-
} else {
217-
false
218-
}
219-
}
220-
221-
fn extend(&mut self, other: &AccessSet<T>) {
222-
match self {
223-
AccessSet::All => (),
224-
AccessSet::Some(set) => match other {
225-
AccessSet::All => *self = AccessSet::All,
226-
AccessSet::Some(other) => set.extend(other),
227-
},
228-
}
229-
}
230-
231-
fn insert(&mut self, item: T) {
232-
match self {
233-
AccessSet::All => (),
234-
AccessSet::Some(set) => {
235-
set.insert(item);
236-
}
237-
}
238-
}
239-
240-
fn clear(&mut self) {
241-
match self {
242-
// If a system had full access before, it'll have full access next time either way.
243-
AccessSet::All => (),
244-
AccessSet::Some(set) => set.clear(),
245-
}
246-
}
247-
248-
fn contains(&self, item: &T) -> bool {
249-
match self {
250-
AccessSet::All => true,
251-
AccessSet::Some(set) => set.contains(item),
252-
}
253-
}
254-
255-
fn find_conflict<'a>(&'a self, other: &'a AccessSet<T>) -> AccessConflict<'a, T> {
256-
match (self, other) {
257-
(AccessSet::Some(set), AccessSet::Some(other)) => {
258-
if let Some(intersection) = set.intersection(other).next() {
259-
return AccessConflict::Element(intersection);
260-
}
261-
}
262-
(AccessSet::Some(set), AccessSet::All) | (AccessSet::All, AccessSet::Some(set)) => {
263-
if let Some(first) = set.iter().next() {
264-
return AccessConflict::Element(first);
265-
}
266-
}
267-
(AccessSet::All, AccessSet::All) => return AccessConflict::All,
268-
}
269-
AccessConflict::None
270-
}
271-
272-
fn distinct_iterator(&self) -> Option<impl Iterator<Item = &T>> {
273-
match self {
274-
AccessSet::All => None,
275-
AccessSet::Some(set) => Some(set.iter()),
276-
}
277-
}
278-
}
279-
280199
pub enum AccessConflict<'a, T> {
281200
None,
282201
Element(&'a T),
@@ -286,17 +205,19 @@ pub enum AccessConflict<'a, T> {
286205
/// Provides information about the types a [System] reads and writes
287206
#[derive(Debug, Eq, PartialEq, Clone)]
288207
pub struct TypeAccess<T: Hash + Eq + PartialEq> {
289-
reads_and_writes: AccessSet<T>,
290-
writes: AccessSet<T>,
291-
reads: AccessSet<T>,
208+
reads_all: bool,
209+
writes_all: bool,
210+
reads_and_writes: HashSet<T>,
211+
writes: HashSet<T>,
292212
}
293213

294214
impl<T: Hash + Eq + PartialEq> Default for TypeAccess<T> {
295215
fn default() -> Self {
296216
Self {
217+
reads_all: false,
218+
writes_all: false,
297219
reads_and_writes: Default::default(),
298220
writes: Default::default(),
299-
reads: Default::default(),
300221
}
301222
}
302223
}
@@ -307,36 +228,72 @@ impl<T: Hash + Eq + PartialEq + Copy> TypeAccess<T> {
307228
for write in writes {
308229
type_access.add_write(write);
309230
}
310-
311231
for read in reads {
312232
type_access.add_read(read);
313233
}
314-
315234
type_access
316235
}
317236

318237
pub fn is_compatible(&self, other: &TypeAccess<T>) -> bool {
319-
self.writes.is_disjoint(&other.reads_and_writes)
320-
&& self.reads_and_writes.is_disjoint(&other.writes)
238+
if self.writes_all() {
239+
!other.writes_all && !other.reads_all && other.reads_and_writes.is_empty()
240+
} else if self.reads_all {
241+
!other.writes_all && other.writes.is_empty()
242+
} else {
243+
self.writes.is_disjoint(&other.reads_and_writes)
244+
&& self.reads_and_writes.is_disjoint(&other.writes)
245+
}
321246
}
322247

323248
pub fn get_conflict<'a>(&'a self, other: &'a TypeAccess<T>) -> AccessConflict<'a, T> {
324-
let conflict = self.writes.find_conflict(&other.reads_and_writes);
325-
if let AccessConflict::None = conflict {
326-
return self.reads_and_writes.find_conflict(&other.writes);
249+
if self.writes_all {
250+
if other.writes_all || other.reads_all {
251+
AccessConflict::All
252+
} else {
253+
match other.reads_and_writes.iter().next() {
254+
Some(element) => AccessConflict::Element(element),
255+
None => AccessConflict::None,
256+
}
257+
}
258+
} else if self.reads_all {
259+
if other.writes_all {
260+
AccessConflict::All
261+
} else {
262+
match other.writes.iter().next() {
263+
Some(element) => AccessConflict::Element(element),
264+
None => AccessConflict::None,
265+
}
266+
}
267+
} else if other.writes_all {
268+
match self.reads_and_writes.iter().next() {
269+
Some(element) => AccessConflict::Element(element),
270+
None => AccessConflict::None,
271+
}
272+
} else if other.reads_all {
273+
match self.writes.iter().next() {
274+
Some(element) => AccessConflict::Element(element),
275+
None => AccessConflict::None,
276+
}
277+
} else {
278+
match self.writes.intersection(&other.reads_and_writes).next() {
279+
Some(element) => AccessConflict::Element(element),
280+
None => match other.writes.intersection(&self.reads_and_writes).next() {
281+
Some(element) => AccessConflict::Element(element),
282+
None => AccessConflict::None,
283+
},
284+
}
327285
}
328-
conflict
329286
}
330287

331288
pub fn extend(&mut self, other: &TypeAccess<T>) {
289+
self.reads_all = self.reads_all || other.reads_all;
290+
self.writes_all = self.writes_all || other.writes_all;
332291
self.writes.extend(&other.writes);
333-
self.reads.extend(&other.reads);
334292
self.reads_and_writes.extend(&other.reads_and_writes);
335293
}
336294

337295
pub fn add_read(&mut self, ty: T) {
338296
self.reads_and_writes.insert(ty);
339-
self.reads.insert(ty);
340297
}
341298

342299
pub fn add_write(&mut self, ty: T) {
@@ -345,51 +302,53 @@ impl<T: Hash + Eq + PartialEq + Copy> TypeAccess<T> {
345302
}
346303

347304
pub fn read_all(&mut self) {
348-
self.reads_and_writes = AccessSet::All;
349-
self.reads = AccessSet::All;
305+
self.reads_all = true;
350306
}
351307

352308
pub fn write_all(&mut self) {
353-
self.reads_and_writes = AccessSet::All;
354-
self.writes = AccessSet::All;
309+
self.reads_all = true;
310+
self.writes_all = true;
355311
}
356312

357-
/// NB: does not reset access sets that have been set to `All`.
358313
pub fn clear(&mut self) {
314+
self.reads_all = false;
315+
self.writes_all = false;
359316
self.reads_and_writes.clear();
360-
self.reads.clear();
361317
self.writes.clear();
362318
}
363319

364320
pub fn is_read_or_write(&self, ty: &T) -> bool {
365-
self.reads_and_writes.contains(ty)
321+
self.reads_all || self.writes_all || self.reads_and_writes.contains(ty)
366322
}
367323

368324
pub fn is_write(&self, ty: &T) -> bool {
369-
self.writes.contains(ty)
325+
self.writes_all || self.writes.contains(ty)
370326
}
371327

372328
pub fn reads_all(&self) -> bool {
373-
self.reads == AccessSet::All
329+
self.reads_all
374330
}
375331

376332
pub fn writes_all(&self) -> bool {
377-
self.writes == AccessSet::All
333+
self.writes_all
378334
}
379335

380-
/// Returns an iterator of distinct accessed types if neither write nor read access is `All`.
336+
/// Returns an iterator of distinct accessed types if only some types are accessed.
381337
pub fn all_distinct_types(&self) -> Option<impl Iterator<Item = &T>> {
382-
self.reads_and_writes.distinct_iterator()
338+
if !(self.reads_all || self.writes_all) {
339+
return Some(self.reads_and_writes.iter());
340+
}
341+
None
383342
}
384343

385344
pub fn condense(&self, all_types: &[T]) -> CondensedTypeAccess {
386-
if self.writes_all() {
345+
if self.writes_all {
387346
unreachable!(
388347
"Access for systems that exclusively access all of `World`\
389348
or `Resources` should never be condensed."
390349
)
391350
}
392-
if self.reads_all() {
351+
if self.reads_all {
393352
let mut writes = FixedBitSet::with_capacity(all_types.len());
394353
for (index, access_type) in all_types.iter().enumerate() {
395354
if self.writes.contains(access_type) {

0 commit comments

Comments
 (0)