gmt_dos-actors 10.1.2

Giant Magellan Telescope Dynamic Optical Simulation Actor Model
Documentation
use std::marker::PhantomData;
use std::{
    fmt::Display,
    ops::{Deref, DerefMut},
};

use crate::framework::model::{Check, Task};
use crate::{actor::Actor, framework::model::SystemFlowChart};

mod implementations;
mod interfaces;

pub use interfaces::{System, SystemInput, SystemOutput};

pub enum New {}
pub enum Built {}

pub struct Sys<T: System, S = Built> {
    sys: T,
    state: PhantomData<S>,
}

impl<T: System, S> Clone for Sys<T, S> {
    fn clone(&self) -> Self {
        let mut sys = self.sys.clone();
        sys.build().unwrap();
        Self {
            sys,
            state: PhantomData,
        }
    }
}

impl<T: System> Deref for Sys<T> {
    type Target = T;

    fn deref(&self) -> &Self::Target {
        &self.sys
    }
}

impl<T: System> DerefMut for Sys<T> {
    fn deref_mut(&mut self) -> &mut Self::Target {
        &mut self.sys
    }
}
impl<T: System> Sys<T, New> {
    pub fn new(sys: T) -> Self {
        Self {
            sys,
            state: PhantomData,
        }
    }

    pub fn build(self) -> anyhow::Result<Sys<T>> {
        let mut this: Sys<T> = Sys {
            sys: self.sys,
            state: PhantomData,
        };
        this.sys.build()?;
        Ok(this)
    }
}
impl<T: System + SystemFlowChart> Sys<T> {
    pub fn flowchart(self) -> Self {
        self.sys.flowchart();
        self
    }
    pub fn sys_flowchart(&self) {
        self.sys.flowchart();
    }
}

impl<T: System> Display for Sys<T> {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        write!(f, "{}", self.sys)
    }
}

impl<'a, T: System> IntoIterator for &'a Sys<T>
where
    &'a T: IntoIterator<
        Item = Box<&'a dyn Check>,
        IntoIter = std::vec::IntoIter<<&'a T as IntoIterator>::Item>,
    >,
{
    type Item = Box<&'a dyn Check>;

    type IntoIter = std::vec::IntoIter<Self::Item>;

    fn into_iter(self) -> Self::IntoIter {
        self.sys.into_iter()
    }
}

impl<T: System> IntoIterator for Box<Sys<T>>
where
    Box<T>: IntoIterator<
        Item = Box<dyn Task>,
        IntoIter = std::vec::IntoIter<<Box<T> as IntoIterator>::Item>,
    >,
{
    type Item = Box<dyn Task>;

    type IntoIter = std::vec::IntoIter<Self::Item>;

    fn into_iter(self) -> Self::IntoIter {
        let q = *self;
        let w = q.sys;
        let b = Box::new(w);
        b.into_iter()
    }
}

impl<
        T: System + SystemInput<C, NI, NO>,
        C: interface::Update,
        const NI: usize,
        const NO: usize,
    > SystemInput<C, NI, NO> for Sys<T>
{
    fn input(&mut self) -> &mut Actor<C, NI, NO> {
        self.sys.input()
    }
}

impl<
        T: System + SystemOutput<C, NI, NO>,
        C: interface::Update,
        const NI: usize,
        const NO: usize,
    > SystemOutput<C, NI, NO> for Sys<T>
{
    fn output(&mut self) -> &mut Actor<C, NI, NO> {
        self.sys.output()
    }
}