接上一篇不同参数的函数怎么注册到零碎中,这个是不同参数怎么在rust中辨认进去在函数调用时候传进去的 上面的剖析是参考了system在b94f26618364ed03b9db1ebc89ad4ff3e30c8581的代码上剖析的

  1. 定义单个参数类型的接口
//接口SystemParam 蕴含一种构造体 这个构造体实现了FetchSystemParam 接口pub trait SystemParam: Sized {    type Fetch: for<'a> FetchSystemParam<'a>;}//FetchSystemParam 接口则须要实现get_param函数,能够动静定义返回的参数类型pub trait FetchSystemParam<'a> {    type Item;    unsafe fn get_param(state :u32) -> Option<Self::Item>;}

大略就是SystemParam绑定到一种类型上,这种类型又实现了FetchSystemParam接口能够调用get_param

  1. 例如实现一个参数类型u32的1中定义的接口
pub struct FetchArcCommands;//为u32 实现SystemParam,这个接口通过FetchArcCommands来实现这个接口,即实现了带u32的get_paramimpl SystemParam for u32 {    type Fetch = FetchArcCommands;}impl<'a> FetchSystemParam<'a> for FetchArcCommands {    type Item = u32;    #[inline]    unsafe fn get_param(state :u32) -> Option<Self::Item> {        None    }}
  1. 而后就是应用的时候对应上一篇文章的一个参数的定义
impl<TestType, A: SystemParam> IntoSystem<(A, )> for TestType    where        TestType:        FnMut(A) +        FnMut(<<A as SystemParam>::Fetch as FetchSystemParam>::Item) +        Send + Sync + 'static{    #[allow(unused_variables)]    #[allow(unused_unsafe)]    #[allow(non_snake_case)]    fn system(mut self){        unsafe {            if let Some((A, )) = <<(A, ) as SystemParam>::Fetch as FetchSystemParam>::get_param(123){            }        }    }}
  1. 而这一个参数放在了一个元组泛型(A,)中,(A,)和A是用同样的办法包了一层
#[allow(unused_variables)]impl<'a, A: FetchSystemParam<'a>> FetchSystemParam<'a> for FetchParamTuple<(A, )> {    type Item = (A::Item, );    #[inline]    unsafe fn get_param(state :u32) -> Option<Self::Item> {        Some((A::get_param(state)?, ))    }}impl<A: SystemParam> SystemParam for Or<(Option<A>, )> {    type Fetch = FetchOr<(A::Fetch, )>;}impl<'a, A: FetchSystemParam<'a>> FetchSystemParam<'a> for FetchOr<(A, )> {    type Item = Or<(Option<A::Item>, )>;    #[inline]    unsafe fn get_param(state :u32) -> Option<Self::Item> {        let mut has_some = false;        let A = A::get_param(state);        if A.is_some() {            has_some = true;        }        if has_some {            Some(Or((A, )))        } else {            None        }    }}

下面是举了一个u32的例子,而system中应用的Query大略是上面这样来实现的

pub struct FetchQuery<Q, F>(PhantomData<(Q, F)>);impl<'a, Q: WorldQuery, F: QueryFilter> SystemParam for Query<'a, Q, F> {    type Fetch = FetchQuery<Q, F>;}impl<'a, Q: WorldQuery, F: QueryFilter> FetchSystemParam<'a> for FetchQuery<Q, F> {    type Item = Query<'a, Q, F>;    #[inline]    unsafe fn get_param(        system_state: &'a SystemState,        world: &'a World,        _resources: &'a Resources,    ) -> Option<Self::Item> {        let query_index = *system_state.current_query_index.get();        let archetype_component_access: &'a TypeAccess<ArchetypeComponent> =            &system_state.query_archetype_component_accesses[query_index];        *system_state.current_query_index.get() += 1;        Some(Query::new(world, archetype_component_access))    }    fn init(system_state: &mut SystemState, _world: &World, _resources: &mut Resources) {        system_state            .query_archetype_component_accesses            .push(TypeAccess::default());        let access = QueryAccess::union(vec![Q::Fetch::access(), F::access()]);        system_state.query_accesses.push(vec![access]);        system_state            .query_type_names            .push(std::any::type_name::<Q>());    }}