1use core::marker::PhantomData;
6use swamp_system_state::State;
7
8pub trait System: 'static {
10 fn run(&self, world: &mut State);
11}
12
13pub trait IntoSystem<Params> {
15 type System: System;
16
17 fn into_system(self) -> Self::System;
18}
19
20impl<F, Params: SystemParam> IntoSystem<Params> for F
22where
23 F: SystemParamFunction<Params>,
24{
25 type System = FunctionSystem<F, Params>;
26
27 fn into_system(self) -> Self::System {
28 FunctionSystem {
29 system: self,
30 params: PhantomData,
31 }
32 }
33}
34
35pub struct FunctionSystem<F: 'static, Params: SystemParam> {
37 system: F,
38 params: PhantomData<Params>,
39}
40
41impl<F, Params: SystemParam> System for FunctionSystem<F, Params>
43where
44 F: SystemParamFunction<Params>,
45{
46 fn run(&self, state: &mut State) {
47 SystemParamFunction::run(&self.system, state);
48 }
49}
50
51trait SystemParamFunction<Params: SystemParam>: 'static {
53 fn run(&self, state: &mut State);
54}
55
56impl<F> SystemParamFunction<()> for F
58where
59 F: Fn() + 'static,
60{
61 fn run(&self, _state: &mut State) {
62 self(); }
64}
65
66impl<F, P1: SystemParam<Item = P1>> SystemParamFunction<(P1,)> for F
68where
69 F: Fn(P1) + 'static,
70{
71 fn run(&self, world: &mut State) {
72 self(P1::fetch(world));
73 }
74}
75
76impl<F, P1: SystemParam<Item = P1>, P2: SystemParam<Item = P2>> SystemParamFunction<(P1, P2)> for F
78where
79 F: Fn(P1, P2) + 'static,
80{
81 fn run(&self, world: &mut State) {
82 let v1 = P1::fetch(world);
83 let v2 = P2::fetch(world);
84 self(v1, v2);
85 }
86}
87
88impl<F, P1: SystemParam<Item = P1>, P2: SystemParam<Item = P2>, P3: SystemParam<Item = P3>>
90 SystemParamFunction<(P1, P2, P3)> for F
91where
92 F: Fn(P1, P2, P3) + 'static,
93{
94 fn run(&self, world: &mut State) {
95 let v1 = P1::fetch(world);
96 let v2 = P2::fetch(world);
97 let v3 = P3::fetch(world);
98 self(v1, v2, v3);
99 }
100}
101
102impl<
104 F,
105 P1: SystemParam<Item = P1>,
106 P2: SystemParam<Item = P2>,
107 P3: SystemParam<Item = P3>,
108 P4: SystemParam<Item = P4>,
109 > SystemParamFunction<(P1, P2, P3, P4)> for F
110where
111 F: Fn(P1, P2, P3, P4) + 'static,
112{
113 fn run(&self, world: &mut State) {
114 let v1 = P1::fetch(world);
115 let v2 = P2::fetch(world);
116 let v3 = P3::fetch(world);
117 let v4 = P4::fetch(world);
118 self(v1, v2, v3, v4);
119 }
120}
121
122impl<
124 F,
125 P1: SystemParam<Item = P1>,
126 P2: SystemParam<Item = P2>,
127 P3: SystemParam<Item = P3>,
128 P4: SystemParam<Item = P4>,
129 P5: SystemParam<Item = P5>,
130 > SystemParamFunction<(P1, P2, P3, P4, P5)> for F
131where
132 F: Fn(P1, P2, P3, P4, P5) + 'static,
133{
134 fn run(&self, world: &mut State) {
135 let v1 = P1::fetch(world);
136 let v2 = P2::fetch(world);
137 let v3 = P3::fetch(world);
138 let v4 = P4::fetch(world);
139 let v5 = P5::fetch(world);
140 self(v1, v2, v3, v4, v5);
141 }
142}
143
144impl<
146 F,
147 P1: SystemParam<Item = P1>,
148 P2: SystemParam<Item = P2>,
149 P3: SystemParam<Item = P3>,
150 P4: SystemParam<Item = P4>,
151 P5: SystemParam<Item = P5>,
152 P6: SystemParam<Item = P6>,
153 > SystemParamFunction<(P1, P2, P3, P4, P5, P6)> for F
154where
155 F: Fn(P1, P2, P3, P4, P5, P6) + 'static,
156{
157 fn run(&self, world: &mut State) {
158 let v1 = P1::fetch(world);
159 let v2 = P2::fetch(world);
160 let v3 = P3::fetch(world);
161 let v4 = P4::fetch(world);
162 let v5 = P5::fetch(world);
163 let v6 = P6::fetch(world);
164 self(v1, v2, v3, v4, v5, v6);
165 }
166}
167
168impl<
170 F,
171 P1: SystemParam<Item = P1>,
172 P2: SystemParam<Item = P2>,
173 P3: SystemParam<Item = P3>,
174 P4: SystemParam<Item = P4>,
175 P5: SystemParam<Item = P5>,
176 P6: SystemParam<Item = P6>,
177 P7: SystemParam<Item = P7>,
178 > SystemParamFunction<(P1, P2, P3, P4, P5, P6, P7)> for F
179where
180 F: Fn(P1, P2, P3, P4, P5, P6, P7) + 'static,
181{
182 fn run(&self, world: &mut State) {
183 let v1 = P1::fetch(world);
184 let v2 = P2::fetch(world);
185 let v3 = P3::fetch(world);
186 let v4 = P4::fetch(world);
187 let v5 = P5::fetch(world);
188 let v6 = P6::fetch(world);
189 let v7 = P7::fetch(world);
190 self(v1, v2, v3, v4, v5, v6, v7);
191 }
192}
193
194impl<
196 F,
197 P1: SystemParam<Item = P1>,
198 P2: SystemParam<Item = P2>,
199 P3: SystemParam<Item = P3>,
200 P4: SystemParam<Item = P4>,
201 P5: SystemParam<Item = P5>,
202 P6: SystemParam<Item = P6>,
203 P7: SystemParam<Item = P7>,
204 P8: SystemParam<Item = P8>,
205 > SystemParamFunction<(P1, P2, P3, P4, P5, P6, P7, P8)> for F
206where
207 F: Fn(P1, P2, P3, P4, P5, P6, P7, P8) + 'static,
208{
209 fn run(&self, world: &mut State) {
210 let v1 = P1::fetch(world);
211 let v2 = P2::fetch(world);
212 let v3 = P3::fetch(world);
213 let v4 = P4::fetch(world);
214 let v5 = P5::fetch(world);
215 let v6 = P6::fetch(world);
216 let v7 = P7::fetch(world);
217 let v8 = P8::fetch(world);
218 self(v1, v2, v3, v4, v5, v6, v7, v8);
219 }
220}
221
222pub trait SystemParam: 'static {
224 type Item;
225
226 fn fetch(world: &mut State) -> Self::Item;
227}
228
229impl SystemParam for () {
230 type Item = ();
231
232 fn fetch(_world: &mut State) -> Self::Item {
233 }
235}
236
237impl<T1> SystemParam for (T1,)
239where
240 T1: SystemParam,
241{
242 type Item = (T1::Item,);
243
244 fn fetch(world: &mut State) -> Self::Item {
245 (T1::fetch(world),)
246 }
247}
248
249impl<T1, T2> SystemParam for (T1, T2)
251where
252 T1: SystemParam,
253 T2: SystemParam,
254{
255 type Item = (T1::Item, T2::Item);
256
257 fn fetch(world: &mut State) -> Self::Item {
258 (T1::fetch(world), T2::fetch(world))
259 }
260}
261
262impl<T1, T2, T3> SystemParam for (T1, T2, T3)
264where
265 T1: SystemParam,
266 T2: SystemParam,
267 T3: SystemParam,
268{
269 type Item = (T1::Item, T2::Item, T3::Item);
270
271 fn fetch(world: &mut State) -> Self::Item {
272 (T1::fetch(world), T2::fetch(world), T3::fetch(world))
273 }
274}
275
276impl<T1, T2, T3, T4> SystemParam for (T1, T2, T3, T4)
278where
279 T1: SystemParam,
280 T2: SystemParam,
281 T3: SystemParam,
282 T4: SystemParam,
283{
284 type Item = (T1::Item, T2::Item, T3::Item, T4::Item);
285
286 fn fetch(world: &mut State) -> Self::Item {
287 (
288 T1::fetch(world),
289 T2::fetch(world),
290 T3::fetch(world),
291 T4::fetch(world),
292 )
293 }
294}
295
296impl<T1, T2, T3, T4, T5> SystemParam for (T1, T2, T3, T4, T5)
298where
299 T1: SystemParam,
300 T2: SystemParam,
301 T3: SystemParam,
302 T4: SystemParam,
303 T5: SystemParam,
304{
305 type Item = (T1::Item, T2::Item, T3::Item, T4::Item, T5::Item);
306
307 fn fetch(world: &mut State) -> Self::Item {
308 (
309 T1::fetch(world),
310 T2::fetch(world),
311 T3::fetch(world),
312 T4::fetch(world),
313 T5::fetch(world),
314 )
315 }
316}
317
318impl<T1, T2, T3, T4, T5, T6> SystemParam for (T1, T2, T3, T4, T5, T6)
320where
321 T1: SystemParam,
322 T2: SystemParam,
323 T3: SystemParam,
324 T4: SystemParam,
325 T5: SystemParam,
326 T6: SystemParam,
327{
328 type Item = (T1::Item, T2::Item, T3::Item, T4::Item, T5::Item, T6::Item);
329
330 fn fetch(world: &mut State) -> Self::Item {
331 (
332 T1::fetch(world),
333 T2::fetch(world),
334 T3::fetch(world),
335 T4::fetch(world),
336 T5::fetch(world),
337 T6::fetch(world),
338 )
339 }
340}
341
342impl<T1, T2, T3, T4, T5, T6, T7> SystemParam for (T1, T2, T3, T4, T5, T6, T7)
344where
345 T1: SystemParam,
346 T2: SystemParam,
347 T3: SystemParam,
348 T4: SystemParam,
349 T5: SystemParam,
350 T6: SystemParam,
351 T7: SystemParam,
352{
353 type Item = (
354 T1::Item,
355 T2::Item,
356 T3::Item,
357 T4::Item,
358 T5::Item,
359 T6::Item,
360 T7::Item,
361 );
362
363 fn fetch(world: &mut State) -> Self::Item {
364 (
365 T1::fetch(world),
366 T2::fetch(world),
367 T3::fetch(world),
368 T4::fetch(world),
369 T5::fetch(world),
370 T6::fetch(world),
371 T7::fetch(world),
372 )
373 }
374}
375
376impl<T1, T2, T3, T4, T5, T6, T7, T8> SystemParam for (T1, T2, T3, T4, T5, T6, T7, T8)
378where
379 T1: SystemParam,
380 T2: SystemParam,
381 T3: SystemParam,
382 T4: SystemParam,
383 T5: SystemParam,
384 T6: SystemParam,
385 T7: SystemParam,
386 T8: SystemParam,
387{
388 type Item = (
389 T1::Item,
390 T2::Item,
391 T3::Item,
392 T4::Item,
393 T5::Item,
394 T6::Item,
395 T7::Item,
396 T8::Item,
397 );
398
399 fn fetch(world: &mut State) -> Self::Item {
400 (
401 T1::fetch(world),
402 T2::fetch(world),
403 T3::fetch(world),
404 T4::fetch(world),
405 T5::fetch(world),
406 T6::fetch(world),
407 T7::fetch(world),
408 T8::fetch(world),
409 )
410 }
411}