summaryrefslogtreecommitdiff
path: root/ecs
diff options
context:
space:
mode:
Diffstat (limited to 'ecs')
-rw-r--r--ecs/src/system.rs6
-rw-r--r--ecs/src/tuple.rs99
2 files changed, 67 insertions, 38 deletions
diff --git a/ecs/src/system.rs b/ecs/src/system.rs
index 3ba693b..e273428 100644
--- a/ecs/src/system.rs
+++ b/ecs/src/system.rs
@@ -14,7 +14,7 @@ use crate::component::{
FromOptionalMut as FromOptionalMutComponent,
};
use crate::lock::{ReadGuard, WriteGuard};
-use crate::tuple::{ReduceElement as TupleReduceElement, With as TupleWith};
+use crate::tuple::{ReduceElement as TupleReduceElement, Tuple};
use crate::World;
pub mod stateful;
@@ -180,9 +180,9 @@ pub struct ParamWithInputFilter;
impl<InputT: Input, Accumulator> TupleReduceElement<Accumulator, ParamWithInputFilter>
for InputT
where
- Accumulator: TupleWith<Self>,
+ Accumulator: Tuple,
{
- type Return = Accumulator::With;
+ type Return = Accumulator::WithElementAtEnd<Self>;
}
impl<Accumulator> TupleReduceElement<Accumulator, ParamWithInputFilter> for ()
diff --git a/ecs/src/tuple.rs b/ecs/src/tuple.rs
index 1434592..b16160c 100644
--- a/ecs/src/tuple.rs
+++ b/ecs/src/tuple.rs
@@ -5,18 +5,28 @@ use paste::paste;
use seq_macro::seq;
use util_macros::sub;
-/// Used to append a element to a tuple type.
-pub trait With<OtherElem>
+pub trait Tuple: sealed::Sealed
{
- type With;
-}
-
-/// Used to remove the last element of a tuple type.
-///
-/// For example: `(u32, String, PathBuf)` becomes `(u32, String)`.
-pub trait WithoutLast
-{
- type Return;
+ /// `Self` with the given type added as the last element.
+ ///
+ /// `(String, i32, u8)::WithElementAtEnd<Path> = (String, i32, u8, Path)`
+ ///
+ /// # Important note
+ /// If `Self` has 16 elements, this will be `()`. The reason for this is that the
+ /// `Tuple` trait is only implemented for tuples with up to and including 16 elements.
+ type WithElementAtEnd<NewElem>: Tuple;
+
+ /// `Self` without the last element.
+ ///
+ /// `(u16, AtomicU8)::WithoutLastElement = (u16,)`
+ type WithoutLastElement: Tuple;
+
+ /// The last element of `Self`.
+ type LastElement;
+
+ /// Pops the last element from this tuple, returning the new tuple and the popped
+ /// element.
+ fn pop_last(self) -> (Self::WithoutLastElement, Self::LastElement);
}
/// Used to make all elements of a tuple type wrapped in [`Option`].
@@ -95,13 +105,6 @@ macro_rules! elem_by_index {
};
}
-pub trait Pop: WithoutLast
-{
- type LastElem;
-
- fn pop(self) -> (<Self as WithoutLast>::Return, Self::LastElem);
-}
-
macro_rules! all_except_last {
(start $($rest: tt)*) => {
all_except_last!(@[] $($rest)*)
@@ -131,14 +134,25 @@ macro_rules! all_except_last {
macro_rules! impl_tuple_traits {
($cnt: tt) => {
seq!(I in 0..$cnt {
- impl<OtherElem, #(Elem~I,)*> With<OtherElem> for (#(Elem~I,)*)
+ impl< #(Elem~I,)*> Tuple for (#(Elem~I,)*)
{
- type With = (#(Elem~I,)* OtherElem,);
+ type WithElementAtEnd<NewElem> = (#(Elem~I,)* NewElem,);
+
+ type WithoutLastElement = all_except_last!(start #(Elem~I)*);
+
+ type LastElement = sub!($cnt - 1, elem_type_by_index);
+
+ fn pop_last(self) -> (Self::WithoutLastElement, Self::LastElement)
+ {
+ (
+ all_except_last!(start #((self.I))*),
+ sub!($cnt - 1, elem_by_index, (self))
+ )
+ }
}
- impl<#(Elem~I,)*> WithoutLast for (#(Elem~I,)*)
+ impl< #(Elem~I,)*> sealed::Sealed for (#(Elem~I,)*)
{
- type Return = all_except_last!(start #(Elem~I)*);
}
impl<#(Element~I: 'static,)*> IntoInOptions for (#(Element~I,)*)
@@ -190,19 +204,6 @@ macro_rules! impl_tuple_traits {
type Out = sub!($cnt - 1, tuple_reduce_elem_tuple);
}
}
-
- impl<#(Elem~I,)*> Pop for (#(Elem~I,)*)
- {
- type LastElem = sub!($cnt - 1, elem_type_by_index);
-
- fn pop(self) -> (<Self as WithoutLast>::Return, Self::LastElem)
- {
- (
- all_except_last!(start #((self.I))*),
- sub!($cnt - 1, elem_by_index, (self))
- )
- }
- }
});
};
}
@@ -210,3 +211,31 @@ macro_rules! impl_tuple_traits {
seq!(N in 0..16 {
impl_tuple_traits!(N);
});
+
+seq!(I in 0..16 {
+ impl< #(Elem~I,)*> Tuple for (#(Elem~I,)*)
+ {
+ type WithElementAtEnd<NewElem> = ();
+
+ type WithoutLastElement = all_except_last!(start #(Elem~I)*);
+
+ type LastElement = Elem15;
+
+ fn pop_last(self) -> (Self::WithoutLastElement, Self::LastElement)
+ {
+ (
+ all_except_last!(start #((self.I))*),
+ self.15
+ )
+ }
+ }
+
+ impl< #(Elem~I,)*> sealed::Sealed for (#(Elem~I,)*)
+ {
+ }
+});
+
+mod sealed
+{
+ pub trait Sealed {}
+}