use std::fmt::Debug;
use thiserror;
use winit;
pub struct EventLoop<T: Default + 'static, E: Clone + Debug> {
event_loop: winit::event_loop::EventLoop<T>,
error: Result<(), EventLoopError<E>>,
}
impl<E: Clone + Debug> EventLoop<(), E> {
pub fn new() -> Result<Self, winit::error::EventLoopError> {
let event_loop = winit::event_loop::EventLoop::new()?;
Ok(Self {
event_loop,
error: Ok(()),
})
}
}
impl<T: Default + 'static, E: Clone + Debug> EventLoop<T, E> {
pub fn from_builder(
builder: &mut winit::event_loop::EventLoopBuilder<T>,
) -> Result<Self, winit::error::EventLoopError> {
let event_loop = builder.build()?;
Ok(Self {
event_loop,
error: Ok(()),
})
}
pub fn get_event_loop(&self) -> &winit::event_loop::EventLoop<T> {
&self.event_loop
}
pub fn run<F>(mut self, mut event_handlers: Vec<F>) -> Result<(), EventLoopError<E>>
where
F: FnMut(
&mut winit::event::Event<T>,
&winit::event_loop::EventLoopWindowTarget<T>,
) -> Result<bool, E>,
{
self.event_loop.run(|mut event, window_target| {
for event_handler in event_handlers.iter_mut() {
match event_handler(&mut event, window_target) {
Ok(captured) => {
if captured {
break;
}
}
Err(error) => {
self.error = Err(EventLoopError::Custom(error));
break;
}
}
}
})?;
self.error
}
}
#[derive(thiserror::Error, Debug, Clone)]
pub enum EventLoopError<E: Clone + Debug> {
#[error("An error occured during the winit event loop: {:?}", .0)]
Winit(String),
#[error("An user error has occured: {:?}", .0)]
Custom(E),
}
impl<E: Clone + Debug> From<winit::error::EventLoopError> for EventLoopError<E> {
fn from(err: winit::error::EventLoopError) -> EventLoopError<E> {
EventLoopError::Winit(err.to_string())
}
}