17
17
18
18
use bevy_ecs:: {
19
19
change_detection:: Mut ,
20
- prelude:: { Commands , Entity , Query } ,
20
+ prelude:: { Commands , Entity , Query , World } ,
21
21
query:: QueryEntityError ,
22
- system:: SystemParam ,
22
+ system:: { SystemParam , SystemState } ,
23
23
} ;
24
24
25
25
use std:: { ops:: RangeBounds , sync:: Arc } ;
@@ -38,7 +38,7 @@ pub use buffer_access_lifecycle::BufferKeyLifecycle;
38
38
pub ( crate ) use buffer_access_lifecycle:: * ;
39
39
40
40
mod buffer_key_builder;
41
- pub ( crate ) use buffer_key_builder:: * ;
41
+ pub use buffer_key_builder:: * ;
42
42
43
43
mod buffer_map;
44
44
pub use buffer_map:: * ;
@@ -402,6 +402,67 @@ where
402
402
}
403
403
}
404
404
405
+ /// This trait allows [`World`] to give you access to any buffer using a [`BufferKey`]
406
+ pub trait BufferWorldAccess {
407
+ /// Call this to get read-only access to a buffer from a [`World`].
408
+ ///
409
+ /// Alternatively you can use [`BufferAccess`] as a regular bevy system parameter,
410
+ /// which does not need direct world access.
411
+ fn buffer_view < T > ( & self , key : & BufferKey < T > ) -> Result < BufferView < ' _ , T > , BufferError >
412
+ where
413
+ T : ' static + Send + Sync ;
414
+
415
+ /// Call this to get mutable access to a buffer.
416
+ ///
417
+ /// Pass in a callback that will receive [`BufferMut`], allowing it to view
418
+ /// and modify the contents of the buffer.
419
+ fn buffer_mut < T , U > (
420
+ & mut self ,
421
+ key : & BufferKey < T > ,
422
+ f : impl FnOnce ( BufferMut < T > ) -> U ,
423
+ ) -> Result < U , BufferError >
424
+ where
425
+ T : ' static + Send + Sync ;
426
+ }
427
+
428
+ impl BufferWorldAccess for World {
429
+ fn buffer_view < T > ( & self , key : & BufferKey < T > ) -> Result < BufferView < ' _ , T > , BufferError >
430
+ where
431
+ T : ' static + Send + Sync ,
432
+ {
433
+ let buffer_ref = self
434
+ . get_entity ( key. tag . buffer )
435
+ . ok_or ( BufferError :: BufferMissing ) ?;
436
+ let storage = buffer_ref
437
+ . get :: < BufferStorage < T > > ( )
438
+ . ok_or ( BufferError :: BufferMissing ) ?;
439
+ let gate = buffer_ref
440
+ . get :: < GateState > ( )
441
+ . ok_or ( BufferError :: BufferMissing ) ?;
442
+ Ok ( BufferView {
443
+ storage,
444
+ gate,
445
+ session : key. tag . session ,
446
+ } )
447
+ }
448
+
449
+ fn buffer_mut < T , U > (
450
+ & mut self ,
451
+ key : & BufferKey < T > ,
452
+ f : impl FnOnce ( BufferMut < T > ) -> U ,
453
+ ) -> Result < U , BufferError >
454
+ where
455
+ T : ' static + Send + Sync ,
456
+ {
457
+ let mut state = SystemState :: < BufferAccessMut < T > > :: new ( self ) ;
458
+ let mut buffer_access_mut = state. get_mut ( self ) ;
459
+ let buffer_mut = buffer_access_mut
460
+ . get_mut ( key)
461
+ . map_err ( |_| BufferError :: BufferMissing ) ?;
462
+ Ok ( f ( buffer_mut) )
463
+ }
464
+ }
465
+
405
466
/// Access to view a buffer that exists inside a workflow.
406
467
pub struct BufferView < ' a , T >
407
468
where
0 commit comments