use super::WindowContext;
use crate::ecs::world::World;
use crate::state::State;
use winit::event_loop::{ControlFlow, EventLoop};
use winit::platform::pump_events::{EventLoopExtPumpEvents, PumpStatus};
pub struct PumpShell {
event_loop: EventLoop<()>,
pub context: WindowContext,
}
pub fn pump_shell_new(state: Box<dyn State>) -> Result<PumpShell, Box<dyn std::error::Error>> {
tracing_subscriber::fmt().try_init().ok();
let event_loop = EventLoop::builder().build()?;
event_loop.set_control_flow(ControlFlow::Poll);
let context = WindowContext {
state,
world: World::default(),
renderer: None,
snapshot_path: None,
snapshot_queued: false,
#[cfg(all(not(target_os = "android"), feature = "core"))]
accesskit: None,
initialized: false,
};
Ok(PumpShell {
event_loop,
context,
})
}
pub fn pump_shell_ready(shell: &PumpShell) -> bool {
shell.context.initialized && shell.context.renderer.is_some()
}
pub fn pump_frame(shell: &mut PumpShell) -> bool {
let status = shell
.event_loop
.pump_app_events(Some(std::time::Duration::ZERO), &mut shell.context);
if matches!(status, PumpStatus::Exit(_)) {
return false;
}
let renderable = shell.context.renderer.is_some()
&& shell
.context
.world
.resources
.window
.handle
.as_ref()
.is_some_and(|handle| {
let size = handle.inner_size();
size.width > 0 && size.height > 0
});
if !renderable {
std::thread::sleep(std::time::Duration::from_millis(1));
}
true
}