#Trying to put code into closures causes lifetime issues

10 messages · Page 1 of 1 (latest)

low sail
#

Helloo, I'm trying to make a simple visualiser in wgpu and currently to render I have a function that takes in a function for how to handle the renderpass

pub struct Graphics {
    window: Window,
    instance: wgpu::Instance,
    surface: wgpu::Surface,
    device: wgpu::Device,
    queue: wgpu::Queue,
    config: wgpu::SurfaceConfiguration,
}

impl Graphics {
  ...
  fn render<F: FnOnce(&mut Self, wgpu::RenderPass)>(&mut self, f: F) {
        let output = self.surface.get_current_texture().unwrap();
        let view = output.texture.create_view(
            &wgpu::TextureViewDescriptor::default());
        let mut encoder = self.device.create_command_encoder(
            &wgpu::CommandEncoderDescriptor {
                label: Some("Render Encoder")
            });
        {
            let mut render_pass = encoder.begin_render_pass(&wgpu::RenderPassDescriptor {
                label: Some("Render Pass"),
                color_attachments: &[Some(wgpu::RenderPassColorAttachment {
                    view: &view,
                    resolve_target: None,
                    ops: wgpu::Operations {
                        load: wgpu::LoadOp::Clear(wgpu::Color {
                            r: 0.1,
                            g: 0.2,
                            b: 0.3,
                            a: 1.0,
                        }),
                        store: true,
                    },
                })],
                depth_stencil_attachment: None,
            });

            f(self, render_pass);
        }
        self.queue.submit(iter::once(encoder.finish()));
        output.present();
    }
}
#

I then use the function like so:

    event_loop.run(move |event, _, control_flow| {
        imgui_state.platform.handle_event(imgui_state.context.io_mut(), &graphics.window, &event);
        if graphics.input(&event) { return; }
        match event {
            Event::WindowEvent { ref event, .. } if event.eq(&WindowEvent::CloseRequested) => {
                *control_flow = ControlFlow::Exit;
            }
            Event::RedrawRequested(window_id) if window_id == graphics.window.id() => {
                graphics.render(|mut graphics, mut renderpass| {
                    imgui_state.prepare_frame(&mut graphics);
                    let ui = imgui_state.context.new_frame();
                    ui.show_demo_window(&mut true);
                    imgui_state.renderer.render(
                        imgui_state.context.render(),
                    &graphics.queue, &graphics.device, &mut renderpass).unwrap();
                });
            }
            Event::MainEventsCleared => {
                graphics.window.request_redraw();
            }
            _ => {}
        }
    });
#

I don't understand where this error comes from as putting the code in the closure directly into the render method compiles fine

#

(I also have to make graphics an argument because using it directly in the closure also causes an error, is there a way around that?)

rigid gazelle
#

RenderPass has a lifetime parameter, which you are not specifying

#

the lifetime of the render pass you are passing to f is going to be shorter than the call to render

#

so you have to say that f is okay with any lifetime

#
  fn render<F: for<'a> FnOnce(&mut Self, wgpu::RenderPass<'a>)>(&mut self, f: F) {
#

I'm not sure if further changes might be needed or not, but that should help