mirror of
https://gitlab.com/gabmus/envision.git
synced 2025-07-29 12:18:56 +00:00
feat: per-profile autostart command
This commit is contained in:
parent
e2ab73500d
commit
bf96a54675
5 changed files with 81 additions and 18 deletions
|
@ -1,9 +1,6 @@
|
|||
use crate::{
|
||||
file_utils::get_writer,
|
||||
paths::{
|
||||
data_monado_path, data_opencomposite_path, get_data_dir, get_ipc_file_path,
|
||||
BWRAP_SYSTEM_PREFIX, SYSTEM_PREFIX,
|
||||
},
|
||||
paths::{get_data_dir, get_ipc_file_path, BWRAP_SYSTEM_PREFIX, SYSTEM_PREFIX},
|
||||
};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::{collections::HashMap, fmt::Display, fs::File, io::BufReader, path::Path, slice::Iter};
|
||||
|
@ -230,6 +227,7 @@ pub struct Profile {
|
|||
pub lighthouse_driver: LighthouseDriver,
|
||||
#[serde(default = "String::default")]
|
||||
pub xrservice_launch_options: String,
|
||||
pub autostart_command: Option<String>,
|
||||
}
|
||||
|
||||
impl Display for Profile {
|
||||
|
@ -284,6 +282,7 @@ impl Default for Profile {
|
|||
lighthouse_driver: LighthouseDriver::default(),
|
||||
xrservice_launch_options: String::default(),
|
||||
uuid,
|
||||
autostart_command: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -92,6 +92,8 @@ pub struct App {
|
|||
#[tracker::do_not_track]
|
||||
xrservice_worker: Option<JobWorker>,
|
||||
#[tracker::do_not_track]
|
||||
autostart_worker: Option<JobWorker>,
|
||||
#[tracker::do_not_track]
|
||||
restart_xrservice: bool,
|
||||
#[tracker::do_not_track]
|
||||
build_worker: Option<JobWorker>,
|
||||
|
@ -112,6 +114,7 @@ pub struct App {
|
|||
pub enum Msg {
|
||||
OnServiceLog(Vec<String>),
|
||||
OnServiceExit(i32),
|
||||
OnAutostartExit(i32),
|
||||
OnBuildLog(Vec<String>),
|
||||
OnBuildExit(i32),
|
||||
ClockTicking,
|
||||
|
@ -197,6 +200,23 @@ impl App {
|
|||
debug,
|
||||
);
|
||||
worker.start();
|
||||
if let Some(autostart_cmd) = prof.autostart_command {
|
||||
let autostart_worker = JobWorker::new_with_timer(
|
||||
Duration::from_secs(5),
|
||||
WorkerJob::new_cmd(
|
||||
Some(prof.environment.clone()),
|
||||
"sh".into(),
|
||||
Some(vec!["-c".into(), autostart_cmd.clone()]),
|
||||
),
|
||||
sender.input_sender(),
|
||||
|msg| match msg {
|
||||
JobWorkerOut::Log(rows) => Msg::OnServiceLog(rows),
|
||||
JobWorkerOut::Exit(code) => Msg::OnAutostartExit(code),
|
||||
},
|
||||
);
|
||||
autostart_worker.start();
|
||||
self.autostart_worker = Some(autostart_worker)
|
||||
}
|
||||
self.xrservice_worker = Some(worker);
|
||||
self.main_view
|
||||
.sender()
|
||||
|
@ -242,6 +262,9 @@ impl App {
|
|||
if let Some(worker) = self.xrservice_worker.as_ref() {
|
||||
worker.stop();
|
||||
}
|
||||
if let Some(worker) = self.autostart_worker.as_ref() {
|
||||
worker.stop();
|
||||
}
|
||||
self.libmonado = None;
|
||||
self.restore_openxr_openvr_files();
|
||||
self.main_view
|
||||
|
@ -325,24 +348,20 @@ impl SimpleComponent for App {
|
|||
.emit(DebugViewMsg::LogUpdated(rows));
|
||||
}
|
||||
}
|
||||
Msg::OnServiceExit(_) => {
|
||||
Msg::OnServiceExit(code) => {
|
||||
self.main_view
|
||||
.sender()
|
||||
.emit(MainViewMsg::XRServiceActiveChanged(false, None));
|
||||
self.debug_view
|
||||
.sender()
|
||||
.emit(DebugViewMsg::XRServiceActiveChanged(false));
|
||||
if let Some(worker) = self.xrservice_worker.as_ref() {
|
||||
if let Some(code) = worker.exit_code() {
|
||||
if code != 0 && code != 15 {
|
||||
// 15 is SIGTERM
|
||||
sender.input(Msg::OnServiceLog(vec![format!(
|
||||
"{} exited with code {}",
|
||||
self.get_selected_profile().xrservice_type,
|
||||
code
|
||||
)]));
|
||||
}
|
||||
}
|
||||
if code != 0 && code != 15 {
|
||||
// 15 is SIGTERM
|
||||
sender.input(Msg::OnServiceLog(vec![format!(
|
||||
"{} exited with code {}",
|
||||
self.get_selected_profile().xrservice_type,
|
||||
code
|
||||
)]));
|
||||
}
|
||||
self.xrservice_worker = None;
|
||||
if self.restart_xrservice {
|
||||
|
@ -350,6 +369,7 @@ impl SimpleComponent for App {
|
|||
self.start_xrservice(sender, false);
|
||||
}
|
||||
}
|
||||
Msg::OnAutostartExit(_) => self.autostart_worker = None,
|
||||
Msg::ClockTicking => {
|
||||
self.main_view.sender().emit(MainViewMsg::ClockTicking);
|
||||
if let Some(w) = self.xrservice_worker.as_ref() {
|
||||
|
@ -798,6 +818,7 @@ impl SimpleComponent for App {
|
|||
config,
|
||||
profiles,
|
||||
xrservice_worker: None,
|
||||
autostart_worker: None,
|
||||
build_worker: None,
|
||||
xr_devices: vec![],
|
||||
fbt_config_editor: None,
|
||||
|
|
|
@ -7,12 +7,21 @@ pub struct CmdWorkerData {
|
|||
pub args: Vec<String>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Default)]
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct FuncWorkerOut {
|
||||
pub success: bool,
|
||||
pub out: Vec<String>,
|
||||
}
|
||||
|
||||
impl Default for FuncWorkerOut {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
success: true,
|
||||
out: vec![],
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct FuncWorkerData {
|
||||
pub func: Box<dyn FnOnce() -> FuncWorkerOut + Send + Sync + 'static>,
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use self::{
|
||||
internal_worker::{InternalJobWorker, JobWorkerInit, JobWorkerMsg, JobWorkerOut},
|
||||
job::WorkerJob,
|
||||
job::{FuncWorkerOut, WorkerJob},
|
||||
state::JobWorkerState,
|
||||
};
|
||||
use crate::profile::Profile;
|
||||
|
@ -44,6 +44,32 @@ impl JobWorker {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn new_with_timer<X: 'static, F: (Fn(JobWorkerOut) -> X) + 'static>(
|
||||
duration: Duration,
|
||||
job: WorkerJob,
|
||||
sender: &Sender<X>,
|
||||
transform: F,
|
||||
) -> Self {
|
||||
let timer_job = WorkerJob::new_func(Box::new(move || {
|
||||
thread::sleep(duration);
|
||||
FuncWorkerOut::default()
|
||||
}));
|
||||
let mut jobs = VecDeque::new();
|
||||
let state = Arc::new(Mutex::new(JobWorkerState::default()));
|
||||
jobs.push_back(timer_job);
|
||||
jobs.push_back(job);
|
||||
let init = JobWorkerInit {
|
||||
jobs,
|
||||
state: state.clone(),
|
||||
};
|
||||
Self {
|
||||
worker: InternalJobWorker::builder()
|
||||
.detach_worker(init)
|
||||
.forward(sender, transform),
|
||||
state,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn xrservice_worker_wrap_from_profile<X: 'static, F: (Fn(JobWorkerOut) -> X) + 'static>(
|
||||
prof: &Profile,
|
||||
sender: &Sender<X>,
|
||||
|
|
|
@ -113,6 +113,14 @@ impl SimpleComponent for ProfileEditor {
|
|||
prof.borrow_mut().prefix = n_path.unwrap_or_default()
|
||||
}),
|
||||
),
|
||||
add: &entry_row("Autostart Command",
|
||||
model.profile.borrow().autostart_command.as_ref().unwrap_or(&String::default()),
|
||||
clone!(@strong prof => move |row| {
|
||||
let txt = row.text().trim().to_string();
|
||||
prof.borrow_mut().autostart_command =
|
||||
if txt.is_empty() {None} else {Some(txt)};
|
||||
})
|
||||
)
|
||||
},
|
||||
add: xrservicegrp = &adw::PreferencesGroup {
|
||||
set_title: "XR Service",
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue