pebble/ecs/
system_condition.rs1use crate::ecs::{
2 resources::Resources,
3 system::{IntoSystem, System},
4};
5
6pub trait RunCondition: 'static {
15 fn should_run(world: &hecs::World, resources: &Resources) -> bool;
16}
17
18pub struct ResourceExists<T>(std::marker::PhantomData<T>);
20impl<T: 'static + Send + Sync> RunCondition for ResourceExists<T> {
21 fn should_run(world: &hecs::World, resources: &Resources) -> bool {
22 resources.has_resource::<T>(world)
23 }
24}
25
26pub struct Conditional<S, C> {
29 inner: S,
30 _marker: std::marker::PhantomData<C>,
31}
32
33impl<S: System, C: RunCondition> System for Conditional<S, C> {
34 fn run(&mut self, world: &hecs::World, resources: &Resources) {
35 if C::should_run(world, resources) {
36 self.inner.run(world, resources);
37 }
38 }
39
40 fn name(&self) -> &'static str {
46 self.inner.name()
47 }
48}
49
50pub trait RunIfExt<Marker>: IntoSystem<Marker> + Sized {
53 fn run_if<C: RunCondition>(self) -> RunIfSystem<Self, Marker, C> {
54 RunIfSystem {
55 inner: self,
56 _marker: std::marker::PhantomData,
57 }
58 }
59}
60
61impl<Marker, T: IntoSystem<Marker>> RunIfExt<Marker> for T {}
62
63pub struct RunIfSystem<T, Marker, C> {
64 inner: T,
65 _marker: std::marker::PhantomData<(Marker, C)>,
66}
67
68impl<T, Marker, C> IntoSystem<Marker> for RunIfSystem<T, Marker, C>
69where
70 T: IntoSystem<Marker>,
71 C: RunCondition,
72{
73 type System = Conditional<T::System, C>;
74
75 fn into_system(self) -> Self::System {
76 Conditional {
77 inner: self.inner.into_system(),
78 _marker: std::marker::PhantomData,
79 }
80 }
81}