use crate::component::Component;
use proc_macro2::TokenStream as TokenStream2;
use quote::quote;
mod components;
mod coupling;
pub use components::Components;
pub use coupling::Couplings;
pub struct Coupled {
pub components: Components,
pub couplings: Option<Couplings>,
}
impl Coupled {
pub fn quote(&self, component: &Component) -> TokenStream2 {
let coupled_ident = &component.ident;
let component = self.components.ident();
let (eoc, xic) = if let Some(couplings) = &self.couplings {
couplings.quote()
} else {
(vec![], vec![])
};
quote! {
unsafe impl xdevs::traits::AbstractSimulator for #coupled_ident {
#[inline]
fn start(&mut self, t_start: f64) -> f64 {
xdevs::traits::Component::set_t_last(self, t_start);
let mut t_next = f64::INFINITY;
#(t_next = f64::min(t_next, xdevs::traits::AbstractSimulator::start(&mut self.#component, t_start));)*
xdevs::traits::Component::set_t_next(self, t_next);
t_next
}
#[inline]
fn stop(&mut self, t_stop: f64) {
#(xdevs::traits::AbstractSimulator::stop(&mut self.#component, t_stop);)*
xdevs::traits::Component::set_t_last(self, t_stop);
xdevs::traits::Component::set_t_next(self, f64::INFINITY);
}
#[inline]
fn lambda(&mut self, t: f64) {
if t >= xdevs::traits::Component::get_t_next(self) {
#(xdevs::traits::AbstractSimulator::lambda(&mut self.#component, t);)*
#(#eoc);*
}
}
#[inline]
fn delta(&mut self, t: f64) -> f64 {
#(#xic);*
let mut t_next = f64::INFINITY;
#(t_next = f64::min(t_next, xdevs::traits::AbstractSimulator::delta(&mut self.#component, t));)*
xdevs::traits::Component::clear_output(self);
xdevs::traits::Component::clear_input(self);
xdevs::traits::Component::set_t_last(self, t);
xdevs::traits::Component::set_t_next(self, t_next);
t_next
}
}
}
}
}