use std::marker::PhantomData;
use std::ops::{Add, Div, Mul, Neg, Sub};
use num_traits::{Float, FromPrimitive};
use specs::{DispatcherBuilder, World};
use specs_bundler::SpecsBundle;
use specs_transform::Transform3DSystem;
use super::{Camera3D, Camera3DSystem, ScreenSize3D};
pub struct Camera3DBundle<T> {
width: usize,
height: usize,
_marker: PhantomData<T>,
}
impl<T> Default for Camera3DBundle<T> {
#[inline(always)]
fn default() -> Self {
Self::new(1024, 768)
}
}
impl<T> Camera3DBundle<T> {
#[inline(always)]
pub fn new(width: usize, height: usize) -> Self {
Camera3DBundle {
width: width,
height: height,
_marker: PhantomData,
}
}
}
impl<'a, 'b, T> SpecsBundle<'a, 'b> for Camera3DBundle<T>
where
T: 'static + Send + Sync + Float + FromPrimitive,
for<'c, 'd> &'c T: Sub<&'d T, Output = T>
+ Add<&'d T, Output = T>
+ Div<&'d T, Output = T>
+ Mul<&'d T, Output = T>
+ Neg<Output = T>,
{
type Error = ();
#[inline]
fn build(
self,
world: &mut World,
dispatch_builder: DispatcherBuilder<'a, 'b>,
) -> Result<DispatcherBuilder<'a, 'b>, Self::Error> {
world.add_resource(ScreenSize3D::new(self.width, self.height));
world.register::<Camera3D<T>>();
Ok(dispatch_builder.with(
Camera3DSystem::<T>::new(),
&Camera3DSystem::<T>::name(),
&[Transform3DSystem::<T>::name()],
))
}
}