Winit Examples outdated for use with new versions of winit / new api
Hi. I was following the basic winit example and noticed it is out of date / incompatible with new versions of winit.
I've made a new version of the minimal-example: https://github.com/allthetime/pixels-winit-minimal
Thanks! There's also #403, which should probably be reopened.
hello, thanks for the example update. I tried on my side with pixels (0.15) and I got a lifetime error
|
28 | pixels: Option<Pixels>,
| ^^^^^^ expected named lifetime parameter
|
help: consider introducing a named lifetime parameter
|
26 ~ pub struct App<'a> {
27 | window: Option<Arc<Window>>,
28 ~ pixels: Option<Pixels<'a>>,
|
For more information about this error, try `rustc --explain E0106`.
error: could not compile `mypixels` (bin "mypixels") due to 1 previous error
~~I fix it this way.~~ the fix is #403
cargo.toml
[package]
name = "mypixels"
version = "0.1.0"
edition = "2021"
[dependencies]
pixels = {version = "0.15.0"}
winit = {version ="0.30.9", features =["x11" ]}
error-iter = "0.4.1"
dotenv = "0.15.0"
main.rs
use error_iter::ErrorIter as _;
use log::error;
use pixels::{Pixels, SurfaceTexture};
use std::sync::Arc;
use winit::{
application::ApplicationHandler,
error::EventLoopError,
event::WindowEvent,
event_loop::{ControlFlow, EventLoop},
keyboard::{KeyCode, PhysicalKey},
window::{Window, WindowAttributes},
};
const WIDTH: u32 = 320;
const HEIGHT: u32 = 240;
const BOX_SIZE: i16 = 64;
struct World {
box_x: i16,
box_y: i16,
velocity_x: i16,
velocity_y: i16,
}
#[derive(Default)]
struct App {
pixels: Option<Pixels<'static>>,
window: Option<Arc<Window>>,
world: World,
}
impl ApplicationHandler for App {
fn resumed(&mut self, event_loop: &ActiveEventLoop) {
let window = {
let size = LogicalSize::new(WIDTH as f64, HEIGHT as f64);
Arc::new(
event_loop
.create_window(
Window::default_attributes()
.with_title("Hello Pixels")
.with_inner_size(size)
.with_min_inner_size(size),
)
.unwrap(),
)
};
self.window = Some(window.clone());
self.pixels = {
let window_size = window.inner_size();
let surface_texture =
SurfaceTexture::new(window_size.width, window_size.height, window.clone());
match Pixels::new(WIDTH, HEIGHT, surface_texture) {
Ok(pixels) => {
// Kick off the redraw loop
window.request_redraw();
Some(pixels)
}
Err(err) => {
log_error("pixels::new", err);
event_loop.exit();
None
}
}
};
}
fn window_event(&mut self, event_loop: &ActiveEventLoop, _id: WindowId, event: WindowEvent) {
match event {
WindowEvent::CloseRequested
| WindowEvent::KeyboardInput {
event:
KeyEvent {
logical_key: Key::Named(NamedKey::Escape),
..
},
..
} => {
event_loop.exit();
}
WindowEvent::Resized(size) => {
if let Err(err) = self
.pixels
.as_mut()
.unwrap()
.resize_surface(size.width, size.height)
{
log_error("pixels.resize_surface", err);
event_loop.exit();
}
}
WindowEvent::RedrawRequested => {
// Update internal state
self.world.update();
// Draw the current frame
self.world.draw(self.pixels.as_mut().unwrap().frame_mut());
if let Err(err) = self.pixels.as_ref().unwrap().render() {
log_error("pixels.render", err);
event_loop.exit();
} else {
// Queue a redraw for the next frame
self.window.as_ref().unwrap().request_redraw();
}
}
_ => (),
}
}
}
impl World {
fn new() -> Self {
Self {
box_x: 24,
box_y: 16,
velocity_x: 1,
velocity_y: 1,
}
}
/// Update the `World` internal state; bounce the box around the screen.
fn update(&mut self) {
if self.box_x <= 0 || self.box_x + BOX_SIZE > WIDTH as i16 {
self.velocity_x *= -1;
}
if self.box_y <= 0 || self.box_y + BOX_SIZE > HEIGHT as i16 {
self.velocity_y *= -1;
}
self.box_x += self.velocity_x;
self.box_y += self.velocity_y;
}
/// Draw the `World` state to the frame buffer.
///
/// Assumes the default texture format: `wgpu::TextureFormat::Rgba8UnormSrgb`
fn draw(&self, frame: &mut [u8]) {
for (i, pixel) in frame.chunks_exact_mut(4).enumerate() {
let x = (i % WIDTH as usize) as i16;
let y = (i / WIDTH as usize) as i16;
let inside_the_box = x >= self.box_x
&& x < self.box_x + BOX_SIZE
&& y >= self.box_y
&& y < self.box_y + BOX_SIZE;
let rgba = if inside_the_box {
[0x5e, 0x48, 0xe8, 0xff]
} else {
[0x48, 0xb2, 0xe8, 0xff]
};
pixel.copy_from_slice(&rgba);
}
}
}
//log_error and main stay the same...
Hi!
pub struct App<'a> { window: Option<Arc<Window>>, pixels: Option<Pixels<'a>>,// added lifetime here world: World, }
'a is equivalent to 'static in this example due to Pixels<'_> owning an Arc<Window> in:
let surface_texture = SurfaceTexture::new(window_width, window_height, window.clone());// clone the window here! match Pixels::new(WIDTH, HEIGHT, surface_texture) {
The link that I provided earlier already does this without introducing an unnecessary named lifetime.
my bad, didn't see the link!