specs_transform 0.5.0

transform 2d and 3d component for specs
#![feature(test)]

extern crate test;

extern crate num_traits;
extern crate specs;
extern crate specs_bundler;
extern crate specs_transform;

use std::marker::PhantomData;
use test::Bencher;

use num_traits::Float;
use specs::{WorldExt,Builder, DispatcherBuilder, Join, System, World, WriteStorage};
use specs_bundler::Bundler;
use specs_transform::{Parent, Transform2D, Transform3D, TransformBundle, TransformSystem};

pub struct AddOneSystem<T>(PhantomData<T>);

impl<T> AddOneSystem<T> {
    #[inline(always)]
    pub fn new() -> Self {
        AddOneSystem(PhantomData)
    }
}

impl<'system, T> System<'system> for AddOneSystem<T>
where
    T: 'static + Sync + Send + Copy + Float,
{
    type SystemData = (
        WriteStorage<'system, Transform2D<T>>,
        WriteStorage<'system, Transform3D<T>>,
    );

    fn run(&mut self, (mut locals_2d, mut locals_3d): Self::SystemData) {
        for local in (&mut locals_2d).join() {
            local.position[0] = local.position[0] + T::one();
            local.position[1] = local.position[1] + T::one();
        }
        for local in (&mut locals_3d).join() {
            local.position[0] = local.position[0] + T::one();
            local.position[1] = local.position[1] + T::one();
            local.position[2] = local.position[2] + T::one();
        }
    }
}

#[bench]
fn bench_stress(b: &mut Bencher) {
    let mut world = World::new();

    let mut dispatcher = Bundler::new(&mut world, DispatcherBuilder::new())
        .bundle(TransformBundle::<f32>::default())
        .unwrap()
        .with(
            AddOneSystem::<f32>::new(),
            "add_one_system",
            &[TransformSystem::<f32>::name()],
        )
        .build();

    for _ in 0..1000 {
        let parent = world
            .create_entity()
            .with(Transform3D::<f32>::default())
            .build();

        let child = world
            .create_entity()
            .with(Parent::new(parent))
            .with(Transform2D::<f32>::default())
            .build();

        let _ = world
            .create_entity()
            .with(Parent::new(child))
            .with(Transform3D::<f32>::default())
            .build();
    }

    b.iter(move || {
        for _ in 0..60 {
            dispatcher.dispatch(&mut world);
        }
    });
}