diff options
author | HampusM <hampus@hampusmat.com> | 2024-12-10 17:25:25 +0100 |
---|---|---|
committer | HampusM <hampus@hampusmat.com> | 2024-12-10 17:25:25 +0100 |
commit | c6de2c7ab9c48223ab307fe0039fae7ab2613e16 (patch) | |
tree | ddbe1daf1521ea30ded662f2e46e62f4afb9a592 | |
parent | e26e548f5730e401797149d5d3254437e68e660e (diff) |
refactor(ecs): merge a couple of tuple traits together
-rw-r--r-- | ecs/src/system.rs | 6 | ||||
-rw-r--r-- | ecs/src/tuple.rs | 99 |
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 {} +} |