feat: persistent xr_devices; parse generic trackers

This commit is contained in:
Gabriele Musco 2023-08-21 20:40:26 +00:00
parent b71e92fa2d
commit 0e6028b0db
3 changed files with 89 additions and 15 deletions

View file

@ -83,7 +83,7 @@ pub struct App {
#[tracker::do_not_track]
profiles: Vec<Profile>,
#[tracker::do_not_track]
devices_processed: bool,
xr_devices: XRDevices,
}
#[derive(Debug)]
@ -100,7 +100,7 @@ pub enum Msg {
OpenLibsurviveSetup,
SaveWinSize(i32, i32),
Quit,
ProcessDevicesLog(Vec<String>),
ParseLog(Vec<String>),
}
impl App {
@ -145,11 +145,8 @@ impl App {
);
return;
};
self.devices_processed = match prof.xrservice_type {
XRServiceType::Monado => false,
XRServiceType::Wivrn => true, // no device from log in wivrn
};
self.debug_view.sender().emit(DebugViewMsg::ClearLog);
self.xr_devices = XRDevices::default();
let mut runner = CmdRunner::xrservice_runner_from_profile(&prof);
match runner.try_start() {
Ok(_) => {
@ -203,6 +200,7 @@ impl App {
self.main_view
.sender()
.emit(MainViewMsg::XRServiceActiveChanged(false, None));
self.xr_devices = XRDevices::default();
}
pub fn profiles_list(config: &Config) -> Vec<Profile> {
@ -277,9 +275,7 @@ impl SimpleComponent for App {
Some(runner) => {
let n_rows = runner.consume_rows();
if !n_rows.is_empty() {
if !self.devices_processed {
sender.input(Msg::ProcessDevicesLog(n_rows.clone()))
}
sender.input(Msg::ParseLog(n_rows.clone()));
self.debug_view
.sender()
.emit(DebugViewMsg::LogUpdated(n_rows));
@ -336,22 +332,25 @@ impl SimpleComponent for App {
};
self.main_view.sender().emit(MainViewMsg::ClockTicking);
}
Msg::ProcessDevicesLog(rows) => {
Msg::ParseLog(rows) => {
for row in rows {
match MonadoLog::new_from_str(row.as_str()) {
None => {}
Some(parsed) => {
if parsed.func == "p_create_system" {
match XRDevices::from_log_message(parsed.message) {
match XRDevices::from_log_message(parsed.message.as_str()) {
None => {}
Some(devices) => {
self.devices_processed = true;
self.xr_devices.merge(devices.clone());
self.main_view
.sender()
.emit(MainViewMsg::UpdateDevices(Some(devices)));
.emit(MainViewMsg::UpdateDevices(Some(self.xr_devices.clone())));
break;
}
};
} else {
self.xr_devices
.search_log_for_generic_trackers(parsed.message.as_str());
}
}
};
@ -616,7 +615,7 @@ impl SimpleComponent for App {
profiles,
xrservice_runner: None,
build_pipeline: None,
devices_processed: false,
xr_devices: XRDevices::default(),
};
let widgets = view_output!();

View file

@ -24,6 +24,13 @@ impl DevicesBox {
XRDevice::Eyes => devs.eyes.clone(),
XRDevice::HandTrackingLeft => devs.hand_tracking_left.clone(),
XRDevice::HandTrackingRight => devs.hand_tracking_right.clone(),
XRDevice::GenericTracker => {
if devs.generic_trackers.is_empty() {
return None;
} else {
return Some(devs.generic_trackers.join(", "));
}
}
},
}
}
@ -223,6 +230,28 @@ impl SimpleComponent for DevicesBox {
}).as_str(),
},
},
// Generic Trackers
gtk::Box {
set_orientation: gtk::Orientation::Horizontal,
set_hexpand: true,
set_spacing: 12,
set_margin_start: 12,
set_margin_end: 12,
#[track = "model.changed(Self::devices())"]
set_visible: model.get_dev(XRDevice::GenericTracker).is_some(),
gtk::Image {
set_icon_name: Some("emblem-ok-symbolic"),
},
gtk::Label {
set_xalign: 0.0,
set_hexpand: true,
#[track = "model.changed(Self::devices())"]
set_label: format!("Generic Trackers: {}", match model.get_dev(XRDevice::GenericTracker) {
Some(v) => v.clone(),
None => "None".to_string(),
}).as_str(),
},
},
}
}

View file

@ -7,6 +7,7 @@ pub enum XRDevice {
Eyes,
HandTrackingLeft,
HandTrackingRight,
GenericTracker,
}
#[derive(Debug, Default, Clone, PartialEq, Eq)]
@ -18,10 +19,13 @@ pub struct XRDevices {
pub eyes: Option<String>,
pub hand_tracking_left: Option<String>,
pub hand_tracking_right: Option<String>,
pub generic_trackers: Vec<String>,
}
const GENERIC_TRACKER_PREFIX: &str = "Found generic tracker device: ";
impl XRDevices {
pub fn from_log_message(s: String) -> Option<Self> {
pub fn from_log_message(s: &str) -> Option<Self> {
let rows = s.split('\n');
let mut in_section = false;
let mut devs = Self::default();
@ -54,4 +58,46 @@ impl XRDevices {
}
None
}
pub fn merge(&mut self, new: Self) {
if new.head.is_some() {
self.head = new.head;
}
if new.left.is_some() {
self.left = new.left;
}
if new.right.is_some() {
self.right = new.right;
}
if new.gamepad.is_some() {
self.gamepad = new.gamepad;
}
if new.eyes.is_some() {
self.eyes = new.eyes;
}
if new.hand_tracking_left.is_some() {
self.hand_tracking_left = new.hand_tracking_left;
}
if new.hand_tracking_right.is_some() {
self.hand_tracking_right = new.hand_tracking_right;
}
if !new.generic_trackers.is_empty() {
self.generic_trackers.extend(
new.generic_trackers
.iter()
.filter(|t| !self.generic_trackers.contains(t))
.cloned()
.collect::<Vec<String>>(),
);
}
}
pub fn search_log_for_generic_trackers(&mut self, s: &str) {
if s.starts_with(GENERIC_TRACKER_PREFIX) {
let n_tracker = s.trim_start_matches(GENERIC_TRACKER_PREFIX);
if !self.generic_trackers.contains(&n_tracker.to_string()) {
self.generic_trackers.push(n_tracker.into());
}
}
}
}