closures in rust like in high-level language

61 Views Asked by At

I'm new to Rust and low-level programming. I'm making simple games with sdl2. My project architecture looks like:

main.rs

void main() -> Result((), String) {
  let mut window = CWindow::new("Playground", 1080, 720);

  let rects: Vec<Rect> = ... // Data I want to have in `update`

  window.set_update(|| update(rects)); // trying wrap my update so I can pass `rects`. THE PROBLEM IS HERE
  window.set_draw(draw);
  window.init()?;
}

fn draw(canvas: &mut Canvas<Window>) -> () {
  //some draw
}

fn update(Vec<Rect>) -> () {
  //some update
}

cwindow.rs

pub struct CWindow {
    title: String,
    width: u32,
    height: u32,
    callbacks: CWindowCallbacks,
    window: Option<Window>,
}

pub struct CWindowCallbacks {
    update: Option<fn() -> ()>,
    draw: Option<fn(&mut Canvas<Window>) -> ()>,
}

impl CWindow {
    pub fn new(title: &str, width: u32, height: u32) -> CWindow {
        CWindow {
            title: String::from(title),
            width: width,
            height: height,
            callbacks: CWindowCallbacks {
                draw: None,
                update: None,
            },
            window: None,
        }
    }

    pub fn init(&self) -> Result<(), String> {
        if self.callbacks.draw.is_none() {
            panic!("Need draw callback")
        }
        if self.callbacks.update.is_none() {
            panic!("Need update callback")
        }
        //...
        //sdl init stuff
        //...


        'running: loop {
             
            //...
            //handling events
            //...

            self.callbacks.update.unwrap()();
            self.callbacks.draw.unwrap()(&mut canvas);
        }
        Ok(())
    }

    pub fn set_draw(&mut self, draw: fn(&mut Canvas<Window>) -> ()) {
        self.callbacks.draw = Some(draw);
    }

    pub fn set_update(&mut self, update: fn() -> ()) {
        self.callbacks.update = Some(update);
    }
}

And rust-analyzer says:

mismatched types
expected fn pointer `fn()`
      found closure `{closure@src\main.rs:15:23: 15:25}`

How can I wrap my update so I can pass data in?

1

There are 1 best solutions below

1
KoalaMaybe On

Although fn and Fn look similar, they are not the same.

The traits Fn, FnMut, and FnOnce all represent closures while fn represents a function pointer.

Rust by Example has some really good info on closures