use std::sync::{Arc, Mutex};
pub use wgpu;
pub use winit;
use winit::event_loop::ControlFlow;
mod app_handler;
pub mod asset_management;
pub mod events;
pub mod math;
pub mod rendering;
pub mod window;
static QUIT: Mutex<bool> = Mutex::new(false);
#[derive(Debug, Clone)]
pub struct RenderSettings {
pub vsync: bool,
pub required_features: wgpu::Features,
pub max_framerate: Option<u16>,
}
impl Default for RenderSettings {
fn default() -> Self {
Self {
vsync: true,
required_features: wgpu::Features::empty(),
max_framerate: None,
}
}
}
pub fn request_quit() {
let mut quit = QUIT.lock().unwrap();
*quit = true;
}
pub struct EventLoop<'a> {
handle: winit::event_loop::EventLoop<()>,
windows: Vec<Arc<Mutex<window::Window<'a>>>>,
pub(crate) render_settings: RenderSettings,
}
impl<'a> EventLoop<'a> {
pub fn new(
render_settings: RenderSettings,
) -> Result<EventLoop<'a>, winit::error::EventLoopError> {
let event_loop = winit::event_loop::EventLoop::new()?;
event_loop.set_control_flow(ControlFlow::Wait);
Ok(EventLoop {
handle: event_loop,
windows: Vec::new(),
render_settings,
})
}
pub fn get_event_loop(&self) -> &winit::event_loop::EventLoop<()> {
&self.handle
}
pub async fn run(self) {
let instance = wgpu::Instance::default();
let adapter = instance
.request_adapter(&wgpu::RequestAdapterOptions {
power_preference: wgpu::PowerPreference::HighPerformance,
force_fallback_adapter: false,
compatible_surface: None,
})
.await;
let adapter = match adapter {
Ok(adapter) => adapter,
Err(e) => {
eprintln!(
"No suitable adapter found, taika will now exit. Error:\n{}",
e
);
return;
}
};
let (device, queue) = adapter
.request_device(&wgpu::DeviceDescriptor {
label: None,
required_features: self.render_settings.required_features,
required_limits: wgpu::Limits::downlevel_defaults()
.using_resolution(adapter.limits()),
memory_hints: wgpu::MemoryHints::Performance,
trace: wgpu::Trace::Off,
})
.await
.expect("Failed to create device");
let windows = self.windows.clone();
let device = Arc::new(Mutex::new(device));
let queue = Arc::new(Mutex::new(queue));
let mut state = app_handler::AppState {
device,
queue,
windows,
adapter,
instance,
render_settings: self.render_settings.clone(),
};
self.handle.run_app(&mut state).unwrap()
}
}