Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add UI button actions to send arbitrary OSC values. #140

Merged
merged 9 commits into from
Jan 26, 2025
Prev Previous commit
run cargo fmt
  • Loading branch information
cubee-cb committed Jan 26, 2025
commit 7ff4d13747ea84ad39740aea5b78711bf471d243
34 changes: 21 additions & 13 deletions src/backend/osc.rs
Original file line number Diff line number Diff line change
@@ -50,7 +50,11 @@ impl OscSender {
Ok(())
}

pub fn send_params<D>(&mut self, overlays: &OverlayContainer<D>, devices: &Vec<TrackedDevice>) -> anyhow::Result<()>
pub fn send_params<D>(
&mut self,
overlays: &OverlayContainer<D>,
devices: &Vec<TrackedDevice>,
) -> anyhow::Result<()>
where
D: Default,
{
@@ -93,7 +97,6 @@ impl OscSender {
"/avatar/parameters/openOverlayCount".into(),
vec![OscType::Int(num_overlays)],
)?;

}

// send battery levels every 10 seconds
@@ -111,19 +114,19 @@ impl OscSender {
// soc is the battery level (set to device status.charge)
let level = device.soc.unwrap_or(-1.0);
let parameter = match device.role {
TrackedDeviceRole::None => {continue}
TrackedDeviceRole::Hmd => {
TrackedDeviceRole::None => continue,
TrackedDeviceRole::Hmd => {
// legacy OVR Toolkit style (int)
// as of 20 Nov 2024 OVR Toolkit uses int 0-100, but this may change in a future update.
//TODO: update this once their implementation matches their docs
self.send_message(
"/avatar/parameters/hmdBattery".into(),
vec![OscType::Int((level * 100.0f32).round() as i32)],
vec![OscType::Int((level * 100.0f32).round() as i32)],
)?;

"headset"
}
TrackedDeviceRole::LeftHand => {
TrackedDeviceRole::LeftHand => {
controller_count += 1;
controller_total_bat += level;
"leftController"
@@ -133,7 +136,7 @@ impl OscSender {
controller_total_bat += level;
"rightController"
}
TrackedDeviceRole::Tracker => {
TrackedDeviceRole::Tracker => {
tracker_count += 1;
tracker_total_bat += level;
tracker_param = format!("tracker{tracker_count}");
@@ -144,32 +147,37 @@ impl OscSender {
// send device battery parameters
self.send_message(
format!("/avatar/parameters/{parameter}Battery").into(),
vec![OscType::Float(level)],
vec![OscType::Float(level)],
)?;
self.send_message(
format!("/avatar/parameters/{parameter}Charging").into(),
vec![OscType::Bool(device.charging)],
vec![OscType::Bool(device.charging)],
)?;
}

// send average controller and tracker battery parameters
self.send_message(
format!("/avatar/parameters/averageControllerBattery").into(),
vec![OscType::Float(controller_total_bat / controller_count as f32)],
vec![OscType::Float(
controller_total_bat / controller_count as f32,
)],
)?;
self.send_message(
format!("/avatar/parameters/averageTrackerBattery").into(),
vec![OscType::Float(tracker_total_bat / tracker_count as f32)],
vec![OscType::Float(tracker_total_bat / tracker_count as f32)],
)?;
}

Ok(())
}

pub fn send_single_param(&mut self, parameter: String, values: Vec<OscType>) -> anyhow::Result<()> {
pub fn send_single_param(
&mut self,
parameter: String,
values: Vec<OscType>,
) -> anyhow::Result<()> {
self.send_message(parameter, values)?;

Ok(())
}

}
24 changes: 11 additions & 13 deletions src/gui/modular/button.rs
Original file line number Diff line number Diff line change
@@ -186,23 +186,23 @@ pub enum ButtonAction {
SendOscValue {
parameter: Arc<str>,
values: Option<Vec<OscValue>>,
}
},
}

#[derive(Deserialize, Clone)]
#[serde(tag = "type")]
#[cfg(feature = "osc")]
pub enum OscValue {
Int {value: i32},
Float {value: f32},
String {value: String},
Bool {value: bool},
Int { value: i32 },
Float { value: f32 },
String { value: String },
Bool { value: bool },
}
#[derive(Deserialize, Clone)]
#[serde(tag = "type")]
#[cfg(not(feature = "osc"))]
pub enum OscValue {
None
None,
}

pub(super) struct PressData {
@@ -415,18 +415,17 @@ fn handle_action(action: &ButtonAction, press: &mut PressData, app: &mut AppStat
app.session.config.space_drag_multiplier += delta;
}
ButtonAction::SendOscValue { parameter, values } => {

#[cfg(feature = "osc")]
if let Some(ref mut sender) = app.osc_sender {
// convert OscValue to OscType
let mut converted: Vec<OscType> = Vec::new();

for value in values.as_ref().unwrap() {
let converted_value = match value {
OscValue::Bool { value } => {OscType::Bool(*value)},
OscValue::Int { value } => {OscType::Int(*value)},
OscValue::Float { value } => {OscType::Float(*value)},
OscValue::String { value } => {OscType::String(value.to_string())},
OscValue::Bool { value } => OscType::Bool(*value),
OscValue::Int { value } => OscType::Int(*value),
OscValue::Float { value } => OscType::Float(*value),
OscValue::String { value } => OscType::String(value.to_string()),
};

converted.push(converted_value);
@@ -442,8 +441,7 @@ fn handle_action(action: &ButtonAction, press: &mut PressData, app: &mut AppStat
let _ = &values;
error_toast_str(app, "OSC feature is not enabled");
}
},

}
}
}

3 changes: 1 addition & 2 deletions src/state.rs
Original file line number Diff line number Diff line change
@@ -109,8 +109,7 @@ impl AppState {
.post_load(&session.config, &mut tasks)?;

#[cfg(feature = "osc")]
let osc_sender =
crate::backend::osc::OscSender::new(session.config.osc_out_port).ok();
let osc_sender = crate::backend::osc::OscSender::new(session.config.osc_out_port).ok();

Ok(AppState {
fc: FontCache::new(session.config.primary_font.clone())?,