Skip to content

Commit

Permalink
#231 Fix feedback when using conditional activation on mappings with …
Browse files Browse the repository at this point in the history
…virtual targets
  • Loading branch information
helgoboss committed Mar 22, 2021
1 parent 7b36d86 commit b2121e0
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 12 deletions.
36 changes: 26 additions & 10 deletions main/src/domain/main_processor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@ use crate::domain::{
NormalRealTimeTask, OscDeviceId, OscFeedbackTask, PartialControlMatch,
PlayPosFeedbackResolution, ProcessorContext, QualifiedSource, RealFeedbackValue, RealSource,
RealTimeSender, RealearnMonitoringFxParameterValueChangedEvent, ReaperTarget,
SourceFeedbackValue, TargetValueChangedEvent, VirtualSourceValue,
SourceFeedbackValue, TargetValueChangedEvent, UnresolvedCompoundMappingTarget,
VirtualSourceValue,
};
use enum_map::EnumMap;
use helgoboss_learn::{ControlValue, MidiSource, OscSource, UnitValue};
Expand Down Expand Up @@ -542,7 +543,7 @@ impl<EH: DomainEventHandler> MainProcessor<EH> {
self.currently_feedback_enabled_sources(compartment, true);
// In order to avoid a mutable borrow of mappings and an immutable borrow of
// parameters at the same time, we need to separate into READ activation
// affects and WRITE activation updates.
// effects and WRITE activation updates.
// 1. Mapping activation: Read
let activation_effects: Vec<MappingActivationEffect> = self
.all_mappings_in_compartment(compartment)
Expand Down Expand Up @@ -958,23 +959,39 @@ impl<EH: DomainEventHandler> MainProcessor<EH> {
compartment: MappingCompartment,
mapping_ids: impl Iterator<Item = MappingId>,
) -> Vec<FeedbackValue> {
// Virtual targets don't deliver feedback, so no need to handle them.
mapping_ids
.filter_map(|id| {
let m = self.mappings[compartment].get(&id)?;
m.feedback_if_enabled()
let m = self.get_normal_or_virtual_target_mapping(compartment, id)?;
self.get_mapping_feedback_follow_virtual(m)
})
.collect()
}

fn feedback_all_in_compartment(&self, compartment: MappingCompartment) -> Vec<FeedbackValue> {
// Virtual targets don't deliver feedback, so no need to handle them.
self.mappings[compartment]
.values()
.filter_map(|m| m.feedback_if_enabled())
self.all_mappings_in_compartment(compartment)
.filter_map(|m| self.get_mapping_feedback_follow_virtual(m))
.collect()
}

fn get_mapping_feedback_follow_virtual(&self, m: &MainMapping) -> Option<FeedbackValue> {
if m.feedback_is_effectively_on() {
let resolved_mapping = if let Some(control_element) = m.virtual_target_control_element()
{
self.mappings[MappingCompartment::MainMappings]
.values()
.find(|m| {
m.virtual_source_control_element() == Some(control_element)
&& m.feedback_is_effectively_on()
})?
} else {
m
};
resolved_mapping.feedback(true)
} else {
None
}
}

fn clear_feedback(&self) {
if self.osc_output_device_id.is_some() {
self.send_feedback(self.feedback_all_zero());
Expand All @@ -995,7 +1012,6 @@ impl<EH: DomainEventHandler> MainProcessor<EH> {
.collect()
}

// TODO-high Check if we need to call this with include_virtual == true sometimes
fn currently_feedback_enabled_sources(
&self,
compartment: MappingCompartment,
Expand Down
21 changes: 19 additions & 2 deletions main/src/domain/mapping.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
use crate::domain::{
ActivationChange, ActivationCondition, ControlOptions, ExtendedProcessorContext,
MappingActivationEffect, Mode, ParameterArray, PlayPosFeedbackResolution, RealearnTarget,
ReaperTarget, TargetCharacter, UnresolvedReaperTarget, VirtualSource, VirtualSourceValue,
VirtualTarget,
ReaperTarget, TargetCharacter, UnresolvedReaperTarget, VirtualControlElement, VirtualSource,
VirtualSourceValue, VirtualTarget,
};
use derive_more::Display;
use enum_iterator::IntoEnumIterator;
Expand Down Expand Up @@ -362,6 +362,7 @@ impl MainMapping {
}
}

/// Not usable for mappings with virtual targets.
fn feedback_after_control_if_unsupported_by_target(
&self,
target: &ReaperTarget,
Expand Down Expand Up @@ -389,13 +390,29 @@ impl MainMapping {
}
}

pub fn virtual_source_control_element(&self) -> Option<VirtualControlElement> {
match &self.core.source {
CompoundMappingSource::Virtual(s) => Some(s.control_element()),
_ => None,
}
}

pub fn virtual_target_control_element(&self) -> Option<VirtualControlElement> {
match self.unresolved_target.as_ref()? {
UnresolvedCompoundMappingTarget::Virtual(t) => Some(t.control_element()),
_ => None,
}
}

/// Returns `None` when used on mappings with virtual targets.
pub fn feedback_if_enabled(&self) -> Option<FeedbackValue> {
if !self.feedback_is_effectively_on() {
return None;
}
self.feedback(true)
}

/// Returns `None` when used on mappings with virtual targets.
pub fn feedback(&self, with_projection_feedback: bool) -> Option<FeedbackValue> {
let target = match &self.core.target {
Some(CompoundMappingTarget::Reaper(t)) => t,
Expand Down

0 comments on commit b2121e0

Please sign in to comment.