bevy_input_sequence/
cond_system.rs1use bevy::ecs::system::{CombinatorSystem, Combine, IntoSystem, System, SystemIn, SystemInput};
3use std::borrow::Cow;
4
5pub trait IntoCondSystem<I, O, M>: IntoSystem<I, O, M>
10where
11 I: SystemInput,
12{
13 fn only_if<B, MarkerB>(self, system: B) -> SilentCondSystem<Self::System, B::System>
17 where
18 B: IntoSystem<(), bool, MarkerB>,
19 {
20 let system_a = IntoSystem::into_system(self);
21 let system_b = IntoSystem::into_system(system);
22 let name = format!("SilentCond({}, {})", system_a.name(), system_b.name());
23 SilentCondSystem::new(system_a, system_b, Cow::Owned(name))
24 }
25
26 fn only_if_with_output<B, MarkerB>(self, system: B) -> CondSystem<Self::System, B::System>
30 where
31 B: IntoSystem<(), bool, MarkerB>,
32 {
33 let system_a = IntoSystem::into_system(self);
34 let system_b = IntoSystem::into_system(system);
35 let name = format!("Cond({}, {})", system_a.name(), system_b.name());
36 CondSystem::new(system_a, system_b, Cow::Owned(name))
37 }
38}
39
40impl<I, O, M, T> IntoCondSystem<I, O, M> for T
41where
42 T: IntoSystem<I, O, M>,
43 I: SystemInput,
44{
45}
46
47pub type CondSystem<SystemA, SystemB> = CombinatorSystem<Cond, SystemA, SystemB>;
50
51#[doc(hidden)]
52pub struct Cond;
53
54impl<A, B> Combine<A, B> for Cond
55where
56 B: System<In = (), Out = bool>,
57 A: System,
58{
59 type In = A::In;
60 type Out = Option<A::Out>;
61
62 fn combine(
63 input: <Self::In as SystemInput>::Inner<'_>,
64 a: impl FnOnce(SystemIn<'_, A>) -> A::Out,
65 b: impl FnOnce(SystemIn<'_, B>) -> B::Out,
66 ) -> Self::Out {
67 b(()).then(|| a(input))
68 }
69}
70
71pub type SilentCondSystem<SystemA, SystemB> = CombinatorSystem<SilentCond, SystemA, SystemB>;
74
75#[doc(hidden)]
76pub struct SilentCond;
77
78impl<A, B> Combine<A, B> for SilentCond
79where
80 B: System<In = (), Out = bool>,
81 A: System,
82{
83 type In = A::In;
84 type Out = ();
85
86 fn combine(
87 input: <Self::In as SystemInput>::Inner<'_>,
88 a: impl FnOnce(SystemIn<'_, A>) -> A::Out,
89 b: impl FnOnce(SystemIn<'_, B>) -> B::Out,
90 ) -> Self::Out {
91 if b(()) {
92 a(input);
93 }
94 }
95}