use std::{cell::Cell, collections::HashMap};

use crate::{
    ability::{Abilities, Ability},
    scaler::ID,
};
use enum_dispatch::enum_dispatch;

/// 实体列表
pub type EntityContainer = HashMap<ID, Cell<Abilities>>;

/// 系统
/// 一个系统处理一种Ability
#[enum_dispatch]
pub trait System {
    /// 获取实体列表
    /// 实体列表本身不可变，使用内部可变借用Cell
    fn entities(&self) -> &EntityContainer;

    //TODO: 考虑使用Rayon并发计算
    /// 对全部实体调用tick
    fn tick_all(&self) -> () {
        let _ = self // 对自身的不可变借用
            .entities()
            .values()
            .map(|ent| -> () {
                let new_ent = ent.get().tick(&self.entities());
                ent.set(new_ent);
            });
    }
}

///在这里注册新的系统，实现静态分发
#[enum_dispatch(System)]
pub enum Systems {
    Velocity,
}

// 速度系统
pub struct Velocity {
    pub entities: EntityContainer,
}
impl Velocity {
    pub fn new() -> Self {
        Velocity {
            entities: HashMap::new(),
        }
    }
}
impl System for Velocity {
    #[doc = " 获取实体列表"]
    #[doc = " 实体列表本身不可变，使用内部可变借用Cell"]
    fn entities(&self) -> &EntityContainer {
        &self.entities
    }
}
