feat!: use libmonado to enumerate devices; role to monado string fixes

This commit is contained in:
Gabriele Musco 2023-11-03 20:29:28 +01:00
parent 6b567fac5b
commit 7266f0b2f0
No known key found for this signature in database
GPG key ID: 1068D795C80E51DE
5 changed files with 88 additions and 67 deletions

View file

@ -33,11 +33,13 @@ cd envision
./dist/appimage/build_appimage.sh
```
<!-- no feature flags for now :)
# Feature flags
|Env var|Values|Default|
|---|---|---|
|`ENVISION_FF_USE_LIBMONADO`|`1`: enabled; `0`: disabled|`0`|
-->
# Common issues

View file

@ -3,7 +3,6 @@ use super::alert::alert;
use super::build_window::{BuildStatus, BuildWindow};
use super::debug_view::{DebugView, DebugViewMsg};
use super::fbt_config_editor::{FbtConfigEditor, FbtConfigEditorInit, FbtConfigEditorMsg};
use super::feature_flags::FF_LIBMONADO_DEVICE_ENUMERATION_ENABLED;
use super::job_worker::internal_worker::JobWorkerOut;
use super::job_worker::job::WorkerJob;
use super::job_worker::JobWorker;
@ -343,26 +342,24 @@ impl SimpleComponent for App {
}
Msg::ClockTicking => {
self.main_view.sender().emit(MainViewMsg::ClockTicking);
if *FF_LIBMONADO_DEVICE_ENUMERATION_ENABLED {
if let Some(w) = self.xrservice_worker.as_ref() {
if {
let state = w.state.lock().unwrap();
state.exit_status.is_none() && !state.stop_requested
} {
if let Some(monado) = self.libmonado.as_ref() {
self.xr_devices = XRDevice::merge(
&self.xr_devices,
&XRDevice::from_libmonado(monado),
);
self.main_view
.sender()
.emit(MainViewMsg::UpdateDevices(self.xr_devices.clone()));
} else {
if let Some(so) = self.get_selected_profile().libmonado_so() {
self.libmonado = libmonado_rs::Monado::create(so).ok();
if self.libmonado.is_some() {
sender.input(Msg::ClockTicking);
}
if let Some(w) = self.xrservice_worker.as_ref() {
if {
let state = w.state.lock().unwrap();
state.exit_status.is_none() && !state.stop_requested
} {
if let Some(monado) = self.libmonado.as_ref() {
self.xr_devices = XRDevice::merge(
&self.xr_devices,
&XRDevice::from_libmonado(monado),
);
self.main_view
.sender()
.emit(MainViewMsg::UpdateDevices(self.xr_devices.clone()));
} else {
if let Some(so) = self.get_selected_profile().libmonado_so() {
self.libmonado = libmonado_rs::Monado::create(so).ok();
if self.libmonado.is_some() {
sender.input(Msg::ClockTicking);
}
}
}
@ -374,15 +371,7 @@ impl SimpleComponent for App {
match MonadoLog::new_from_str(row.as_str()) {
None => {}
Some(parsed) => {
if !*FF_LIBMONADO_DEVICE_ENUMERATION_ENABLED
&& parsed.func == "p_create_system"
{
let n_devs = XRDevice::from_log_message(parsed.message.as_str());
self.xr_devices = XRDevice::merge(&self.xr_devices, &n_devs);
self.main_view
.sender()
.emit(MainViewMsg::UpdateDevices(self.xr_devices.clone()));
} else if let Some(tracker) =
if let Some(tracker) =
XRDevice::generic_tracker_from_log_row(parsed.message.as_str())
{
self.xr_devices.push(tracker);

View file

@ -4,7 +4,7 @@ use super::{
};
use crate::{
file_builders::monado_config_v0::dump_generic_trackers,
xr_devices::{XRDevice, XRDeviceType},
xr_devices::{XRDevice, XRDeviceRole},
};
use adw::prelude::*;
use relm4::{factory::AsyncFactoryVecDeque, prelude::*, Sender};
@ -75,7 +75,7 @@ impl SimpleComponent for DevicesBox {
let mut generic: Vec<&XRDevice> = vec![];
for dev in &self.devices {
match dev.dev_type {
XRDeviceType::Head => {
XRDeviceRole::Head => {
has_head = true;
let mut init = DeviceRowModelInit::from_xr_device(&dev);
if dev.name == "Simulated HMD" {
@ -84,15 +84,15 @@ impl SimpleComponent for DevicesBox {
}
models.push(init);
}
XRDeviceType::Left => {
XRDeviceRole::Left => {
has_left = true;
models.push(DeviceRowModelInit::from_xr_device(&dev));
}
XRDeviceType::Right => {
XRDeviceRole::Right => {
has_right = true;
models.push(DeviceRowModelInit::from_xr_device(&dev));
}
XRDeviceType::GenericTracker => {
XRDeviceRole::GenericTracker => {
generic.push(dev);
}
_ => {
@ -102,7 +102,7 @@ impl SimpleComponent for DevicesBox {
}
if !generic.is_empty() {
models.push(DeviceRowModelInit {
title: Some(XRDeviceType::GenericTracker.to_string()),
title: Some(XRDeviceRole::GenericTracker.to_string()),
subtitle: Some(
generic
.iter()
@ -118,20 +118,20 @@ impl SimpleComponent for DevicesBox {
});
}
if !has_right {
models.push(DeviceRowModelInit::new_missing(XRDeviceType::Right));
models.push(DeviceRowModelInit::new_missing(XRDeviceRole::Right));
}
if !has_left {
models.push(DeviceRowModelInit::new_missing(XRDeviceType::Left));
models.push(DeviceRowModelInit::new_missing(XRDeviceRole::Left));
}
if !has_head {
models.push(DeviceRowModelInit::new_missing(XRDeviceType::Head));
models.push(DeviceRowModelInit::new_missing(XRDeviceRole::Head));
}
models.sort_by(|m1, m2| {
let dt1 = XRDeviceType::from_display_str(
let dt1 = XRDeviceRole::from_display_str(
m1.title.as_ref().unwrap_or(&String::new()),
);
let dt2 = XRDeviceType::from_display_str(
let dt2 = XRDeviceRole::from_display_str(
m2.title.as_ref().unwrap_or(&String::new()),
);
dt1.cmp(&dt2)
@ -147,7 +147,7 @@ impl SimpleComponent for DevicesBox {
&self
.devices
.iter()
.filter(|d| d.dev_type == XRDeviceType::GenericTracker)
.filter(|d| d.dev_type == XRDeviceRole::GenericTracker)
.map(|d| d.id.clone())
.collect::<Vec<String>>(),
);

View file

@ -3,7 +3,7 @@ use relm4::{factory::AsyncFactoryComponent, prelude::*, AsyncFactorySender};
use crate::{
ui::devices_box::DevicesBoxMsg,
xr_devices::{XRDevice, XRDeviceType},
xr_devices::{XRDevice, XRDeviceRole},
};
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
@ -62,7 +62,7 @@ impl DeviceRowModelInit {
}
}
pub fn new_missing(t: XRDeviceType) -> Self {
pub fn new_missing(t: XRDeviceRole) -> Self {
DeviceRowModelInit {
title: Some(t.to_string()),
subtitle: Some("None".into()),

View file

@ -3,7 +3,7 @@ use std::{fmt::Display, slice::Iter};
const GENERIC_TRACKER_PREFIX: &str = "Found generic tracker device: ";
#[derive(Debug, Clone, PartialEq, Eq, Copy)]
pub enum XRDeviceType {
pub enum XRDeviceRole {
Head,
Left,
Right,
@ -12,9 +12,19 @@ pub enum XRDeviceType {
HandTrackingLeft,
HandTrackingRight,
GenericTracker,
/**
* Devices with no role
*/
Other,
}
impl Display for XRDeviceType {
impl Default for XRDeviceRole {
fn default() -> Self {
Self::Other
}
}
impl Display for XRDeviceRole {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.write_str(match self {
Self::Head => "Head",
@ -25,23 +35,24 @@ impl Display for XRDeviceType {
Self::HandTrackingLeft => "Hand tracking left",
Self::HandTrackingRight => "Hand tracking right",
Self::GenericTracker => "Generic tracker",
Self::Other => "",
})
}
}
impl PartialOrd for XRDeviceType {
impl PartialOrd for XRDeviceRole {
fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
Some(self.as_number().cmp(&other.as_number()))
}
}
impl Ord for XRDeviceType {
impl Ord for XRDeviceRole {
fn cmp(&self, other: &Self) -> std::cmp::Ordering {
self.partial_cmp(other).unwrap()
}
}
impl XRDeviceType {
impl XRDeviceRole {
pub fn iter() -> Iter<'static, Self> {
[
Self::Head,
@ -63,9 +74,10 @@ impl XRDeviceType {
Self::Right => "right",
Self::Gamepad => "gamepad",
Self::Eyes => "eyes",
Self::HandTrackingLeft => "hand_tracking.left",
Self::HandTrackingRight => "hand_tracking.right",
Self::GenericTracker => "generic_tracker",
Self::HandTrackingLeft => "hand-tracking-left",
Self::HandTrackingRight => "hand-tracking-right",
Self::GenericTracker => "generic-tracker", // not actually in monado
Self::Other => "other", // not actually in monado
}
}
@ -79,6 +91,7 @@ impl XRDeviceType {
Self::HandTrackingLeft => 5,
Self::HandTrackingRight => 6,
Self::GenericTracker => 7,
Self::Other => 8,
}
}
@ -89,8 +102,8 @@ impl XRDeviceType {
"right" => Some(Self::Right),
"gamepad" => Some(Self::Gamepad),
"eyes" => Some(Self::Eyes),
"hand_tracking.left" => Some(Self::HandTrackingLeft),
"hand_tracking.right" => Some(Self::HandTrackingRight),
"hand-tracking-left" => Some(Self::HandTrackingLeft),
"hand-tracking-right" => Some(Self::HandTrackingRight),
_ => None,
}
}
@ -112,7 +125,7 @@ impl XRDeviceType {
#[derive(Debug, Clone, PartialEq)]
pub struct XRDevice {
pub dev_type: XRDeviceType,
pub dev_type: XRDeviceRole,
pub name: String,
pub id: String,
pub battery: f32, // battery percentage, from 0 to 1 maybe
@ -122,7 +135,7 @@ pub struct XRDevice {
impl Default for XRDevice {
fn default() -> Self {
Self {
dev_type: XRDeviceType::GenericTracker,
dev_type: XRDeviceRole::GenericTracker,
name: String::default(),
id: String::default(),
battery: f32::default(),
@ -135,7 +148,7 @@ impl XRDevice {
if s.starts_with(GENERIC_TRACKER_PREFIX) {
let n_tracker = s.trim_start_matches(GENERIC_TRACKER_PREFIX);
return Some(Self {
dev_type: XRDeviceType::GenericTracker,
dev_type: XRDeviceRole::GenericTracker,
id: n_tracker.into(),
..Default::default()
});
@ -143,14 +156,31 @@ impl XRDevice {
None
}
/* pub fn from_libmonado_devices(monado: &libmonado_rs::Monado) -> Vec<Self> {
if let Ok(devs) = monado.devices() {
return devs
.into_iter()
.map(|xrd| Self {
id: xrd.id.to_string(),
name: xrd.name,
..Default::default()
})
.collect();
}
vec![]
} */
pub fn from_libmonado(monado: &libmonado_rs::Monado) -> Vec<Self> {
let mut res = vec![];
[
XRDeviceType::Head,
XRDeviceType::Left,
XRDeviceType::Right,
XRDeviceType::Gamepad,
XRDeviceType::Eyes,
XRDeviceRole::Head,
XRDeviceRole::Left,
XRDeviceRole::Right,
XRDeviceRole::HandTrackingLeft,
XRDeviceRole::HandTrackingRight,
XRDeviceRole::Gamepad,
XRDeviceRole::Eyes,
]
.iter()
.for_each(|xrd| {
@ -182,7 +212,7 @@ impl XRDevice {
match row.trim().split(": ").collect::<Vec<&str>>()[..] {
[_, "<none>"] => {}
[dev_type_s, name] => {
if let Some(xrdt) = XRDeviceType::from_monado_str(dev_type_s) {
if let Some(xrdt) = XRDeviceRole::from_monado_str(dev_type_s) {
res.push(Self {
dev_type: xrdt,
name: name.to_string(),
@ -204,12 +234,12 @@ impl XRDevice {
let new_dev_types = new
.iter()
.filter_map(|d| {
if d.dev_type == XRDeviceType::GenericTracker {
if d.dev_type == XRDeviceRole::GenericTracker {
return None;
}
Some(d.dev_type)
})
.collect::<Vec<XRDeviceType>>();
.collect::<Vec<XRDeviceRole>>();
let mut res = old
.iter()
.filter(|d| !new_dev_types.contains(&d.dev_type))
@ -218,14 +248,14 @@ impl XRDevice {
let old_tracker_ids = old
.iter()
.filter_map(|d| {
if d.dev_type == XRDeviceType::GenericTracker {
if d.dev_type == XRDeviceRole::GenericTracker {
return Some(d.id.clone());
}
None
})
.collect::<Vec<String>>();
for n_dev in new {
if n_dev.dev_type == XRDeviceType::GenericTracker {
if n_dev.dev_type == XRDeviceRole::GenericTracker {
if !old_tracker_ids.contains(&n_dev.id) {
res.push(n_dev.clone());
}