use std::marker::PhantomData;
use std::ops::{Add, Mul, Neg, Sub};
use num_traits::Float;
use specs::{WorldExt, System};
use specs_bundler::{Bundle, Bundler};
use specs_scene_graph::{SceneGraphBundle, SceneGraphSystem};
use super::{
GlobalTransform2D, GlobalTransform3D, Parent, Transform2D, Transform3D, TransformSystem,
};
#[derive(Debug)]
pub struct TransformBundle<'deps, T> {
deps: Vec<&'deps str>,
_marker: PhantomData<T>,
}
impl<'deps, T> Default for TransformBundle<'deps, T> {
#[inline]
fn default() -> Self {
TransformBundle::new(&[])
}
}
impl<'deps, T> TransformBundle<'deps, T> {
#[inline]
pub fn new(deps: &[&'deps str]) -> Self {
TransformBundle {
deps: deps.to_vec(),
_marker: PhantomData,
}
}
}
impl<'deps, 'world, 'a, 'b, T> Bundle<'world, 'a, 'b> for TransformBundle<'deps, T>
where
T: 'static + Sync + Send + Float,
for<'c, 'd> &'c T:
Mul<&'d T, Output = T> + Neg<Output = T> + Add<&'d T, Output = T> + Sub<&'d T, Output = T>,
{
type Error = ();
#[inline]
fn bundle(
mut self,
mut bundler: Bundler<'world, 'a, 'b>,
) -> Result<Bundler<'world, 'a, 'b>, Self::Error> {
bundler.world.register::<GlobalTransform3D<T>>();
bundler.world.register::<Transform3D<T>>();
bundler.world.register::<GlobalTransform2D<T>>();
bundler.world.register::<Transform2D<T>>();
bundler = bundler.bundle(SceneGraphBundle::<Parent>::default())?;
self.deps.push(SceneGraphSystem::<Parent>::name());
let mut system = TransformSystem::<T>::new();
system.setup(&mut bundler.world);
bundler.dispatcher_builder = bundler.dispatcher_builder.with(
system,
TransformSystem::<T>::name(),
self.deps.as_slice(),
);
Ok(bundler)
}
}