use bevy_app::prelude::*;
use bevy_ecs::component::Mutable;
use bevy_ecs::prelude::*;
use motiongfx::prelude::*;
use crate::pipeline::PipelineRegistryExt;
use crate::world::MotionGfxWorld;
#[macro_export]
macro_rules! register_fields {
(
$app:ident.$reg_func:ident(),
$root:ty $(, $($rest:tt)*)?
) => {
register_fields!(
$app.$reg_func::<$root>(),
$root $(, $($rest)*)?
)
};
(
$app:ident.$reg_func:ident::<$source:ty>(),
$root:ty $(, $($rest:tt)*)?
) => {
$crate::registry::FieldPathRegisterAppExt
::$reg_func::<$source, _>(
$app,
::motiongfx::field_path::field::field!(<$root>),
::motiongfx::field_path::accessor::accessor!(<$root>),
);
register_fields!(
@fields $app.$reg_func::<$source>, $root, []
$(, $($rest)*)?
);
};
(
@fields $app:ident.$reg_func:ident::<$source:ty>,
$root:ty, [$(::$path:tt)*],
(
$field:tt $(( $($sub_field:tt)+ ))?
$(,$($rest:tt)*)?
)
) => {
$crate::registry::FieldPathRegisterAppExt
::$reg_func::<$source, _>(
$app,
motiongfx::field_path::field::field!(<$root>$(::$path)*::$field),
::motiongfx::field_path::accessor::accessor!(<$root>$(::$path)*::$field),
);
register_fields!(
@fields $app.$reg_func::<$source>,
$root, [$(::$path)*::$field],
$(( $($sub_field)+ ))?
);
register_fields!(
@fields $app.$reg_func::<$source>,
$root, [$(::$path)*],
$(( $($rest)* ))?
);
};
(
@fields $app:ident.$reg_func:ident::<$source:ty>,
$root:ty, [$(::$path:tt)*]
$(,)? $(,())?
) => {};
}
pub trait FieldPathRegisterAppExt {
fn register_component_field<S, T>(
&mut self,
field: Field<S, T>,
accessor: Accessor<S, T>,
) -> &mut Self
where
S: Component<Mutability = Mutable>,
T: Clone + ThreadSafe;
#[cfg(feature = "asset")]
fn register_asset_field<S, T>(
&mut self,
field: Field<S, T>,
accessor: Accessor<S, T>,
) -> &mut Self
where
S: bevy_asset::Asset,
T: Clone + ThreadSafe;
}
impl FieldPathRegisterAppExt for App {
fn register_component_field<S, T>(
&mut self,
field: Field<S, T>,
accessor: Accessor<S, T>,
) -> &mut Self
where
S: Component<Mutability = Mutable>,
T: Clone + ThreadSafe,
{
let mut motiongfx =
self.world_mut().resource_mut::<MotionGfxWorld>();
motiongfx
.accessor_registry
.register(field.untyped(), accessor);
motiongfx.pipeline_registry.register_component::<S, T>();
self
}
#[cfg(feature = "asset")]
fn register_asset_field<S, T>(
&mut self,
field: Field<S, T>,
accessor: Accessor<S, T>,
) -> &mut Self
where
S: bevy_asset::Asset,
T: Clone + ThreadSafe,
{
let mut motiongfx =
self.world_mut().resource_mut::<MotionGfxWorld>();
motiongfx
.accessor_registry
.register(field.untyped(), accessor);
motiongfx.pipeline_registry.register_asset::<S, T>();
self
}
}