Hello. I have a problem with Rust closures, namely holding them inside a struct.
I am writing a library to draw on an analog oscilloscope screen using a Raspberry Pi Pico (thumbv6m-none-eabi
). I have the following struct for drawing a path defined by a parametric equation:
pub struct ParametricPath<F>
where F: Fn(f32) -> (f32, f32) {
t_0: f32,
t_step: f32,
t_1: f32,
us: u32,
function: F,
}
which while drawing calls the function
to calculate consecutive points of the curve (performance sensitive).
This all works beautifully when i simply create a ParametricPath
object:
let mut u = 0.;
loop {
let lissajous = ParametricPath::new(0., 0.04, 2. * PI, 0, |t| {
(3.* libm::sinf(t), 3. * libm::sinf(2. * t))
});
display.draw(&lissajous);
u += 0.05;
}
produces a beautiful spinning Lissajous curve.
The problem arises when I want to create a method to create a circle (ParametricPath::circle
), like this:
pub fn circle(o: (f32, f32), r: f32, t_step: f32, us: u32) -> Self {
let f = |t| {
let (y, x) = libm::sincosf(t);
(r * (x - o.0), r * (y - o.1))
};
Self {
t_0: 0.,
t_step,
t_1: 2. * PI,
us,
function: f,
}
}
The compiler complains that he "expected type parameter F
: found closure {closure@src/drawable/parametric_path.rs:33:17: 33:20}
". I don't fully understand why passing in a closure while creating Lissajous figures worked, whereas here I receive an error.
Is there a way to overcome this error? Keep in mind this is a #![no_std]
environment, I would really like to avoid Box<dyn Fn ...>
, it requires me to bring in an allocator, and I don't like the performance overhead introduced by dynamic dispatch.
Thank you in advance for your help