From 41baba5c9a85c53d0873f797c06f18699b6c4722 Mon Sep 17 00:00:00 2001 From: GabMus Date: Sat, 15 Jun 2024 20:11:37 +0000 Subject: [PATCH] feat: list generic trackers from libmonado, remove log parsing --- Cargo.lock | 27 +- Cargo.toml | 2 +- src/file_builders/mod.rs | 1 - src/file_builders/monado_config_v0.rs | 259 ------------------ src/linux_distro.rs | 1 + src/steam_linux_runtime_injector.rs | 6 +- src/ui/app.rs | 43 --- src/ui/devices_box.rs | 74 +---- src/ui/factories/mod.rs | 1 - .../factories/tracker_role_group_factory.rs | 106 ------- src/ui/fbt_config_editor.rs | 173 ------------ src/ui/main_view.rs | 4 +- src/ui/mod.rs | 1 - src/xr_devices.rs | 55 +++- 14 files changed, 70 insertions(+), 683 deletions(-) delete mode 100644 src/file_builders/monado_config_v0.rs delete mode 100644 src/ui/factories/tracker_role_group_factory.rs delete mode 100644 src/ui/fbt_config_editor.rs diff --git a/Cargo.lock b/Cargo.lock index 432fad0..f91c1fd 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -67,17 +67,17 @@ checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" [[package]] name = "bindgen" -version = "0.68.1" +version = "0.69.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "726e4313eb6ec35d2730258ad4e15b547ee75d6afaa1361a922e78e59b7d8078" +checksum = "a00dc851838a2120612785d195287475a3ac45514741da670b735818822129a0" dependencies = [ "bitflags 2.4.0", "cexpr", "clang-sys", + "itertools", "lazy_static", "lazycell", "log", - "peeking_take_while", "prettyplease", "proc-macro2", "quote", @@ -230,9 +230,9 @@ checksum = "e496a50fda8aacccc86d7529e2c1e0892dbd0f898a6b5645b5561b89c3210efa" [[package]] name = "dlopen2" -version = "0.6.1" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6bc2c7ed06fd72a8513ded8d0d2f6fd2655a85d6885c48cae8625d80faf28c03" +checksum = "9e1297103d2bbaea85724fcee6294c2d50b1081f9ad47d0f6f6f61eda65315a6" dependencies = [ "dlopen2_derive", "libc", @@ -967,6 +967,15 @@ version = "2.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "28b29a3cd74f0f4598934efe3aeba42bae0eb4680554128851ebbecb02af14e6" +[[package]] +name = "itertools" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba291022dbbd398a455acf126c1e341954079855bc60dfdda641363bd6922569" +dependencies = [ + "either", +] + [[package]] name = "itoa" version = "1.0.9" @@ -1068,7 +1077,7 @@ dependencies = [ [[package]] name = "libmonado-rs" version = "0.1.0" -source = "git+https://github.com/technobaboo/libmonado-rs#d79d5bf11586b8010d8aa016097ebdb07f683c64" +source = "git+https://github.com/technobaboo/libmonado-rs?rev=e32e78c79ce9ec4a5a5de9eff30661c6c4307347#e32e78c79ce9ec4a5a5de9eff30661c6c4307347" dependencies = [ "bindgen", "cmake", @@ -1378,12 +1387,6 @@ dependencies = [ "system-deps", ] -[[package]] -name = "peeking_take_while" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19b17cddbe7ec3f8bc800887bab5e717348c95ea2ca0b1bf0837fb964dc67099" - [[package]] name = "percent-encoding" version = "2.3.0" diff --git a/Cargo.toml b/Cargo.toml index fd82872..c3470b1 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -18,7 +18,7 @@ lazy_static = "1.4.0" libadwaita = { version = "0.6.0", features = [ "v1_4" ] } -libmonado-rs = { git = "https://github.com/technobaboo/libmonado-rs", version = "0.1.0" } +libmonado-rs = { git = "https://github.com/technobaboo/libmonado-rs", rev = "e32e78c79ce9ec4a5a5de9eff30661c6c4307347" } rusb = "0.9.4" nix = { version = "0.29.0", features = [ "fs", diff --git a/src/file_builders/mod.rs b/src/file_builders/mod.rs index 73bb8db..ab8ccfc 100644 --- a/src/file_builders/mod.rs +++ b/src/file_builders/mod.rs @@ -1,5 +1,4 @@ pub mod active_runtime_json; pub mod monado_autorun; -pub mod monado_config_v0; pub mod openvrpaths_vrpath; pub mod wivrn_config; diff --git a/src/file_builders/monado_config_v0.rs b/src/file_builders/monado_config_v0.rs deleted file mode 100644 index cec5fe8..0000000 --- a/src/file_builders/monado_config_v0.rs +++ /dev/null @@ -1,259 +0,0 @@ -use crate::{ - file_utils::{deserialize_file, get_writer_legacy}, - paths::get_xdg_config_dir, -}; -use serde::{Deserialize, Serialize}; -use std::slice::Iter; - -#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] -pub enum XrtInputName { - #[serde(rename = "XRT_INPUT_GENERIC_TRACKER_POSE")] - XrtInputGenericTrackerPose, -} - -#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] -pub enum XrtTrackerRole { - #[serde(rename = "/user/vive_tracker_htcx/role/waist")] - ViveTrackerHtcxWaist, - #[serde(rename = "/user/vive_tracker_htcx/role/left_foot")] - ViveTrackerHtcxLeftFoot, - #[serde(rename = "/user/vive_tracker_htcx/role/right_foot")] - ViveTrackerHtcxRightFoot, - #[serde(rename = "/user/vive_tracker_htcx/role/handheld_object")] - ViveTrackerHtcxHandheldObject, - #[serde(rename = "/user/vive_tracker_htcx/role/left_shoulder")] - ViveTrackerHtcxLeftShoulder, - #[serde(rename = "/user/vive_tracker_htcx/role/right_shoulder")] - ViveTrackerHtcxRightShoulder, - #[serde(rename = "/user/vive_tracker_htcx/role/left_elbow")] - ViveTrackerHtcxLeftElbow, - #[serde(rename = "/user/vive_tracker_htcx/role/right_elbow")] - ViveTrackerHtcxRightElbow, - #[serde(rename = "/user/vive_tracker_htcx/role/left_knee")] - ViveTrackerHtcxLeftKnee, - #[serde(rename = "/user/vive_tracker_htcx/role/right_knee")] - ViveTrackerHtcxRightKnee, - #[serde(rename = "/user/vive_tracker_htcx/role/chest")] - ViveTrackerHtcxChest, - #[serde(rename = "/user/vive_tracker_htcx/role/camera")] - ViveTrackerHtcxCamera, - #[serde(rename = "/user/vive_tracker_htcx/role/keyboard")] - ViveTrackerHtcxKeyboard, -} - -impl XrtTrackerRole { - pub fn to_picker_string(&self) -> &str { - match self { - Self::ViveTrackerHtcxWaist => "Waist", - Self::ViveTrackerHtcxLeftFoot => "Left foot", - Self::ViveTrackerHtcxRightFoot => "Right foot", - Self::ViveTrackerHtcxHandheldObject => "Handheld object", - Self::ViveTrackerHtcxLeftShoulder => "Left shoulder", - Self::ViveTrackerHtcxRightShoulder => "Right shoulder", - Self::ViveTrackerHtcxLeftElbow => "Left elbow", - Self::ViveTrackerHtcxRightElbow => "Right elbow", - Self::ViveTrackerHtcxLeftKnee => "Left knee", - Self::ViveTrackerHtcxRightKnee => "Right knee", - Self::ViveTrackerHtcxChest => "Chest", - Self::ViveTrackerHtcxCamera => "Camera", - Self::ViveTrackerHtcxKeyboard => "Keyboard", - } - } - - pub fn from_picker_string(s: &str) -> Self { - match s.to_lowercase().trim() { - "waist" => Self::ViveTrackerHtcxWaist, - "left foot" => Self::ViveTrackerHtcxLeftFoot, - "right foot" => Self::ViveTrackerHtcxRightFoot, - "handheld object" => Self::ViveTrackerHtcxHandheldObject, - "left shoulder" => Self::ViveTrackerHtcxLeftShoulder, - "right shoulder" => Self::ViveTrackerHtcxRightShoulder, - "left elbow" => Self::ViveTrackerHtcxLeftElbow, - "right elbow" => Self::ViveTrackerHtcxRightElbow, - "left knee" => Self::ViveTrackerHtcxLeftKnee, - "right knee" => Self::ViveTrackerHtcxRightKnee, - "chest" => Self::ViveTrackerHtcxChest, - "camera" => Self::ViveTrackerHtcxCamera, - "keyboard" => Self::ViveTrackerHtcxKeyboard, - _ => Self::ViveTrackerHtcxWaist, - } - } - - pub fn iter() -> Iter<'static, Self> { - [ - Self::ViveTrackerHtcxWaist, - Self::ViveTrackerHtcxLeftFoot, - Self::ViveTrackerHtcxRightFoot, - Self::ViveTrackerHtcxHandheldObject, - Self::ViveTrackerHtcxLeftShoulder, - Self::ViveTrackerHtcxRightShoulder, - Self::ViveTrackerHtcxLeftElbow, - Self::ViveTrackerHtcxRightElbow, - Self::ViveTrackerHtcxLeftKnee, - Self::ViveTrackerHtcxRightKnee, - Self::ViveTrackerHtcxChest, - Self::ViveTrackerHtcxCamera, - Self::ViveTrackerHtcxKeyboard, - ] - .iter() - } - - pub fn to_number(&self) -> u32 { - match self { - Self::ViveTrackerHtcxWaist => 0, - Self::ViveTrackerHtcxLeftFoot => 1, - Self::ViveTrackerHtcxRightFoot => 2, - Self::ViveTrackerHtcxHandheldObject => 3, - Self::ViveTrackerHtcxLeftShoulder => 4, - Self::ViveTrackerHtcxRightShoulder => 5, - Self::ViveTrackerHtcxLeftElbow => 6, - Self::ViveTrackerHtcxRightElbow => 7, - Self::ViveTrackerHtcxLeftKnee => 8, - Self::ViveTrackerHtcxRightKnee => 9, - Self::ViveTrackerHtcxChest => 10, - Self::ViveTrackerHtcxCamera => 11, - Self::ViveTrackerHtcxKeyboard => 12, - } - } - - pub fn from_number(n: &u32) -> Self { - match n { - 0 => Self::ViveTrackerHtcxWaist, - 1 => Self::ViveTrackerHtcxLeftFoot, - 2 => Self::ViveTrackerHtcxRightFoot, - 3 => Self::ViveTrackerHtcxHandheldObject, - 4 => Self::ViveTrackerHtcxLeftShoulder, - 5 => Self::ViveTrackerHtcxRightShoulder, - 6 => Self::ViveTrackerHtcxLeftElbow, - 7 => Self::ViveTrackerHtcxRightElbow, - 8 => Self::ViveTrackerHtcxLeftKnee, - 9 => Self::ViveTrackerHtcxRightKnee, - 10 => Self::ViveTrackerHtcxChest, - 11 => Self::ViveTrackerHtcxCamera, - 12 => Self::ViveTrackerHtcxKeyboard, - _ => Self::ViveTrackerHtcxWaist, - } - } -} - -#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] -pub struct TrackerRole { - pub device_serial: String, - pub role: XrtTrackerRole, - pub xrt_input_name: XrtInputName, -} - -impl Default for TrackerRole { - fn default() -> Self { - Self { - device_serial: "".into(), - role: XrtTrackerRole::ViveTrackerHtcxWaist, - xrt_input_name: XrtInputName::XrtInputGenericTrackerPose, - } - } -} - -#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] -pub struct MonadoConfigV0 { - #[serde(skip_serializing_if = "Option::is_none", rename = "$schema")] - _schema: Option, - #[serde(skip_serializing_if = "Vec::is_empty")] - pub tracker_roles: Vec, -} - -impl Default for MonadoConfigV0 { - fn default() -> Self { - Self { - _schema: Some( - "https://monado.pages.freedesktop.org/monado/config_v0.schema.json".to_string(), - ), - tracker_roles: vec![], - } - } -} - -impl MonadoConfigV0 { - pub fn has_tracker_serial(&self, serial: &str) -> bool { - self.tracker_roles.iter().any(|t| t.device_serial == serial) - } - - pub fn get_next_free_xrt_tracker_role(&self) -> XrtTrackerRole { - XrtTrackerRole::iter() - .find(|role| !self.tracker_roles.iter().any(|et| et.role == **role)) - .unwrap_or(&XrtTrackerRole::ViveTrackerHtcxHandheldObject) - .clone() - } -} - -fn get_monado_config_v0_path() -> String { - format!( - "{config}/monado/config_v0.json", - config = get_xdg_config_dir() - ) -} - -fn get_monado_config_v0_from_path(path_s: &String) -> Option { - deserialize_file(path_s) -} - -pub fn get_monado_config_v0() -> MonadoConfigV0 { - get_monado_config_v0_from_path(&get_monado_config_v0_path()) - .unwrap_or(MonadoConfigV0::default()) -} - -fn dump_monado_config_v0_to_path(config: &MonadoConfigV0, path_s: &String) { - let writer = get_writer_legacy(path_s); - serde_json::to_writer_pretty(writer, config).expect("Unable to save Monado config V0"); -} - -pub fn dump_monado_config_v0(config: &MonadoConfigV0) { - dump_monado_config_v0_to_path(config, &get_monado_config_v0_path()); -} - -pub fn dump_generic_trackers(trackers: &[String]) -> usize { - let mut conf = get_monado_config_v0(); - let mut added: usize = 0; - trackers.iter().for_each(|serial| { - if !conf.has_tracker_serial(serial) { - conf.tracker_roles.push(TrackerRole { - device_serial: serial.to_string(), - role: conf.get_next_free_xrt_tracker_role(), - ..TrackerRole::default() - }); - added += 1; - } - }); - - if added > 0 { - dump_monado_config_v0(&conf); - } - - added -} - -#[cfg(test)] -mod tests { - use super::get_monado_config_v0_from_path; - use crate::file_builders::monado_config_v0::{XrtInputName, XrtTrackerRole}; - - #[test] - fn can_read_monado_config_v0() { - let conf = get_monado_config_v0_from_path(&"./test/files/monado_config_v0.json".into()) - .expect("Couldn't find monado config v0"); - assert_eq!(conf.tracker_roles.len(), 3); - assert_eq!( - conf.tracker_roles - .get(0) - .expect("could not get tracker role zero") - .role, - XrtTrackerRole::ViveTrackerHtcxWaist - ); - assert_eq!( - conf.tracker_roles - .get(0) - .expect("could not get tracker role zero") - .xrt_input_name, - XrtInputName::XrtInputGenericTrackerPose - ); - } -} diff --git a/src/linux_distro.rs b/src/linux_distro.rs index 46faf68..7c53864 100644 --- a/src/linux_distro.rs +++ b/src/linux_distro.rs @@ -51,6 +51,7 @@ impl LinuxDistro { let mut buf = String::new(); if reader.read_to_string(&mut buf).is_ok() { buf = buf.trim().to_lowercase(); + return Self::name_matcher(&buf); } } diff --git a/src/steam_linux_runtime_injector.rs b/src/steam_linux_runtime_injector.rs index 083eede..e9fa920 100644 --- a/src/steam_linux_runtime_injector.rs +++ b/src/steam_linux_runtime_injector.rs @@ -4,11 +4,7 @@ use crate::{ profile::Profile, }; use anyhow::bail; -use std::{ - fs::read_to_string, - io::{Read, Write}, - path::Path, -}; +use std::{fs::read_to_string, io::Write, path::Path}; fn get_runtime_entrypoint_path() -> Option { let mut out = format!( diff --git a/src/ui/app.rs b/src/ui/app.rs index 7e9c4cb..fd27117 100644 --- a/src/ui/app.rs +++ b/src/ui/app.rs @@ -3,7 +3,6 @@ use super::alert::{alert, alert_w_widget}; use super::build_window::{BuildStatus, BuildWindow}; use super::cmdline_opts::CmdLineOpts; use super::debug_view::{DebugView, DebugViewMsg}; -use super::fbt_config_editor::{FbtConfigEditor, FbtConfigEditorInit, FbtConfigEditorMsg}; use super::job_worker::internal_worker::JobWorkerOut; use super::job_worker::job::WorkerJob; use super::job_worker::JobWorker; @@ -35,7 +34,6 @@ use crate::file_builders::openvrpaths_vrpath::{ }; use crate::file_utils::setcap_cap_sys_nice_eip; use crate::linux_distro::LinuxDistro; -use crate::log_parser::MonadoLog; use crate::paths::{get_data_dir, get_ipc_file_path}; use crate::profile::{Profile, XRServiceType}; use crate::stateless_action; @@ -100,8 +98,6 @@ pub struct App { #[tracker::do_not_track] xr_devices: Vec, #[tracker::do_not_track] - fbt_config_editor: Option>, - #[tracker::do_not_track] libmonado: Option, #[tracker::do_not_track] @@ -132,8 +128,6 @@ pub enum Msg { OpenLibsurviveSetup, SaveWinSize(i32, i32), Quit, - ParseLog(Vec), - ConfigFbt, DebugOpenPrefix, DebugOpenData, OpenWivrnConfig, @@ -331,7 +325,6 @@ impl SimpleComponent for App { match message { Msg::OnServiceLog(rows) => { if !rows.is_empty() { - sender.input(Msg::ParseLog(rows.clone())); self.debug_view .sender() .emit(DebugViewMsg::LogUpdated(rows)); @@ -387,20 +380,6 @@ impl SimpleComponent for App { } } } - Msg::ParseLog(rows) => { - for row in rows { - match MonadoLog::new_from_str(row.as_str()) { - None => {} - Some(parsed) => { - if let Some(tracker) = - XRDevice::generic_tracker_from_log_row(parsed.message.as_str()) - { - self.xr_devices.push(tracker); - } - } - }; - } - } Msg::EnableDebugViewChanged(val) => { self.set_enable_debug_view(val); self.config.debug_view_enabled = val; @@ -685,19 +664,6 @@ impl SimpleComponent for App { )) .expect("Failed to present Libsurvive Setup Window"); } - Msg::ConfigFbt => { - self.fbt_config_editor = Some( - FbtConfigEditor::builder() - .launch(FbtConfigEditorInit { - root_win: self.app_win.clone().upcast::(), - }) - .detach(), - ); - self.fbt_config_editor - .as_ref() - .unwrap() - .emit(FbtConfigEditorMsg::Present); - } Msg::SaveWinSize(w, h) => { self.config.win_size = [w, h]; self.config.save(); @@ -829,7 +795,6 @@ impl SimpleComponent for App { autostart_worker: None, build_worker: None, xr_devices: vec![], - fbt_config_editor: None, restart_xrservice: false, libmonado: None, wivrn_conf_editor: None, @@ -853,13 +818,6 @@ impl SimpleComponent for App { sender.input_sender().emit(Msg::BuildProfile(true)); }) ); - stateless_action!( - actions, - ConfigFbtAction, - clone!(@strong sender => move |_| { - sender.input_sender().emit(Msg::ConfigFbt); - }) - ); { let abd_sender = model.about_dialog.sender().clone(); stateless_action!(actions, AboutAction, move |_| { @@ -928,7 +886,6 @@ new_action_group!(pub AppActionGroup, "win"); new_stateless_action!(pub AboutAction, AppActionGroup, "about"); new_stateless_action!(pub BuildProfileAction, AppActionGroup, "buildprofile"); new_stateless_action!(pub BuildProfileCleanAction, AppActionGroup, "buildprofileclean"); -new_stateless_action!(pub ConfigFbtAction, AppActionGroup, "configfbt"); new_stateless_action!(pub QuitAction, AppActionGroup, "quit"); new_stateful_action!(pub DebugViewToggleAction, AppActionGroup, "debugviewtoggle", (), bool); diff --git a/src/ui/devices_box.rs b/src/ui/devices_box.rs index 84cc6f9..8084b14 100644 --- a/src/ui/devices_box.rs +++ b/src/ui/devices_box.rs @@ -1,11 +1,5 @@ -use super::{ - alert::alert, - factories::device_row_factory::{DeviceRowModel, DeviceRowModelInit, DeviceRowState}, -}; -use crate::{ - file_builders::monado_config_v0::dump_generic_trackers, - xr_devices::{XRDevice, XRDeviceRole}, -}; +use super::factories::device_row_factory::{DeviceRowModel, DeviceRowModelInit, DeviceRowState}; +use crate::xr_devices::{XRDevice, XRDeviceRole}; use adw::prelude::*; use relm4::{factory::AsyncFactoryVecDeque, prelude::*, Sender}; @@ -20,25 +14,6 @@ pub struct DevicesBox { #[derive(Debug)] pub enum DevicesBoxMsg { UpdateDevices(Vec), - DumpGenericTrackers, -} - -impl DevicesBox { - fn create_save_trackers_btn(sender: Sender) -> gtk::Button { - let btn = gtk::Button::builder() - .halign(gtk::Align::Center) - .valign(gtk::Align::Center) - .icon_name("document-save-symbolic") - .tooltip_text("Save current trackers") - .css_classes(["circular", "flat"]) - .build(); - - btn.connect_clicked(move |_| { - sender.emit(DevicesBoxMsg::DumpGenericTrackers); - }); - - btn - } } #[relm4::component(pub)] @@ -106,13 +81,9 @@ impl SimpleComponent for DevicesBox { subtitle: Some( generic .iter() - .map(|d| d.id.as_str()) - .collect::>() - .join(", "), - ), - suffix: Some( - Self::create_save_trackers_btn(sender.input_sender().clone()) - .upcast::(), + .map(|d| format!("{} ({})", d.name, d.index)) + .collect::>() + .join("\n"), ), ..Default::default() }); @@ -142,41 +113,6 @@ impl SimpleComponent for DevicesBox { } } } - Self::Input::DumpGenericTrackers => { - let added = dump_generic_trackers( - &self - .devices - .iter() - .filter(|d| d.dev_type == XRDeviceRole::GenericTracker) - .map(|d| d.id.clone()) - .collect::>(), - ); - let multi_title = format!("Added {} new trackers", added); - let (title, msg) = match added { - 0 => ( - "No new trackers found", - concat!( - "All the currently connected trackers ", - "are already present in your configuration" - ), - ), - 1 => ( - "Added 1 new tracker", - concat!( - "Edit your configuration to make sure that ", - "all the trackers have the appropriate roles assigned" - ), - ), - _ => ( - multi_title.as_str(), - concat!( - "Edit your configuration to make sure that ", - "all the trackers have the appropriate roles assigned" - ), - ), - }; - alert(title, Some(msg), None); - } } } diff --git a/src/ui/factories/mod.rs b/src/ui/factories/mod.rs index 6ff4479..dfa3b3d 100644 --- a/src/ui/factories/mod.rs +++ b/src/ui/factories/mod.rs @@ -1,4 +1,3 @@ pub mod device_row_factory; pub mod env_var_row_factory; -pub mod tracker_role_group_factory; pub mod wivrn_encoder_group_factory; diff --git a/src/ui/factories/tracker_role_group_factory.rs b/src/ui/factories/tracker_role_group_factory.rs deleted file mode 100644 index 9df2471..0000000 --- a/src/ui/factories/tracker_role_group_factory.rs +++ /dev/null @@ -1,106 +0,0 @@ -use crate::{ - file_builders::monado_config_v0::{TrackerRole, XrtTrackerRole}, - ui::fbt_config_editor::FbtConfigEditorMsg, - ui::preference_rows::{combo_row, entry_row}, -}; -use adw::prelude::*; -use gtk::glib::clone; -use relm4::{factory::AsyncFactoryComponent, prelude::*, AsyncFactorySender}; - -#[derive(Debug)] -pub struct TrackerRoleModel { - index: usize, - tracker_role: TrackerRole, -} - -pub struct TrackerRoleModelInit { - pub index: usize, - pub tracker_role: Option, -} - -#[derive(Debug)] -pub enum TrackerRoleModelMsg { - Changed(TrackerRole), - Delete, -} - -#[derive(Debug)] -pub enum TrackerRoleModelOutMsg { - Changed(usize, TrackerRole), - Delete(usize), -} - -#[relm4::factory(async pub)] -impl AsyncFactoryComponent for TrackerRoleModel { - type Init = TrackerRoleModelInit; - type Input = TrackerRoleModelMsg; - type Output = TrackerRoleModelOutMsg; - type CommandOutput = (); - type ParentWidget = adw::PreferencesPage; - - view! { - root = adw::PreferencesGroup { - set_title: "Tracker", - #[wrap(Some)] - set_header_suffix: del_btn = >k::Button { - set_icon_name: "edit-delete-symbolic", - set_tooltip_text: Some("Delete Tracker"), - set_valign: gtk::Align::Center, - add_css_class: "flat", - add_css_class: "circular", - connect_clicked[sender] => move |_| { - sender.input(Self::Input::Delete); - } - }, - add: { - let tr = self.tracker_role.clone(); - &entry_row( - "Device serial", - self.tracker_role.device_serial.as_str(), - clone!(@strong sender => move |row| { - let mut ntr = tr.clone(); - ntr.device_serial = row.text().to_string(); - sender.input(Self::Input::Changed(ntr)); - }) - ) - }, - add: { - let tr = self.tracker_role.clone(); - &combo_row("Tracker role", None, &tr.role.clone().to_picker_string(), - XrtTrackerRole::iter() - .map(XrtTrackerRole::to_picker_string) - .map(String::from) - .collect::>(), - clone!(@strong sender => move |row| { - let mut ntr = tr.clone(); - ntr.role = XrtTrackerRole::from_number(&row.selected()); - sender.input(Self::Input::Changed(ntr)); - }) - ) - }, - } - } - - async fn update(&mut self, message: Self::Input, sender: AsyncFactorySender) { - match message { - Self::Input::Changed(r) => { - self.tracker_role = r; - sender.output(Self::Output::Changed(self.index, self.tracker_role.clone())); - } - Self::Input::Delete => { - sender.output(Self::Output::Delete(self.index)); - } - } - } - - async fn init_model( - init: Self::Init, - _index: &DynamicIndex, - _sender: AsyncFactorySender, - ) -> Self { - Self { - index: init.index, - tracker_role: init.tracker_role.unwrap_or_else(|| TrackerRole::default()), - } - } -} diff --git a/src/ui/fbt_config_editor.rs b/src/ui/fbt_config_editor.rs deleted file mode 100644 index 1ea6ebd..0000000 --- a/src/ui/fbt_config_editor.rs +++ /dev/null @@ -1,173 +0,0 @@ -use super::factories::tracker_role_group_factory::{TrackerRoleModel, TrackerRoleModelOutMsg}; -use crate::{ - file_builders::monado_config_v0::{ - dump_monado_config_v0, get_monado_config_v0, MonadoConfigV0, TrackerRole, - }, - ui::factories::tracker_role_group_factory::TrackerRoleModelInit, -}; -use adw::prelude::*; -use gtk::glib::clone; -use relm4::{factory::AsyncFactoryVecDeque, prelude::*}; - -#[tracker::track] -pub struct FbtConfigEditor { - monado_config_v0: MonadoConfigV0, - - #[tracker::do_not_track] - win: Option, - - #[tracker::do_not_track] - tracker_role_groups: AsyncFactoryVecDeque, -} - -#[derive(Debug)] -pub enum FbtConfigEditorMsg { - Present, - Save, - TrackerRoleNew, - TrackerRoleChanged(usize, TrackerRole), - TrackerRoleDeleted(usize), - Repopulate, -} - -pub struct FbtConfigEditorInit { - pub root_win: gtk::Window, -} -#[relm4::component(pub)] -impl SimpleComponent for FbtConfigEditor { - type Init = FbtConfigEditorInit; - type Input = FbtConfigEditorMsg; - type Output = (); - - view! { - #[name(win)] - adw::Window { - set_title: Some("Full Body Trackers"), - set_modal: true, - set_transient_for: Some(&init.root_win), - set_default_height: 500, - set_default_width: 600, - adw::ToolbarView { - set_top_bar_style: adw::ToolbarStyle::Flat, - add_top_bar: headerbar = &adw::HeaderBar { - set_vexpand: false, - set_hexpand: true, - add_css_class: "flat", - pack_start: &add_btn, - pack_end: &save_btn, - }, - set_content: Some(&model.tracker_role_groups.widget().clone().upcast::()), - }, - } - } - - fn update(&mut self, message: Self::Input, sender: ComponentSender) { - self.reset(); - - match message { - Self::Input::Present => { - self.win.as_ref().unwrap().present(); - } - Self::Input::Save => { - dump_monado_config_v0(&self.monado_config_v0); - self.win.as_ref().unwrap().close(); - } - Self::Input::TrackerRoleChanged(index, n_role) => { - let role = self.monado_config_v0.tracker_roles.get_mut(index).unwrap(); - role.device_serial = n_role.device_serial; - role.role = n_role.role; - role.xrt_input_name = n_role.xrt_input_name; - } - Self::Input::TrackerRoleDeleted(index) => { - self.monado_config_v0.tracker_roles.remove(index); - sender.input(Self::Input::Repopulate); - } - Self::Input::TrackerRoleNew => { - self.monado_config_v0 - .tracker_roles - .push(TrackerRole::default()); - self.tracker_role_groups - .guard() - .push_back(TrackerRoleModelInit { - index: self.monado_config_v0.tracker_roles.len() - 1, - tracker_role: None, - }); - } - Self::Input::Repopulate => { - self.populate_tracker_roles(); - } - } - } - - fn init( - init: Self::Init, - root: Self::Root, - sender: ComponentSender, - ) -> ComponentParts { - let page = adw::PreferencesPage::builder().build(); - let add_btn = gtk::Button::builder() - .tooltip_text("Add Tracker") - .icon_name("list-add-symbolic") - .build(); - let save_btn = gtk::Button::builder() - .label("Save") - .css_classes(["suggested-action"]) - .build(); - add_btn.connect_clicked(clone!(@strong sender => move |_| { - sender.input(Self::Input::TrackerRoleNew); - })); - save_btn.connect_clicked(clone!(@strong sender => move |_| { - sender.input(Self::Input::Save); - })); - - let mut model = Self { - win: None, - tracker: 0, - monado_config_v0: get_monado_config_v0(), - tracker_role_groups: AsyncFactoryVecDeque::builder().launch(page).forward( - sender.input_sender(), - |msg| match msg { - TrackerRoleModelOutMsg::Changed(index, tracker_role) => { - Self::Input::TrackerRoleChanged(index, tracker_role.clone()) - } - TrackerRoleModelOutMsg::Delete(index) => Self::Input::TrackerRoleDeleted(index), - }, - ), - }; - - model.populate_tracker_roles(); - - let widgets = view_output!(); - model.win = Some(widgets.win.clone()); - - widgets.headerbar.pack_start(&add_btn); - widgets.headerbar.pack_end(&save_btn); - { - let win = widgets.win.clone(); - let sc = gtk::ShortcutController::new(); - sc.add_shortcut(gtk::Shortcut::new( - gtk::ShortcutTrigger::parse_string("Escape"), - Some(gtk::CallbackAction::new(move |_, _| { - win.close(); - gtk::glib::Propagation::Proceed - })), - )); - widgets.win.add_controller(sc); - } - - ComponentParts { model, widgets } - } -} - -impl FbtConfigEditor { - fn populate_tracker_roles(&mut self) { - let mut guard = self.tracker_role_groups.guard(); - guard.clear(); - for (i, v) in self.monado_config_v0.tracker_roles.iter().enumerate() { - guard.push_back(TrackerRoleModelInit { - index: i, - tracker_role: Some(v.clone()), - }); - } - } -} diff --git a/src/ui/main_view.rs b/src/ui/main_view.rs index d43d252..5c09e78 100644 --- a/src/ui/main_view.rs +++ b/src/ui/main_view.rs @@ -11,8 +11,7 @@ use crate::gpu_profile::{get_amd_gpu_power_profile, GpuPowerProfile}; use crate::profile::{LighthouseDriver, Profile, XRServiceType}; use crate::steamvr_utils::chaperone_info_exists; use crate::ui::app::{ - AboutAction, BuildProfileAction, BuildProfileCleanAction, ConfigFbtAction, - DebugViewToggleAction, + AboutAction, BuildProfileAction, BuildProfileCleanAction, DebugViewToggleAction, }; use crate::ui::profile_editor::ProfileEditorInit; use crate::ui::steamvr_calibration_box::SteamVrCalibrationBoxMsg; @@ -114,7 +113,6 @@ impl SimpleComponent for MainView { "_Debug View" => DebugViewToggleAction, "_Build Profile" => BuildProfileAction, "C_lean Build Profile" => BuildProfileCleanAction, - "Configure Full Body _Tracking" => ConfigFbtAction, }, section! { "_About" => AboutAction, diff --git a/src/ui/mod.rs b/src/ui/mod.rs index d474fca..862d9a6 100644 --- a/src/ui/mod.rs +++ b/src/ui/mod.rs @@ -7,7 +7,6 @@ pub mod cmdline_opts; mod debug_view; mod devices_box; mod factories; -mod fbt_config_editor; mod install_wivrn_box; pub mod job_worker; mod libsurvive_setup_window; diff --git a/src/xr_devices.rs b/src/xr_devices.rs index 795e8a6..2f34945 100644 --- a/src/xr_devices.rs +++ b/src/xr_devices.rs @@ -1,3 +1,4 @@ +use libmonado_rs; use std::{fmt::Display, slice::Iter}; const GENERIC_TRACKER_PREFIX: &str = "Found generic tracker device: "; @@ -105,7 +106,6 @@ impl XRDeviceRole { Self::Chest, Self::Camera, Self::Keyboard, - Self::GenericTracker, ] .iter() } @@ -228,7 +228,8 @@ impl XRDeviceRole { pub struct XRDevice { pub dev_type: XRDeviceRole, pub name: String, - pub id: String, + pub index: String, + pub serial: Option, pub battery: Option, // battery percentage, from 0 to 1 maybe // still need to implement it in monado } @@ -238,19 +239,21 @@ impl Default for XRDevice { Self { dev_type: XRDeviceRole::GenericTracker, name: String::default(), - id: String::default(), + index: String::default(), + serial: None, battery: Option::default(), } } } impl XRDevice { + #[deprecated] pub fn generic_tracker_from_log_row(s: &str) -> Option { if s.starts_with(GENERIC_TRACKER_PREFIX) { let n_tracker = s.trim_start_matches(GENERIC_TRACKER_PREFIX); return Some(Self { dev_type: XRDeviceRole::GenericTracker, - id: n_tracker.into(), + index: n_tracker.into(), ..Default::default() }); } @@ -274,6 +277,7 @@ impl XRDevice { pub fn from_libmonado(monado: &libmonado_rs::Monado) -> Vec { let mut res = vec![]; + let mut devs_with_role = vec![]; [ XRDeviceRole::Head, XRDeviceRole::Left, @@ -299,17 +303,48 @@ impl XRDevice { .iter() .for_each(|xrd| { if let Ok(dev) = monado.device_from_role(xrd.to_monado_str()) { + devs_with_role.push(dev.id); + // let serial = match dev.serial() { + // Ok(s) => { + // serials.push(s.clone()); + // Some(s) + // } + // Err(e) => { + // eprintln!( + // "Warning: could not get serial for monado device {} ({}): {:#?}", + // dev.name, dev.id, e + // ); + // None + // } + // }; res.push(Self { name: dev.name, - id: dev.id.to_string(), + index: dev.id.to_string(), + // serial, + serial: None, dev_type: xrd.clone(), ..Default::default() }) } }); + if let Ok(all_devs) = monado.devices() { + all_devs + .into_iter() + .filter(|dev| !devs_with_role.contains(&dev.id)) + .for_each(|dev_gt| { + res.push(Self { + name: dev_gt.name.clone(), + index: dev_gt.id.to_string(), + serial: dev_gt.serial().ok(), + dev_type: XRDeviceRole::GenericTracker, + ..Default::default() + }) + }) + } res } + #[deprecated] pub fn from_log_message(s: &str) -> Vec { let mut res = vec![]; let rows = s.split('\n'); @@ -359,19 +394,21 @@ impl XRDevice { .filter(|d| !new_dev_types.contains(&d.dev_type)) .map(Self::clone) .collect::>(); - let old_tracker_ids = old + let old_tracker_serials = old .iter() .filter_map(|d| { if d.dev_type == XRDeviceRole::GenericTracker { - return Some(d.id.clone()); + return d.serial.clone(); } None }) .collect::>(); for n_dev in new { if n_dev.dev_type == XRDeviceRole::GenericTracker { - if !old_tracker_ids.contains(&n_dev.id) { - res.push(n_dev.clone()); + if let Some(n_serial) = n_dev.serial.as_ref() { + if !old_tracker_serials.contains(n_serial) { + res.push(n_dev.clone()); + } } } else { res.push(n_dev.clone());