首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >winit铁锈箱上的小包装纸

winit铁锈箱上的小包装纸
EN

Stack Overflow用户
提问于 2021-04-27 23:24:22
回答 1查看 117关注 0票数 0

我有下面的代码,我尝试在winit板条箱上创建一个翘曲。我想包装winit,因为我希望将来能够用最少的工作替换它。

代码无法编译,但我想不出一种方法来使它工作。如果有人对如何保持我的设计有一些建议,但同时包装winit请让我知道。

谢谢!

main.rs

代码语言:javascript
复制
use crate::events::WindowResizeEvent;
use crate::window::Window;
use crate::window::WindowProps;

mod events;
mod window;

fn main() {
    let props = WindowProps {
        title: "Foo".to_string(),
        width: 1024,
        height: (1024.0 * 16.0 / 9.0) as usize,
    };

    let mut main_window = Window::new(props);

    main_window.set_on_window_resize(|event: WindowResizeEvent| {
        println!("{}", event);
    });

    main_window.run();
}

events.rs

代码语言:javascript
复制
use std::fmt::{Display, Formatter};

pub struct WindowResizeEvent {
    width: u32,
    height: u32,
}

impl Display for WindowResizeEvent {
    fn fmt(&self, fmt: &mut Formatter<'_>) -> Result<(), std::fmt::Error> {
        fmt.write_fmt(format_args!(
            "WindowResizeEvent[width = {}, height = {}]",
            self.width, self.height
        ))
    }
}

pub struct WindowCloseEvent;

impl Display for WindowCloseEvent {
    fn fmt(&self, fmt: &mut Formatter<'_>) -> Result<(), std::fmt::Error> {
        fmt.write_str("WindowCloseEvent")
    }
}

最后是window.rs

代码语言:javascript
复制
use winit::{
    dpi::LogicalSize,
    event::{Event, WindowEvent},
    event_loop::{ControlFlow, EventLoop},
    window::WindowBuilder,
};

use crate::events::{WindowCloseEvent, WindowResizeEvent};

pub struct WindowProps {
    pub title: String,
    pub width: usize,
    pub height: usize,
}

pub struct Window {
    event_loop: EventLoop<()>,
    window: winit::window::Window,

    on_window_resize: Option<fn(WindowResizeEvent)>,
    on_window_close: Option<fn(WindowCloseEvent)>,
}

impl Window {
    pub fn new(props: WindowProps) -> Self {
        let event_loop = EventLoop::with_user_event();

        let window = WindowBuilder::new()
            .with_visible(false)
            .with_title(&props.title)
            .with_inner_size(LogicalSize::new(props.width as f32, props.height as f32))
            .build(&event_loop)
            .expect("Unable to create window");

        Self {
            event_loop,
            window,
            on_window_resize: None,
            on_window_close: None,
        }
    }

    pub fn set_on_window_resize(&mut self, f: fn(WindowResizeEvent)) {
        self.on_window_resize = Some(f);
    }

    pub fn run(&self) {
        self.event_loop
            .run(move |event, _, control_flow| match event {
                Event::WindowEvent { event, .. } => match event {
                    WindowEvent::Resized(physical_size) => {
                        if let Some(on_window_resize) = self.on_window_resize.clone() {
                            on_window_resize(WindowResizeEvent {
                                width: physical_size.width,
                                height: physical_size.height,
                            });
                        }
                    }
                    WindowEvent::CloseRequested => {
                        if let Some(on_window_close) = self.on_window_close.clone() {
                            on_window_close(WindowCloseEvent);
                        }

                        *control_flow = ControlFlow::Exit;
                    }
                    _ => (),
                },

                _ => (),
            });
    }
}

我想要winit上的抽象层,因为我更喜欢它,也许在某个时候我想用其他东西替换winit,我不想改变所有可能使用窗口的地方。

现在,当我试图编译它时,我得到了这个错误,并且我找不到一种方法来使它工作:

代码语言:javascript
复制
error[E0759]: `self` has an anonymous lifetime `'_` but it needs to satisfy a `'static` lifetime requirement
  --> ghost-sandbox/src/window.rs:49:18
   |
47 |       pub fn run(&self) {
   |                  ----- this data with an anonymous lifetime `'_`...
48 |           self.event_loop
49 |               .run(move |event, _, control_flow| match event {
   |  __________________^
50 | |                 Event::WindowEvent { event, .. } => match event {
51 | |                     WindowEvent::Resized(physical_size) => {
52 | |                         if let Some(on_window_resize) = self.on_window_resize.clone() {
...  |
69 | |                 _ => (),
70 | |             });
   | |_____________^ ...is captured here...
   |
note: ...and is required to live as long as `'static` here
  --> ghost-sandbox/src/window.rs:49:14
   |
49 |             .run(move |event, _, control_flow| match event {
   |              ^^^

error: aborting due to previous error

For more information about this error, try `rustc --explain E0759`.
error: could not compile `ghost-sandbox`
EN

回答 1

Stack Overflow用户

发布于 2021-04-28 00:34:45

看起来您正在尝试将self移动到一个要求所有捕获的引用都在'static生命周期内(即直到程序结束)的function中。

您可以通过将self by value传递给Window::run()函数来解决此问题,或者通过向Window::run()函数添加'static注释来确保self一直存在到程序结束。

代码语言:javascript
复制
pub fn run(&'static self) { ...

但是,如果您使用'static生存期选项,则可能会遇到另一个错误,因为run要求EventLoop对象按值传递。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/67286017

复制
相关文章

相似问题

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