use std::ops::Deref;
use codegen::impl_save_tuples;
use crate::{
schematic::{HasNestedView, NestedInstance, NestedView, Schematic},
simulation::{Analysis, SimulationContext, Simulator},
types::schematic::{IoTerminalBundle, NestedNode},
};
#[derive(Debug, Clone, Copy)]
pub struct SaveOutput;
#[derive(Debug, Clone, Copy)]
pub struct SaveTime;
#[derive(Debug, Clone, Copy)]
pub struct SaveFreq;
impl HasNestedView for SaveOutput {
type NestedView = SaveOutput;
fn nested_view(&self, _parent: &substrate::schematic::InstancePath) -> Self::NestedView {
*self
}
}
impl HasNestedView for SaveTime {
type NestedView = SaveTime;
fn nested_view(&self, _parent: &substrate::schematic::InstancePath) -> Self::NestedView {
*self
}
}
pub type SaveKey<T, S, A> = <T as Save<S, A>>::SaveKey;
pub type Saved<T, S, A> = <T as Save<S, A>>::Saved;
pub trait Save<S: Simulator, A: Analysis> {
type SaveKey;
type Saved;
fn save(
&self,
ctx: &SimulationContext<S>,
opts: &mut <S as Simulator>::Options,
) -> <Self as Save<S, A>>::SaveKey;
fn from_saved(
output: &<A as Analysis>::Output,
key: &<Self as Save<S, A>>::SaveKey,
) -> <Self as Save<S, A>>::Saved;
}
impl_save_tuples! {64, NestedNode}
#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)]
pub struct NestedInstanceOutput<D, I> {
data: D,
io: I,
}
impl<D, I> Deref for NestedInstanceOutput<D, I> {
type Target = D;
fn deref(&self) -> &Self::Target {
&self.data
}
}
impl<D, I> NestedInstanceOutput<D, I> {
pub fn io(&self) -> &I {
&self.io
}
pub fn data(&self) -> &D {
&self.data
}
}
impl<S: Simulator, A: Analysis> Save<S, A> for () {
type SaveKey = ();
type Saved = ();
fn save(
&self,
_ctx: &SimulationContext<S>,
_opts: &mut <S as Simulator>::Options,
) -> <Self as Save<S, A>>::SaveKey {
}
fn from_saved(
_output: &<A as Analysis>::Output,
_key: &<Self as Save<S, A>>::SaveKey,
) -> <Self as Save<S, A>>::Saved {
}
}
impl<T, S, A> Save<S, A> for NestedInstance<T>
where
T: Schematic,
S: Simulator,
A: Analysis,
NestedView<T::NestedData>: Save<S, A>,
NestedView<IoTerminalBundle<T>>: Save<S, A>,
{
type SaveKey = (
<NestedView<T::NestedData> as Save<S, A>>::SaveKey,
<NestedView<IoTerminalBundle<T>> as Save<S, A>>::SaveKey,
);
type Saved = NestedInstanceOutput<
<NestedView<T::NestedData> as Save<S, A>>::Saved,
<NestedView<IoTerminalBundle<T>> as Save<S, A>>::Saved,
>;
fn save(
&self,
ctx: &SimulationContext<S>,
opts: &mut <S as Simulator>::Options,
) -> <Self as Save<S, A>>::SaveKey {
let data = self.data().save(ctx, opts);
let io = self.io().save(ctx, opts);
(data, io)
}
fn from_saved(
output: &<A as Analysis>::Output,
key: &<Self as Save<S, A>>::SaveKey,
) -> <Self as Save<S, A>>::Saved {
NestedInstanceOutput {
data: <NestedView<T::NestedData> as Save<S, A>>::from_saved(output, &key.0),
io: <NestedView<IoTerminalBundle<T>> as Save<S, A>>::from_saved(output, &key.1),
}
}
}