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
use alloc::string::String;

use core::intrinsics;
use core::marker::PhantomData;

use specs::{World, DispatcherBuilder};
use specs_bundler::{SpecsBundle, Result};
use number_traits::Float;

use super::{
    Init, Child,
    LocalTransform2D, Transform2D,
    LocalTransform3D, Transform3D,
    TransformSystem, TransformGuide
};

pub struct TransformBundle<T> {
    _marker: PhantomData<T>,
}

impl<T> TransformBundle<T> {
    #[inline]
    pub fn system_name() -> String {
        let type_name = unsafe {
            intrinsics::type_name::<T>().replace("::", "_")
        };
        let mut name = String::from("transform_system");

        if !type_name.is_empty() {
            name.push('_');
            name.push_str(&type_name);
        }

        name
    }
}

impl<'a, 'b, T> SpecsBundle<'a, 'b> for TransformBundle<T>
    where T: 'static + Sync + Send + Copy + Float,
{
    type Args = ();

    #[inline]
    fn build(
        world: &mut World,
        dispatch_builder: DispatcherBuilder<'a, 'b>,
        _: Self::Args
    ) -> Result<DispatcherBuilder<'a, 'b>> {

        world.register::<Child>();
        world.register::<Init>();

        world.register::<LocalTransform3D<T>>();
        world.register::<Transform3D<T>>();

        world.register::<LocalTransform2D<T>>();
        world.register::<Transform2D<T>>();

        world.add_resource(TransformGuide::new());

        Ok(dispatch_builder.add(TransformSystem::<T>::new(), &Self::system_name(), &[]))
    }
}


#[test]
fn test_transform_system_name() {
    assert_eq!(
        TransformBundle::<f32>::system_name(),
        "transform_system_f32"
    );

    struct Example;
    assert_eq!(
        TransformBundle::<Example>::system_name(),
        "transform_system_transform_bundle_test_transform_system_name_Example"
    );
}