feat: tell the user they need to build the profile if starting fails

This commit is contained in:
Gabriele Musco 2023-07-01 11:13:30 +02:00
commit c27fc65c62
No known key found for this signature in database
GPG key ID: 1068D795C80E51DE
2 changed files with 52 additions and 31 deletions

View file

@ -1,4 +1,7 @@
use crate::{file_utils::get_writer, profile::{Profile, XRServiceType}}; use crate::{
file_utils::get_writer,
profile::{Profile, XRServiceType},
};
use expect_dialog::ExpectDialog; use expect_dialog::ExpectDialog;
use nix::{ use nix::{
sys::signal::{kill, Signal::SIGTERM}, sys::signal::{kill, Signal::SIGTERM},
@ -98,23 +101,29 @@ impl Runner {
) )
} }
pub fn start(&mut self) { pub fn try_start(&mut self) -> Result<(), std::io::Error> {
self.threads = Vec::new(); self.threads = Vec::new();
self.process = Some( let cmd = Command::new(self.command.clone())
Command::new(self.command.clone())
.args(self.args.clone()) .args(self.args.clone())
.envs(self.environment.clone()) .envs(self.environment.clone())
.stderr(Stdio::piped()) .stderr(Stdio::piped())
.stdout(Stdio::piped()) .stdout(Stdio::piped())
.spawn() .spawn();
.expect_dialog("Failed to execute runner"), if cmd.is_err() {
); return Err(cmd.unwrap_err());
}
self.process = Some(cmd.unwrap());
let stdout = self.process.as_mut().unwrap().stdout.take().unwrap(); let stdout = self.process.as_mut().unwrap().stdout.take().unwrap();
let stderr = self.process.as_mut().unwrap().stderr.take().unwrap(); let stderr = self.process.as_mut().unwrap().stderr.take().unwrap();
let stdout_sender = self.sender.clone(); let stdout_sender = self.sender.clone();
let stderr_sender = self.sender.clone(); let stderr_sender = self.sender.clone();
self.threads.push(logger_thread!(stdout, stdout_sender)); self.threads.push(logger_thread!(stdout, stdout_sender));
self.threads.push(logger_thread!(stderr, stderr_sender)); self.threads.push(logger_thread!(stderr, stderr_sender));
Ok(())
}
pub fn start(&mut self) {
self.try_start().expect_dialog("Failed to execute runner");
} }
fn join_threads(&mut self) { fn join_threads(&mut self) {

View file

@ -58,6 +58,8 @@ pub struct App {
setcap_confirm_dialog: adw::MessageDialog, setcap_confirm_dialog: adw::MessageDialog,
#[tracker::do_not_track] #[tracker::do_not_track]
libsurvive_setup_window: Controller<LibsurviveSetupWindow>, libsurvive_setup_window: Controller<LibsurviveSetupWindow>,
#[tracker::do_not_track]
profile_runner_failed_dialog: adw::MessageDialog,
#[tracker::do_not_track] #[tracker::do_not_track]
config: Config, config: Config,
@ -101,9 +103,24 @@ impl App {
pub fn start_xrservice(&mut self) { pub fn start_xrservice(&mut self) {
self.xrservice_log.clear(); self.xrservice_log.clear();
self.debug_view
.sender()
.emit(DebugViewMsg::LogUpdated(vec![]));
let mut runner = Runner::xrservice_runner_from_profile(self.get_selected_profile().clone()); let mut runner = Runner::xrservice_runner_from_profile(self.get_selected_profile().clone());
runner.start(); match runner.try_start() {
Ok(_) => {
self.xrservice_runner = Some(runner); self.xrservice_runner = Some(runner);
self.main_view
.sender()
.emit(MainViewMsg::XRServiceActiveChanged(
true,
Some(self.get_selected_profile()),
));
}
Err(_) => {
self.profile_runner_failed_dialog.present();
}
};
} }
pub fn profiles_list(config: &Config) -> Vec<Profile> { pub fn profiles_list(config: &Config) -> Vec<Profile> {
@ -243,16 +260,7 @@ impl SimpleComponent for App {
} }
Msg::DoStartStopXRService => match &mut self.xrservice_runner { Msg::DoStartStopXRService => match &mut self.xrservice_runner {
None => { None => {
self.debug_view
.sender()
.emit(DebugViewMsg::LogUpdated(vec![]));
self.start_xrservice(); self.start_xrservice();
self.main_view
.sender()
.emit(MainViewMsg::XRServiceActiveChanged(
true,
Some(self.get_selected_profile()),
));
} }
Some(runner) => match runner.status() { Some(runner) => match runner.status() {
RunnerStatus::Running => { RunnerStatus::Running => {
@ -262,16 +270,7 @@ impl SimpleComponent for App {
.emit(MainViewMsg::XRServiceActiveChanged(false, None)); .emit(MainViewMsg::XRServiceActiveChanged(false, None));
} }
RunnerStatus::Stopped(_) => { RunnerStatus::Stopped(_) => {
self.debug_view
.sender()
.emit(DebugViewMsg::LogUpdated(vec![]));
self.start_xrservice(); self.start_xrservice();
self.main_view
.sender()
.emit(MainViewMsg::XRServiceActiveChanged(
true,
Some(self.get_selected_profile()),
));
} }
}, },
}, },
@ -449,6 +448,18 @@ impl SimpleComponent for App {
}); });
} }
let profile_runner_failed_dialog = adw::MessageDialog::builder()
.modal(true)
.transient_for(root)
.heading("Failed to start profile")
.body(concat!(
"You need to build the current profile before starting it.",
"\n\nYou can do this from the menu."
))
.hide_on_close(true)
.build();
profile_runner_failed_dialog.add_response("ok", "_Ok");
let model = App { let model = App {
application: init.application, application: init.application,
main_view: MainView::builder() main_view: MainView::builder()
@ -485,6 +496,7 @@ impl SimpleComponent for App {
.detach(), .detach(),
dependencies_dialog, dependencies_dialog,
setcap_confirm_dialog, setcap_confirm_dialog,
profile_runner_failed_dialog,
enable_debug_view: config.debug_view_enabled, enable_debug_view: config.debug_view_enabled,
config, config,
tracker: 0, tracker: 0,