Search code examples
rustclosuresownershiprust-crates

Can't use struct after its partially moved by closure


I'm trying to code a wrapper struct around the creation of an event_loop and a graphical context:

struct GraphicalContext {
    pub el: crow::glutin::event_loop::EventLoop<()>,
    pub ctx: crow::Context
}

impl GraphicalContext {
    pub fn new(wb: WindowBuilder) -> Result<GraphicalContext, Box<dyn Error>> {
        let el = EventLoop::new();
        let ctx = Context::new(wb, &el)?;
        Ok( GraphicalContext { el, ctx } )
    }
}

fn main() {
    let window_bld = crow::glutin::window::WindowBuilder::new();
    let mut gc = GraphicalContext::new(window_bld).unwrap();
    let mut screen_texture: Option<crow::Texture> = None;
    gc.el.run(move |event, _, control_flow| {
        match event {
            ...
            Event::RedrawRequested(..) => {
                Some(t) => {
                    let mut surface = gc.ctx.surface();
                    gc.ctx.draw(&mut surface, &t, (0, 0), &DrawConfig::default());
                    gc.ctx.present(surface).unwrap(); // swap back-buffer
                },
                None => ()
            }
        }
    }

}

Problem is that the compiler complains that gc has been partially moved when gc.el.run() is called. It tells me it's because run() takes ownership of self but in this case, self is just gc.el, but I can't use gc.ctx inside the closure. At first I thought it was because the closure used move, however, removing it didn't fix the problem and gave me another error. Is there any way I can go around this?


Solution

  • What you want is to destructure your structure to get its parts, so that you can move only one of them to the closure:

    let GraphicalContext { el, ctx } = gc;
    el.run(move |event, _, control_flow| {
        // use ctx
    });