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