Skip to content

Commit

Permalink
#403 Save and load OSC value ranges
Browse files Browse the repository at this point in the history
  • Loading branch information
helgoboss committed Apr 5, 2022
1 parent a25fbc4 commit bd4bde8
Show file tree
Hide file tree
Showing 11 changed files with 98 additions and 7 deletions.
2 changes: 2 additions & 0 deletions api/src/schema/mapping.rs
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,8 @@ pub struct OscArgument {
pub index: Option<u32>,
#[serde(skip_serializing_if = "Option::is_none")]
pub kind: Option<OscArgKind>,
#[serde(skip_serializing_if = "Option::is_none")]
pub value_range: Option<Interval<f64>>,
}

#[derive(Copy, Clone, PartialEq, Serialize, Deserialize, JsonSchema)]
Expand Down
2 changes: 1 addition & 1 deletion main/lib/helgoboss-learn
11 changes: 10 additions & 1 deletion main/src/infrastructure/api/convert/from_data/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,9 @@ mod target;
use crate::application::{ActivationType, VirtualControlElementType};
use crate::domain::{Keystroke, Tag};
use crate::infrastructure::api::convert::defaults;
use crate::infrastructure::data::{ActivationConditionData, VirtualControlElementIdData};
use crate::infrastructure::data::{
ActivationConditionData, OscValueRange, VirtualControlElementIdData,
};
use helgoboss_learn::OscTypeTag;
use realearn_api::schema;
use realearn_api::schema::ParamRef;
Expand Down Expand Up @@ -53,16 +55,23 @@ fn convert_keystroke(v: Keystroke) -> schema::Keystroke {
fn convert_osc_argument(
arg_index: Option<u32>,
arg_type: OscTypeTag,
value_range: OscValueRange,
style: ConversionStyle,
) -> Option<schema::OscArgument> {
let arg_index = arg_index?;
let arg = schema::OscArgument {
index: style.required_value_with_default(arg_index, defaults::OSC_ARG_INDEX),
kind: style.required_value(convert_osc_arg_kind(arg_type)),
value_range: style.required_value(convert_osc_value_range(value_range)),
};
style.required_value(arg)
}

fn convert_osc_value_range(v: OscValueRange) -> schema::Interval<f64> {
let interval = v.to_interval();
schema::Interval(interval.min_val(), interval.max_val())
}

fn convert_osc_arg_kind(v: OscTypeTag) -> schema::OscArgKind {
use schema::OscArgKind as T;
use OscTypeTag::*;
Expand Down
7 changes: 6 additions & 1 deletion main/src/infrastructure/api/convert/from_data/source.rs
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,12 @@ pub fn convert_source(
let s = schema::OscSource {
feedback_behavior,
address: style.required_value(data.osc_address_pattern),
argument: convert_osc_argument(data.osc_arg_index, data.osc_arg_type, style),
argument: convert_osc_argument(
data.osc_arg_index,
data.osc_arg_type,
data.osc_arg_value_range,
style,
),
relative: style.required_value_with_default(
data.osc_arg_is_relative,
defaults::SOURCE_OSC_IS_RELATIVE,
Expand Down
7 changes: 6 additions & 1 deletion main/src/infrastructure/api/convert/from_data/target.rs
Original file line number Diff line number Diff line change
Expand Up @@ -464,7 +464,12 @@ fn convert_real_target(
SendOsc => T::SendOsc(SendOscTarget {
commons,
address: style.required_value(data.osc_address_pattern),
argument: convert_osc_argument(data.osc_arg_index, data.osc_arg_type, style),
argument: convert_osc_argument(
data.osc_arg_index,
data.osc_arg_type,
data.osc_arg_value_range,
style,
),
destination: {
use schema::OscDestination as T;
let v = match data.osc_dev_id {
Expand Down
9 changes: 7 additions & 2 deletions main/src/infrastructure/api/convert/to_data/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,13 @@ use crate::application::{BankConditionModel, ModifierConditionModel};
use crate::domain::CompartmentParamIndex;
use crate::infrastructure::api::convert::ConversionResult;
use crate::infrastructure::data;
use crate::infrastructure::data::ActivationConditionData;
use crate::infrastructure::data::{ActivationConditionData, OscValueRange};
use crate::{application, domain};
pub use compartment::*;
use enumflags2::BitFlags;
pub use mapping::*;
use realearn_api::schema::{
ActivationCondition, Keystroke, ModifierState, OscArgKind, ParamRef,
ActivationCondition, Interval, Keystroke, ModifierState, OscArgKind, ParamRef,
VirtualControlElementCharacter, VirtualControlElementId,
};
use reaper_medium::AcceleratorKeyCode;
Expand Down Expand Up @@ -70,6 +70,11 @@ fn convert_osc_arg_type(s: OscArgKind) -> helgoboss_learn::OscTypeTag {
}
}

fn convert_osc_value_range(v: Interval<f64>) -> OscValueRange {
let domain_interval = helgoboss_learn::Interval::new_auto(v.0, v.1);
OscValueRange::from_interval(domain_interval)
}

pub trait ApiToDataConversionContext {
fn param_index_by_key(&self, key: &str) -> Option<CompartmentParamIndex>;
}
Expand Down
10 changes: 9 additions & 1 deletion main/src/infrastructure/api/convert/to_data/source.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use crate::application::{MidiSourceType, ReaperSourceType, SourceCategory};
use crate::infrastructure::api::convert::to_data::{
convert_control_element_id, convert_control_element_type, convert_keystroke,
convert_osc_arg_type,
convert_osc_arg_type, convert_osc_value_range,
};
use crate::infrastructure::api::convert::{defaults, ConversionResult};
use crate::infrastructure::data::SourceModelData;
Expand Down Expand Up @@ -85,6 +85,14 @@ pub fn convert_source(s: Source) -> ConversionResult<SourceModelData> {
Osc(s) => s.relative.unwrap_or(defaults::SOURCE_OSC_IS_RELATIVE),
_ => false,
},
osc_arg_value_range: match &s {
Osc(s) => s
.argument
.and_then(|a| a.value_range)
.map(convert_osc_value_range)
.unwrap_or_default(),
_ => Default::default(),
},
osc_feedback_args: match &s {
Osc(s) => s.feedback_arguments.as_ref().cloned().unwrap_or_default(),
_ => Default::default(),
Expand Down
40 changes: 40 additions & 0 deletions main/src/infrastructure/data/common.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
use helgoboss_learn::{Interval, DEFAULT_OSC_ARG_VALUE_RANGE};
use serde::{Deserialize, Serialize};

#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
pub struct IntervalData<T> {
min: T,
max: T,
}

impl<T: Copy + PartialOrd> IntervalData<T> {
pub fn from_interval(interval: Interval<T>) -> Self {
Self {
min: interval.min_val(),
max: interval.max_val(),
}
}

pub fn to_interval(&self) -> Interval<T> {
Interval::new_auto(self.min, self.max)
}
}

#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
pub struct OscValueRange(IntervalData<f64>);

impl Default for OscValueRange {
fn default() -> Self {
Self(IntervalData::from_interval(DEFAULT_OSC_ARG_VALUE_RANGE))
}
}

impl OscValueRange {
pub fn from_interval(interval: Interval<f64>) -> Self {
Self(IntervalData::from_interval(interval))
}

pub fn to_interval(&self) -> Interval<f64> {
self.0.to_interval()
}
}
3 changes: 3 additions & 0 deletions main/src/infrastructure/data/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,3 +53,6 @@ mod virtual_control;
pub use virtual_control::*;

mod clip_legacy;

mod common;
pub use common::*;
7 changes: 7 additions & 0 deletions main/src/infrastructure/data/source_model_data.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ use crate::application::{
use crate::base::default_util::is_default;
use crate::base::notification;
use crate::domain::{Keystroke, MappingCompartment};
use crate::infrastructure::data::common::OscValueRange;
use crate::infrastructure::data::VirtualControlElementIdData;
use helgoboss_learn::{DisplayType, MidiClockTransportMessage, OscTypeTag, SourceCharacter};
use helgoboss_midi::{Channel, U14, U7};
Expand Down Expand Up @@ -64,6 +65,8 @@ pub struct SourceModelData {
#[serde(default, skip_serializing_if = "is_default")]
pub osc_arg_is_relative: bool,
#[serde(default, skip_serializing_if = "is_default")]
pub osc_arg_value_range: OscValueRange,
#[serde(default, skip_serializing_if = "is_default")]
pub osc_feedback_args: Vec<String>,
// Keyboard
pub keystroke: Option<Keystroke>,
Expand Down Expand Up @@ -103,6 +106,7 @@ impl SourceModelData {
osc_arg_index: model.osc_arg_index(),
osc_arg_type: model.osc_arg_type_tag(),
osc_arg_is_relative: model.osc_arg_is_relative(),
osc_arg_value_range: OscValueRange::from_interval(model.osc_arg_value_range()),
osc_feedback_args: model.osc_feedback_args().to_vec(),
keystroke: model.keystroke(),
control_element_type: model.control_element_type(),
Expand Down Expand Up @@ -179,6 +183,9 @@ impl SourceModelData {
model.change(P::SetOscArgIndex(self.osc_arg_index));
model.change(P::SetOscArgTypeTag(self.osc_arg_type));
model.change(P::SetOscArgIsRelative(self.osc_arg_is_relative));
model.change(P::SetOscArgValueRange(
self.osc_arg_value_range.to_interval(),
));
model.change(P::SetOscFeedbackArgs(self.osc_feedback_args.clone()));
model.change(P::SetControlElementType(self.control_element_type));
model.change(P::SetControlElementId(
Expand Down
7 changes: 7 additions & 0 deletions main/src/infrastructure/data/target_model_data.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ use crate::domain::{
SendMidiDestination, SoloBehavior, Tag, TouchedParameterType, TrackExclusivity, TrackRouteType,
TransportAction, VirtualTrack,
};
use crate::infrastructure::data::common::OscValueRange;
use crate::infrastructure::data::{
DataToModelConversionContext, ModelToDataConversionContext, VirtualControlElementIdData,
};
Expand Down Expand Up @@ -121,6 +122,8 @@ pub struct TargetModelData {
#[serde(default, skip_serializing_if = "is_default")]
pub osc_arg_type: OscTypeTag,
#[serde(default, skip_serializing_if = "is_default")]
pub osc_arg_value_range: OscValueRange,
#[serde(default, skip_serializing_if = "is_default")]
pub osc_dev_id: Option<OscDeviceId>,
#[serde(default = "bool_true", skip_serializing_if = "is_bool_true")]
pub poll_for_feedback: bool,
Expand Down Expand Up @@ -202,6 +205,7 @@ impl TargetModelData {
osc_address_pattern: model.osc_address_pattern().to_owned(),
osc_arg_index: model.osc_arg_index(),
osc_arg_type: model.osc_arg_type_tag(),
osc_arg_value_range: OscValueRange::from_interval(model.osc_arg_value_range()),
osc_dev_id: model.osc_dev_id(),
slot_index: 0,
clip_management_action: model.clip_management_action(),
Expand Down Expand Up @@ -375,6 +379,9 @@ impl TargetModelData {
model.change(C::SetOscAddressPattern(self.osc_address_pattern.clone()));
model.change(C::SetOscArgIndex(self.osc_arg_index));
model.change(C::SetOscArgTypeTag(self.osc_arg_type));
model.change(C::SetOscArgValueRange(
self.osc_arg_value_range.to_interval(),
));
model.change(C::SetOscDevId(self.osc_dev_id));
model.change(C::SetPollForFeedback(self.poll_for_feedback));
model.change(C::SetTags(self.tags.clone()));
Expand Down

0 comments on commit bd4bde8

Please sign in to comment.