簡體   English   中英

如何修改由 Rust 閉包捕獲的變量?

[英]How can I modify a variable captured by a Rust closure?

我正在嘗試為 Rust 應用程序制作 GUI,看起來對我來說效果很好的是imgui-rs 我想要做的就是從用戶那里獲取一些輸入值,然后 output 是一個不斷變化的 png。 我在啟動樣板時遇到了一些麻煩,但是提供的存儲庫的支持代碼足以讓我讓 hello world 演示工作,但是當我嘗試修改它以獲取輸入和更改顯示時,我遇到了所有權問題。 我現在要做的是讓用戶輸入圖像名稱,然后打開該文件並將其顯示在 GUI 中。

這是我現在擁有的(不包括上面鏈接的支持代碼):

struct State {
    path: ImString,
    has_image: bool,
}
impl Default for State {
    fn default() -> Self {
        Self {
            path: ImString::with_capacity(128),
            has_image: false,
        }
    }
}
fn main() {
    let mut system = imgui_support::init(file!()); // this is from support code
    let mut state = State::default();

    system.main_loop(move |_, ui| {
        Window::new(im_str!("hello world"))
            .size([330.0, 110.0], imgui::Condition::FirstUseEver)
            .position([0f32, 0f32], imgui::Condition::FirstUseEver)
            .build(ui, || {
                ui.input_text(im_str!("File path"), &mut state.path).build();
                if ui.small_button(im_str!("Submit file")) {
                    system.add_img(state.path.to_str()); // try to open file and parse as texture
                }
                ui.separator();
            });
        if state.has_image {
            Window::new(im_str!("Render:"))
                .size([720f32, 720f32], imgui::Condition::FirstUseEver)
                .build(ui, || {
                    imgui::Image::new(TextureId::new(0), [720f32, 720f32]).build(ui);
                });
        }
    });
}

add_img function,我作為System結構上的一個方法添加,定義為:

    pub fn add_img(&mut self, path: &str) -> TextureId {
        let textures: &mut Textures<Texture> = &mut self.renderer.textures();
        let res_img = image::open(path);
        match res_img {
            Ok(image) => {
                let image = image.to_rgba8();
                let dimensions = image.dimensions();
                let texture = RawImage2d::from_raw_rgba(image.into_raw(), dimensions);
                let gl_texture = Texture2d::new(self.display.get_context(), texture).unwrap();
                let texture = imgui_glium_renderer::Texture {
                    texture: Rc::new(gl_texture),
                    sampler: SamplerBehavior {
                        magnify_filter: MagnifySamplerFilter::Linear,
                        minify_filter: MinifySamplerFilter::Linear,
                        ..Default::default()
                    },
                };
                textures.insert(texture)
            }
            Err(_) => TextureId::new(usize::MAX),
        }
    }

現在,我得到了use of moved value system無論我如何嘗試排列數據,我似乎都無法避免移動后使用錯誤。

有沒有更好的方法來組織我的代碼,或者可能是一個不太健壯的 Rust GUI 庫,因為我不需要 99% 的 imgui 功能?

問題是,方法main_loop取得了system的所有權。 之后系統將永遠無法使用。

一個快速的解決方法是更新方法main_loop以將rendererdisplay傳遞給閉包。 像這樣的東西:

pub fn main_loop<F>(self, mut run_ui: F)
where F: FnMut(&mut bool, &mut Ui, &mut Renderer, &mut glium::Display) + 'static {}

然后在調用run_ui時只需添加渲染器並顯示。

run_ui(&mut run, &mut ui, &mut renderer, &mut display);

方法add_img應該是獨立的 function 和渲染器和顯示分開,不依賴於 System.

pub fn add_img(path: &str, renderer: &mut Renderer, display: &mut glium::Display) -> TextureId {}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM