summaryrefslogtreecommitdiff
path: root/ecs/src/system.rs
diff options
context:
space:
mode:
authorHampusM <hampus@hampusmat.com>2024-02-28 22:30:38 +0100
committerHampusM <hampus@hampusmat.com>2024-02-28 22:30:38 +0100
commit21c582507ae2dc9d264c80719e39ac47d3b0122b (patch)
treec564e8507dcc3060442821cbfdce1788c472cb9c /ecs/src/system.rs
parentc1ec41dffb488109740bce2c2354db917fb6c20f (diff)
refactor(ecs): use better system input type filtering solution
Diffstat (limited to 'ecs/src/system.rs')
-rw-r--r--ecs/src/system.rs83
1 files changed, 6 insertions, 77 deletions
diff --git a/ecs/src/system.rs b/ecs/src/system.rs
index d90e0a2..cbf004f 100644
--- a/ecs/src/system.rs
+++ b/ecs/src/system.rs
@@ -1,13 +1,13 @@
-use std::any::{Any, TypeId};
+use std::any::Any;
use std::convert::Infallible;
use std::fmt::Debug;
-use std::mem::{transmute_copy, ManuallyDrop};
use std::ptr::addr_of_mut;
use seq_macro::seq;
use crate::component::Component;
use crate::system::util::check_params_are_compatible;
+use crate::tuple::{FilterElement as TupleFilterElement, With as TupleWith};
use crate::ComponentStorage;
pub mod stateful;
@@ -166,80 +166,9 @@ pub struct NoInitParamFlag {}
/// A type which can be used as input to a [`System`].
pub trait Input: 'static {}
-pub trait InputFilter
+impl<InputT: Input, Tup> TupleFilterElement<Tup> for InputT
+where
+ Tup: TupleWith<Self>,
{
- type Filtered: FilteredInputs;
+ type Tuple = Tup::With;
}
-
-pub trait FilteredInputs
-{
- type InOptions: OptionInputs;
-
- fn into_in_options(self) -> Self::InOptions;
-}
-
-macro_rules! impl_filtered_inputs {
- ($cnt: tt) => {
- seq!(I in 0..$cnt {
- impl<#(Input~I: Input,)*> FilteredInputs for (#(Input~I,)*) {
- type InOptions = (#(Option<Input~I>,)*);
-
- fn into_in_options(self) -> Self::InOptions {
- #![allow(clippy::unused_unit)]
- (#(Some(self.I),)*)
- }
- }
- });
- };
-}
-
-seq!(N in 0..4 {
- impl_filtered_inputs!(N);
-});
-
-pub trait OptionInputs
-{
- fn take<Input: 'static>(&mut self) -> TakeOptionInputResult<Input>;
-}
-
-macro_rules! impl_option_inputs {
- ($cnt: tt) => {
- seq!(I in 0..$cnt {
- impl<#(Input~I: 'static,)*> OptionInputs for (#(Option<Input~I>,)*) {
- fn take<Input: 'static>(&mut self) -> TakeOptionInputResult<Input> {
- #(
- if TypeId::of::<Input~I>() == TypeId::of::<Input>() {
- let input = match self.I.take() {
- Some(input) => ManuallyDrop::new(input),
- None => {
- return TakeOptionInputResult::AlreadyTaken;
- }
- };
-
- return TakeOptionInputResult::Found(
- // SAFETY: It can be transmuted safely since it is the
- // same type and the type is 'static
- unsafe { transmute_copy(&input) }
- );
- }
- )*
-
- TakeOptionInputResult::NotFound
- }
- }
- });
- };
-}
-
-seq!(N in 0..4 {
- impl_option_inputs!(N);
-});
-
-pub enum TakeOptionInputResult<Input>
-{
- Found(Input),
- NotFound,
- AlreadyTaken,
-}
-
-include!(concat!(env!("OUT_DIR"), "/system_input_impls.rs"));