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 100 101 102 103 104 105 106
use std::cmp::Ordering; use std::marker::PhantomData; use num_traits::Float; use specs::{Entities, Entity, Join, System, Write, WriteStorage}; use type_name; use super::{Sprite, SpriteGuide}; pub struct SpriteSystem<T, I> { swap: Vec<Entity>, _marker: PhantomData<(T, I)>, } impl<T, I> SpriteSystem<T, I> { #[inline] pub fn name() -> &'static str { type_name::get::<Self>() } } impl<T, I> SpriteSystem<T, I> where T: 'static + Float + Send + Sync, I: 'static + Send + Sync, { #[inline(always)] pub fn new() -> Self { SpriteSystem { swap: Vec::new(), _marker: PhantomData, } } } impl<T, I> Default for SpriteSystem<T, I> where T: 'static + Float + Send + Sync, I: 'static + Send + Sync, { #[inline(always)] fn default() -> Self { Self::new() } } impl<'a, T, I> System<'a> for SpriteSystem<T, I> where T: 'static + Float + Send + Sync, I: 'static + Send + Sync, { type SystemData = ( Entities<'a>, Write<'a, SpriteGuide<T>>, WriteStorage<'a, Sprite<T, I>>, ); #[inline] fn run(&mut self, (entities, mut sprite_guide, sprites): Self::SystemData) { let mut needs_sort = false; for (entity, sprite) in (&*entities, &sprites).join() { if sprite.is_dirty() { sprite.flag(false); needs_sort = true; } self.swap.push(entity); } if needs_sort { sprite_guide.swap(&mut self.swap); sprite_guide.as_slice_mut().sort_by(|a, b| { if let Some(a) = sprites.get(*a) { if let Some(b) = sprites.get(*b) { if a.layer() == b.layer() { a.z().cmp(b.z()) } else { a.layer().cmp(b.layer()) } } else { Ordering::Equal } } else { Ordering::Equal } }); } self.swap.clear(); } } #[test] fn test_sprite_system_name() { assert_eq!( SpriteSystem::<f32, Option<usize>>::name(), "sprite_system::SpriteSystem<f32, std::option::Option<usize>>" ); struct Example; assert_eq!( SpriteSystem::<Example, usize>::name(), "sprite_system::SpriteSystem<sprite_system::test_sprite_system_name::Example, usize>" ); }