Skip to content

Commit 87387e3

Browse files
authored
BufferKeyMap macro (#56)
Signed-off-by: Michael X. Grey <[email protected]>
1 parent 4e35ec8 commit 87387e3

File tree

8 files changed

+642
-163
lines changed

8 files changed

+642
-163
lines changed

macros/src/buffer.rs

+281-61
Large diffs are not rendered by default.

macros/src/lib.rs

+13-1
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
*/
1717

1818
mod buffer;
19-
use buffer::impl_joined_value;
19+
use buffer::{impl_buffer_key_map, impl_joined_value};
2020

2121
use proc_macro::TokenStream;
2222
use quote::quote;
@@ -76,3 +76,15 @@ pub fn derive_joined_value(input: TokenStream) -> TokenStream {
7676
.into(),
7777
}
7878
}
79+
80+
#[proc_macro_derive(BufferKeyMap, attributes(key))]
81+
pub fn derive_buffer_key_map(input: TokenStream) -> TokenStream {
82+
let input = parse_macro_input!(input as ItemStruct);
83+
match impl_buffer_key_map(&input) {
84+
Ok(tokens) => tokens.into(),
85+
Err(msg) => quote! {
86+
compile_error!(#msg);
87+
}
88+
.into(),
89+
}
90+
}

src/buffer.rs

+64-3
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,9 @@
1717

1818
use 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

2525
use std::{ops::RangeBounds, sync::Arc};
@@ -38,7 +38,7 @@ pub use buffer_access_lifecycle::BufferKeyLifecycle;
3838
pub(crate) use buffer_access_lifecycle::*;
3939

4040
mod buffer_key_builder;
41-
pub(crate) use buffer_key_builder::*;
41+
pub use buffer_key_builder::*;
4242

4343
mod buffer_map;
4444
pub 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.
406467
pub struct BufferView<'a, T>
407468
where

src/buffer/any_buffer.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -517,7 +517,7 @@ pub trait AnyBufferWorldAccess {
517517
/// For technical reasons this requires direct [`World`] access, but you can
518518
/// do other read-only queries on the world while holding onto the
519519
/// [`AnyBufferView`].
520-
fn any_buffer_view<'a>(&self, key: &AnyBufferKey) -> Result<AnyBufferView<'_>, BufferError>;
520+
fn any_buffer_view(&self, key: &AnyBufferKey) -> Result<AnyBufferView<'_>, BufferError>;
521521

522522
/// Call this to get mutable access to any buffer.
523523
///
@@ -531,7 +531,7 @@ pub trait AnyBufferWorldAccess {
531531
}
532532

533533
impl AnyBufferWorldAccess for World {
534-
fn any_buffer_view<'a>(&self, key: &AnyBufferKey) -> Result<AnyBufferView<'_>, BufferError> {
534+
fn any_buffer_view(&self, key: &AnyBufferKey) -> Result<AnyBufferView<'_>, BufferError> {
535535
key.interface.create_any_buffer_view(key, self)
536536
}
537537

0 commit comments

Comments
 (0)