nya-ecs 0.2.0

nya entity component system
Documentation
//! Components
use crate::{Any, TypeId};

/// A component that can be attached to an entity in a [crate::World]
pub trait Component: Send + Sync + 'static {}

/// [Box] wrapper for [Component]s
pub type ComponentBox = Box<dyn Any + Send + Sync + 'static>;

/// An identifier for a component
#[derive(Clone, PartialEq, Eq, Hash)]
pub struct ComponentKey {
    type_id: TypeId,
}

impl ComponentKey {
    /// Get the component key of a type
    pub fn of<T: Component>() -> Self {
        Self {
            type_id: TypeId::of::<T>(),
        }
    }

    /// Get a component key from a value
    pub fn from_value<T: Component>(value: &T) -> Self {
        Self {
            type_id: value.type_id(),
        }
    }
}

/// Get the [ComponentKey] of a component type, can accept either a type or an expression
#[macro_export]
macro_rules! component_id {
    ($type: ty) => {
        $crate::ComponentKey::of::<$type>()
    };

    ($value: expr) => {
        $crate::ComponentKey::from_value($value)
    };
}

/// Implement [Component] for `type`
#[macro_export]
macro_rules! component {
    ($type: ty) => {
        impl $crate::Component for $type {}
    };
}

/// A bundle of components
pub trait Bundle {
    /// Convert into a vector of [ComponentBox]
    fn into_boxes(self) -> Vec<(ComponentKey, ComponentBox)>;
}

impl<T: Component> Bundle for T {
    fn into_boxes(self) -> Vec<(ComponentKey, ComponentBox)> {
        vec![(ComponentKey::of::<Self>(), Box::new(self))]
    }
}

macro_rules! bundle_tuple_impl {
    ($($key: tt => $name: ident),*) => {
        impl<$($name: $crate::Component),*> Bundle for ($($name,)*) {
            fn into_boxes(self) -> Vec<(ComponentKey, ComponentBox)> {
                vec![
                    $((ComponentKey::of::<$name>(), Box::new(self.$key))),*
                ]
            }
        }
    }
}

bundle_tuple_impl!(0 => A);
bundle_tuple_impl!(0 => A, 1 => B);
bundle_tuple_impl!(0 => A, 1 => B, 2 => C);
bundle_tuple_impl!(0 => A, 1 => B, 2 => C, 3 => D);
bundle_tuple_impl!(0 => A, 1 => B, 2 => C, 3 => D, 4 => E);
bundle_tuple_impl!(0 => A, 1 => B, 2 => C, 3 => D, 4 => E, 5 => F);
bundle_tuple_impl!(0 => A, 1 => B, 2 => C, 3 => D, 4 => E, 5 => F, 6 => G);
bundle_tuple_impl!(0 => A, 1 => B, 2 => C, 3 => D, 4 => E, 5 => F, 6 => G, 7 => H);
bundle_tuple_impl!(0 => A, 1 => B, 2 => C, 3 => D, 4 => E, 5 => F, 6 => G, 7 => H, 8 => I);
bundle_tuple_impl!(0 => A, 1 => B, 2 => C, 3 => D, 4 => E, 5 => F, 6 => G, 7 => H, 8 => I, 9 => J);
bundle_tuple_impl!(0 => A, 1 => B, 2 => C, 3 => D, 4 => E, 5 => F, 6 => G, 7 => H, 8 => I, 9 => J, 10 => K);
bundle_tuple_impl!(0 => A, 1 => B, 2 => C, 3 => D, 4 => E, 5 => F, 6 => G, 7 => H, 8 => I, 9 => J, 10 => K, 11 => L);
bundle_tuple_impl!(0 => A, 1 => B, 2 => C, 3 => D, 4 => E, 5 => F, 6 => G, 7 => H, 8 => I, 9 => J, 10 => K, 11 => L, 12 => M);
bundle_tuple_impl!(0 => A, 1 => B, 2 => C, 3 => D, 4 => E, 5 => F, 6 => G, 7 => H, 8 => I, 9 => J, 10 => K, 11 => L, 12 => M, 13 => N);
bundle_tuple_impl!(0 => A, 1 => B, 2 => C, 3 => D, 4 => E, 5 => F, 6 => G, 7 => H, 8 => I, 9 => J, 10 => K, 11 => L, 12 => M, 13 => N, 14 => O);