1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99
use std::marker::PhantomData; use std::ops::{Add, Div, Mul, Neg, Sub}; use num_traits::{Float, FromPrimitive}; use type_name; use specs::{Join, Read, ReadStorage, System, WriteStorage}; use specs_transform::Transform2D; use super::super::ScreenSize; use super::Camera2D; pub struct Camera2DSystem<T> { screen_size: Option<ScreenSize>, _marker: PhantomData<T>, } impl<T> Camera2DSystem<T> { #[inline] pub fn name() -> &'static str { type_name::get::<Self>() } } impl<T> Camera2DSystem<T> { #[inline(always)] pub fn new() -> Self { Camera2DSystem { screen_size: None, _marker: PhantomData, } } } impl<T> Default for Camera2DSystem<T> { #[inline(always)] fn default() -> Self { Camera2DSystem::new() } } impl<'system, T> System<'system> for Camera2DSystem<T> where T: 'static + Send + Sync + Float + FromPrimitive, for<'a, 'b> &'a T: Sub<&'b T, Output = T> + Add<&'b T, Output = T> + Div<&'b T, Output = T> + Mul<&'b T, Output = T> + Neg<Output = T>, { type SystemData = ( Read<'system, ScreenSize>, ReadStorage<'system, Transform2D<T>>, WriteStorage<'system, Camera2D<T>>, ); fn run(&mut self, (size, transforms_2d, mut cameras_2d): Self::SystemData) { let screen_size_changed = if self.screen_size.is_some() { if &*size != self.screen_size.as_ref().unwrap() { self.screen_size = Some(*size); true } else { false } } else { self.screen_size = Some(*size); true }; for camera_2d in (&mut cameras_2d).join() { let is_dirty = camera_2d.is_dirty(); if screen_size_changed || is_dirty { camera_2d.update_projection(size.0, size.1); } if is_dirty { camera_2d.flag(false); } } for (transform_2d, camera_2d) in (&transforms_2d, &mut cameras_2d).join() { camera_2d.update_view(&transform_2d.0); } } } #[test] fn test_camera_system_name() { assert_eq!( Camera2DSystem::<f32>::name(), "camera_2d::camera_2d_system::Camera2DSystem<f32>" ); struct Example; assert_eq!( Camera2DSystem::<Example>::name(), "camera_2d::camera_2d_system::Camera2DSystem<camera_2d::camera_2d_system::test_camera_system_name::Example>" ); }