Skip to content

Commit b612a05

Browse files
committed
Merge remote-tracking branch 'origin/buffer_map' into koonpeng/derive_joined
Signed-off-by: Teo Koon Peng <[email protected]>
2 parents 1deada0 + aa22f87 commit b612a05

File tree

12 files changed

+672
-606
lines changed

12 files changed

+672
-606
lines changed

macros/src/buffer.rs

Lines changed: 39 additions & 119 deletions
Original file line numberDiff line numberDiff line change
@@ -11,54 +11,28 @@ pub(crate) fn impl_joined_value(ast: DeriveInput) -> Result<TokenStream> {
1111
_ => return Err("expected struct".to_string()),
1212
};
1313
let map_key: Vec<String> = field_ident.iter().map(|v| v.to_string()).collect();
14-
let struct_buffer_ident = format_ident!("__{}Buffers", struct_ident);
14+
let struct_buffer_ident = format_ident!("__bevy_impulse_{}_Buffers", struct_ident);
1515

1616
let impl_buffer_map_layout =
17-
buffer_map_layout(&struct_ident, &field_ident, &field_type, &map_key);
17+
buffer_map_layout(&struct_buffer_ident, &field_ident, &field_type, &map_key);
18+
let impl_joined = joined(&struct_buffer_ident, &struct_ident, &field_ident);
1819

1920
let gen = quote! {
20-
#impl_buffer_map_layout
21-
2221
impl ::bevy_impulse::JoinedValue for #struct_ident {
2322
type Buffers = #struct_buffer_ident;
24-
25-
fn pull(
26-
buffers: &::bevy_impulse::BufferMap,
27-
session: ::bevy_ecs::prelude::Entity,
28-
world: &mut ::bevy_ecs::prelude::World,
29-
) -> Result<Self, ::bevy_impulse::OperationError> {
30-
use ::bevy_impulse::{ManageBuffer, OrBroken};
31-
32-
#(
33-
let #field_ident = world
34-
.get_entity_mut(buffers.get(#map_key).or_broken()?.id())
35-
.or_broken()?
36-
.pull_from_buffer::<#field_type>(session)?;
37-
)*
38-
39-
Ok(Self {
40-
#(
41-
#field_ident
42-
),*
43-
})
44-
}
4523
}
4624

25+
#[derive(Clone)]
26+
#[allow(non_camel_case_types)]
4727
struct #struct_buffer_ident {
4828
#(
49-
#field_ident: ::bevy_impulse::Buffer<#field_type>
50-
),*
29+
#field_ident: ::bevy_impulse::Buffer<#field_type>,
30+
)*
5131
}
5232

53-
impl From<#struct_buffer_ident> for ::bevy_impulse::BufferMap {
54-
fn from(value: #struct_buffer_ident) -> Self {
55-
let mut buffers = ::bevy_impulse::BufferMap::default();
56-
#(
57-
buffers.insert(std::borrow::Cow::Borrowed(#map_key), value.#field_ident);
58-
)*
59-
buffers
60-
}
61-
}
33+
#impl_buffer_map_layout
34+
35+
#impl_joined
6236
};
6337

6438
Ok(gen.into())
@@ -86,103 +60,49 @@ fn buffer_map_layout(
8660
) -> proc_macro2::TokenStream {
8761
quote! {
8862
impl ::bevy_impulse::BufferMapLayout for #struct_ident {
89-
fn is_compatible(buffers: &BufferMap) -> Result<(), ::bevy_impulse::IncompatibleLayout> {
90-
let mut compatibility = ::bevy_impulse::IncompatibleLayout::default();
91-
#(
92-
compatibility.require_buffer::<#field_type>(#map_key, buffers);
93-
)*
94-
compatibility.into_result()
63+
fn buffer_list(&self) -> ::smallvec::SmallVec<[AnyBuffer; 8]> {
64+
use smallvec::smallvec;
65+
smallvec![#(
66+
self.#field_ident.as_any_buffer(),
67+
)*]
9568
}
9669

97-
fn buffered_count(
98-
buffers: &::bevy_impulse::BufferMap,
99-
session: ::bevy_ecs::prelude::Entity,
100-
world: &::bevy_ecs::prelude::World,
101-
) -> Result<usize, ::bevy_impulse::OperationError> {
102-
use ::bevy_impulse::{InspectBuffer, OrBroken};
103-
104-
#(
105-
let #field_ident = world
106-
.get_entity(buffers.get(#map_key).or_broken()?.id())
107-
.or_broken()?
108-
.buffered_count::<#field_type>(session)?;
109-
)*
110-
111-
Ok([#( #field_ident ),*]
112-
.iter()
113-
.min()
114-
.copied()
115-
.unwrap_or(0))
116-
}
117-
118-
fn ensure_active_session(
119-
buffers: &::bevy_impulse::BufferMap,
120-
session: ::bevy_ecs::prelude::Entity,
121-
world: &mut ::bevy_ecs::prelude::World,
122-
) -> ::bevy_impulse::OperationResult {
123-
use ::bevy_impulse::{ManageBuffer, OrBroken};
124-
70+
fn try_from_buffer_map(buffers: &::bevy_impulse::BufferMap) -> Result<Self, ::bevy_impulse::IncompatibleLayout> {
71+
let mut compatibility = ::bevy_impulse::IncompatibleLayout::default();
12572
#(
126-
world
127-
.get_entity_mut(buffers.get(#map_key).or_broken()?.id())
128-
.or_broken()?
129-
.ensure_session::<#field_type>(session)?;
73+
let #field_ident = if let Ok(buffer) = compatibility.require_message_type::<#field_type>(#map_key, buffers) {
74+
buffer
75+
} else {
76+
return Err(compatibility);
77+
};
13078
)*
13179

132-
Ok(())
80+
Ok(Self {#(
81+
#field_ident,
82+
)*})
13383
}
13484
}
13585
}
13686
}
13787

