Hello
This code just want to implement a basic time-function generator
type sound = f64;
struct Ugen<T>
where T : Fn(f64) -> sound,
{
time: f64,
handler: T
}
impl<T> Ugen<T>
where T : Fn(f64) -> sound,
{
pub fn new(handler: T) -> Self { Ugen{time: 0.0, handler} }
}
impl<T> Iterator for Ugen<T>
where T : Fn(f64) -> sound,
{
type Item = sound;
fn next(&mut self) -> Option<Self::Item> {
self.time += 0.1;
Some((self.handler)(self.time))
}
}
That is the basic implementation.
It just acts like a sinus generator if created like
let i = Ugen::new(|time| -> sound { time.sin() });
Now, i would like to implement a + overloading, to simulate something like
Sin(x) + Sin(y),
I was thinking doing something like
fn add(self, rhs:Ugen<U>) -> Self::Output { Ugen::new(|time| { self.next().unwrap() + rhs.next().unwrap()}) }
The problem is, if I understand correctly, I have to specify 3 differents traits, two for the inputs and one for the output, like the used closures are not exactly the same type (like variables bindings etc.)
I could not achieve this because I would need to bind a new generic trait in the output type of the Add trait, and it seems impossible
Any help greatly wanted !
impl<T, U> std::ops::Add<Ugen<U>> for Ugen<T> where
T : Fn(f64) -> sound,
U : Fn(f64) -> sound,
{
type Output = Ugen<UKN_TRAIT>; // here is the problem, since i can not declare it in the trait impl def
fn add(self, rhs:Ugen<U>) -> Self::Output
{
Ugen::new(|time| { self.next().unwrap() + rhs.next().unwrap()})
}
}