feat: can add xr service cmake flags in profile editor

This commit is contained in:
Gabriele Musco 2023-10-07 19:46:57 +02:00
commit d17e37357e
No known key found for this signature in database
GPG key ID: 1068D795C80E51DE
5 changed files with 153 additions and 48 deletions

View file

@ -51,6 +51,13 @@ pub fn get_build_monado_jobs(profile: &Profile, clean_build: bool) -> VecDeque<W
"CMAKE_CXX_FLAGS".into(),
format!("-Wl,-rpath='{}/lib'", profile.prefix),
);
profile.xrservice_cmake_flags.iter().for_each(|(k, v)| {
if k == "CMAKE_C_FLAGS" || k == "CMAKE_CXX_FLAGS" {
cmake_vars.insert(k.clone(), format!("{} {}", cmake_vars.get(k).unwrap(), v));
} else {
cmake_vars.insert(k.clone(), v.clone());
}
});
let cmake = Cmake {
env: Some(env),

View file

@ -39,6 +39,13 @@ pub fn get_build_wivrn_jobs(profile: &Profile, clean_build: bool) -> VecDeque<Wo
cmake_vars.insert("XRT_HAVE_SYSTEM_CJSON".into(), "NO".into());
cmake_vars.insert("WIVRN_BUILD_CLIENT".into(), "OFF".into());
cmake_vars.insert("CMAKE_INSTALL_PREFIX".into(), profile.prefix.clone());
profile.xrservice_cmake_flags.iter().for_each(|(k, v)| {
if k == "CMAKE_C_FLAGS" || k == "CMAKE_CXX_FLAGS" {
cmake_vars.insert(k.clone(), format!("{} {}", cmake_vars.get(k).unwrap(), v));
} else {
cmake_vars.insert(k.clone(), v.clone());
}
});
let cmake = Cmake {
env: None,

View file

@ -210,6 +210,8 @@ pub struct Profile {
pub xrservice_type: XRServiceType,
pub xrservice_path: String,
pub xrservice_repo: Option<String>,
#[serde(default = "HashMap::<String, String>::default")]
pub xrservice_cmake_flags: HashMap<String, String>,
pub opencomposite_path: String,
pub opencomposite_repo: Option<String>,
pub features: ProfileFeatures,
@ -239,6 +241,8 @@ impl Default for Profile {
name: "Default profile name".into(),
xrservice_path: data_monado_path(),
xrservice_type: XRServiceType::Monado,
xrservice_repo: None,
xrservice_cmake_flags: HashMap::<String, String>::default(),
opencomposite_path: data_opencomposite_path(),
features: ProfileFeatures::default(),
environment: HashMap::new(),
@ -248,7 +252,6 @@ impl Default for Profile {
),
can_be_built: true,
pull_on_build: true,
xrservice_repo: None,
opencomposite_repo: None,
editable: true,
lighthouse_driver: LighthouseDriver::default(),

View file

@ -2,15 +2,23 @@ use crate::ui::profile_editor::ProfileEditorMsg;
use adw::prelude::*;
use relm4::{factory::AsyncFactoryComponent, prelude::*, AsyncFactorySender};
#[derive(Debug, Clone, Copy)]
pub enum VarType {
EnvVar,
XrServiceCmakeFlags,
}
#[derive(Debug)]
pub struct EnvVarModel {
pub name: String,
value: String,
var_type: VarType,
}
pub struct EnvVarModelInit {
pub name: String,
pub value: String,
pub var_type: VarType,
}
#[derive(Debug)]
@ -21,8 +29,8 @@ pub enum EnvVarModelMsg {
#[derive(Debug)]
pub enum EnvVarModelOutMsg {
Changed(String, String),
Delete(String),
Changed(VarType, String, String),
Delete(VarType, String),
}
#[relm4::factory(async pub)]
@ -58,20 +66,30 @@ impl AsyncFactoryComponent for EnvVarModel {
match message {
Self::Input::Changed(val) => {
self.value = val.clone();
sender
.output_sender()
.emit(Self::Output::Changed(self.name.clone(), val));
sender.output_sender().emit(Self::Output::Changed(
self.var_type,
self.name.clone(),
val,
));
}
Self::Input::Delete => {
sender.output(Self::Output::Delete(self.name.clone()));
sender.output(Self::Output::Delete(self.var_type, self.name.clone()));
}
}
}
fn forward_to_parent(output: Self::Output) -> Option<Self::ParentInput> {
Some(match output {
Self::Output::Changed(name, value) => ProfileEditorMsg::EnvVarChanged(name, value),
Self::Output::Delete(name) => ProfileEditorMsg::EnvVarDelete(name),
Self::Output::Changed(var_type, name, value) => match var_type {
VarType::EnvVar => ProfileEditorMsg::EnvVarChanged(name, value),
VarType::XrServiceCmakeFlags => {
ProfileEditorMsg::XrServiceCmakeFlagsChanged(name, value)
}
},
Self::Output::Delete(var_type, name) => match var_type {
VarType::EnvVar => ProfileEditorMsg::EnvVarDelete(name),
VarType::XrServiceCmakeFlags => ProfileEditorMsg::XrServiceCmakeFlagsDelete(name),
},
})
}
@ -83,6 +101,7 @@ impl AsyncFactoryComponent for EnvVarModel {
Self {
name: init.name,
value: init.value,
var_type: init.var_type,
}
}
}

View file

@ -1,6 +1,6 @@
use super::{
alert::alert,
factories::env_var_row_factory::{EnvVarModel, EnvVarModelInit},
factories::env_var_row_factory::{EnvVarModel, EnvVarModelInit, VarType},
};
use crate::{
env_var_descriptions::env_var_descriptions_as_paragraph,
@ -19,6 +19,8 @@ pub struct ProfileEditor {
win: Option<adw::Window>,
#[tracker::do_not_track]
env_rows: AsyncFactoryVecDeque<EnvVarModel>,
#[tracker::do_not_track]
xrservice_cmake_flags_rows: AsyncFactoryVecDeque<EnvVarModel>,
}
#[derive(Debug)]
@ -26,7 +28,10 @@ pub enum ProfileEditorMsg {
Present,
EnvVarChanged(String, String),
EnvVarDelete(String),
XrServiceCmakeFlagsChanged(String, String),
XrServiceCmakeFlagsDelete(String),
AddEnvVar(String),
AddXrServiceCmakeFlag(String),
SaveProfile,
}
@ -112,7 +117,7 @@ impl SimpleComponent for ProfileEditor {
"specific git ref (branch, tag, commit...) by ",
"appending a '#' followed by the ref.\n\n",
"For launch options, you can insert %command% as ",
"a placeholder for the actual XR Service command."
"a placeholder for the actual XR Service command.",
)),
add: {
withclones![prof];
@ -183,6 +188,7 @@ impl SimpleComponent for ProfileEditor {
)
},
},
add: model.xrservice_cmake_flags_rows.widget(),
add: opencompgrp = &adw::PreferencesGroup {
set_title: "OpenComposite",
set_description: Some("OpenVR driver built on top of OpenXR\n\nWhen specifying a repository, you can set a specific git ref (branch, tag, commit...) by appending a '#' followed by the ref"),
@ -377,6 +383,26 @@ impl SimpleComponent for ProfileEditor {
self.env_rows.guard().remove(p);
}
}
Self::Input::XrServiceCmakeFlagsChanged(name, value) => {
self.profile
.borrow_mut()
.xrservice_cmake_flags
.insert(name, value);
}
Self::Input::XrServiceCmakeFlagsDelete(name) => {
self.profile
.borrow_mut()
.xrservice_cmake_flags
.remove(&name);
let pos = self
.xrservice_cmake_flags_rows
.guard()
.iter()
.position(|evr| evr.unwrap().name == name);
if let Some(p) = pos {
self.xrservice_cmake_flags_rows.guard().remove(p);
}
}
Self::Input::AddEnvVar(name) => {
let mut prof = self.profile.borrow_mut();
if !prof.environment.contains_key(&name) {
@ -384,9 +410,24 @@ impl SimpleComponent for ProfileEditor {
self.env_rows.guard().push_back(EnvVarModelInit {
name,
value: "".to_string(),
var_type: VarType::EnvVar,
});
}
}
Self::Input::AddXrServiceCmakeFlag(name) => {
let mut prof = self.profile.borrow_mut();
if !prof.xrservice_cmake_flags.contains_key(&name) {
prof.xrservice_cmake_flags
.insert(name.clone(), "".to_string());
self.xrservice_cmake_flags_rows
.guard()
.push_back(EnvVarModelInit {
name,
value: "".to_string(),
var_type: VarType::XrServiceCmakeFlags,
});
}
}
}
}
@ -395,31 +436,53 @@ impl SimpleComponent for ProfileEditor {
root: &Self::Root,
sender: ComponentSender<Self>,
) -> ComponentParts<Self> {
let add_env_popover = gtk::Popover::builder().build();
let add_env_popover_box = gtk::Box::builder()
.orientation(gtk::Orientation::Horizontal)
.css_classes(["linked"])
.build();
let add_env_name_entry = gtk::Entry::builder()
.placeholder_text("Env Var Name...")
.build();
let add_env_btn = gtk::Button::builder()
.css_classes(["suggested-action"])
.icon_name("list-add-symbolic")
.tooltip_text("Add Env Var")
.build();
add_env_popover_box.append(&add_env_name_entry);
add_env_popover_box.append(&add_env_btn);
add_env_popover.set_child(Some(&add_env_popover_box));
let (add_env_var_btn, add_cmake_flag_btn) = {
macro_rules! add_var_btn {
($name:expr, $event:expr) => {{
let popover = gtk::Popover::builder().build();
let popover_box = gtk::Box::builder()
.orientation(gtk::Orientation::Horizontal)
.css_classes(["linked"])
.build();
let name_entry = gtk::Entry::builder()
.placeholder_text(format!("{} Name...", $name))
.build();
let add_btn = gtk::Button::builder()
.css_classes(["suggested-action"])
.icon_name("list-add-symbolic")
.tooltip_text("Add Env Var")
.build();
popover_box.append(&name_entry);
popover_box.append(&add_btn);
popover.set_child(Some(&popover_box));
let add_env_var_btn = gtk::MenuButton::builder()
.icon_name("list-add-symbolic")
.tooltip_text("Add Environment Variable")
.css_classes(["flat"])
.popover(&add_env_popover)
.valign(gtk::Align::Start)
.halign(gtk::Align::End)
.build();
let btn = gtk::MenuButton::builder()
.icon_name("list-add-symbolic")
.tooltip_text("Add Environment Variable")
.css_classes(["flat"])
.popover(&popover)
.valign(gtk::Align::Start)
.halign(gtk::Align::End)
.build();
withclones![sender, name_entry, popover];
add_btn.connect_clicked(move |_| {
let key_gstr = name_entry.text();
let key = key_gstr.trim();
if !key.is_empty() {
popover.popdown();
name_entry.set_text("");
sender.input($event(key.to_string()));
}
});
btn
}};
}
(
add_var_btn!("Env Var", Self::Input::AddEnvVar),
add_var_btn!("XR Service CMake Flag", Self::Input::AddXrServiceCmakeFlag),
)
};
let profile = Rc::new(RefCell::new(init.profile));
let prof = profile.clone();
@ -435,6 +498,13 @@ impl SimpleComponent for ProfileEditor {
.build(),
sender.input_sender(),
),
xrservice_cmake_flags_rows: AsyncFactoryVecDeque::new(
adw::PreferencesGroup::builder()
.title("XR Service CMake Flags")
.header_suffix(&add_cmake_flag_btn)
.build(),
sender.input_sender(),
),
tracker: 0,
};
{
@ -444,6 +514,18 @@ impl SimpleComponent for ProfileEditor {
guard.push_back(EnvVarModelInit {
name: k.clone(),
value: v.clone(),
var_type: VarType::EnvVar,
});
}
}
{
let mut guard = model.xrservice_cmake_flags_rows.guard();
guard.clear();
for (k, v) in prof.borrow().xrservice_cmake_flags.iter() {
guard.push_back(EnvVarModelInit {
name: k.clone(),
value: v.clone(),
var_type: VarType::XrServiceCmakeFlags,
});
}
}
@ -451,19 +533,6 @@ impl SimpleComponent for ProfileEditor {
let widgets = view_output!();
model.win = Some(widgets.win.clone());
{
withclones![sender, add_env_name_entry, add_env_popover];
add_env_btn.connect_clicked(move |_| {
let name_gstr = add_env_name_entry.text();
let name = name_gstr.trim();
if !name.is_empty() {
add_env_popover.popdown();
add_env_name_entry.set_text("");
sender.input(Self::Input::AddEnvVar(name.to_string()));
}
});
}
ComponentParts { model, widgets }
}
}