Skip to content

Commit af7b768

Browse files
Implement ForkCloneBuilder
Signed-off-by: Luca Della Vedova <[email protected]>
1 parent 5b09a59 commit af7b768

File tree

1 file changed

+40
-58
lines changed

1 file changed

+40
-58
lines changed

src/chain/fork_clone_builder.rs

+40-58
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,10 @@
1515
*
1616
*/
1717

18+
use bevy::prelude::Entity;
19+
use bevy::utils::all_tuples;
20+
use smallvec::SmallVec;
21+
1822
use crate::{
1923
Chain, UnusedTarget, AddOperation, ForkClone, ForkTargetStorage, Builder,
2024
Output,
@@ -30,65 +34,43 @@ pub trait ForkCloneBuilder<Response> {
3034
) -> Self::Outputs;
3135
}
3236

33-
impl<R, F0, U0, F1, U1> ForkCloneBuilder<R> for (F0, F1)
34-
where
35-
R: 'static + Send + Sync + Clone,
36-
F0: FnOnce(Chain<R>) -> U0,
37-
F1: FnOnce(Chain<R>) -> U1,
38-
{
39-
type Outputs = (U0, U1);
37+
macro_rules! impl_forkclonebuilder_for_tuple {
38+
($(($F:ident, $U:ident)),*) => {
39+
#[allow(non_snake_case)]
40+
impl<R: 'static + Send + Sync + Clone, $($F: FnOnce(Chain<R>) -> $U),*, $($U),*> ForkCloneBuilder<R> for ($($F,)*)
41+
{
42+
type Outputs = ($($U,)*);
43+
fn build_fork_clone(
44+
self,
45+
source: Output<R>,
46+
builder: &mut Builder,
47+
) -> Self::Outputs {
48+
let mut targets = SmallVec::<[Entity; 8]>::new();
49+
let ($($F,)*) = self;
50+
let u =
51+
(
52+
$(
53+
{
54+
let target = builder.commands.spawn(UnusedTarget).id();
55+
targets.push(target);
56+
($F)(Chain::new(target, builder))
57+
},
58+
)*
59+
);
4060

41-
fn build_fork_clone(
42-
self,
43-
source: Output<R>,
44-
builder: &mut Builder,
45-
) -> Self::Outputs {
46-
let target_0 = builder.commands.spawn(UnusedTarget).id();
47-
let target_1 = builder.commands.spawn(UnusedTarget).id();
48-
49-
builder.commands.add(AddOperation::new(
50-
Some(source.scope()),
51-
source.id(),
52-
ForkClone::<R>::new(
53-
ForkTargetStorage::from_iter([target_0, target_1])
54-
)
55-
));
56-
57-
let u_0 = (self.0)(Chain::new(target_0, builder));
58-
let u_1 = (self.1)(Chain::new(target_1, builder));
59-
(u_0, u_1)
61+
builder.commands.add(AddOperation::new(
62+
Some(source.scope()),
63+
source.id(),
64+
ForkClone::<R>::new(
65+
ForkTargetStorage::from_iter(targets)
66+
)
67+
));
68+
u
69+
}
70+
}
6071
}
6172
}
6273

63-
impl<R, F0, U0, F1, U1, F2, U2> ForkCloneBuilder<R> for (F0, F1, F2)
64-
where
65-
R: 'static + Send + Sync + Clone,
66-
F0: FnOnce(Chain<R>) -> U0,
67-
F1: FnOnce(Chain<R>) -> U1,
68-
F2: FnOnce(Chain<R>) -> U2,
69-
{
70-
type Outputs = (U0, U1, U2);
71-
72-
fn build_fork_clone(
73-
self,
74-
source: Output<R>,
75-
builder: &mut Builder,
76-
) -> Self::Outputs {
77-
let target_0 = builder.commands.spawn(UnusedTarget).id();
78-
let target_1 = builder.commands.spawn(UnusedTarget).id();
79-
let target_2 = builder.commands.spawn(UnusedTarget).id();
80-
81-
builder.commands.add(AddOperation::new(
82-
Some(source.scope()),
83-
source.id(),
84-
ForkClone::<R>::new(
85-
ForkTargetStorage::from_iter([target_0, target_1, target_2])
86-
)
87-
));
88-
89-
let u_0 = (self.0)(Chain::new(target_0, builder));
90-
let u_1 = (self.1)(Chain::new(target_1, builder));
91-
let u_2 = (self.2)(Chain::new(target_2, builder));
92-
(u_0, u_1, u_2)
93-
}
94-
}
74+
// Implements the `ForkCloneBUilder` trait for all tuples between size 2 and 15
75+
// (inclusive)
76+
all_tuples!(impl_forkclonebuilder_for_tuple, 2, 15, F, U);

0 commit comments

Comments
 (0)