use bevy_app::{App, AppExit, Plugin, PluginsState}; use config::WindowConfig; use raw_handle::{DisplayHandleWrapper, EventLoopProxyWrapper, WindowWrapper}; use state::WindowState; use winit::event_loop::EventLoop; pub mod config; pub mod raw_handle; pub mod state; #[derive(Debug, thiserror::Error)] pub enum WindowError { #[error("Failed to create event loop")] FailedToCreateEventLoop, } pub struct WindowPlugin { pub window_config: WindowConfig, } impl Plugin for WindowPlugin { fn build(&self, app: &mut App) { let world = app.world_mut(); world.insert_resource(self.window_config.clone()); let mut event_loop_builder = EventLoop::with_user_event(); let event_loop = event_loop_builder .build() .map_err(|_| WindowError::FailedToCreateEventLoop) .expect("Failed to create event loop"); world.insert_resource(DisplayHandleWrapper(event_loop.owned_display_handle())); app.set_runner(Box::new(move |app| runner(app, event_loop))); } } fn runner(mut app: App, event_loop: EventLoop<()>) -> AppExit { if app.plugins_state() == PluginsState::Ready { app.finish(); app.cleanup(); } app.world_mut() .insert_resource(EventLoopProxyWrapper::new(event_loop.create_proxy())); let mut window_state = WindowState::new(app); match event_loop.run_app(&mut window_state) { Ok(_) => AppExit::Success, Err(e) => { log::error!("Error running window state: {e}"); AppExit::error() } } }