1use crate::ecs::resources::Resources;
2
3pub trait SystemParam {
10 type Item<'a>;
12 type State: Default + 'static;
15
16 fn fetch<'a>(
17 world: &'a hecs::World,
18 resources: &'a Resources,
19 state: &'a mut Self::State,
20 ) -> Self::Item<'a>;
21}
22
23impl<'a> SystemParam for &'a hecs::World {
24 type Item<'w> = &'w hecs::World;
25 type State = ();
26
27 fn fetch<'w>(
28 world: &'w hecs::World,
29 _resources: &'w Resources,
30 _state: &'w mut Self::State,
31 ) -> Self::Item<'w> {
32 world
33 }
34}
35
36impl<'a> SystemParam for &'a Resources {
37 type Item<'w> = &'w Resources;
38 type State = ();
39
40 fn fetch<'w>(
41 _world: &'w hecs::World,
42 resources: &'w Resources,
43 _state: &'w mut Self::State,
44 ) -> Self::Item<'w> {
45 resources
46 }
47}
48
49pub trait System: 'static {
53 fn run(&mut self, world: &hecs::World, resources: &Resources);
54}
55
56pub struct FunctionSystem<F, Marker, State = ()> {
59 pub func: F,
60 state: State,
61 _marker: std::marker::PhantomData<Marker>,
62}
63
64pub trait IntoSystem<Marker> {
68 type System: System;
69
70 fn into_system(self) -> Self::System;
71}
72
73macro_rules! impl_system {
74 ($($param:ident),*) => {
75 impl<T, $($param),*> IntoSystem<($($param,)*)> for T
76 where
77 T: FnMut($($param),*) + for<'a> FnMut($($param::Item<'a>),*) + 'static,
78 $($param: SystemParam + 'static),*
79 {
80 type System = FunctionSystem<T, ($($param,)*), ($($param::State,)*)>;
81 fn into_system(self) -> Self::System {
82 FunctionSystem {
83 func: self,
84 state: Default::default(),
85 _marker: std::marker::PhantomData,
86 }
87 }
88 }
89 impl<T, $($param),*> System for FunctionSystem<T, ($($param,)*), ($($param::State,)*)>
90 where
91 T: FnMut($($param),*) + for<'a> FnMut($($param::Item<'a>),*) + 'static,
92 $($param: SystemParam + 'static),*
93 {
94 fn run(&mut self, _world: &hecs::World, _resources: &Resources) {
95 #[allow(non_snake_case)]
96 let ($($param,)*) = &mut self.state;
97 (self.func)($($param::fetch(_world, _resources, $param)),*);
98 }
99 }
100 };
101}
102
103impl_system!();
104impl_system!(A);
105impl_system!(A, B);
106impl_system!(A, B, C);
107impl_system!(A, B, C, D);
108impl_system!(A, B, C, D, E);
109impl_system!(A, B, C, D, E, F);
110impl_system!(A, B, C, D, E, F, G);
111impl_system!(A, B, C, D, E, F, G, H);
112impl_system!(A, B, C, D, E, F, G, H, I);
113impl_system!(A, B, C, D, E, F, G, H, I, J);
114impl_system!(A, B, C, D, E, F, G, H, I, J, K);
115impl_system!(A, B, C, D, E, F, G, H, I, J, K, L);