@@ -196,87 +196,6 @@ impl QueryAccess {
196
196
}
197
197
}
198
198
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
-
280
199
pub enum AccessConflict < ' a , T > {
281
200
None ,
282
201
Element ( & ' a T ) ,
@@ -286,17 +205,19 @@ pub enum AccessConflict<'a, T> {
286
205
/// Provides information about the types a [System] reads and writes
287
206
#[ derive( Debug , Eq , PartialEq , Clone ) ]
288
207
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 > ,
292
212
}
293
213
294
214
impl < T : Hash + Eq + PartialEq > Default for TypeAccess < T > {
295
215
fn default ( ) -> Self {
296
216
Self {
217
+ reads_all : false ,
218
+ writes_all : false ,
297
219
reads_and_writes : Default :: default ( ) ,
298
220
writes : Default :: default ( ) ,
299
- reads : Default :: default ( ) ,
300
221
}
301
222
}
302
223
}
@@ -307,36 +228,72 @@ impl<T: Hash + Eq + PartialEq + Copy> TypeAccess<T> {
307
228
for write in writes {
308
229
type_access. add_write ( write) ;
309
230
}
310
-
311
231
for read in reads {
312
232
type_access. add_read ( read) ;
313
233
}
314
-
315
234
type_access
316
235
}
317
236
318
237
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
+ }
321
246
}
322
247
323
248
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
+ }
327
285
}
328
- conflict
329
286
}
330
287
331
288
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 ;
332
291
self . writes . extend ( & other. writes ) ;
333
- self . reads . extend ( & other. reads ) ;
334
292
self . reads_and_writes . extend ( & other. reads_and_writes ) ;
335
293
}
336
294
337
295
pub fn add_read ( & mut self , ty : T ) {
338
296
self . reads_and_writes . insert ( ty) ;
339
- self . reads . insert ( ty) ;
340
297
}
341
298
342
299
pub fn add_write ( & mut self , ty : T ) {
@@ -345,51 +302,53 @@ impl<T: Hash + Eq + PartialEq + Copy> TypeAccess<T> {
345
302
}
346
303
347
304
pub fn read_all ( & mut self ) {
348
- self . reads_and_writes = AccessSet :: All ;
349
- self . reads = AccessSet :: All ;
305
+ self . reads_all = true ;
350
306
}
351
307
352
308
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 ;
355
311
}
356
312
357
- /// NB: does not reset access sets that have been set to `All`.
358
313
pub fn clear ( & mut self ) {
314
+ self . reads_all = false ;
315
+ self . writes_all = false ;
359
316
self . reads_and_writes . clear ( ) ;
360
- self . reads . clear ( ) ;
361
317
self . writes . clear ( ) ;
362
318
}
363
319
364
320
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)
366
322
}
367
323
368
324
pub fn is_write ( & self , ty : & T ) -> bool {
369
- self . writes . contains ( ty)
325
+ self . writes_all || self . writes . contains ( ty)
370
326
}
371
327
372
328
pub fn reads_all ( & self ) -> bool {
373
- self . reads == AccessSet :: All
329
+ self . reads_all
374
330
}
375
331
376
332
pub fn writes_all ( & self ) -> bool {
377
- self . writes == AccessSet :: All
333
+ self . writes_all
378
334
}
379
335
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 .
381
337
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
383
342
}
384
343
385
344
pub fn condense ( & self , all_types : & [ T ] ) -> CondensedTypeAccess {
386
- if self . writes_all ( ) {
345
+ if self . writes_all {
387
346
unreachable ! (
388
347
"Access for systems that exclusively access all of `World`\
389
348
or `Resources` should never be condensed."
390
349
)
391
350
}
392
- if self . reads_all ( ) {
351
+ if self . reads_all {
393
352
let mut writes = FixedBitSet :: with_capacity ( all_types. len ( ) ) ;
394
353
for ( index, access_type) in all_types. iter ( ) . enumerate ( ) {
395
354
if self . writes . contains ( access_type) {
0 commit comments