#Argument requires _ is borrowed for 'static + Infinite loop with "Never" return

22 messages · Page 1 of 1 (latest)

stiff rivet
#

So I have the following code: basically I'm creating a texture, creating a binder which basically holds a reference to the texture to send it to the GPU and then start the rendering loop with a "Never" return (Which is basically infinite until the program closes).

    //Load texture from path.
    let texture = Texture::from_path(window_view, Path::new("examples/draw_cube/UV_1k.jpg"));
    let mut binder = Binder::new();
    binder.set_bind(0, &texture);
    binder.set_bind(1, &BinderPart::Sampler);    

    //Create brush to draw the shapes.
    let mut brush = Brush::from_path(
        window.view(),
        Path::new("examples/shared_assets/basic.wgsl"#),
    )?;
    // Add binder information to the brush
    brush.set_binder(0, binder);
    ...
    //Setup the window render loop.
    window.run(move |wnd| {
        let mut frame = wnd.start_frame(None).expect("Issue creating frame.");
        frame.render(wnd, &mut brush, &buffer);
        frame.finish(wnd).expect("Error finishing frame.");
    });

I was expecting the render loop to move the texture ownership to the loop itself but I'm getting the following errors:

error[E0597]: `texture` does not live long enough
   --> examples\draw_cube\main.rs:110:24
    |
110 |       binder.set_bind(0, &texture);
    |                          ^^^^^^^^ borrowed value does not live long enough
...
133 | /     window.run(move |wnd| {
134 | |         let mut frame = wnd.start_frame(None).expect("Issue creating frame.");
135 | |         ...
136 | |         frame.finish(wnd).expect("Error finishing frame.");
137 | |     });
    | |______- argument requires that `texture` is borrowed for `'static`
...
141 |   }
    |   - `texture` dropped here while still borrowed

I'm not understanding ownership correctly? Do I need to hold the texture ownership in another way in order to be able to modify it inside the render loop?

Thanks!

turbid wraith
#

what does window.run expect for a type?

stiff rivet
#

Here's the fn (WindowView is a struct that holds a bunch of data related to the GPU):

    pub fn run(&mut self, func: impl FnMut(&mut WindowView) + 'static) {
        self.user_loop = Some(Box::new(func));
    }
#

I'm storing the closure to later call "window.start" which runs the closure infinitely

agile chasm
#

I think a function that never returns would have to assume the closure passed to it lives for the entire duration of the program 'static. I'm not at a computer so can't unfortunately test things out. However if you need to make texture live for 'static you can do:

Box::leak(Box::new(texture))

Which leaks the memory and gives you a static reference to the data

white spire
#

wow an actually good use of Box::leak, impressive

stiff rivet
#

For now that would work, but if later I need to load / unload textures as they are needed I would need to find another solution

agile chasm
#

Sure, in that case you could have a vec/hashmap of 'static lifetime with the textures stored inside and load/unload them as needed I would guess

turbid wraith
#

wait, why is the fn called run if it doesn't run anything? 😅

stiff rivet
stiff rivet
white spire
#

you won't be able to put things in the hashmap if someone has a reference to it

#

so just making it 'static without anything special is pointless

stiff rivet
#

What would be the solution then? I'm guessing I need some kind of "database" or struct that holds all resources like textures and meshes, but not sure how to structure it in a way the language will be happy with ownership and references

white spire
#

yeah this is a really hard problem

stiff rivet
#

Would a struct with Vec<RefCell<Asset>> work to share the references or this is not the use case for RefCell?

white spire
#

it wouldn't work because you can't get a &'static Asset from &'static Vec<RefCell<Asset>> due to how RefCell works

#

if you can fit it into a smaller lifetime maybe

#

but from what you described the event loop requires these things

#

and with how the Binder works

#

although you cannot remove elements from it