//! Provides APIs to schedule/manage systems.

use std::{any::TypeId, collections::HashMap};
use super::{system::System, world::World};

/// Contains systems which can be executed at set intervals.
#[derive(Default)]
pub struct Schedule {
    systems: HashMap<TypeId, Vec<Box<dyn System>>>,
}

impl Schedule {
    /// Registers a [`System`] to run at the specified [`SystemSchedule`].
    pub fn add_system<TSchedule, TSystem>(&mut self, _: TSchedule, system: TSystem)
        where
            TSchedule: 'static,
            TSystem: System + 'static,
    {
        let id = TypeId::of::<TSchedule>();

        self.systems
            .entry(id)
            .or_insert(vec![])
            .push(Box::new(system));
    }

    pub fn run_schedule<TSchedule>(&self, _: TSchedule, world: &mut World)
        where
            TSchedule: 'static,
    {
        let id = TypeId::of::<TSchedule>();

        self.systems
            .get(&id)
            .map(|s| s.iter().for_each(|s| s.run(world)));
    }
}
