首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何修改由Rust闭包捕获的变量?

如何修改由Rust闭包捕获的变量?
EN

Stack Overflow用户
提问于 2021-03-18 09:41:02
回答 1查看 154关注 0票数 0

我正在尝试为一个Rust应用程序做一个图形用户界面,看起来对我来说效果很好的是imgui-rs。我想要做的就是从用户那里获得一些输入值,并输出一个不断变化的png。我在启动样板文件时遇到了一些麻烦,但是提供的存储库有足够好的support code,足以让我的hello world演示程序工作,但当我尝试修改它以获取输入和更改显示时,我遇到了所有权问题。我现在要做的是让用户输入一个图像名称,然后打开该文件并在GUI中显示它。

这是我现在所拥有的(不包括上面链接的支持代码):

代码语言:javascript
复制
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);
                });
        }
    });
}

我在System结构上作为方法添加的add_img函数的定义如下:

代码语言:javascript
复制
    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特性?

EN

Stack Overflow用户

回答已采纳

发布于 2021-03-18 10:16:18

问题是,main_loop方法取得了system的所有权。系统将永远不会对您可用。

一种快速的解决方法是更新方法main_loop,将rendererdisplay传递给闭包。如下所示:

代码语言:javascript
复制
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时,只需添加渲染器和显示即可。

代码语言:javascript
复制
run_ui(&mut run, &mut ui, &mut renderer, &mut display);

方法add_img应该成为一个独立的函数,并将渲染器和显示器分开,而不依赖于系统。

代码语言:javascript
复制
pub fn add_img(path: &str, renderer: &mut Renderer, display: &mut glium::Display) -> TextureId {}
票数 2
EN
查看全部 1 条回答
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/66683624

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档