pkecs 9.0.0

Another ECS implementation.
Documentation
//! Types for storing component sets.

use std::{any::Any, collections::HashMap, hash::Hash};

/// A type-erased, contiguous span of components.
pub trait ErasedComponentChannel {
    /// Upcasts [`self`] as [`Any`].
    fn as_any(&self) -> &dyn Any;

    /// Upcasts [`self`] as [`Any`].
    fn as_any_mut(&mut self) -> &mut dyn Any;
}

/// A heterogenous collection of components.
pub struct ComponentChannel<C> {
    components: Vec<C>,
}

impl<C> ComponentChannel<C> {
    /// Initializes a new, empty instance of [`self`].
    pub fn new() -> Self {
        let components = vec![];

        Self { components }
    }

    /// Initializes a new, empty instance of [`self`] within a [`Box`].
    pub fn new_box() -> Box<Self> {
        let this = Self::new();

        Box::new(this)
    }

    /// Retrieves an immutable iterator over [`self`].
    pub fn iter(&self) -> impl Iterator<Item = &C> {
        self.components.iter()
    }

    /// Retrieves a mutable iterator over [`self`].
    pub fn iter_mut(&mut self) -> impl Iterator<Item = &mut C> {
        self.components.iter_mut()
    }

    /// Adds a component onto [`self`].
    pub fn push(&mut self, component: C) {
        self.components.push(component);
    }
}

impl<C> ErasedComponentChannel for ComponentChannel<C>
    where
        C: 'static,
{
    fn as_any(&self) -> &dyn Any {
        self
    }

    fn as_any_mut(&mut self) -> &mut dyn Any {
        self
    }
}

/// An indexed map of components.
pub struct ComponentMap<K, C> {
    components: HashMap<K, C>,
}

impl<K, C> ComponentMap<K, C>
    where
        K: Eq + Hash,
{
    /// Initializes a new, empty [`ComponentMap`].
    pub fn new() -> Self {
        let components = HashMap::new();

        Self { components }
    }

    /// Initializes a new, empty instance of [`self`] in a [`Box`].
    pub fn new_box() -> Box<Self> {
        let this = Self::new();

        Box::new(this)
    }

    /// Inserts a component into [`self`].
    pub fn insert(&mut self, key: K, component: C) -> bool {
        self.components
            .insert(key, component)
            .is_some()
    }

    /// Returns an immutable reference to a component via their key.
    pub fn get(&self, key: &K) -> Option<&C> {
        self.components.get(key)
    }

    /// Returns a mutable reference to a component via their key.
    pub fn get_mut(&mut self, key: &K) -> Option<&mut C> {
        self.components.get_mut(key)
    }

    /// Returns an [`Iterator`] over all key-value pairs in [`self`].
    pub fn iter(&self) -> impl Iterator<Item = (&K, &C)> {
        self.components.iter()
    }

    /// Returns an [`Iterator`] over all key-value pairs in [`self`].
    pub fn iter_mut(&mut self) -> impl Iterator<Item = (&K, &mut C)> {
        self.components.iter_mut()
    }
}

impl<K, C> ErasedComponentChannel for ComponentMap<K, C>
    where
        K: 'static,
        C: 'static,
{
    fn as_any(&self) -> &dyn Any {
        self
    }

    fn as_any_mut(&mut self) -> &mut dyn Any {
        self
    }
}