use crate::Number;
use super::Term;
struct PiecewisePair<T: Number>
{
term: Box<dyn Term<T> + Send + Sync>,
after: T
}
pub struct PiecewiseTerm<T: Number>
{
parts: Vec<PiecewisePair<T>>,
cycle: Option<T>
}
impl<T: Number> PiecewiseTerm<T>
{
pub fn new() -> PiecewiseTerm<T>
{
return PiecewiseTerm { parts: Vec::new(), cycle: None };
}
pub fn looping(c: T) -> PiecewiseTerm<T>
{
return PiecewiseTerm { parts: Vec::new(), cycle: Some(c) };
}
pub fn add_part(&mut self, term: Box<dyn Term<T> + Send + Sync>, after: T)
{
self.parts.push(PiecewisePair::<T> { term, after });
}
}
impl<T: Number> Term<T> for PiecewiseTerm<T>
{
fn evaluate(&self, time: T) -> T
{
let mut iter = self.parts.iter();
let mut current = match iter.next()
{
Some(t) => &t.term,
None => return T::zero()
};
let mut t = time;
if let Some(c) = self.cycle
{
if t > c
{
t = t % c;
}
}
for part in iter
{
if t >= part.after
{
current = &part.term;
}
else
{
return current.evaluate(t);
}
}
return current.evaluate(t);
}
}