use super::w_graphics_device::WGraphicsDevice;
use crate::{system::chrono::w_gametime::WGameTime, w_log};
use anyhow::{anyhow, Result};
use winit::{
event::*,
event_loop::{ControlFlow, EventLoop},
window::WindowBuilder,
};
pub trait IWScene {
fn load(&self, _p_g_device: &mut WGraphicsDevice) -> Result<()> {
Ok(())
}
fn render(&self, _p_g_device: &mut WGraphicsDevice, _p_gametime: &mut WGameTime) -> Result<()> {
Ok(())
}
}
pub struct WSceneManager {}
impl WSceneManager {
pub async fn run<I>(p_scene: I) -> Result<()>
where
I: IWScene + Sync + 'static,
{
const TRACE: &str = "WSceneManager::run";
#[cfg(target_arch = "wasm32")]
{
std::panic::set_hook(Box::new(console_error_panic_hook::hook));
}
let event_loop = EventLoop::new();
let window = WindowBuilder::new()
.build(&event_loop)
.map_err(|e| anyhow!("could not create window {:?}", e))?;
#[cfg(target_arch = "wasm32")]
{
use winit::dpi::PhysicalSize;
window.set_inner_size(PhysicalSize::new(960, 540));
use winit::platform::web::WindowExtWebSys;
web_sys::window()
.and_then(|win| win.document())
.and_then(|doc| {
let dst = doc.get_element_by_id("wolf")?;
let canvas = web_sys::Element::from(window.canvas());
dst.append_child(&canvas).ok()?;
Some(())
})
.expect("couldn't append canvas to document body.");
}
let mut g_device = WGraphicsDevice::new(Some(&window)).await?;
let mut game_time = WGameTime::new();
let load_res = p_scene.load(&mut g_device);
match load_res {
Ok(_) => {}
Err(e) => {
w_log!("could not load scene because {:?} trace info: {}", e, TRACE);
}
}
event_loop.run(move |event, _, control_flow| match event {
Event::WindowEvent {
ref event,
window_id,
} if window_id == window.id() => match event {
WindowEvent::CloseRequested
| WindowEvent::KeyboardInput {
input:
KeyboardInput {
state: ElementState::Pressed,
virtual_keycode: Some(VirtualKeyCode::Escape),
..
},
..
} => *control_flow = ControlFlow::Exit,
_ => {}
},
Event::RedrawRequested(window_id) if window_id == window.id() => {
game_time.tick();
let _ = p_scene.render(&mut g_device, &mut game_time);
match g_device.render() {
Ok(_) => {}
Err(wgpu::SurfaceError::Lost) => {
g_device.resize(g_device.size);
}
Err(wgpu::SurfaceError::OutOfMemory) => {
*control_flow = ControlFlow::Exit;
}
Err(e) => {
w_log!("render failed because of {:?}", e);
}
};
}
Event::RedrawEventsCleared => {
window.request_redraw();
}
_ => {}
});
}
}