gpt4 book ai didi

rust - 如何获得rust-sdl2窗口表面并同时使用事件迭代器?

转载 作者:行者123 更新时间:2023-12-03 11:42:50 27 4
gpt4 key购买 nike

sdl2::video::Window::surface需要对事件泵的可变引用,但是当我遍历sdl2::EventPump::wait_iter()给定的事件时,事件泵被阻止了。
重现步骤:
创建一个新的 cargo 项目:

$ cargo new foo
$ cd foo
$ echo 'sdl2 = "0.34.3"' >> Cargo.toml
用以下命令替换src/main.rs:
extern crate sdl2; 

use sdl2::event::Event;
use sdl2::event::EventType;

pub fn main() {
let sdl_context = sdl2::init().unwrap();
let video_subsystem = sdl_context.video().unwrap();
let window = video_subsystem.window("foo", 600, 600).build().unwrap();
let mut event_pump = sdl_context.event_pump().unwrap();
for event in event_pump.wait_iter() {
let mut wsuf = window.surface(&event_pump).unwrap();
}
}
不使用迭代器是一种解决方法。因此,这个main.rs会做同样的事情,但是这个会编译:
use sdl2::event::Event;
use sdl2::event::EventType;

pub fn main() {
let sdl_context = sdl2::init().unwrap();
let video_subsystem = sdl_context.video().unwrap();
let window = video_subsystem.window("foo", 600, 600).build().unwrap();
let mut event_pump = sdl_context.event_pump().unwrap();
loop {
let event = event_pump.wait_event();
let mut wsuf = window.surface(&event_pump).unwrap();
}
}
这感觉不那么惯用了。
我看不出 sdl2::video::Window::surface借用事件泵的原因,尤其是在函数忽略该参数的情况下。 Take a look at the sdl2::video::Window::surface source code

最佳答案

此函数的文档未提及此神秘论点,因此我将进行有根据的猜测。
首先,查看函数 Window::surface declaration:

pub fn surface<'a>(&'a self, _e: &'a EventPump) -> Result<WindowSurfaceRef<'a>, String>
并注意在参数和返回的 'a中都使用了生存期 WindowSurfaceRef<'a>。因此,只要返回的值存在,就将借用 selfEventPump
看一下代码,它是 native SDL2-sys函数 SDL_GetWindowSurface()的简单包装,因此我们可以看一下它的 documentation:

A new surface will be created with the optimal format for the window, if necessary. This surface will be freed when the window is destroyed. Do not free this surface.

This surface will be invalidated if the window is resized. After resizing a window this function must be called again to return a valid surface.

You may not combine this with 3D or the rendering API on this window.


关键字是粗体字。如果调整了窗口的大小,则此窗口将无效,这可能应解释为“如果调整窗口的大小然后使用此表面,则会导致未定义的行为”。
为了使此包装器使用rust 安全,您必须避免在返回的 WindowSurfaceRef的生命周期内调整大小。这是通过借用 EventPump来实现的:在借用 EventPump时,无法处理任何消息,并且不会调整窗口的大小。
请注意,要借用 EventPump,您实际上不需要保留对其的引用,只需保留其生存期即可。通过返回 WindowSurfaceRef<'a>,可以保留借用期限为 'a的任何内容。
关于文档的最后一段,关于不在该窗口上使用渲染API,是通过类似的方式实现的,方法是也保持借用的 Window和相同的生存期 'a

关于rust - 如何获得rust-sdl2窗口表面并同时使用事件迭代器?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63814662/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com