1use crate::*;
16
17pub trait Nest: private::Sealed {
25 type Nested;
27 fn flatten(v: Self::Nested) -> Self;
29 fn nest(self) -> Self::Nested;
31}
32
33pub trait Flatten: private::Sealed {
35 type Flattened;
37 fn flatten(self) -> Self::Flattened;
39 fn nest(v: Self::Flattened) -> Self;
41}
42
43macro_rules! unnest {
45 (($layer:expr); ($($v:expr),*); ($u:ident, $($us:ident,)*)) => {
46 unnest!(($layer . 1); ($($v,)* $layer . 0); ($($us,)*))
47 };
48 (($layer:expr); ($($v:expr),*); ()) => { ($($v,)*) };
49}
50
51impl Nest for () {
52 type Nested = ();
53 #[inline]
54 fn flatten(_v: ()) -> () {
55 ()
56 }
57 #[inline]
58 fn nest(self) -> () {
59 ()
60 }
61}
62
63macro_rules! nest {
64 ($v:ident,) => { () };
65 ($v:ident, $n:tt, $($ns:tt,)*) => {
66 ($v.$n, nest!($v, $($ns,)*))
67 }
68}
69
70macro_rules! impl_nested {
72 (@impl_internal {($t:ident, $n:tt), $(($ts:ident, $ns:tt),)*}) => {
73 impl<$t, $($ts),*> Nest for ($t, $($ts,)*) where ($($ts,)*): Nest {
74 type Nested = impl_nested!(@nest_type $t, $($ts,)*);
75 #[inline]
76 fn flatten(v: Self::Nested) -> Self {
77 unnest!((v); (); ($t, $($ts,)*))
78 }
79 #[inline]
80 fn nest(self) -> Self::Nested {
81 nest!(self, $n, $($ns,)*)
82 }
83 }
84
85 impl<$t, $($ts),*> Flatten for impl_nested!(@nest_type $t, $($ts,)*) {
86 type Flattened = ($t, $($ts,)*);
87 #[inline]
88 fn flatten(self) -> Self::Flattened {
89 unnest!((self); (); ($t, $($ts,)*))
90 }
91 #[inline]
92 fn nest(v: Self::Flattened) -> Self {
93 nest!(v, $n, $($ns,)*)
94 }
95 }
96 };
97
98 (@nest_type) => {
99 ()
100 };
101
102 (@nest_type $t:ident, $($ts:ident,)*) => {
103 ($t, impl_nested!(@nest_type $($ts,)*))
104 };
105
106 (@internal {$(($t:ident,$n:tt),)+}; {}; {}) => {
108 impl_nested!(@impl_internal {$(($t, $n),)*});
109 };
110
111 (@internal {$(($t1:ident,$n1:tt),)+};
114 {$t2:ident, $($t3:ident,)*};
115 {$n2:tt, $($n3:tt,)*}) => {
116 impl_nested!(@impl_internal {$(($t1, $n1),)*});
117 impl_nested!(@internal {$(($t1, $n1),)* ($t2, $n2),};
118 {$($t3,)*};
119 {$($n3,)*});
120 };
121
122 (($t:ident, $($ts:ident,)+); ($n:tt, $($ns:tt,)+)) => {
124 impl_nested!(@internal {($t, $n),}; {$($ts,)*}; {$($ns,)*});
125 };
126}
127
128impl_nested!(
129 (A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, AA, BB, CC, DD,
130 EE, FF,);
131 (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,)
132);
133
134pub trait ComponentProviderRec<'a, T> {
136 fn fetch(&'a self) -> T;
138}
139
140pub trait ComponentProvider<'a, T: Nest> {
142 fn fetch(&'a self) -> T;
144}
145
146impl<'a, T, W> ComponentProvider<'a, T> for W
147where
148 T: Nest,
149 W: WorldInterface<'a> + ComponentProviderRec<'a, T::Nested>,
150{
151 #[inline]
152 fn fetch(&'a self) -> T {
153 <T as Nest>::flatten(<Self as ComponentProviderRec<'a, T::Nested>>::fetch(self))
154 }
155}
156
157impl<'a, H, T, WD> ComponentProviderRec<'a, (ReadComponent<'a, H>, T)> for WD
158where
159 H: 'a + StorageSpec<'a>,
160 H::Storage: ComponentStorage<'a>,
161 WD: WorldInterface<'a> + ComponentProviderRec<'a, T> + GetComponent<'a, H>,
162{
163 #[inline]
164 fn fetch(&'a self) -> (ReadComponent<'a, H>, T) {
165 (
166 ReadComponent {
167 storage: <Self as GetComponent<'a, H>>::get(self),
168 },
169 <Self as ComponentProviderRec<T>>::fetch(self),
170 )
171 }
172}
173
174impl<'a, H, T, WD> ComponentProviderRec<'a, (ReadResource<'a, H>, T)> for WD
175where
176 H: 'a,
177 WD: WorldInterface<'a> + ComponentProviderRec<'a, T> + GetResource<H>,
178{
179 #[inline]
180 fn fetch(&'a self) -> (ReadResource<'a, H>, T) {
181 (
182 ReadResource {
183 resource: <Self as GetResource<H>>::get(self),
184 },
185 <Self as ComponentProviderRec<T>>::fetch(self),
186 )
187 }
188}
189
190impl<'a, H, T, WD> ComponentProviderRec<'a, (WriteResource<'a, H>, T)> for WD
191where
192 H: 'a,
193 WD: WorldInterface<'a> + ComponentProviderRec<'a, T> + GetResource<H>,
194{
195 #[inline]
196 fn fetch(&'a self) -> (WriteResource<'a, H>, T) {
197 (
198 WriteResource {
199 resource: <Self as GetResource<H>>::get_mut(self),
200 },
201 <Self as ComponentProviderRec<T>>::fetch(self),
202 )
203 }
204}
205
206impl<'a, H, T, WD> ComponentProviderRec<'a, (WriteComponent<'a, H>, T)> for WD
207where
208 H: 'a + StorageSpec<'a>,
209 H::Storage: ComponentStorage<'a>,
210 WD: WorldInterface<'a> + ComponentProviderRec<'a, T> + GetComponent<'a, H>,
211{
212 #[inline]
213 fn fetch(&'a self) -> (WriteComponent<'a, H>, T) {
214 (
215 WriteComponent {
216 storage: <Self as GetComponent<'a, H>>::get_mut(self),
217 },
218 <Self as ComponentProviderRec<T>>::fetch(self),
219 )
220 }
221}
222
223impl<'a, WD> ComponentProviderRec<'a, ()> for WD {
224 #[inline]
225 fn fetch(&'a self) -> () {
226 ()
227 }
228}
229
230impl<'a, WD, T> ComponentProviderRec<'a, ReadComponent<'a, T>> for WD
231where
232 T: 'a + StorageSpec<'a>,
233 WD: WorldInterface<'a> + GetComponent<'a, T>,
234{
235 fn fetch(&'a self) -> ReadComponent<T> {
236 ReadComponent {
237 storage: <Self as GetComponent<'a, T>>::get(self),
238 }
239 }
240}
241
242impl<'a, WD, T> ComponentProviderRec<'a, WriteComponent<'a, T>> for WD
243where
244 T: 'a + StorageSpec<'a>,
245 WD: WorldInterface<'a> + GetComponent<'a, T>,
246{
247 fn fetch(&'a self) -> WriteComponent<T> {
248 WriteComponent {
249 storage: <Self as GetComponent<'a, T>>::get_mut(self),
250 }
251 }
252}
253
254pub trait System<'a> {
256 type Dependencies: Nest; fn run(&'a mut self, dependencies: Self::Dependencies);
260}
261pub enum SystemOutput<T> {
263 Ignore,
265 Delete,
267 Update(T),
269}
270
271impl<T> Default for SystemOutput<T> {
272 fn default() -> Self {
273 SystemOutput::Ignore
274 }
275}
276
277pub trait PureFunctionalSystem {
281 type Inputs;
283 type Outputs: SystemOutputTuple;
285 fn process(&self, data: &Self::Inputs) -> <Self::Outputs as SystemOutputTuple>::OutputTuple;
287}
288
289pub trait WorldInterface<'a>
291where
292 Self: Sized,
293{
294 type EntityBuilder: 'a;
296 type ComponentSet;
298 type AvailableTypes;
300 fn new_entity(&'a mut self) -> Self::EntityBuilder;
302 fn build_entity(&mut self, c: Self::ComponentSet) -> Entity;
305 fn delete_entity(&mut self, e: Entity);
307 fn run_system<'b, S, T >(&'a mut self, system: &'b mut S)
309 where
310 S: System<'b, Dependencies = T>,
311 T: Nest,
312 Self: ComponentProviderRec<'a, T::Nested>,
315 {
316 system.run(<Self as ComponentProvider<'a, T>>::fetch(self));
317 }
318}
319
320pub trait BuildWith<T> {
322 fn with(self, data: T) -> Self;
324}
325
326pub trait ResourceProvider {
328 type Resources;
330 fn get_resources(&mut self) -> &Self::Resources;
332}
333
334pub trait GetComponent<'a, T: StorageSpec<'a>> {
336 fn get(&self) -> std::cell::Ref<T::Storage>;
338 fn get_mut(&self) -> std::cell::RefMut<T::Storage>;
340}
341
342pub trait GetResource<T> {
344 fn get(&self) -> std::cell::Ref<T>;
346 fn get_mut(&self) -> std::cell::RefMut<T>;
348 fn set(&self, t: T);
350}
351
352mod private {
353 pub trait Sealed {}
354 impl Sealed for () {}
355}
356
357pub trait SystemOutputTuple: private::Sealed {
359 type OutputTuple;
361}
362
363macro_rules! impl_output_tuple {
365 (@impl_internal $($t:ident,)+) => {
366 impl<$($t),*> SystemOutputTuple for ($($t,)*) {
367 #[allow(unused_parens)]
368 type OutputTuple = ($(SystemOutput<$t>),*);
369 }
370 impl<$($t),*> private::Sealed for ($($t,)*) {}
371 };
372
373 (($($t:ident,)+);) => {
375 impl_output_tuple!(@impl_internal $($t,)*);
376 };
377
378 (($($t1:ident,)+); $t2:ident $(,)* $($t3:ident),*) => {
381 impl_output_tuple!(@impl_internal $($t1,)*);
382 impl_output_tuple!(($($t1),*, $t2,); $($t3),*);
383 };
384
385 ($t1:ident, $($t:ident),+) => {
387 impl_output_tuple!(($t1,); $($t),*);
388 };
389}
390
391impl_output_tuple!(
392 A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, AA, BB, CC, DD,
393 EE, FF
394);