use async_trait::async_trait;
use log::info;
use std::fmt::Debug;
use std::sync::Arc;
use swamp_render::Render;
use swamp_wgpu_window::WgpuWindow;
use swamp_window::AppHandler;
use winit::dpi;
use winit::window::Window;
pub trait Application: Debug {
fn init(&mut self, render: &mut Render);
fn tick(&mut self);
fn render(&mut self, render: &mut Render);
fn virtual_surface_size(&self) -> (u16, u16);
fn physical_surface_size(&self) -> (u16, u16);
}
#[derive(Debug)]
pub struct App<'a> {
main_render: Option<Render>,
wgpu_window: Option<WgpuWindow<'a>>,
app: &'a mut dyn Application,
}
#[async_trait(?Send)]
impl<'a> AppHandler for App<'a> {
fn create_window(&mut self, window: Arc<Window>) {
info!("create window!");
let physical_size = window.inner_size();
let virtual_size = self.app.virtual_surface_size();
let wgpu_window = pollster::block_on(WgpuWindow::new(window)).expect("REASON");
self.main_render = Some(Render::new(
Arc::clone(wgpu_window.device()),
Arc::clone(wgpu_window.queue()),
wgpu_window.surface_config().format,
(physical_size.width as u16, physical_size.height as u16),
virtual_size,
));
self.wgpu_window = Some(wgpu_window);
self.app.init(self.main_render.as_mut().unwrap())
}
fn resized(&mut self, physical_size: dpi::PhysicalSize<u32>) {
info!("resized! (physical_size: {:?})", physical_size);
self.wgpu_window.as_mut().unwrap().resize(physical_size);
self.main_render
.as_mut()
.unwrap()
.resize((physical_size.width as u16, physical_size.height as u16));
}
fn min_size(&self) -> (u16, u16) {
self.app.virtual_surface_size()
}
fn start_size(&self) -> (u16, u16) {
self.app.physical_surface_size()
}
fn redraw(&mut self) {
let main_render = self.main_render.as_mut().expect("REASON");
self.app.tick(); self.app.render(main_render);
self.wgpu_window
.as_mut()
.unwrap()
.render(main_render.clear_color(), |render_pass, _, _| {
main_render.render(render_pass)
})
.expect("TODO: panic message");
}
}
impl<'a> App<'a> {
pub fn run(application: &'a mut impl Application, title: &str) {
let mut app = Self {
main_render: None,
app: application,
wgpu_window: None,
};
let _ = swamp_window::WindowRunner::run_app(&mut app, title);
}
}