drain all accumulated events in the channel per frame (#15)

This commit is contained in:
Akash Shakdwipeea
2025-10-23 21:02:06 +05:30
committed by GitHub
parent b295c0bf0b
commit 8addf60eea
2 changed files with 74 additions and 15 deletions
+36
View File
@@ -1,4 +1,6 @@
use core::fmt; use core::fmt;
use std::sync::mpsc::TryRecvError;
use std::cell::BorrowMutError;
#[derive(Debug)] #[derive(Debug)]
pub enum WindowEvent { pub enum WindowEvent {
@@ -111,3 +113,37 @@ impl KeyboardMessage {
} }
} }
} }
#[derive(Debug)]
pub enum DrainEventError {
BorrowError(BorrowMutError),
ChannelDisconnected,
ChannelEmpty,
}
impl fmt::Display for DrainEventError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
DrainEventError::BorrowError(err) => write!(f, "Failed to borrow renderer: {}", err),
DrainEventError::ChannelDisconnected => write!(f, "Event channel disconnected"),
DrainEventError::ChannelEmpty => write!(f, "Event channel empty"),
}
}
}
impl std::error::Error for DrainEventError {}
impl From<TryRecvError> for DrainEventError {
fn from(err: TryRecvError) -> Self {
match err {
TryRecvError::Empty => DrainEventError::ChannelEmpty,
TryRecvError::Disconnected => DrainEventError::ChannelDisconnected,
}
}
}
impl From<BorrowMutError> for DrainEventError {
fn from(err: BorrowMutError) -> Self {
DrainEventError::BorrowError(err)
}
}
+36 -13
View File
@@ -1,4 +1,10 @@
use std::{cell::RefCell, collections::HashMap, marker::PhantomData, rc::Rc, sync::mpsc::Receiver}; use std::{
cell::RefCell,
collections::HashMap,
marker::PhantomData,
rc::Rc,
sync::mpsc::Receiver,
};
use futures::channel::oneshot; use futures::channel::oneshot;
use log::info; use log::info;
@@ -9,7 +15,7 @@ use web_sys::{DedicatedWorkerGlobalScope, File, MessageEvent};
use crate::{ use crate::{
gltf::{load_gltf_model, ImportError, ModelBounds}, gltf::{load_gltf_model, ImportError, ModelBounds},
message::{MouseMessage, ResizeMessage, WindowEvent}, message::{DrainEventError, MouseMessage, ResizeMessage, WindowEvent},
renderer::scene::Scene, renderer::scene::Scene,
}; };
@@ -561,6 +567,8 @@ impl<T: Scene + 'static> Renderer<T> {
} }
WindowEvent::PointerClick(msg) => { WindowEvent::PointerClick(msg) => {
{ {
log::info!("click start");
let mut r = renderer.borrow_mut(); let mut r = renderer.borrow_mut();
let x = (msg.offset_x * msg.scale_factor) as f32; let x = (msg.offset_x * msg.scale_factor) as f32;
let y = (msg.offset_y * msg.scale_factor) as f32; let y = (msg.offset_y * msg.scale_factor) as f32;
@@ -603,18 +611,34 @@ impl<T: Scene + 'static> Renderer<T> {
} }
} }
pub fn run_render_loop(renderer: Rc<RefCell<Renderer<T>>>) { fn drain_events(renderer: &Rc<RefCell<Self>>) -> Result<(), DrainEventError> {
let render_frame: Closure<dyn FnMut(f32)> = Closure::new(move |time: f32| { loop {
{ let event = renderer.try_borrow_mut()?
if let Ok(r) = renderer.try_borrow_mut() { .events_chan.try_recv()?;
let event = r.events_chan.try_recv();
if let Ok(event) = event {
let renderer_clone = renderer.clone(); let renderer_clone = renderer.clone();
spawn_local(async move { spawn_local(async move {
Self::handle_event(renderer_clone, event).await; Self::handle_event(renderer_clone, event).await;
}); });
} }
} }
pub fn run_render_loop(renderer: Rc<RefCell<Renderer<T>>>) {
let render_frame: Closure<dyn FnMut(f32)> = Closure::new(move |time: f32| {
{
if let Err(e) = Self::drain_events(&renderer) {
match e {
DrainEventError::ChannelEmpty => {
// Normal condition, no error needed
}
DrainEventError::ChannelDisconnected => {
log::warn!("Event channel disconnected; stopping event polling");
}
DrainEventError::BorrowError(_) => {
log::error!("Failed to borrow renderer: {}", e);
}
}
}
} }
{ {
@@ -672,10 +696,7 @@ impl<T: Scene + 'static> Renderer<T> {
pub async fn load_assets_async(renderer: Rc<RefCell<Renderer<T>>>) -> Result<(), ImportError> { pub async fn load_assets_async(renderer: Rc<RefCell<Renderer<T>>>) -> Result<(), ImportError> {
let (device, surface_format) = { let (device, surface_format) = {
let r = renderer.borrow(); let r = renderer.borrow();
( (r.context.device.clone(), r.context.surface_config.format)
r.context.device.clone(),
r.context.surface_config.format,
)
}; };
let mut meshes = Vec::new(); let mut meshes = Vec::new();
@@ -734,7 +755,9 @@ impl<T: Scene + 'static> Renderer<T> {
Ok(()) Ok(())
} }
async fn show_file_picker_and_load(renderer: Rc<RefCell<Renderer<T>>>) -> Result<(), ImportError> { async fn show_file_picker_and_load(
renderer: Rc<RefCell<Renderer<T>>>,
) -> Result<(), ImportError> {
// For now, we'll just call load_assets_async which loads the default model // For now, we'll just call load_assets_async which loads the default model
// In a full implementation, we'd modify load_gltf_model to accept the file data // In a full implementation, we'd modify load_gltf_model to accept the file data
Self::load_assets_async(renderer).await Self::load_assets_async(renderer).await