|
1 | 1 | use std::num::NonZeroU32;
|
2 | 2 |
|
| 3 | +use eyre::{format_err, Result, WrapErr}; |
3 | 4 | use winit::{
|
| 5 | + dpi::PhysicalSize, |
4 | 6 | event::{Event, WindowEvent},
|
5 | 7 | event_loop::{ControlFlow, EventLoop},
|
6 |
| - window::Window, dpi::PhysicalSize, |
| 8 | + window::Window, |
7 | 9 | };
|
8 | 10 |
|
9 | 11 | struct State {
|
10 | 12 | // reverse order is important for safety (though I doubt anyone cares at exit)
|
11 | 13 | surface: softbuffer::Surface,
|
12 |
| - context: softbuffer::Context, |
| 14 | + _context: softbuffer::Context, |
13 | 15 | window: Window,
|
14 | 16 | }
|
15 | 17 |
|
16 | 18 | impl State {
|
17 |
| - pub fn new(event_loop: &EventLoop<()>) -> Self { |
18 |
| - let window = Window::new(event_loop).unwrap(); |
| 19 | + pub fn new(event_loop: &EventLoop<()>) -> Result<Self> { |
| 20 | + let window = Window::new(event_loop).wrap_err("while creating window")?; |
19 | 21 |
|
20 | 22 | // SAFETY: window is only dropped at the end of the struct
|
21 |
| - let context = unsafe { softbuffer::Context::new(&window) }.unwrap(); |
22 |
| - let surface = unsafe { softbuffer::Surface::new(&context, &window) }.unwrap(); |
| 23 | + // can't use wrap_err since softbuffer's error is neither send nor sync |
| 24 | + let context = unsafe { softbuffer::Context::new(&window) } |
| 25 | + .map_err(|e| format_err!("while creating softbuffer context: {e}"))?; |
| 26 | + let surface = unsafe { softbuffer::Surface::new(&context, &window) } |
| 27 | + .map_err(|e| format_err!("while creating surface: {e}"))?; |
23 | 28 |
|
24 | 29 | let mut state = Self {
|
25 | 30 | surface,
|
26 |
| - context, |
| 31 | + _context: context, |
27 | 32 | window,
|
28 | 33 | };
|
29 | 34 |
|
30 | 35 | // initial resize needed for the surface to configure itself
|
31 | 36 | let initial_size = state.window.inner_size();
|
32 |
| - state.resize(initial_size); |
| 37 | + state.resize(initial_size)?; |
33 | 38 |
|
34 |
| - state |
| 39 | + Ok(state) |
35 | 40 | }
|
36 | 41 |
|
37 |
| - pub fn process(&mut self, event: Event<()>) -> ControlFlow { |
| 42 | + pub fn process(&mut self, event: Event<()>) -> Result<ControlFlow> { |
38 | 43 | match event {
|
39 |
| - Event::RedrawRequested(_) => self.draw(), |
| 44 | + Event::RedrawRequested(_) => self.draw()?, |
40 | 45 | Event::WindowEvent { event, .. } => match event {
|
41 |
| - WindowEvent::Resized(new_size) => self.resize(new_size), |
42 |
| - WindowEvent::CloseRequested => return ControlFlow::Exit, |
| 46 | + WindowEvent::Resized(new_size) => self.resize(new_size)?, |
| 47 | + WindowEvent::CloseRequested => return Ok(ControlFlow::Exit), |
43 | 48 | _ => (),
|
44 |
| - } |
| 49 | + }, |
45 | 50 | _ => (),
|
46 | 51 | }
|
47 | 52 |
|
48 |
| - ControlFlow::Wait |
| 53 | + Ok(ControlFlow::Wait) |
49 | 54 | }
|
50 | 55 |
|
51 |
| - pub fn resize(&mut self, new_size: PhysicalSize<u32>) { |
52 |
| - let (width, height) = ( |
53 |
| - NonZeroU32::new(new_size.width).unwrap(), |
54 |
| - NonZeroU32::new(new_size.height).unwrap(), |
55 |
| - ); |
56 |
| - self.surface.resize(width, height).unwrap(); |
| 56 | + pub fn resize(&mut self, new_size: PhysicalSize<u32>) -> Result<()> { |
| 57 | + let Some(width) = NonZeroU32::new(new_size.width) else { |
| 58 | + // probably minimized, won't be drawn then anyway |
| 59 | + return Ok(()); |
| 60 | + }; |
| 61 | + let Some(height) = NonZeroU32::new(new_size.height) else { |
| 62 | + return Ok(()); |
| 63 | + }; |
| 64 | + |
| 65 | + self.surface |
| 66 | + .resize(width, height) |
| 67 | + .map_err(|e| format_err!("could not resize surface: {e}")) |
57 | 68 | }
|
58 | 69 |
|
59 |
| - pub fn draw(&mut self) { |
60 |
| - let mut buffer = self.surface.buffer_mut().unwrap(); |
| 70 | + pub fn draw(&mut self) -> Result<()> { |
| 71 | + let mut buffer = self |
| 72 | + .surface |
| 73 | + .buffer_mut() |
| 74 | + .map_err(|e| format_err!("could not get reference to display buffer: {e}"))?; |
61 | 75 |
|
62 | 76 | let light_color = (255 << 16) | (255 << 8) | 255;
|
63 | 77 | buffer.fill(light_color);
|
64 | 78 |
|
65 |
| - buffer.present().unwrap(); |
| 79 | + buffer |
| 80 | + .present() |
| 81 | + .map_err(|e| format_err!("could not present display buffer: {e}")) |
66 | 82 | }
|
67 | 83 | }
|
68 | 84 |
|
69 |
| -fn main() -> Result<(), winit::error::EventLoopError> { |
70 |
| - let event_loop = EventLoop::new().unwrap(); |
71 |
| - let mut state = State::new(&event_loop); |
| 85 | +fn main() -> Result<()> { |
| 86 | + let event_loop = EventLoop::new().wrap_err("while creating event loop")?; |
| 87 | + let mut state = State::new(&event_loop).wrap_err("while creating state")?; |
72 | 88 |
|
73 |
| - event_loop.run(move |event, _, flow| { |
74 |
| - *flow = state.process(event); |
75 |
| - }) |
| 89 | + event_loop |
| 90 | + .run(move |event, _, flow| { |
| 91 | + *flow = match state.process(event) { |
| 92 | + Ok(flow) => flow, |
| 93 | + Err(e) => { |
| 94 | + eprintln!("error: {e}"); |
| 95 | + ControlFlow::Exit |
| 96 | + } |
| 97 | + } |
| 98 | + }) |
| 99 | + .wrap_err("while running event loop") |
76 | 100 | }
|
0 commit comments