1717
1818use bevy_ecs:: {
1919 change_detection:: Mut ,
20- prelude:: { Commands , Entity , Query } ,
20+ prelude:: { Commands , Entity , Query , World } ,
2121 query:: QueryEntityError ,
22- system:: SystemParam ,
22+ system:: { SystemParam , SystemState } ,
2323} ;
2424
2525use std:: { ops:: RangeBounds , sync:: Arc } ;
@@ -38,7 +38,7 @@ pub use buffer_access_lifecycle::BufferKeyLifecycle;
3838pub ( crate ) use buffer_access_lifecycle:: * ;
3939
4040mod buffer_key_builder;
41- pub ( crate ) use buffer_key_builder:: * ;
41+ pub use buffer_key_builder:: * ;
4242
4343mod buffer_map;
4444pub use buffer_map:: * ;
@@ -402,6 +402,67 @@ where
402402 }
403403}
404404
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+
405466/// Access to view a buffer that exists inside a workflow.
406467pub struct BufferView < ' a , T >
407468where
0 commit comments