Skip to content

Commit

Permalink
Exits immediately when RuntimeWindow fails (#1188)
Browse files Browse the repository at this point in the history
  • Loading branch information
ultimaweapon authored Dec 16, 2024
1 parent 152f0df commit 102ebc5
Show file tree
Hide file tree
Showing 3 changed files with 65 additions and 26 deletions.
72 changes: 53 additions & 19 deletions gui/src/rt/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,9 +56,15 @@ where
main,
windows: HashMap::default(),
on_close: WindowEvent::default(),
error: None,
};

el.run_app(&mut rt).map_err(RuntimeError::RunEventLoop)
el.run_app(&mut rt).map_err(RuntimeError::RunEventLoop)?;

match rt.error {
Some(e) => Err(e),
None => Ok(()),
}
}

/// # Panics
Expand Down Expand Up @@ -109,6 +115,7 @@ struct Runtime {
main: u64,
windows: HashMap<WindowId, Weak<dyn RuntimeWindow>>,
on_close: WindowEvent<()>,
error: Option<RuntimeError>,
}

impl Runtime {
Expand Down Expand Up @@ -148,16 +155,16 @@ impl Runtime {
true
}

fn dispatch_window(
fn dispatch_window<R>(
&mut self,
el: &ActiveEventLoop,
win: WindowId,
f: impl FnOnce(&dyn RuntimeWindow) -> Result<(), Box<dyn Error>>,
) {
f: impl FnOnce(&dyn RuntimeWindow) -> R,
) -> Option<R> {
// Get target window.
let win = match self.windows.get(&win).unwrap().upgrade() {
Some(v) => v,
None => return,
None => return None,
};

// Setup context.
Expand All @@ -170,12 +177,7 @@ impl Runtime {
};

// Dispatch the event.
let e = match cx.run(move || f(win.as_ref())) {
Ok(_) => return,
Err(e) => e,
};

todo!()
Some(cx.run(move || f(win.as_ref())))
}
}

Expand All @@ -200,17 +202,40 @@ impl ApplicationHandler<Event> for Runtime {
) {
use winit::event::WindowEvent;

match event {
WindowEvent::Resized(v) => self.dispatch_window(el, id, move |w| w.update_size(v)),
WindowEvent::CloseRequested => self.on_close.raise(id, ()),
WindowEvent::Destroyed => drop(self.windows.remove(&id)),
// Process the event.
let e = match event {
WindowEvent::Resized(v) => match self.dispatch_window(el, id, |w| w.update_size(v)) {
Some(Err(e)) => RuntimeError::UpdateWindowSize(e),
_ => return,
},
WindowEvent::CloseRequested => {
self.on_close.raise(id, ());
return;
}
WindowEvent::Destroyed => {
// It is possible for the window to not in the list if the function passed to
// create_window() fails.
self.windows.remove(&id);
return;
}
WindowEvent::ScaleFactorChanged {
scale_factor,
inner_size_writer: _,
} => self.dispatch_window(el, id, move |w| w.update_scale_factor(scale_factor)),
WindowEvent::RedrawRequested => self.dispatch_window(el, id, |w| w.redraw()),
_ => {}
}
} => match self.dispatch_window(el, id, move |w| w.update_scale_factor(scale_factor)) {
Some(Err(e)) => RuntimeError::UpdateWindowScaleFactor(e),
_ => return,
},
WindowEvent::RedrawRequested => match self.dispatch_window(el, id, |w| w.redraw()) {
Some(Err(e)) => RuntimeError::RedrawWindow(e),
_ => return,
},
_ => return,
};

// Store error then exit.
self.error = Some(e);

el.exit();
}
}

Expand All @@ -233,4 +258,13 @@ pub enum RuntimeError {

#[error("couldn't create runtime window")]
CreateRuntimeWindow(#[source] Box<dyn Error + Send + Sync>),

#[error("couldn't update window size")]
UpdateWindowSize(#[source] Box<dyn Error + Send + Sync>),

#[error("couldn't update window scale factor")]
UpdateWindowScaleFactor(#[source] Box<dyn Error + Send + Sync>),

#[error("couldn't redraw the window")]
RedrawWindow(#[source] Box<dyn Error + Send + Sync>),
}
10 changes: 6 additions & 4 deletions gui/src/rt/window.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
use std::error::Error;
use winit::dpi::PhysicalSize;

/// Encapsulates winit window with application-specific logic.
/// Encapsulates winit window with window-specific logic.
///
/// The event loop will exit immediately if any method return an error.
pub trait RuntimeWindow {
fn update_size(&self, v: PhysicalSize<u32>) -> Result<(), Box<dyn Error>>;
fn update_scale_factor(&self, v: f64) -> Result<(), Box<dyn Error>>;
fn redraw(&self) -> Result<(), Box<dyn Error>>;
fn update_size(&self, v: PhysicalSize<u32>) -> Result<(), Box<dyn Error + Send + Sync>>;
fn update_scale_factor(&self, v: f64) -> Result<(), Box<dyn Error + Send + Sync>>;
fn redraw(&self) -> Result<(), Box<dyn Error + Send + Sync>>;
}
9 changes: 6 additions & 3 deletions gui/src/ui/backend/window.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,10 @@ impl Window {
}

impl RuntimeWindow for Window {
fn update_size(&self, v: winit::dpi::PhysicalSize<u32>) -> Result<(), Box<dyn Error>> {
fn update_size(
&self,
v: winit::dpi::PhysicalSize<u32>,
) -> Result<(), Box<dyn Error + Send + Sync>> {
let size = PhysicalSize::new(v.width, v.height);
let size = LogicalSize::from_physical(size, self.winit.scale_factor() as f32);

Expand All @@ -47,7 +50,7 @@ impl RuntimeWindow for Window {
Ok(())
}

fn update_scale_factor(&self, v: f64) -> Result<(), Box<dyn Error>> {
fn update_scale_factor(&self, v: f64) -> Result<(), Box<dyn Error + Send + Sync>> {
let scale_factor = v as f32;

self.slint
Expand All @@ -56,7 +59,7 @@ impl RuntimeWindow for Window {
Ok(())
}

fn redraw(&self) -> Result<(), Box<dyn Error>> {
fn redraw(&self) -> Result<(), Box<dyn Error + Send + Sync>> {
// Wayland will show the window on the first render so we need to check visibility flag
// here.
if self.visible.get().is_some_and(|v| v) {
Expand Down

0 comments on commit 102ebc5

Please sign in to comment.