138-
pub(crate) fn impl_buffer_key_map(ast: DeriveInput) -> Result<TokenStream> {
139-
let struct_ident = ast.ident;
140-
let (field_ident, field_type): (Vec<Ident>, Vec<Type>) = match ast.data {
141-
syn::Data::Struct(data) => get_fields_map(data.fields)?.into_iter().unzip(),
142-
_ => return Err("expected struct".to_string()),
143-
};
144-
let map_key: Vec<String> = field_ident.iter().map(|v| v.to_string()).collect();
145-
146-
let impl_buffer_map_layout =
147-
buffer_map_layout(&struct_ident, &field_ident, &field_type, &map_key);
148-
149-
// FIXME(koonpeng): `create_key` does not allow failure and we can't guarantee that the buffer
150-
// from the buffer map is valid.
151-
let gen = quote! {
152-
impl ::bevy_impulse::BufferKeyMap for #struct_ident {
153-
fn add_accessor(buffers: &::bevy_impulse::BufferMap, accessor: ::bevy_ecs::prelude::Entity, world: &mut ::bevy_ecs::prelude::World) -> ::bevy_impulse::OperationResult {
154-
use ::bevy_impulse::{Accessed, OrBroken};
88+
fn joined(
89+
struct_ident: &Ident,
90+
item_struct_ident: &Ident,
91+
field_ident: &Vec<Ident>,
92+
) -> proc_macro2::TokenStream {
93+
quote! {
94+
impl ::bevy_impulse::Joined for #struct_ident {
95+
type Item = #item_struct_ident;
15596

97+
fn pull(&self, session: ::bevy_ecs::prelude::Entity, world: &mut ::bevy_ecs::prelude::World) -> Result<Self::Item, ::bevy_impulse::OperationError> {
15698
#(
157-
buffers.get(#map_key).or_broken()?.add_accessor(accessor, world)?;
99+
let #field_ident = self.#field_ident.pull(session, world)?;
158100
)*
159101

160-
Ok(())
161-
}
162-
163-
fn create_key(buffers: &::bevy_impulse::BufferMap, builder: &::bevy_impulse::BufferKeyBuilder) -> Self {
164-
use ::bevy_impulse::{Accessed, OrBroken};
165-
166-
Self {#(
167-
#field_ident: buffers.get(#map_key).unwrap().create_key(builder).try_into().unwrap(),
168-
)*}
169-
}
170-
171-
fn deep_clone_key(&self) -> Self {
172-
Self {#(
173-
#field_ident: self.#field_ident.deep_clone(),
174-
)*}
175-
}
176-
177-
fn is_key_in_use(&self) -> bool {
178-
#(
179-
self.#field_ident.is_in_use()
180-
)||*
102+
Ok(Self::Item {#(
103+
#field_ident,
104+
)*})
181105
}
182106
}
183-
184-
#impl_buffer_map_layout
185-
};
186-
187-
Ok(gen.into())
107+
}
188108
}

macros/src/lib.rs

Lines changed: 1 addition & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
*/
1717

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

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

src/buffer.rs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,14 @@ impl<T> Buffer<T> {
113113
pub fn location(&self) -> BufferLocation {
114114
self.location
115115
}
116+
117+
/// Cast this into an [`AnyBuffer`].
118+
pub fn as_any_buffer(&self) -> AnyBuffer
119+
where
120+
T: 'static + Send + Sync,
121+
{
122+
self.clone().into()
123+
}
116124
}
117125

118126
impl<T> Clone for Buffer<T> {
@@ -225,7 +233,7 @@ impl Default for RetentionPolicy {
225233
/// To obtain a `BufferKey`, use [`Chain::with_access`][1], or [`listen`][2].
226234
///
227235
/// [1]: crate::Chain::with_access
228-
/// [2]: crate::Bufferable::listen
236+
/// [2]: crate::Accessible::listen
229237
pub struct BufferKey<T> {
230238
tag: BufferKeyTag,
231239
_ignore: std::marker::PhantomData<fn(T)>,

0 commit comments

Comments
 (0)