goud_engine/ecs/system/function_system/
impls.rs1use std::marker::PhantomData;
19
20use crate::ecs::query::Access;
21use crate::ecs::system::{BoxedSystem, IntoSystem, SystemParam};
22use crate::ecs::World;
23
24use super::core::{FunctionSystem, SystemParamFunction};
25
26pub struct FnMarker1<P>(PhantomData<P>);
32pub struct FnMarker2<P1, P2>(PhantomData<(P1, P2)>);
34pub struct FnMarker3<P1, P2, P3>(PhantomData<(P1, P2, P3)>);
36pub struct FnMarker4<P1, P2, P3, P4>(PhantomData<(P1, P2, P3, P4)>);
38pub struct FnMarker5<P1, P2, P3, P4, P5>(PhantomData<(P1, P2, P3, P4, P5)>);
40pub struct FnMarker6<P1, P2, P3, P4, P5, P6>(PhantomData<(P1, P2, P3, P4, P5, P6)>);
42pub struct FnMarker7<P1, P2, P3, P4, P5, P6, P7>(PhantomData<(P1, P2, P3, P4, P5, P6, P7)>);
44pub struct FnMarker8<P1, P2, P3, P4, P5, P6, P7, P8>(PhantomData<(P1, P2, P3, P4, P5, P6, P7, P8)>);
46
47macro_rules! impl_system_param_function_1 {
52 ($marker:ident, $param:ident) => {
53 #[allow(non_snake_case)]
54 impl<F, $param: SystemParam + 'static> SystemParamFunction<$marker<$param>> for F
55 where
56 F: FnMut($param) + Send + 'static,
57 for<'w, 's> F: FnMut($param::Item<'w, 's>),
58 $param::State: Send + Sync + Clone + 'static,
59 {
60 type Param = $param;
61 type State = $param::State;
62
63 #[inline]
64 fn build_access(state: &Self::State) -> Access {
65 let mut access = Access::new();
66 $param::update_access(state, &mut access);
67 access
68 }
69
70 #[inline]
71 unsafe fn run_unsafe(&mut self, state: &mut Self::State, world: &mut World) {
72 let world_ptr = world as *mut World;
75 let param = $param::get_param_mut(state, &mut *world_ptr);
76 self(param);
77 }
78 }
79
80 impl<F, $param: SystemParam + 'static> IntoSystem<($marker<$param>,)> for F
81 where
82 F: FnMut($param) + Send + 'static,
83 for<'w, 's> F: FnMut($param::Item<'w, 's>),
84 $param::State: Send + Sync + Clone + 'static,
85 {
86 type System = FunctionSystem<$marker<$param>, F>;
87
88 #[inline]
89 fn into_system(self) -> BoxedSystem {
90 BoxedSystem::new(FunctionSystem::new(self))
91 }
92 }
93 };
94}
95
96impl_system_param_function_1!(FnMarker1, P1);
97
98macro_rules! impl_system_param_function_multi {
109 ($marker:ident $(, $param:ident)* ; $($state_name:ident)*) => {
110 #[allow(non_snake_case)]
111 #[allow(unused_parens)]
112 impl<F, $($param: SystemParam + 'static),*> SystemParamFunction<$marker<$($param),*>> for F
113 where
114 F: FnMut($($param),*) + Send + 'static,
115 for<'w, 's> F: FnMut($($param::Item<'w, 's>),*),
116 $($param::State: Send + Sync + Clone + 'static,)*
117 {
118 type Param = ($($param,)*);
119 type State = ($($param::State,)*);
120
121 #[inline]
122 fn build_access(state: &Self::State) -> Access {
123 let mut access = Access::new();
124 let ($($state_name,)*) = state;
125 $($param::update_access($state_name, &mut access);)*
126 access
127 }
128
129 #[inline]
130 unsafe fn run_unsafe(&mut self, state: &mut Self::State, world: &mut World) {
131 let world_ptr = world as *mut World;
136 let ($($state_name,)*) = state;
137 $(let $param = $param::get_param_mut($state_name, &mut *world_ptr);)*
138 self($($param),*);
139 }
140 }
141
142 impl<F, $($param: SystemParam + 'static),*> IntoSystem<($marker<$($param),*>,)> for F
143 where
144 F: FnMut($($param),*) + Send + 'static,
145 for<'w, 's> F: FnMut($($param::Item<'w, 's>),*),
146 $($param::State: Send + Sync + Clone + 'static,)*
147 {
148 type System = FunctionSystem<$marker<$($param),*>, F>;
149
150 #[inline]
151 fn into_system(self) -> BoxedSystem {
152 BoxedSystem::new(FunctionSystem::new(self))
153 }
154 }
155 };
156}
157
158impl_system_param_function_multi!(FnMarker2, P1, P2; s1 s2);
160impl_system_param_function_multi!(FnMarker3, P1, P2, P3; s1 s2 s3);
161impl_system_param_function_multi!(FnMarker4, P1, P2, P3, P4; s1 s2 s3 s4);
162impl_system_param_function_multi!(FnMarker5, P1, P2, P3, P4, P5; s1 s2 s3 s4 s5);
163impl_system_param_function_multi!(FnMarker6, P1, P2, P3, P4, P5, P6; s1 s2 s3 s4 s5 s6);
164impl_system_param_function_multi!(FnMarker7, P1, P2, P3, P4, P5, P6, P7; s1 s2 s3 s4 s5 s6 s7);
165impl_system_param_function_multi!(FnMarker8, P1, P2, P3, P4, P5, P6, P7, P8; s1 s2 s3 s4 s5 s6 s7 s8);