elvsb

2 commits
Updated 2026-06-12 16:42:33
examples
examples/plop.rs
use std::marker::PhantomData;

pub trait QueryBundle {}

pub struct Query<'a, QUERY: QueryBundle>(PhantomData<&'a QUERY>);
pub struct RegistryMutHandle<'a>(PhantomData<&'a ()>);

impl QueryBundle for () {}
impl QueryBundle for (&mut u32,) {}
impl QueryBundle for (&f32, &mut i8) {}

pub trait System {}
impl System for () {}

enum FnProvider<
    'a,
    QUERY1: QueryBundle,
    QUERY2: QueryBundle,
    F1: FnMut(Query<'a, QUERY1>),
    F2: FnMut(Query<'a, QUERY1>, Query<'a, QUERY2>),
> {
    ARG1 {
        value: F1,
        _marker: PhantomData<&'a QUERY1>,
    },
    ARG2 {
        value: F2,
        _marker: PhantomData<&'a QUERY2>,
    },
}

impl<'a, QUERY1: QueryBundle, F: FnMut(Query<'a, QUERY1>)> From<F>
    for FnProvider<'a, QUERY1, (), F, fn(Query<'a, QUERY1>, Query<'a, ()>)>
{
    fn from(value: F) -> Self {
        Self::ARG1 {
            value,
            _marker: PhantomData,
        }
    }
}

impl<
    'a,
    QUERY1: QueryBundle,
    QUERY2: QueryBundle,
    F1: FnMut(Query<'a, QUERY1>),
    F2: FnMut(Query<'a, QUERY1>, Query<'a, QUERY2>),
> From<F2> for FnProvider<'a, QUERY1, QUERY2, F1, F2>
{
    fn from(value: F2) -> Self {
        Self::ARG2 {
            value,
            _marker: PhantomData,
        }
    }
}

impl<
    'a,
    QUERY1: QueryBundle,
    QUERY2: QueryBundle,
    F1: FnMut(Query<'a, QUERY1>),
    F2: FnMut(Query<'a, QUERY1>, Query<'a, QUERY2>),
> FnProvider<'a, QUERY1, QUERY2, F1, F2>
{
    pub fn into_executor(self, handle: &mut RegistryMutHandle) -> impl System {
        match self {
            Self::ARG1 { value, _marker } => {}
            Self::ARG2 { value, _marker } => {}
        }
    }
}

fn system1(positions: Query<(&mut u32,)>) {}
fn system2(positions: Query<(&mut u32,)>, velocities: Query<(&f32, &mut i8)>) {}

fn main() {
    let mut handle = RegistryMutHandle(PhantomData);
    let executor1 = FnProvider::from(system1).into_executor(&mut handle);
    let executor2 = FnProvider::from(system2).into_executor(&mut handle);
}

// pub trait Arg {
//     type Of<'a, QUERY: QueryBundle + 'static>;
// }

// struct QueryHKT;
// impl Arg for QueryHKT {
//     type Of<'a, QUERY: QueryBundle + 'static> = Query<'a, QUERY>;
// }

// pub trait SystemBuilder<T: Arg, QUERY: QueryBundle + 'static> {
//     fn get_executor<EXCUTOR: FnMut(T::Of<'_, QUERY>)>(&mut self, executor: EXCUTOR) -> impl System;
// }

// impl<QUERY: QueryBundle + 'static> SystemBuilder<QueryHKT, QUERY> for RegistryMutHandle<'_> {
//     fn get_executor<EXCUTOR: FnMut(Query<'_, QUERY>)>(&mut self, executor: EXCUTOR) -> impl System {
//         ()
//     }
// }