Skip to content

Commit

Permalink
#217 Allow wildcards for name selectors
Browse files Browse the repository at this point in the history
  • Loading branch information
helgoboss committed Mar 11, 2021
1 parent 6494dd6 commit 5164a61
Show file tree
Hide file tree
Showing 4 changed files with 56 additions and 40 deletions.
7 changes: 7 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions main/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,8 @@ serde_yaml = "0.8.17"
hex = "0.4.2"
# For evaluation of <Dynamic> formulas
fasteval = { version = "0.2.4", default-features = false }
# For wildcard support when using "By name" selector
wildmatch = "1.1.0"

[target.'cfg(windows)'.dependencies]
# For detecting the Windows version (to determine whether special charactes can be displayed)
Expand Down
22 changes: 12 additions & 10 deletions main/src/application/target_model.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ use reaper_medium::{BookmarkId, TrackSendDirection};
use std::fmt;
use std::fmt::{Display, Formatter};
use std::rc::Rc;
use wildmatch::WildMatch;

/// A model for creating targets
#[derive(Clone, Debug)]
Expand Down Expand Up @@ -378,11 +379,12 @@ impl TargetModel {
Selected => VirtualTrack::Selected,
Master => VirtualTrack::Master,
ById => VirtualTrack::ById(self.track_id.get()?),
ByName => VirtualTrack::ByName(self.track_name.get_ref().clone()),
ByName => VirtualTrack::ByName(WildMatch::new(self.track_name.get_ref())),
ByIndex => VirtualTrack::ByIndex(self.track_index.get()),
ByIdOrName => {
VirtualTrack::ByIdOrName(self.track_id.get()?, self.track_name.get_ref().clone())
}
ByIdOrName => VirtualTrack::ByIdOrName(
self.track_id.get()?,
WildMatch::new(self.track_name.get_ref()),
),
Dynamic => {
let evaluator =
ExpressionEvaluator::compile(self.track_expression.get_ref()).ok()?;
Expand Down Expand Up @@ -430,7 +432,7 @@ impl TargetModel {
TrackRouteSelector::ById(self.route_id.get()?)
}
}
ByName => TrackRouteSelector::ByName(self.route_name.get_ref().clone()),
ByName => TrackRouteSelector::ByName(WildMatch::new(self.route_name.get_ref())),
ByIndex => TrackRouteSelector::ByIndex(self.route_index.get()),
};
Some(selector)
Expand All @@ -441,7 +443,7 @@ impl TargetModel {
let fx = match self.fx_type.get() {
Focused => return None,
ById => VirtualChainFx::ById(self.fx_id.get()?, Some(self.fx_index.get())),
ByName => VirtualChainFx::ByName(self.fx_name.get_ref().clone()),
ByName => VirtualChainFx::ByName(WildMatch::new(self.fx_name.get_ref())),
ByIndex => VirtualChainFx::ByIndex(self.fx_index.get()),
ByIdOrIndex => VirtualChainFx::ByIdOrIndex(self.fx_id.get(), self.fx_index.get()),
Dynamic => {
Expand Down Expand Up @@ -519,7 +521,7 @@ impl TargetModel {
pub fn virtual_fx_parameter(&self) -> Option<VirtualFxParameter> {
use VirtualFxParameterType::*;
let param = match self.param_type.get() {
ByName => VirtualFxParameter::ByName(self.param_name.get_ref().clone()),
ByName => VirtualFxParameter::ByName(WildMatch::new(self.param_name.get_ref())),
ByIndex => VirtualFxParameter::ByIndex(self.param_index.get()),
Dynamic => {
let evaluator =
Expand Down Expand Up @@ -1524,7 +1526,7 @@ impl TrackPropValues {
Self {
r#type: VirtualTrackType::from_virtual_track(&track),
id: track.id(),
name: track.name().cloned().unwrap_or_default(),
name: track.name().unwrap_or_default(),
index: track.index().unwrap_or_default(),
expression: Default::default(),
}
Expand All @@ -1547,7 +1549,7 @@ impl TrackRoutePropValues {
selector_type: TrackRouteSelectorType::from_route_selector(&route.selector),
r#type: route.r#type,
id: route.id(),
name: route.name().cloned().unwrap_or_default(),
name: route.name().unwrap_or_default(),
index: route.index().unwrap_or_default(),
expression: Default::default(),
}
Expand All @@ -1570,7 +1572,7 @@ impl FxPropValues {
r#type: VirtualFxType::from_virtual_fx(&fx),
is_input_fx: fx.is_input_fx(),
id: fx.id(),
name: fx.name().map(|s| s.to_owned()).unwrap_or_default(),
name: fx.name().unwrap_or_default(),
index: fx.index().unwrap_or_default(),
expression: Default::default(),
}
Expand Down
65 changes: 35 additions & 30 deletions main/src/domain/unresolved_reaper_target.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ use smallvec::alloc::fmt::Formatter;
use std::fmt;
use std::num::NonZeroU32;
use std::rc::Rc;
use wildmatch::WildMatch;

#[derive(Debug)]
pub enum UnresolvedReaperTarget {
Expand Down Expand Up @@ -375,7 +376,7 @@ pub struct VirtualTrackRoute {
pub enum TrackRouteSelector {
Dynamic(Box<ExpressionEvaluator>),
ById(Guid),
ByName(String),
ByName(WildMatch),
ByIndex(u32),
}

Expand Down Expand Up @@ -445,10 +446,10 @@ impl TrackRouteSelector {
}
}

pub fn name(&self) -> Option<&String> {
pub fn name(&self) -> Option<String> {
use TrackRouteSelector::*;
match self {
ByName(name) => Some(name),
ByName(name) => Some(name.to_string()),
_ => None,
}
}
Expand Down Expand Up @@ -483,7 +484,7 @@ impl VirtualTrackRoute {
self.selector.index()
}

pub fn name(&self) -> Option<&String> {
pub fn name(&self) -> Option<String> {
self.selector.name()
}
}
Expand Down Expand Up @@ -533,18 +534,18 @@ pub enum VirtualTrack {
/// Particular.
ById(Guid),
/// Particular.
ByName(String),
ByName(WildMatch),
/// Particular.
ByIndex(u32),
/// This is the old default for targeting a particular track and it exists solely for backward
/// compatibility.
ByIdOrName(Guid, String),
ByIdOrName(Guid, WildMatch),
}

#[derive(Debug)]
pub enum VirtualFxParameter {
Dynamic(Box<ExpressionEvaluator>),
ByName(String),
ByName(WildMatch),
ByIndex(u32),
}

Expand All @@ -562,7 +563,7 @@ impl VirtualFxParameter {
}
ByName(name) => fx
.parameters()
.find(|p| p.name().to_str() == name.as_str())
.find(|p| name.is_match(p.name().to_str()))
.ok_or_else(|| FxParameterResolveError::FxParameterNotFound {
name: Some(name.clone()),
index: None,
Expand Down Expand Up @@ -595,10 +596,10 @@ impl VirtualFxParameter {
}
}

pub fn name(&self) -> Option<&String> {
pub fn name(&self) -> Option<String> {
use VirtualFxParameter::*;
match self {
ByName(name) => Some(name),
ByName(name) => Some(name.to_string()),
_ => None,
}
}
Expand Down Expand Up @@ -705,7 +706,7 @@ impl VirtualFx {
}
}

pub fn name(&self) -> Option<&String> {
pub fn name(&self) -> Option<String> {
match self {
VirtualFx::Focused => None,
VirtualFx::ChainFx { chain_fx, .. } => chain_fx.name(),
Expand Down Expand Up @@ -812,10 +813,10 @@ impl VirtualTrack {
}
}

pub fn name(&self) -> Option<&String> {
pub fn name(&self) -> Option<String> {
use VirtualTrack::*;
match self {
ByName(name) | ByIdOrName(_, name) => Some(name),
ByName(name) | ByIdOrName(_, name) => Some(name.to_string()),
_ => None,
}
}
Expand All @@ -829,7 +830,7 @@ pub enum VirtualChainFx {
///
/// The index is just used as performance hint, not as fallback.
ById(Guid, Option<u32>),
ByName(String),
ByName(WildMatch),
ByIndex(u32),
/// This is the old default.
///
Expand All @@ -856,41 +857,41 @@ impl fmt::Display for VirtualChainFx {
}
}

fn find_track_by_name(project: Project, name: &str) -> Option<Track> {
fn find_track_by_name(project: Project, name: &WildMatch) -> Option<Track> {
project.tracks().find(|t| match t.name() {
None => false,
Some(n) => n.to_str() == name,
Some(n) => name.is_match(n.to_str()),
})
}

#[derive(Clone, Eq, PartialEq, Debug, Display, Error)]
#[derive(Clone, Debug, Display, Error)]
pub enum TrackResolveError {
#[display(fmt = "TrackNotFound")]
TrackNotFound {
guid: Option<Guid>,
name: Option<String>,
name: Option<WildMatch>,
index: Option<u32>,
},
NoTrackSelected,
}

#[derive(Clone, Eq, PartialEq, Debug, Display, Error)]
#[derive(Clone, Debug, Display, Error)]
pub enum FxParameterResolveError {
#[display(fmt = "FxParameterNotFound")]
FxParameterNotFound {
name: Option<String>,
name: Option<WildMatch>,
index: Option<u32>,
},
}

#[derive(Clone, Eq, PartialEq, Debug, Display, Error)]
#[derive(Clone, Debug, Display, Error)]
pub enum TrackRouteResolveError {
#[display(fmt = "InvalidRoute")]
InvalidRoute,
#[display(fmt = "TrackRouteNotFound")]
TrackRouteNotFound {
guid: Option<Guid>,
name: Option<String>,
name: Option<WildMatch>,
index: Option<u32>,
},
}
Expand Down Expand Up @@ -986,25 +987,25 @@ impl VirtualChainFx {
}
}

pub fn name(&self) -> Option<&String> {
pub fn name(&self) -> Option<String> {
use VirtualChainFx::*;
match self {
ByName(name) => Some(name),
ByName(name) => Some(name.to_string()),
_ => None,
}
}
}

fn find_fx_by_name(chain: &FxChain, name: &str) -> Option<Fx> {
chain.fxs().find(|fx| fx.name().to_str() == name)
fn find_fx_by_name(chain: &FxChain, name: &WildMatch) -> Option<Fx> {
chain.fxs().find(|fx| name.is_match(fx.name().to_str()))
}

#[derive(Clone, Eq, PartialEq, Debug, Display, Error)]
#[derive(Clone, Debug, Display, Error)]
pub enum FxResolveError {
#[display(fmt = "FxNotFound")]
FxNotFound {
guid: Option<Guid>,
name: Option<String>,
name: Option<WildMatch>,
index: Option<u32>,
},
}
Expand Down Expand Up @@ -1244,8 +1245,12 @@ fn find_route_by_related_track(
Ok(option)
}

fn find_route_by_name(track: &Track, name: &str, route_type: TrackRouteType) -> Option<TrackRoute> {
let matcher = |r: &TrackRoute| r.name().to_str() == name;
fn find_route_by_name(
track: &Track,
name: &WildMatch,
route_type: TrackRouteType,
) -> Option<TrackRoute> {
let matcher = |r: &TrackRoute| name.is_match(r.name().to_str());
match route_type {
TrackRouteType::Send => track.typed_sends(SendPartnerType::Track).find(matcher),
TrackRouteType::Receive => track.receives().find(matcher),
Expand Down

0 comments on commit 5164a61

Please sign in to comment.