1use core::marker::PhantomData;
6use limnus_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 let Some(v1) = P1::get(world) else { return };
73
74 self(v1);
75 }
76}
77
78impl<F, P1: SystemParam<Item = P1>, P2: SystemParam<Item = P2>> SystemParamFunction<(P1, P2)> for F
80where
81 F: Fn(P1, P2) + 'static,
82{
83 fn run(&self, world: &mut State) {
84 let Some(v1) = P1::get(world) else { return };
85 let Some(v2) = P2::get(world) else { return };
86
87 self(v1, v2);
88 }
89}
90
91impl<F, P1: SystemParam<Item = P1>, P2: SystemParam<Item = P2>, P3: SystemParam<Item = P3>>
93 SystemParamFunction<(P1, P2, P3)> for F
94where
95 F: Fn(P1, P2, P3) + 'static,
96{
97 fn run(&self, world: &mut State) {
98 let Some(v1) = P1::get(world) else { return };
99 let Some(v2) = P2::get(world) else { return };
100 let Some(v3) = P3::get(world) else { return };
101
102 self(v1, v2, v3);
103 }
104}
105
106impl<
108 F,
109 P1: SystemParam<Item = P1>,
110 P2: SystemParam<Item = P2>,
111 P3: SystemParam<Item = P3>,
112 P4: SystemParam<Item = P4>,
113 > SystemParamFunction<(P1, P2, P3, P4)> for F
114where
115 F: Fn(P1, P2, P3, P4) + 'static,
116{
117 fn run(&self, world: &mut State) {
118 let Some(v1) = P1::get(world) else { return };
119 let Some(v2) = P2::get(world) else { return };
120 let Some(v3) = P3::get(world) else { return };
121 let Some(v4) = P4::get(world) else { return };
122
123 self(v1, v2, v3, v4);
124 }
125}
126
127impl<
129 F,
130 P1: SystemParam<Item = P1>,
131 P2: SystemParam<Item = P2>,
132 P3: SystemParam<Item = P3>,
133 P4: SystemParam<Item = P4>,
134 P5: SystemParam<Item = P5>,
135 > SystemParamFunction<(P1, P2, P3, P4, P5)> for F
136where
137 F: Fn(P1, P2, P3, P4, P5) + 'static,
138{
139 fn run(&self, world: &mut State) {
140 let Some(v1) = P1::get(world) else { return };
141 let Some(v2) = P2::get(world) else { return };
142 let Some(v3) = P3::get(world) else { return };
143 let Some(v4) = P4::get(world) else { return };
144 let Some(v5) = P5::get(world) else { return };
145
146 self(v1, v2, v3, v4, v5);
147 }
148}
149
150impl<
152 F,
153 P1: SystemParam<Item = P1>,
154 P2: SystemParam<Item = P2>,
155 P3: SystemParam<Item = P3>,
156 P4: SystemParam<Item = P4>,
157 P5: SystemParam<Item = P5>,
158 P6: SystemParam<Item = P6>,
159 > SystemParamFunction<(P1, P2, P3, P4, P5, P6)> for F
160where
161 F: Fn(P1, P2, P3, P4, P5, P6) + 'static,
162{
163 fn run(&self, world: &mut State) {
164 let Some(v1) = P1::get(world) else { return };
165 let Some(v2) = P2::get(world) else { return };
166 let Some(v3) = P3::get(world) else { return };
167 let Some(v4) = P4::get(world) else { return };
168 let Some(v5) = P5::get(world) else { return };
169 let Some(v6) = P6::get(world) else { return };
170
171 self(v1, v2, v3, v4, v5, v6);
172 }
173}
174
175impl<
177 F,
178 P1: SystemParam<Item = P1>,
179 P2: SystemParam<Item = P2>,
180 P3: SystemParam<Item = P3>,
181 P4: SystemParam<Item = P4>,
182 P5: SystemParam<Item = P5>,
183 P6: SystemParam<Item = P6>,
184 P7: SystemParam<Item = P7>,
185 > SystemParamFunction<(P1, P2, P3, P4, P5, P6, P7)> for F
186where
187 F: Fn(P1, P2, P3, P4, P5, P6, P7) + 'static,
188{
189 fn run(&self, world: &mut State) {
190 let Some(v1) = P1::get(world) else { return };
191 let Some(v2) = P2::get(world) else { return };
192 let Some(v3) = P3::get(world) else { return };
193 let Some(v4) = P4::get(world) else { return };
194 let Some(v5) = P5::get(world) else { return };
195 let Some(v6) = P6::get(world) else { return };
196 let Some(v7) = P7::get(world) else { return };
197
198 self(v1, v2, v3, v4, v5, v6, v7);
199 }
200}
201
202impl<
204 F,
205 P1: SystemParam<Item = P1>,
206 P2: SystemParam<Item = P2>,
207 P3: SystemParam<Item = P3>,
208 P4: SystemParam<Item = P4>,
209 P5: SystemParam<Item = P5>,
210 P6: SystemParam<Item = P6>,
211 P7: SystemParam<Item = P7>,
212 P8: SystemParam<Item = P8>,
213 > SystemParamFunction<(P1, P2, P3, P4, P5, P6, P7, P8)> for F
214where
215 F: Fn(P1, P2, P3, P4, P5, P6, P7, P8) + 'static,
216{
217 fn run(&self, world: &mut State) {
218 let Some(v1) = P1::get(world) else { return };
219 let Some(v2) = P2::get(world) else { return };
220 let Some(v3) = P3::get(world) else { return };
221 let Some(v4) = P4::get(world) else { return };
222 let Some(v5) = P5::get(world) else { return };
223 let Some(v6) = P6::get(world) else { return };
224 let Some(v7) = P7::get(world) else { return };
225 let Some(v8) = P8::get(world) else { return };
226
227 self(v1, v2, v3, v4, v5, v6, v7, v8);
228 }
229}
230
231pub trait SystemParam: 'static {
233 type Item;
234
235 fn get(world: &mut State) -> Option<Self::Item>;
236}
237
238impl SystemParam for () {
239 type Item = ();
240
241 fn get(_world: &mut State) -> Option<Self::Item> {
242 None
244 }
245}
246
247impl<T1> SystemParam for (T1,)
249where
250 T1: SystemParam,
251{
252 type Item = (T1::Item,);
253
254 fn get(world: &mut State) -> Option<Self::Item> {
255 T1::get(world).map(|t1| (t1,))
256 }
257}
258
259impl<T1, T2> SystemParam for (T1, T2)
261where
262 T1: SystemParam,
263 T2: SystemParam,
264{
265 type Item = (T1::Item, T2::Item);
266
267 fn get(world: &mut State) -> Option<Self::Item> {
268 T1::get(world).zip(T2::get(world))
269 }
270}
271
272impl<T1, T2, T3> SystemParam for (T1, T2, T3)
274where
275 T1: SystemParam,
276 T2: SystemParam,
277 T3: SystemParam,
278{
279 type Item = (T1::Item, T2::Item, T3::Item);
280
281 fn get(world: &mut State) -> Option<Self::Item> {
282 Some((T1::get(world)?, T2::get(world)?, T3::get(world)?))
283 }
284}
285
286impl<T1, T2, T3, T4> SystemParam for (T1, T2, T3, T4)
288where
289 T1: SystemParam,
290 T2: SystemParam,
291 T3: SystemParam,
292 T4: SystemParam,
293{
294 type Item = (T1::Item, T2::Item, T3::Item, T4::Item);
295
296 fn get(world: &mut State) -> Option<Self::Item> {
297 Some((
298 T1::get(world)?,
299 T2::get(world)?,
300 T3::get(world)?,
301 T4::get(world)?,
302 ))
303 }
304}
305
306impl<T1, T2, T3, T4, T5> SystemParam for (T1, T2, T3, T4, T5)
308where
309 T1: SystemParam,
310 T2: SystemParam,
311 T3: SystemParam,
312 T4: SystemParam,
313 T5: SystemParam,
314{
315 type Item = (T1::Item, T2::Item, T3::Item, T4::Item, T5::Item);
316
317 fn get(world: &mut State) -> Option<Self::Item> {
318 Some((
319 T1::get(world)?,
320 T2::get(world)?,
321 T3::get(world)?,
322 T4::get(world)?,
323 T5::get(world)?,
324 ))
325 }
326}
327
328impl<T1, T2, T3, T4, T5, T6> SystemParam for (T1, T2, T3, T4, T5, T6)
330where
331 T1: SystemParam,
332 T2: SystemParam,
333 T3: SystemParam,
334 T4: SystemParam,
335 T5: SystemParam,
336 T6: SystemParam,
337{
338 type Item = (T1::Item, T2::Item, T3::Item, T4::Item, T5::Item, T6::Item);
339
340 fn get(world: &mut State) -> Option<Self::Item> {
341 Some((
342 T1::get(world)?,
343 T2::get(world)?,
344 T3::get(world)?,
345 T4::get(world)?,
346 T5::get(world)?,
347 T6::get(world)?,
348 ))
349 }
350}
351
352impl<T1, T2, T3, T4, T5, T6, T7> SystemParam for (T1, T2, T3, T4, T5, T6, T7)
354where
355 T1: SystemParam,
356 T2: SystemParam,
357 T3: SystemParam,
358 T4: SystemParam,
359 T5: SystemParam,
360 T6: SystemParam,
361 T7: SystemParam,
362{
363 type Item = (
364 T1::Item,
365 T2::Item,
366 T3::Item,
367 T4::Item,
368 T5::Item,
369 T6::Item,
370 T7::Item,
371 );
372
373 fn get(world: &mut State) -> Option<Self::Item> {
374 Some((
375 T1::get(world)?,
376 T2::get(world)?,
377 T3::get(world)?,
378 T4::get(world)?,
379 T5::get(world)?,
380 T6::get(world)?,
381 T7::get(world)?,
382 ))
383 }
384}
385
386impl<T1, T2, T3, T4, T5, T6, T7, T8> SystemParam for (T1, T2, T3, T4, T5, T6, T7, T8)
388where
389 T1: SystemParam,
390 T2: SystemParam,
391 T3: SystemParam,
392 T4: SystemParam,
393 T5: SystemParam,
394 T6: SystemParam,
395 T7: SystemParam,
396 T8: SystemParam,
397{
398 type Item = (
399 T1::Item,
400 T2::Item,
401 T3::Item,
402 T4::Item,
403 T5::Item,
404 T6::Item,
405 T7::Item,
406 T8::Item,
407 );
408
409 fn get(world: &mut State) -> Option<Self::Item> {
410 Some((
411 T1::get(world)?,
412 T2::get(world)?,
413 T3::get(world)?,
414 T4::get(world)?,
415 T5::get(world)?,
416 T6::get(world)?,
417 T7::get(world)?,
418 T8::get(world)?,
419 ))
420 }
421}