Skip to content

Commit

Permalink
Event loop
Browse files Browse the repository at this point in the history
  • Loading branch information
nanoqsh committed Jan 8, 2024
1 parent 81e90a4 commit c09d46b
Show file tree
Hide file tree
Showing 9 changed files with 208 additions and 107 deletions.
7 changes: 4 additions & 3 deletions dunge/src/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@ use {
sl::IntoModule,
state::{Render, RenderView, State},
texture::{
self, CopyBuffer, CopyBufferView, DrawTexture, Format, Make, MapResult, Mapped, Sampler,
self, CopyBuffer, CopyBufferView, DrawTexture, Filter, Format, Make, MapResult, Mapped,
Sampler,
},
Vertex,
},
Expand Down Expand Up @@ -57,8 +58,8 @@ impl Context {
texture::make(&self.0, data)
}

pub fn make_sampler(&self) -> Sampler {
Sampler::new(&self.0)
pub fn make_sampler(&self, filter: Filter) -> Sampler {
Sampler::new(&self.0, filter)
}

pub fn make_copy_buffer(&self, size: (u32, u32)) -> CopyBuffer {
Expand Down
134 changes: 134 additions & 0 deletions dunge/src/el.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
use {
crate::{
context::Context,
state::{Render, RenderView},
time::{Fps, Time},
update::Update,
window::View,
},
std::{error, fmt},
wgpu::SurfaceError,
winit::{
error::EventLoopError,
event,
event_loop::{self, EventLoop},
keyboard,
},
};

pub(crate) struct Loop(pub EventLoop<()>);

impl Loop {
#[cfg(not(target_arch = "wasm32"))]
pub fn run<U>(self, cx: Context, view: View, update: U) -> Result<(), LoopError>
where
U: Update,
{
let handler = handler(cx, view, update);
self.0.run(handler).map_err(LoopError)
}

#[cfg(target_arch = "wasm32")]
pub fn spawn<U>(self, cx: Context, view: View, update: U)
where
U: Update + 'static,
{
use winit::platform::web::EventLoopExtWebSys;

let handler = handler(cx, view, update);
self.0.spawn(handler)
}
}

#[derive(Debug)]
pub struct LoopError(EventLoopError);

impl fmt::Display for LoopError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
self.0.fmt(f)
}
}

impl error::Error for LoopError {}

type Event = event::Event<()>;
type Target = event_loop::EventLoopWindowTarget<()>;

fn handler<U>(cx: Context, mut view: View, mut update: U) -> impl FnMut(Event, &Target)
where
U: Update,
{
use {
event::{KeyEvent, StartCause, WindowEvent},
event_loop::ControlFlow,
keyboard::{KeyCode, PhysicalKey},
std::time::Duration,
};

let mut render = Render::default();
let mut time = Time::now();
let mut fps = Fps::default();
move |ev: Event, target: &Target| match ev {
Event::NewEvents(cause) => match cause {
StartCause::ResumeTimeReached { .. } => view.request_redraw(),
StartCause::WaitCancelled {
requested_resume, ..
} => {
let flow = match requested_resume {
Some(resume) => ControlFlow::WaitUntil(resume),
None => {
const WAIT_TIME: Duration = Duration::from_millis(100);

ControlFlow::wait_duration(WAIT_TIME)
}
};

target.set_control_flow(flow)
}
StartCause::Poll => {}
StartCause::Init => {}
},
Event::WindowEvent { event, window_id } if window_id == view.id() => match event {
WindowEvent::Resized(_) => view.resize(cx.state()),
WindowEvent::CloseRequested
| WindowEvent::KeyboardInput {
event:
KeyEvent {
physical_key: PhysicalKey::Code(KeyCode::Escape),
..
},
..
} => target.exit(),
WindowEvent::RedrawRequested => {
let delta_time = time.delta();
let min_delta_time = 1. / 60.;
if delta_time < min_delta_time {
let wait = Duration::from_secs_f32(min_delta_time - delta_time);
target.set_control_flow(ControlFlow::wait_duration(wait));
return;
}

time.reset();
if let Some(fps) = fps.count(delta_time) {
println!("fps: {fps}");
}

update.update();
match view.output() {
Ok(output) => {
let view = RenderView::from_output(&output);
cx.state().draw(&mut render, view, &update);
output.present();
}
Err(SurfaceError::Lost) => view.resize(cx.state()),
Err(SurfaceError::OutOfMemory) => target.exit(),
Err(err) => eprintln!("{err:?}"),
}
}
_ => {}
},
Event::Suspended => {}
Event::Resumed => view.request_redraw(),
_ => {}
}
}
2 changes: 2 additions & 0 deletions dunge/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ pub mod texture;
pub mod update;
pub mod vertex;

#[cfg(feature = "winit")]
mod el;
#[cfg(feature = "winit")]
mod time;
#[cfg(feature = "winit")]
Expand Down
26 changes: 21 additions & 5 deletions dunge/src/texture.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ use {
crate::state::State,
std::{error, fmt, future::IntoFuture, mem},
wgpu::{
Buffer, BufferAsyncError, BufferSlice, BufferView, CommandEncoder, TextureFormat,
TextureUsages, TextureView, WasmNotSend,
Buffer, BufferAsyncError, BufferSlice, BufferView, CommandEncoder, FilterMode,
TextureFormat, TextureUsages, TextureView, WasmNotSend,
},
};

Expand Down Expand Up @@ -203,16 +203,32 @@ where
})
}

#[derive(Clone, Copy)]
pub enum Filter {
Nearest,
Linear,
}

impl Filter {
pub(crate) const fn wgpu(self) -> FilterMode {
match self {
Self::Nearest => FilterMode::Nearest,
Self::Linear => FilterMode::Linear,
}
}
}

pub struct Sampler(wgpu::Sampler);

impl Sampler {
pub(crate) fn new(state: &State) -> Self {
pub(crate) fn new(state: &State, filter: Filter) -> Self {
use wgpu::*;

let inner = {
let filter = filter.wgpu();
let desc = SamplerDescriptor {
mag_filter: FilterMode::Nearest,
min_filter: FilterMode::Nearest,
mag_filter: filter,
min_filter: filter,
..Default::default()
};

Expand Down
Loading

0 comments on commit c09d46b

Please sign in to comment.