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::Transform2DSystem;
use super::{Camera2D, Camera2DSystem, ScreenSize2D};
pub struct Camera2DBundle<T> {
width: usize,
height: usize,
_marker: PhantomData<T>,
}
impl<T> Default for Camera2DBundle<T> {
#[inline(always)]
fn default() -> Self {
Self::new(1024, 768)
}
}
impl<T> Camera2DBundle<T> {
#[inline(always)]
pub fn new(width: usize, height: usize) -> Self {
Camera2DBundle {
width: width,
height: height,
_marker: PhantomData,
}
}
}
impl<'a, 'b, T> SpecsBundle<'a, 'b> for Camera2DBundle<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(ScreenSize2D::new(self.width, self.height));
world.register::<Camera2D<T>>();
Ok(dispatch_builder.with(
Camera2DSystem::<T>::new(),
&Camera2DSystem::<T>::name(),
&[Transform2DSystem::<T>::name()],
))
}
}