bevy_input_sequence/
cond_system.rs1use bevy::ecs::system::{CombinatorSystem, Combine, IntoSystem, System, SystemIn, SystemInput};
3use bevy::prelude::DebugName;
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, DebugName::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, DebugName::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<T>(
63 input: <Self::In as SystemInput>::Inner<'_>,
64 data: &mut T,
65 a: impl FnOnce(SystemIn<'_, A>, &mut T) -> Result<A::Out, bevy::ecs::system::RunSystemError>,
66 b: impl FnOnce(SystemIn<'_, B>, &mut T) -> Result<B::Out, bevy::ecs::system::RunSystemError>,
67 ) -> Result<Self::Out, bevy::ecs::system::RunSystemError> {
68 let condition = b((), data)?;
69 if condition {
70 Ok(Some(a(input, data)?))
71 } else {
72 Ok(None)
73 }
74 }
75}
76
77pub type SilentCondSystem<SystemA, SystemB> = CombinatorSystem<SilentCond, SystemA, SystemB>;
80
81#[doc(hidden)]
82pub struct SilentCond;
83
84impl<A, B> Combine<A, B> for SilentCond
85where
86 B: System<In = (), Out = bool>,
87 A: System,
88{
89 type In = A::In;
90 type Out = ();
91
92 fn combine<T>(
93 input: <Self::In as SystemInput>::Inner<'_>,
94 data: &mut T,
95 a: impl FnOnce(SystemIn<'_, A>, &mut T) -> Result<A::Out, bevy::ecs::system::RunSystemError>,
96 b: impl FnOnce(SystemIn<'_, B>, &mut T) -> Result<B::Out, bevy::ecs::system::RunSystemError>,
97 ) -> Result<Self::Out, bevy::ecs::system::RunSystemError> {
98 let condition = b((), data)?;
99 if condition {
100 a(input, data)?;
101 }
102 Ok(())
103 }
104}