-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
3f2b7ac
commit de21dc4
Showing
3 changed files
with
73 additions
and
31 deletions.
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,76 +1,100 @@ | ||
use std::num::NonZeroU32; | ||
|
||
use eyre::{format_err, Result, WrapErr}; | ||
use winit::{ | ||
dpi::PhysicalSize, | ||
event::{Event, WindowEvent}, | ||
event_loop::{ControlFlow, EventLoop}, | ||
window::Window, dpi::PhysicalSize, | ||
window::Window, | ||
}; | ||
|
||
struct State { | ||
// reverse order is important for safety (though I doubt anyone cares at exit) | ||
surface: softbuffer::Surface, | ||
context: softbuffer::Context, | ||
_context: softbuffer::Context, | ||
window: Window, | ||
} | ||
|
||
impl State { | ||
pub fn new(event_loop: &EventLoop<()>) -> Self { | ||
let window = Window::new(event_loop).unwrap(); | ||
pub fn new(event_loop: &EventLoop<()>) -> Result<Self> { | ||
let window = Window::new(event_loop).wrap_err("while creating window")?; | ||
|
||
// SAFETY: window is only dropped at the end of the struct | ||
let context = unsafe { softbuffer::Context::new(&window) }.unwrap(); | ||
let surface = unsafe { softbuffer::Surface::new(&context, &window) }.unwrap(); | ||
// can't use wrap_err since softbuffer's error is neither send nor sync | ||
let context = unsafe { softbuffer::Context::new(&window) } | ||
.map_err(|e| format_err!("while creating softbuffer context: {e}"))?; | ||
let surface = unsafe { softbuffer::Surface::new(&context, &window) } | ||
.map_err(|e| format_err!("while creating surface: {e}"))?; | ||
|
||
let mut state = Self { | ||
surface, | ||
context, | ||
_context: context, | ||
window, | ||
}; | ||
|
||
// initial resize needed for the surface to configure itself | ||
let initial_size = state.window.inner_size(); | ||
state.resize(initial_size); | ||
state.resize(initial_size)?; | ||
|
||
state | ||
Ok(state) | ||
} | ||
|
||
pub fn process(&mut self, event: Event<()>) -> ControlFlow { | ||
pub fn process(&mut self, event: Event<()>) -> Result<ControlFlow> { | ||
match event { | ||
Event::RedrawRequested(_) => self.draw(), | ||
Event::RedrawRequested(_) => self.draw()?, | ||
Event::WindowEvent { event, .. } => match event { | ||
WindowEvent::Resized(new_size) => self.resize(new_size), | ||
WindowEvent::CloseRequested => return ControlFlow::Exit, | ||
WindowEvent::Resized(new_size) => self.resize(new_size)?, | ||
WindowEvent::CloseRequested => return Ok(ControlFlow::Exit), | ||
_ => (), | ||
} | ||
}, | ||
_ => (), | ||
} | ||
|
||
ControlFlow::Wait | ||
Ok(ControlFlow::Wait) | ||
} | ||
|
||
pub fn resize(&mut self, new_size: PhysicalSize<u32>) { | ||
let (width, height) = ( | ||
NonZeroU32::new(new_size.width).unwrap(), | ||
NonZeroU32::new(new_size.height).unwrap(), | ||
); | ||
self.surface.resize(width, height).unwrap(); | ||
pub fn resize(&mut self, new_size: PhysicalSize<u32>) -> Result<()> { | ||
let Some(width) = NonZeroU32::new(new_size.width) else { | ||
// probably minimized, won't be drawn then anyway | ||
return Ok(()); | ||
}; | ||
let Some(height) = NonZeroU32::new(new_size.height) else { | ||
return Ok(()); | ||
}; | ||
|
||
self.surface | ||
.resize(width, height) | ||
.map_err(|e| format_err!("could not resize surface: {e}")) | ||
} | ||
|
||
pub fn draw(&mut self) { | ||
let mut buffer = self.surface.buffer_mut().unwrap(); | ||
pub fn draw(&mut self) -> Result<()> { | ||
let mut buffer = self | ||
.surface | ||
.buffer_mut() | ||
.map_err(|e| format_err!("could not get reference to display buffer: {e}"))?; | ||
|
||
let light_color = (255 << 16) | (255 << 8) | 255; | ||
buffer.fill(light_color); | ||
|
||
buffer.present().unwrap(); | ||
buffer | ||
.present() | ||
.map_err(|e| format_err!("could not present display buffer: {e}")) | ||
} | ||
} | ||
|
||
fn main() -> Result<(), winit::error::EventLoopError> { | ||
let event_loop = EventLoop::new().unwrap(); | ||
let mut state = State::new(&event_loop); | ||
fn main() -> Result<()> { | ||
let event_loop = EventLoop::new().wrap_err("while creating event loop")?; | ||
let mut state = State::new(&event_loop).wrap_err("while creating state")?; | ||
|
||
event_loop.run(move |event, _, flow| { | ||
*flow = state.process(event); | ||
}) | ||
event_loop | ||
.run(move |event, _, flow| { | ||
*flow = match state.process(event) { | ||
Ok(flow) => flow, | ||
Err(e) => { | ||
eprintln!("error: {e}"); | ||
ControlFlow::Exit | ||
} | ||
} | ||
}) | ||
.wrap_err("while running event loop") | ||
} |