diff --git a/crates/topola-egui/src/viewport.rs b/crates/topola-egui/src/viewport.rs index 9bb2e5b..b23021a 100644 --- a/crates/topola-egui/src/viewport.rs +++ b/crates/topola-egui/src/viewport.rs @@ -138,6 +138,27 @@ impl Viewport { if let Some(workspace) = maybe_workspace { let latest_point = point! {x: latest_pos.x as f64, y: -latest_pos.y as f64}; + // Advances the app's state by the delta time `dt`. May call + // `.update_state()` more than once if the delta time is more than a multiple of + // the timestep. + let dt = ctx.input(|i| i.stable_dt); + let active_layer = workspace.appearance_panel.active_layer; + self.update_counter += dt; + while self.update_counter >= menu_bar.frame_timestep { + self.update_counter -= menu_bar.frame_timestep; + if let ControlFlow::Break(()) = workspace.update_state( + tr, + error_dialog, + &InteractiveInput { + active_layer, + pointer_pos: point! {x: latest_pos.x as f64, y: latest_pos.y as f64}, + dt, + }, + ) { + break; + } + } + if !workspace.interactor.maybe_activity().as_ref().map_or(true, |activity| { matches!(activity.maybe_status(), Some(ControlFlow::Break(..))) }) { @@ -149,27 +170,10 @@ impl Viewport { } else { None }; - if let Some(event) = interactive_event { - log::debug!("got {:?}", event); - } - // Advances the app's state by the delta time `dt`. May call - // `.update_state()` more than once if the delta time is more than a multiple of - // the timestep. - let dt = ctx.input(|i| i.stable_dt); - let active_layer = workspace.appearance_panel.active_layer; - self.update_counter += if interactive_event.is_some() { - // make sure we run the loop below at least once on clicks - let mut dtx = menu_bar.frame_timestep; - if dt > dtx { - dtx = dt; - } - dtx - } else { - dt - }; - while self.update_counter >= menu_bar.frame_timestep { - self.update_counter -= menu_bar.frame_timestep; - if let ControlFlow::Break(()) = workspace.update_state( + if let Some(interactive_event) = interactive_event { + let dt = ctx.input(|i| i.stable_dt); + let active_layer = workspace.appearance_panel.active_layer; + let _ = workspace.update_state_for_event( tr, error_dialog, &InteractiveInput { @@ -178,32 +182,9 @@ impl Viewport { dt, }, interactive_event, - ) { - break; - } + ); } } else { - // Advances the app's state by the delta time `dt`. May call - // `.update_state()` more than once if the delta time is more than a multiple of - // the timestep. - let dt = ctx.input(|i| i.stable_dt); - let active_layer = workspace.appearance_panel.active_layer; - self.update_counter += dt; - while self.update_counter >= menu_bar.frame_timestep { - self.update_counter -= menu_bar.frame_timestep; - if let ControlFlow::Break(()) = workspace.update_state( - tr, - error_dialog, - &InteractiveInput { - active_layer, - pointer_pos: point! {x: latest_pos.x as f64, y: latest_pos.y as f64}, - dt, - }, - None, - ) { - break; - } - } let layers = &mut workspace.appearance_panel; let overlay = &mut workspace.overlay; let board = workspace.interactor.invoker().autorouter().board(); diff --git a/crates/topola-egui/src/workspace.rs b/crates/topola-egui/src/workspace.rs index 0b292ba..087fe6d 100644 --- a/crates/topola-egui/src/workspace.rs +++ b/crates/topola-egui/src/workspace.rs @@ -61,12 +61,31 @@ impl Workspace { }) } + pub fn update_state_for_event( + &mut self, + tr: &Translator, + error_dialog: &mut ErrorDialog, + interactive_input: &InteractiveInput, + interactive_event: InteractiveEvent, + ) -> ControlFlow<()> { + match self + .interactor + .update_for_event(interactive_input, interactive_event) + { + ControlFlow::Continue(()) => ControlFlow::Continue(()), + ControlFlow::Break(Ok(())) => ControlFlow::Break(()), + ControlFlow::Break(Err(err)) => { + error_dialog.push_error("tr-module-invoker", format!("{}", err)); + ControlFlow::Break(()) + } + } + } + pub fn update_state( &mut self, tr: &Translator, error_dialog: &mut ErrorDialog, interactive_input: &InteractiveInput, - interactive_event: Option, ) -> ControlFlow<()> { if let Ok(data) = self.history_channel.1.try_recv() { match data { @@ -92,7 +111,7 @@ impl Workspace { } } - match self.interactor.update(interactive_input, interactive_event) { + match self.interactor.update(interactive_input) { ControlFlow::Continue(()) => ControlFlow::Continue(()), ControlFlow::Break(Ok(())) => ControlFlow::Break(()), ControlFlow::Break(Err(err)) => { diff --git a/src/interactor/interactor.rs b/src/interactor/interactor.rs index a0a54ef..cb2679e 100644 --- a/src/interactor/interactor.rs +++ b/src/interactor/interactor.rs @@ -79,41 +79,49 @@ impl Interactor { self.invoker.replay(history); } + /// Update the currently running execution or activity, given an event + pub fn update_for_event( + &mut self, + interactive_input: &InteractiveInput, + interactive_event: InteractiveEvent, + ) -> ControlFlow> { + if let Some(ref mut activity) = self.activity { + match activity.on_event( + &mut ActivityContext { + interactive_input, + invoker: &mut self.invoker, + }, + interactive_event, + ) { + Ok(()) => ControlFlow::Continue(()), + Err(err) => { + self.activity = None; + ControlFlow::Break(Err(err.into())) + } + } + } else { + ControlFlow::Break(Ok(())) + } + } + /// Update the currently running execution or activity pub fn update( &mut self, interactive_input: &InteractiveInput, - interactive_event: Option, ) -> ControlFlow> { if let Some(ref mut activity) = self.activity { - if let Some(event) = interactive_event { - match activity.on_event( - &mut ActivityContext { - interactive_input, - invoker: &mut self.invoker, - }, - event, - ) { - Ok(()) => ControlFlow::Continue(()), - Err(err) => { - self.activity = None; - ControlFlow::Break(Err(err.into())) - } + match activity.step(&mut ActivityContext { + interactive_input, + invoker: &mut self.invoker, + }) { + Ok(ControlFlow::Continue(())) => ControlFlow::Continue(()), + Ok(ControlFlow::Break(_msg)) => { + self.activity = None; + ControlFlow::Break(Ok(())) } - } else { - match activity.step(&mut ActivityContext { - interactive_input, - invoker: &mut self.invoker, - }) { - Ok(ControlFlow::Continue(())) => ControlFlow::Continue(()), - Ok(ControlFlow::Break(_msg)) => { - self.activity = None; - ControlFlow::Break(Ok(())) - } - Err(err) => { - self.activity = None; - ControlFlow::Break(Err(err)) - } + Err(err) => { + self.activity = None; + ControlFlow::Break(Err(err)) } } } else {