summaryrefslogtreecommitdiff
path: root/ecs/src/system/initializable.rs
diff options
context:
space:
mode:
authorHampusM <hampus@hampusmat.com>2025-08-15 13:38:27 +0200
committerHampusM <hampus@hampusmat.com>2025-08-22 17:18:54 +0200
commite229b104593d3afede47cc07e9917a42d6d13e60 (patch)
tree25cd15befc8bf3e5864158aa791895c6d5bea751 /ecs/src/system/initializable.rs
parentc8d3b211b8328452c9d15955004030430a99d1fc (diff)
refactor(ecs): store local components as system entity components
Diffstat (limited to 'ecs/src/system/initializable.rs')
-rw-r--r--ecs/src/system/initializable.rs131
1 files changed, 131 insertions, 0 deletions
diff --git a/ecs/src/system/initializable.rs b/ecs/src/system/initializable.rs
new file mode 100644
index 0000000..40fbb0f
--- /dev/null
+++ b/ecs/src/system/initializable.rs
@@ -0,0 +1,131 @@
+use std::marker::PhantomData;
+
+use seq_macro::seq;
+
+use crate::system::{Input, Param as SystemParam, System};
+use crate::tuple::{Reduce as TupleReduce, ReduceElement as TupleReduceElement, Tuple};
+
+/// A initializable system.
+pub trait Initializable<'world, Impl>: System<'world, Impl>
+{
+ type Inputs;
+
+ #[must_use]
+ fn initialize(self, inputs: Self::Inputs) -> Self;
+}
+
+pub trait Param<'world, SystemT>: SystemParam<'world>
+{
+ fn initialize(system: &mut SystemT, input: Self::Input);
+}
+
+pub struct ParamTupleFilter<'world, SystemT>
+{
+ _pd: PhantomData<(&'world (), SystemT)>,
+}
+
+impl<'world, SystemT, ParamT, Accumulator>
+ TupleReduceElement<Accumulator, ParamTupleFilter<'world, SystemT>> for ParamT
+where
+ ParamT: SystemParam<
+ 'world,
+ Input: AppendInitializableParam<'world, Accumulator, ParamT, SystemT>,
+ >,
+ Accumulator: Tuple,
+{
+ type Return = <ParamT::Input as AppendInitializableParam<
+ 'world,
+ Accumulator,
+ ParamT,
+ SystemT,
+ >>::Return;
+}
+
+pub trait AppendInitializableParam<'world, Accumulator, ParamT, SystemT>
+{
+ type Return;
+}
+
+impl<'world, InputT, ParamT, Accumulator, SystemT>
+ AppendInitializableParam<'world, Accumulator, ParamT, SystemT> for InputT
+where
+ InputT: Input,
+ Accumulator: Tuple,
+ ParamT: Param<'world, SystemT>,
+{
+ type Return = Accumulator::WithElementAtEnd<ParamT>;
+}
+
+impl<'world, ParamT, Accumulator, SystemT>
+ AppendInitializableParam<'world, Accumulator, ParamT, SystemT> for ()
+where
+ Accumulator: Tuple,
+{
+ type Return = Accumulator;
+}
+
+pub trait ParamTuple<'world, SystemT>
+{
+ type Inputs;
+
+ fn initialize_all(system: &mut SystemT, inputs: Self::Inputs);
+}
+
+macro_rules! impl_initializable_param_tuple {
+ ($c: tt) => {
+ seq!(I in 0..$c {
+ impl<'world, SystemT, #(Param~I,)*> ParamTuple<'world, SystemT>
+ for (#(Param~I,)*)
+ where
+ #(Param~I: Param<'world, SystemT>,)*
+ {
+ type Inputs = (#(Param~I::Input,)*);
+
+ fn initialize_all(
+ system: &mut SystemT,
+ inputs: Self::Inputs,
+ ) {
+ #(
+ <Param~I as Param<'world, SystemT>>::initialize(
+ system,
+ inputs.I
+ );
+ )*
+ }
+ }
+ });
+ };
+}
+
+seq!(C in 1..16 {
+ impl_initializable_param_tuple!(C);
+});
+
+impl<'world, SystemT> ParamTuple<'world, SystemT> for ()
+{
+ type Inputs = ();
+
+ fn initialize_all(_system: &mut SystemT, _inputs: Self::Inputs) {}
+}
+
+/// A tuple of system parameters that may or may not be initializable.
+pub trait MaybeInitializableParamTuple<'world, SystemT>
+{
+ /// A tuple of the inputs of the initializable system parameters in this tuple.
+ type Inputs;
+
+ fn init_initializable(system: &mut SystemT, inputs: Self::Inputs);
+}
+
+impl<'world, SystemT, Params> MaybeInitializableParamTuple<'world, SystemT> for Params
+where
+ Params:
+ TupleReduce<ParamTupleFilter<'world, SystemT>, Out: ParamTuple<'world, SystemT>>,
+{
+ type Inputs = <Params::Out as ParamTuple<'world, SystemT>>::Inputs;
+
+ fn init_initializable(system: &mut SystemT, inputs: Self::Inputs)
+ {
+ Params::Out::initialize_all(system, inputs);
+ }
+}