diff --git a/src/builders/build_basalt.rs b/src/builders/build_basalt.rs index 24e445c..a72e0d5 100644 --- a/src/builders/build_basalt.rs +++ b/src/builders/build_basalt.rs @@ -4,7 +4,7 @@ use crate::{constants::PKG_DATA_DIR, profile::Profile, runner::Runner}; pub fn get_build_basalt_runner(profile: Profile) -> Runner { let mut args = vec![ profile - .basalt_path + .features.basalt.path .expect_dialog("Missing basalt path for given profile"), profile.prefix, match profile.pull_on_build { @@ -12,8 +12,8 @@ pub fn get_build_basalt_runner(profile: Profile) -> Runner { false => "0".into(), }, ]; - if profile.basalt_repo.is_some() { - args.push(profile.basalt_repo.unwrap()); + if profile.features.basalt.repo.is_some() { + args.push(profile.features.basalt.repo.unwrap()); } let runner = Runner::new( None, diff --git a/src/builders/build_libsurvive.rs b/src/builders/build_libsurvive.rs index df9f7ff..a784ac5 100644 --- a/src/builders/build_libsurvive.rs +++ b/src/builders/build_libsurvive.rs @@ -4,7 +4,7 @@ use expect_dialog::ExpectDialog; pub fn get_build_libsurvive_runner(profile: Profile) -> Runner { let mut args = vec![ profile - .libsurvive_path + .features.libsurvive.path .expect_dialog("Missing libsurvive path for given profile"), profile.prefix, match profile.pull_on_build { @@ -12,8 +12,8 @@ pub fn get_build_libsurvive_runner(profile: Profile) -> Runner { false => "0".into(), }, ]; - if profile.libsurvive_repo.is_some() { - args.push(profile.libsurvive_repo.unwrap()); + if profile.features.libsurvive.repo.is_some() { + args.push(profile.features.libsurvive.repo.unwrap()); } let runner = Runner::new( None, diff --git a/src/profile.rs b/src/profile.rs index 292fe16..7edfc50 100644 --- a/src/profile.rs +++ b/src/profile.rs @@ -43,24 +43,93 @@ impl Display for XRServiceType { } } +#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] +pub enum ProfileFeatureType { + Libsurvive, + Basalt, + Mercury, +} + +impl ProfileFeatureType { + pub fn from_string(s: String) -> Self { + match s.trim().to_lowercase().as_str() { + "libsurvive" => Self::Libsurvive, + "basalt" => Self::Basalt, + "mercury" => Self::Mercury, + _ => panic!("Unknown profile feature type"), + } + } + + pub fn iter() -> Iter<'static, ProfileFeatureType> { + [Self::Libsurvive, Self::Basalt, Self::Mercury].iter() + } +} + +impl Display for ProfileFeatureType { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.write_str(match self { + Self::Libsurvive => "Libsurvive", + Self::Basalt => "Basalt", + Self::Mercury => "Mercury", + }) + } +} + +#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] +pub struct ProfileFeature { + pub feature_type: ProfileFeatureType, + pub enabled: bool, + pub path: Option, + pub repo: Option, +} + +impl Default for ProfileFeature { + fn default() -> Self { + Self { + feature_type: ProfileFeatureType::Libsurvive, + enabled: false, + path: None, + repo: None, + } + } +} + +#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] +pub struct ProfileFeatures { + pub libsurvive: ProfileFeature, + pub basalt: ProfileFeature, + pub mercury: ProfileFeature, +} + +impl Default for ProfileFeatures { + fn default() -> Self { + Self { + libsurvive: ProfileFeature { + feature_type: ProfileFeatureType::Libsurvive, + ..Default::default() + }, + basalt: ProfileFeature { + feature_type: ProfileFeatureType::Basalt, + ..Default::default() + }, + mercury: ProfileFeature { + feature_type: ProfileFeatureType::Mercury, + ..Default::default() + }, + } + } +} + #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] pub struct Profile { pub uuid: String, pub name: String, - pub xrservice_path: String, pub xrservice_type: XRServiceType, - pub opencomposite_path: String, - pub libsurvive_path: Option, - pub basalt_path: Option, - pub mercury_path: Option, - pub libsurvive_enabled: bool, - pub basalt_enabled: bool, - pub mercury_enabled: bool, + pub xrservice_path: String, pub xrservice_repo: Option, + pub opencomposite_path: String, pub opencomposite_repo: Option, - pub libsurvive_repo: Option, - pub basalt_repo: Option, - pub mercury_repo: Option, + pub features: ProfileFeatures, pub environment: HashMap, /** Install prefix */ pub prefix: String, @@ -83,12 +152,20 @@ impl Default for Profile { xrservice_path: data_monado_path(), xrservice_type: XRServiceType::Monado, opencomposite_path: data_opencomposite_path(), - basalt_path: None, - mercury_path: None, - libsurvive_path: None, - basalt_enabled: false, - mercury_enabled: false, - libsurvive_enabled: false, + features: ProfileFeatures { + libsurvive: ProfileFeature { + feature_type: ProfileFeatureType::Libsurvive, + ..Default::default() + }, + basalt: ProfileFeature { + feature_type: ProfileFeatureType::Basalt, + ..Default::default() + }, + mercury: ProfileFeature { + feature_type: ProfileFeatureType::Mercury, + ..Default::default() + }, + }, environment: HashMap::new(), prefix: format!( "{data}/prefixes/default_profile_prefix", @@ -98,9 +175,6 @@ impl Default for Profile { pull_on_build: true, xrservice_repo: None, opencomposite_repo: None, - libsurvive_repo: None, - basalt_repo: None, - mercury_repo: None, editable: true, } } @@ -156,21 +230,27 @@ impl Profile { && !self.uuid.is_empty() && !self.xrservice_path.is_empty() && !self.prefix.is_empty() - && (!self.libsurvive_enabled + && (!self.features.libsurvive.enabled || !self - .libsurvive_path + .features + .libsurvive + .path .as_ref() .unwrap_or(&"".to_string()) .is_empty()) - && (!self.basalt_enabled + && (!self.features.basalt.enabled || !self - .basalt_path + .features + .basalt + .path .as_ref() .unwrap_or(&"".to_string()) .is_empty()) - && (!self.mercury_enabled + && (!self.features.mercury.enabled || !self - .mercury_path + .features + .mercury + .path .as_ref() .unwrap_or(&"".to_string()) .is_empty()) @@ -181,7 +261,7 @@ impl Profile { mod tests { use std::collections::HashMap; - use crate::profile::XRServiceType; + use crate::profile::{ProfileFeature, ProfileFeatureType, ProfileFeatures, XRServiceType}; use super::Profile; @@ -193,14 +273,14 @@ mod tests { assert_eq!(profile.opencomposite_path, "/home/user/opencomposite"); assert_eq!(profile.prefix, "/home/user/rex2prefix"); assert_eq!( - profile.libsurvive_path.as_deref(), + profile.features.libsurvive.path.as_deref(), Some("/home/user/libsurvive") ); - assert_eq!(profile.mercury_path, None); - assert_eq!(profile.basalt_path, None); - assert_eq!(profile.libsurvive_enabled, true); - assert_eq!(profile.basalt_enabled, false); - assert_eq!(profile.mercury_enabled, false); + assert_eq!(profile.features.mercury.path, None); + assert_eq!(profile.features.basalt.path, None); + assert_eq!(profile.features.libsurvive.enabled, true); + assert_eq!(profile.features.basalt.enabled, false); + assert_eq!(profile.features.mercury.enabled, false); assert!(profile .environment .contains_key("XRT_COMPOSITOR_SCALE_PERCENTAGE")); @@ -221,12 +301,22 @@ mod tests { xrservice_path: String::from("/home/user/monado"), xrservice_type: XRServiceType::Monado, opencomposite_path: String::from("/home/user/opencomposite"), - libsurvive_path: Some(String::from("/home/user/libsurvive")), - basalt_path: None, - mercury_path: None, - libsurvive_enabled: true, - basalt_enabled: false, - mercury_enabled: false, + features: ProfileFeatures { + libsurvive: ProfileFeature { + feature_type: ProfileFeatureType::Libsurvive, + enabled: true, + path: Some(String::from("/home/user/libsurvive")), + repo: None, + }, + basalt: ProfileFeature { + feature_type: ProfileFeatureType::Basalt, + ..Default::default() + }, + mercury: ProfileFeature { + feature_type: ProfileFeatureType::Mercury, + ..Default::default() + }, + }, environment: env, prefix: String::from("/home/user/rex2prefix"), editable: true, @@ -237,7 +327,7 @@ mod tests { let loaded = Profile::load_profile(&fpath); assert_eq!(loaded.name, "Demo profile"); assert_eq!( - loaded.libsurvive_path, + loaded.features.libsurvive.path, Some(String::from("/home/user/libsurvive")) ); assert_eq!( diff --git a/src/profiles/system_valve_index.rs b/src/profiles/system_valve_index.rs index 23b9fd4..d7f0380 100644 --- a/src/profiles/system_valve_index.rs +++ b/src/profiles/system_valve_index.rs @@ -1,4 +1,8 @@ -use crate::{constants::APP_NAME, paths::{data_opencomposite_path, SYSTEM_PREFIX}, profile::{Profile, XRServiceType}}; +use crate::{ + constants::APP_NAME, + paths::{data_opencomposite_path, SYSTEM_PREFIX}, + profile::{Profile, ProfileFeatures, XRServiceType}, +}; use std::collections::HashMap; pub fn system_valve_index_profile() -> Profile { @@ -13,12 +17,9 @@ pub fn system_valve_index_profile() -> Profile { opencomposite_path: data_opencomposite_path(), xrservice_path: "".into(), xrservice_type: XRServiceType::Monado, - libsurvive_path: None, - basalt_path: None, - mercury_path: None, - libsurvive_enabled: false, - mercury_enabled: false, - basalt_enabled: false, + features: ProfileFeatures { + ..Default::default() + }, environment, prefix: SYSTEM_PREFIX.into(), can_be_built: false, diff --git a/src/profiles/valve_index.rs b/src/profiles/valve_index.rs index cd02a47..3b5cbde 100644 --- a/src/profiles/valve_index.rs +++ b/src/profiles/valve_index.rs @@ -1,4 +1,9 @@ -use crate::{constants::APP_NAME, file_utils::get_data_dir, profile::{Profile, XRServiceType}, paths::{data_monado_path, data_opencomposite_path, data_libsurvive_path}}; +use crate::{ + constants::APP_NAME, + file_utils::get_data_dir, + paths::{data_libsurvive_path, data_monado_path, data_opencomposite_path}, + profile::{Profile, ProfileFeature, ProfileFeatureType, ProfileFeatures, XRServiceType}, +}; use std::collections::HashMap; pub fn valve_index_profile() -> Profile { @@ -16,12 +21,15 @@ pub fn valve_index_profile() -> Profile { xrservice_path: data_monado_path(), xrservice_type: XRServiceType::Monado, opencomposite_path: data_opencomposite_path(), - libsurvive_path: Some(data_libsurvive_path()), - basalt_path: None, - mercury_path: None, - libsurvive_enabled: true, - basalt_enabled: false, - mercury_enabled: false, + features: ProfileFeatures { + libsurvive: ProfileFeature { + feature_type: ProfileFeatureType::Libsurvive, + enabled: true, + path: Some(data_libsurvive_path()), + repo: None, + }, + ..Default::default() + }, environment, prefix, can_be_built: true, diff --git a/src/profiles/wivrn.rs b/src/profiles/wivrn.rs index 729c09d..34da608 100644 --- a/src/profiles/wivrn.rs +++ b/src/profiles/wivrn.rs @@ -1,7 +1,11 @@ +use crate::{ + constants::APP_NAME, + file_utils::get_data_dir, + paths::{data_opencomposite_path, data_wivrn_path}, + profile::{Profile, ProfileFeatures, XRServiceType}, +}; use std::collections::HashMap; -use crate::{file_utils::get_data_dir, profile::{Profile, XRServiceType}, paths::{data_wivrn_path, data_opencomposite_path}, constants::APP_NAME}; - pub fn wivrn_profile() -> Profile { let data_dir = get_data_dir(); let prefix = format!("{data}/prefixes/wivrn_default", data = data_dir); @@ -13,12 +17,9 @@ pub fn wivrn_profile() -> Profile { xrservice_path: data_wivrn_path(), xrservice_type: XRServiceType::Wivrn, opencomposite_path: data_opencomposite_path(), - libsurvive_path: None, - basalt_path: None, - mercury_path: None, - libsurvive_enabled: false, - basalt_enabled: false, - mercury_enabled: false, + features: ProfileFeatures { + ..Default::default() + }, environment, prefix, can_be_built: true, diff --git a/src/ui/app.rs b/src/ui/app.rs index aee203b..bed15bf 100644 --- a/src/ui/app.rs +++ b/src/ui/app.rs @@ -285,15 +285,15 @@ impl SimpleComponent for App { XRServiceType::Monado => get_missing_monado_deps(), XRServiceType::Wivrn => get_missing_wivrn_deps(), }); - if profile.libsurvive_enabled { + if profile.features.libsurvive.enabled { missing_deps.extend(get_missing_libsurvive_deps()); runners.push(get_build_libsurvive_runner(profile.clone())); } - if profile.basalt_enabled { + if profile.features.basalt.enabled { missing_deps.extend(get_missing_basalt_deps()); runners.push(get_build_basalt_runner(profile.clone())); } - // if profile.mercury_enabled { + // if profile.features.mercury.enabled { // missing_deps.extend(get_missing_mercury_deps()); // runners.push(get_build_mercury_runner(profile.clone())); // } diff --git a/src/ui/profile_editor.rs b/src/ui/profile_editor.rs index a1dd873..c205cd5 100644 --- a/src/ui/profile_editor.rs +++ b/src/ui/profile_editor.rs @@ -148,19 +148,19 @@ impl SimpleComponent for ProfileEditor { name: "Libsurvive".into(), description: Some("Lighthouse based spacial tracking".into()), key: "libsurvive_enabled".into(), - value: p.libsurvive_enabled, + value: p.features.libsurvive.enabled, }); guard.push_back(SwitchModelInit { name: "Basalt".into(), description: Some("Camera based SLAM tracking".into()), key: "basalt_enabled".into(), - value: p.basalt_enabled, + value: p.features.basalt.enabled, }); guard.push_back(SwitchModelInit { name: "Mercury".into(), description: Some("Camera based hand tracking".into()), key: "mercury_enabled".into(), - value: p.mercury_enabled, + value: p.features.mercury.enabled, }); } @@ -180,17 +180,17 @@ impl SimpleComponent for ProfileEditor { guard.push_back(PathModelInit { name: "Libsurvive Path".into(), key: "libsurvive_path".into(), - value: p.libsurvive_path, + value: p.features.libsurvive.path, }); guard.push_back(PathModelInit { name: "Basalt Path".into(), key: "basalt_path".into(), - value: p.basalt_path, + value: p.features.basalt.path, }); guard.push_back(PathModelInit { name: "Mercury Path".into(), key: "mercury_path".into(), - value: p.mercury_path, + value: p.features.mercury.path, }); guard.push_back(PathModelInit { name: "Install Prefix".into(), @@ -215,17 +215,17 @@ impl SimpleComponent for ProfileEditor { guard.push_back(EntryModelInit { key: "libsurvive_repo".into(), name: "Libsurvive Repo".into(), - value: p.libsurvive_repo.unwrap_or("".into()), + value: p.features.libsurvive.repo.unwrap_or("".into()), }); guard.push_back(EntryModelInit { key: "basalt_repo".into(), name: "Basalt Repo".into(), - value: p.basalt_repo.unwrap_or("".into()), + value: p.features.basalt.repo.unwrap_or("".into()), }); guard.push_back(EntryModelInit { key: "mercury_repo".into(), name: "Mercury Repo".into(), - value: p.mercury_repo.unwrap_or("".into()), + value: p.features.mercury.repo.unwrap_or("".into()), }); } @@ -271,9 +271,9 @@ impl SimpleComponent for ProfileEditor { "opencomposite_path" => { prof.opencomposite_path = value.unwrap_or("".to_string()) } - "libsurvive_path" => prof.libsurvive_path = value, - "basalt_path" => prof.basalt_path = value, - "mercury_path" => prof.mercury_path = value, + "libsurvive_path" => prof.features.libsurvive.path = value, + "basalt_path" => prof.features.basalt.path = value, + "mercury_path" => prof.features.mercury.path = value, "prefix" => prof.prefix = value.unwrap_or("".to_string()), _ => panic!("Unknown profile path key"), } @@ -281,9 +281,9 @@ impl SimpleComponent for ProfileEditor { Self::Input::SwitchChanged(key, value) => { let prof = self.profile.as_mut().unwrap(); match key.as_str() { - "libsurvive_enabled" => prof.libsurvive_enabled = value, - "basalt_enabled" => prof.basalt_enabled = value, - "mercury_enabled" => prof.mercury_enabled = value, + "libsurvive_enabled" => prof.features.libsurvive.enabled = value, + "basalt_enabled" => prof.features.basalt.enabled = value, + "mercury_enabled" => prof.features.mercury.enabled = value, "pull_on_build" => prof.pull_on_build = value, _ => panic!("Unknown profile switch key"), } @@ -305,19 +305,19 @@ impl SimpleComponent for ProfileEditor { } } "libsurvive_repo" => { - prof.libsurvive_repo = match value.trim() { + prof.features.libsurvive.repo = match value.trim() { "" => None, s => Some(s.to_string()), } } "basalt_repo" => { - prof.basalt_repo = match value.trim() { + prof.features.basalt.repo = match value.trim() { "" => None, s => Some(s.to_string()), } } "mercury_repo" => { - prof.mercury_repo = match value.trim() { + prof.features.mercury.repo = match value.trim() { "" => None, s => Some(s.to_string()), } diff --git a/test/files/profile.json b/test/files/profile.json index ba94c82..eec734b 100644 --- a/test/files/profile.json +++ b/test/files/profile.json @@ -1,15 +1,31 @@ { "uuid": "demo", "name": "Demo profile", - "xrservice_path": "/home/user/monado", "xrservice_type": "Monado", + "xrservice_path": "/home/user/monado", + "xrservice_repo": null, "opencomposite_path": "/home/user/opencomposite", - "libsurvive_path": "/home/user/libsurvive", - "basalt_path": null, - "mercury_path": null, - "libsurvive_enabled": true, - "basalt_enabled": false, - "mercury_enabled": false, + "opencomposite_repo": null, + "features": { + "libsurvive": { + "feature_type": "Libsurvive", + "enabled": true, + "path": "/home/user/libsurvive", + "repo": null + }, + "basalt": { + "feature_type": "Basalt", + "enabled": false, + "path": null, + "repo": null + }, + "mercury": { + "feature_type": "Mercury", + "enabled": false, + "path": null, + "repo": null + } + }, "environment": { "XRT_COMPOSITOR_SCALE_PERCENTAGE": "140", "XRT_COMPOSITOR_COMPUTE": "1", @@ -18,10 +34,5 @@ "prefix": "/home/user/rex2prefix", "can_be_built": true, "editable": true, - "pull_on_build": true, - "xrservice_repo": null, - "opencomposite_repo": null, - "libsurvive_repo": null, - "basalt_repo": null, - "mercury_repo": null + "pull_on_build": true }