[STATE] Update
This commit is contained in:
parent
ebb5ac8fae
commit
2039b4b543
3 changed files with 37 additions and 101 deletions
|
@ -1,93 +0,0 @@
|
||||||
use winit::{
|
|
||||||
event::{ElementState, Event, KeyboardInput, VirtualKeyCode, WindowEvent},
|
|
||||||
event_loop::{ControlFlow, EventLoop},
|
|
||||||
window::Window,
|
|
||||||
};
|
|
||||||
|
|
||||||
pub struct Display {
|
|
||||||
window: Window,
|
|
||||||
event_loop: EventLoop<()>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Display {
|
|
||||||
pub async fn init(title: &str) -> Self {
|
|
||||||
cfg_if::cfg_if! {
|
|
||||||
if #[cfg(target_arch = "wasm32")] {
|
|
||||||
std::panic::set_hook(Box::new(console_error_panic_hook::hook));
|
|
||||||
console_log::init_with_level(log::Level::Info).expect("Could't initialize logger");
|
|
||||||
} else {
|
|
||||||
env_logger::init();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let event_loop = EventLoop::new();
|
|
||||||
let window = winit::window::WindowBuilder::new()
|
|
||||||
.with_title(title)
|
|
||||||
.build(&event_loop)
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
#[cfg(target_arch = "wasm32")]
|
|
||||||
{
|
|
||||||
// Winit prevents sizing with CSS, so we have to set
|
|
||||||
// the size manually when on web.
|
|
||||||
use winit::dpi::PhysicalSize;
|
|
||||||
window.set_inner_size(PhysicalSize::new(450, 400));
|
|
||||||
|
|
||||||
use winit::platform::web::WindowExtWebSys;
|
|
||||||
web_sys::window()
|
|
||||||
.and_then(|win| win.document())
|
|
||||||
.and_then(|doc| {
|
|
||||||
let dst = doc.get_element_by_id("wasm-example")?;
|
|
||||||
let canvas = web_sys::Element::from(window.canvas());
|
|
||||||
dst.append_child(&canvas).ok()?;
|
|
||||||
Some(())
|
|
||||||
})
|
|
||||||
.expect("Couldn't append canvas to document body.");
|
|
||||||
}
|
|
||||||
|
|
||||||
Self { window, event_loop }
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn run(self) {
|
|
||||||
// let mut last_render_time = instant::Instant::now();
|
|
||||||
self.event_loop.run(move |event, _, control_flow| {
|
|
||||||
*control_flow = ControlFlow::Poll;
|
|
||||||
match event {
|
|
||||||
Event::MainEventsCleared => self.window.request_redraw(),
|
|
||||||
Event::WindowEvent {
|
|
||||||
ref event,
|
|
||||||
window_id,
|
|
||||||
} if window_id == self.window.id() => match event {
|
|
||||||
#[cfg(not(target_arch = "wasm32"))]
|
|
||||||
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 == self.window.id() => {
|
|
||||||
// let now = instant::Instant::now();
|
|
||||||
// let dt = now - last_render_time;
|
|
||||||
// last_render_time = now;
|
|
||||||
// state.update(dt);
|
|
||||||
// match state.render() {
|
|
||||||
// Ok(_) => {}
|
|
||||||
// // Reconfigure the surface if it's lost or outdated
|
|
||||||
// Err(wgpu::SurfaceError::Lost | wgpu::SurfaceError::Outdated) => state.resize(state.size),
|
|
||||||
// // The system is out of memory, we should probably quit
|
|
||||||
// Err(wgpu::SurfaceError::OutOfMemory) => *control_flow = ControlFlow::Exit,
|
|
||||||
// // We're ignoring timeouts
|
|
||||||
// Err(wgpu::SurfaceError::Timeout) => log::warn!("Surface timeout"),
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
_ => {}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,4 +1,13 @@
|
||||||
mod renderer;
|
mod renderer;
|
||||||
mod display;
|
|
||||||
|
|
||||||
pub use renderer::Renderer;
|
pub use renderer::Renderer;
|
||||||
|
use wgpu::{TextureView, CommandEncoder};
|
||||||
|
use winit::event::WindowEvent;
|
||||||
|
|
||||||
|
pub trait State {
|
||||||
|
fn new(renderer: &Renderer) -> Self where Self: Sized;
|
||||||
|
fn resize(&mut self, new_size: winit::dpi::PhysicalSize<u32>);
|
||||||
|
fn input(&mut self, event: &WindowEvent) -> bool;
|
||||||
|
fn update(&mut self, dt: instant::Duration);
|
||||||
|
fn render(&mut self, view: &TextureView, encoder: &mut CommandEncoder) -> Result<(), wgpu::SurfaceError>;
|
||||||
|
}
|
|
@ -2,16 +2,19 @@ use std::iter;
|
||||||
|
|
||||||
use winit::{event::WindowEvent, window::Window};
|
use winit::{event::WindowEvent, window::Window};
|
||||||
|
|
||||||
|
use super::State;
|
||||||
|
|
||||||
pub struct Renderer {
|
pub struct Renderer {
|
||||||
surface: wgpu::Surface,
|
surface: wgpu::Surface,
|
||||||
device: wgpu::Device,
|
device: wgpu::Device,
|
||||||
queue: wgpu::Queue,
|
queue: wgpu::Queue,
|
||||||
size: winit::dpi::PhysicalSize<u32>,
|
size: winit::dpi::PhysicalSize<u32>,
|
||||||
config: wgpu::SurfaceConfiguration,
|
config: wgpu::SurfaceConfiguration,
|
||||||
|
state: Option<Box<dyn State>>
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Renderer {
|
impl Renderer {
|
||||||
async fn new(window: &Window) -> Self {
|
pub async fn new(window: &Window) -> Self {
|
||||||
let size = window.inner_size();
|
let size = window.inner_size();
|
||||||
|
|
||||||
// The instance is a handle to our GPU
|
// The instance is a handle to our GPU
|
||||||
|
@ -60,27 +63,37 @@ impl Renderer {
|
||||||
queue,
|
queue,
|
||||||
config,
|
config,
|
||||||
size,
|
size,
|
||||||
|
state: None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn resize(&mut self, new_size: winit::dpi::PhysicalSize<u32>) {
|
pub fn resize(&mut self, new_size: winit::dpi::PhysicalSize<u32>) {
|
||||||
if new_size.width > 0 && new_size.height > 0 {
|
if new_size.width > 0 && new_size.height > 0 {
|
||||||
self.size = new_size;
|
self.size = new_size;
|
||||||
self.config.width = new_size.width;
|
self.config.width = new_size.width;
|
||||||
self.config.height = new_size.height;
|
self.config.height = new_size.height;
|
||||||
self.surface.configure(&self.device, &self.config);
|
self.surface.configure(&self.device, &self.config);
|
||||||
|
|
||||||
|
if let Some(state) = self.state.as_mut() {
|
||||||
|
state.resize(new_size);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn input(&mut self, event: &WindowEvent) -> bool {
|
pub fn input(&mut self, event: &WindowEvent) -> bool {
|
||||||
|
if let Some(state) = self.state.as_mut() {
|
||||||
|
return state.input(event);
|
||||||
|
}
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
|
|
||||||
fn update(&mut self, dt: instant::Duration) {
|
pub fn update(&mut self, dt: instant::Duration) {
|
||||||
|
if let Some(state) = self.state.as_mut() {
|
||||||
|
state.update(dt);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn render(&mut self) -> Result<(), wgpu::SurfaceError> {
|
pub fn render(&mut self) -> Result<(), wgpu::SurfaceError> {
|
||||||
let output = self.surface.get_current_texture()?;
|
let output = self.surface.get_current_texture()?;
|
||||||
let view = output
|
let view = output
|
||||||
.texture
|
.texture
|
||||||
|
@ -92,10 +105,17 @@ impl Renderer {
|
||||||
label: Some("Render Encoder"),
|
label: Some("Render Encoder"),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if let Some(state) = self.state.as_mut() {
|
||||||
|
state.render(&view, &mut encoder)?;
|
||||||
|
}
|
||||||
|
|
||||||
self.queue.submit(iter::once(encoder.finish()));
|
self.queue.submit(iter::once(encoder.finish()));
|
||||||
output.present();
|
output.present();
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn set_state(&mut self, state: Option<Box<dyn State>>) {
|
||||||
|
self.state = state;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue