Skip to content

Commit

Permalink
#231 Make compartment-private parameters fully work
Browse files Browse the repository at this point in the history
  • Loading branch information
helgoboss committed Mar 23, 2021
1 parent bb70663 commit c67f81e
Show file tree
Hide file tree
Showing 19 changed files with 451 additions and 195 deletions.
41 changes: 23 additions & 18 deletions main/src/application/group_model.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use crate::application::{ActivationConditionModel, GroupData};
use crate::core::{prop, Prop};
use crate::domain::MappingCompartment;
use core::fmt;
use rx_util::UnitEvent;
use serde::{Deserialize, Serialize};
Expand All @@ -10,25 +11,14 @@ use uuid::Uuid;
/// A mapping group.
#[derive(Clone, Debug)]
pub struct GroupModel {
compartment: MappingCompartment,
id: GroupId,
pub name: Prop<String>,
pub control_is_enabled: Prop<bool>,
pub feedback_is_enabled: Prop<bool>,
pub activation_condition_model: ActivationConditionModel,
}

impl Default for GroupModel {
fn default() -> Self {
Self {
id: Default::default(),
name: Default::default(),
control_is_enabled: prop(true),
feedback_is_enabled: prop(true),
activation_condition_model: ActivationConditionModel::default(),
}
}
}

impl fmt::Display for GroupModel {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}", self.name.get_ref())
Expand Down Expand Up @@ -76,22 +66,37 @@ impl fmt::Display for GroupId {
}

impl GroupModel {
pub fn new_from_ui(name: String) -> Self {
Self::new_internal(GroupId::random(), name)
pub fn new_from_ui(compartment: MappingCompartment, name: String) -> Self {
Self::new_internal(compartment, GroupId::random(), name)
}

pub fn new_from_data(id: GroupId) -> Self {
Self::new_internal(id, "".to_string())
pub fn new_from_data(compartment: MappingCompartment, id: GroupId) -> Self {
Self::new_internal(compartment, id, "".to_string())
}

fn new_internal(id: GroupId, name: String) -> Self {
pub fn default_for_compartment(compartment: MappingCompartment) -> Self {
Self {
compartment,
id: Default::default(),
name: Default::default(),
control_is_enabled: prop(true),
feedback_is_enabled: prop(true),
activation_condition_model: ActivationConditionModel::default(),
}
}

fn new_internal(compartment: MappingCompartment, id: GroupId, name: String) -> Self {
Self {
id,
name: prop(name),
..Default::default()
..Self::default_for_compartment(compartment)
}
}

pub fn compartment(&self) -> MappingCompartment {
self.compartment
}

pub fn id(&self) -> GroupId {
self.id
}
Expand Down
4 changes: 3 additions & 1 deletion main/src/application/mapping_model.rs
Original file line number Diff line number Diff line change
Expand Up @@ -363,6 +363,8 @@ impl<'a> MappingModelWithContext<'a> {
}

fn target_with_context(&self) -> TargetModelWithContext<'_> {
self.mapping.target_model.with_context(self.context)
self.mapping
.target_model
.with_context(self.context, self.mapping.compartment)
}
}
5 changes: 3 additions & 2 deletions main/src/application/preset.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,13 +53,14 @@ fn mapping_has_project_references(mapping: &MappingModel) -> bool {
}

fn make_mapping_project_independent(mapping: &mut MappingModel, context: ExtendedProcessorContext) {
let compartment = mapping.compartment();
let target = &mut mapping.target_model;
match target.category.get() {
TargetCategory::Reaper => {
let changed_to_track_ignore_fx = if target.supports_fx() {
let refers_to_project = target.fx_type.get().refers_to_project();
if refers_to_project {
let target_with_context = target.with_context(context);
let target_with_context = target.with_context(context, compartment);
let virtual_fx = if target_with_context.fx().ok().as_ref()
== Some(context.context.containing_fx())
{
Expand All @@ -80,7 +81,7 @@ fn make_mapping_project_independent(mapping: &mut MappingModel, context: Extende
let new_virtual_track = if changed_to_track_ignore_fx {
// Track doesn't matter at all. We change it to <This>. Looks nice.
Some(VirtualTrack::This)
} else if let Ok(t) = target.with_context(context).effective_track() {
} else if let Ok(t) = target.with_context(context, compartment).effective_track() {
if let Some(i) = t.index() {
Some(VirtualTrack::ByIndex(i))
} else {
Expand Down
47 changes: 30 additions & 17 deletions main/src/application/session.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@ use crate::domain::{
MappingCompartment, MappingId, MidiControlInput, MidiFeedbackOutput, NormalMainTask,
NormalRealTimeTask, OscDeviceId, ParameterArray, ProcessorContext, ProjectionFeedbackValue,
QualifiedMappingId, RealSource, RealTimeSender, ReaperTarget, TargetValueChangedEvent,
VirtualSource, PLUGIN_PARAMETER_COUNT, ZEROED_PLUGIN_PARAMETERS,
VirtualSource, COMPARTMENT_PARAMETER_COUNT, PLUGIN_PARAMETER_COUNT, ZEROED_PLUGIN_PARAMETERS,
};
use enum_map::EnumMap;
use enum_map::{enum_map, EnumMap};

use reaper_high::Reaper;
use rx_util::{BoxedUnitEvent, Event, Notifier, SharedItemEvent, SharedPayload, UnitEvent};
Expand Down Expand Up @@ -80,7 +80,7 @@ pub struct Session {
party_is_over_subject: LocalSubject<'static, (), ()>,
ui: WrapDebug<Box<dyn SessionUi>>,
parameters: ParameterArray,
parameter_settings: Vec<ParameterSetting>,
parameter_settings: EnumMap<MappingCompartment, Vec<ParameterSetting>>,
controller_preset_manager: Box<dyn PresetManager<PresetType = ControllerPreset>>,
main_preset_manager: Box<dyn PresetManager<PresetType = MainPreset>>,
main_preset_link_manager: Box<dyn PresetLinkManager>,
Expand Down Expand Up @@ -176,8 +176,12 @@ impl Session {
active_main_preset_id: None,
context,
mappings: Default::default(),
default_main_group: Default::default(),
default_controller_group: Default::default(),
default_main_group: Rc::new(RefCell::new(GroupModel::default_for_compartment(
MappingCompartment::MainMappings,
))),
default_controller_group: Rc::new(RefCell::new(GroupModel::default_for_compartment(
MappingCompartment::ControllerMappings,
))),
groups: Default::default(),
everything_changed_subject: Default::default(),
mapping_list_changed_subject: Default::default(),
Expand All @@ -192,8 +196,10 @@ impl Session {
party_is_over_subject: Default::default(),
ui: WrapDebug(Box::new(ui)),
parameters: ZEROED_PLUGIN_PARAMETERS,
// TODO-high This should be probably divided per compartment!
parameter_settings: vec![Default::default(); PLUGIN_PARAMETER_COUNT as usize],
parameter_settings: enum_map! {
ControllerMappings => vec![Default::default(); COMPARTMENT_PARAMETER_COUNT as usize],
MainMappings => vec![Default::default(); COMPARTMENT_PARAMETER_COUNT as usize],
},
controller_preset_manager: Box::new(controller_manager),
main_preset_manager: Box::new(main_preset_manager),
main_preset_link_manager: Box::new(preset_link_manager),
Expand Down Expand Up @@ -253,12 +259,16 @@ impl Session {
})
}

pub fn get_parameter_settings(&self, index: u32) -> &ParameterSetting {
&self.parameter_settings[index as usize]
pub fn get_parameter_settings(
&self,
compartment: MappingCompartment,
index: u32,
) -> &ParameterSetting {
&self.parameter_settings[compartment][index as usize]
}

pub fn get_parameter_name(&self, index: u32) -> String {
let setting = &self.parameter_settings[index as usize];
pub fn get_parameter_name(&self, compartment: MappingCompartment, index: u32) -> String {
let setting = &self.parameter_settings[compartment][index as usize];
match &setting.custom_name {
None => format!("Parameter {}", index + 1),
Some(n) => n.clone(),
Expand All @@ -267,9 +277,10 @@ impl Session {

pub fn set_parameter_settings_without_notification(
&mut self,
compartment: MappingCompartment,
parameter_settings: Vec<ParameterSetting>,
) {
self.parameter_settings = parameter_settings;
self.parameter_settings[compartment] = parameter_settings;
}

fn initial_sync(&mut self, weak_session: WeakSession) {
Expand Down Expand Up @@ -431,9 +442,10 @@ impl Session {

fn invalidate_fx_indexes_of_mapping_targets(&self) {
for m in self.all_mappings() {
m.borrow_mut()
.target_model
.invalidate_fx_index(self.extended_context());
let mut m = m.borrow_mut();
let compartment = m.compartment();
m.target_model
.invalidate_fx_index(self.extended_context(), compartment);
}
}

Expand Down Expand Up @@ -663,7 +675,7 @@ impl Session {
}

pub fn add_default_group(&mut self, compartment: MappingCompartment, name: String) -> GroupId {
let group = GroupModel::new_from_ui(name);
let group = GroupModel::new_from_ui(compartment, name);
self.add_group(compartment, group)
}

Expand Down Expand Up @@ -1373,7 +1385,8 @@ impl Session {
);
} else {
// <None> preset
self.default_main_group.replace(Default::default());
self.default_main_group
.replace(GroupModel::default_for_compartment(compartment));
self.set_groups_without_notification(compartment, std::iter::empty());
self.set_mappings_without_notification(compartment, std::iter::empty());
}
Expand Down
38 changes: 29 additions & 9 deletions main/src/application/target_model.rs
Original file line number Diff line number Diff line change
Expand Up @@ -155,8 +155,9 @@ impl TargetModel {
pub fn take_fx_snapshot(
&self,
context: ExtendedProcessorContext,
compartment: MappingCompartment,
) -> Result<FxSnapshot, &'static str> {
let fx = self.with_context(context).fx()?;
let fx = self.with_context(context, compartment).fx()?;
let fx_info = fx.info();
let fx_snapshot = FxSnapshot {
fx_type: if fx_info.sub_type_expression.is_empty() {
Expand All @@ -171,11 +172,15 @@ impl TargetModel {
Ok(fx_snapshot)
}

pub fn invalidate_fx_index(&mut self, context: ExtendedProcessorContext) {
pub fn invalidate_fx_index(
&mut self,
context: ExtendedProcessorContext,
compartment: MappingCompartment,
) {
if !self.supports_fx() {
return;
}
if let Ok(actual_fx) = self.with_context(context).fx() {
if let Ok(actual_fx) = self.with_context(context, compartment).fx() {
let new_virtual_fx = match self.virtual_fx() {
Some(virtual_fx) => {
match virtual_fx {
Expand Down Expand Up @@ -691,10 +696,12 @@ impl TargetModel {
pub fn with_context<'a>(
&'a self,
context: ExtendedProcessorContext<'a>,
compartment: MappingCompartment,
) -> TargetModelWithContext<'a> {
TargetModelWithContext {
target: self,
context,
compartment,
}
}

Expand Down Expand Up @@ -843,6 +850,7 @@ pub fn get_fx_label(index: u32, fx: &Fx) -> String {
pub struct TargetModelWithContext<'a> {
target: &'a TargetModel,
context: ExtendedProcessorContext<'a>,
compartment: MappingCompartment,
}

impl<'a> TargetModelWithContext<'a> {
Expand All @@ -858,7 +866,7 @@ impl<'a> TargetModelWithContext<'a> {
/// track/FX/parameter) is not available.
pub fn create_target(&self) -> Result<CompoundMappingTarget, &'static str> {
let unresolved = self.target.create_target()?;
unresolved.resolve(self.context)
unresolved.resolve(self.context, self.compartment)
}

pub fn is_known_to_be_roundable(&self) -> bool {
Expand All @@ -874,7 +882,11 @@ impl<'a> TargetModelWithContext<'a> {
}
// Returns an error if the FX doesn't exist.
pub fn fx(&self) -> Result<Fx, &'static str> {
get_fx(self.context, &self.target.fx_descriptor()?)
get_fx(
self.context,
&self.target.fx_descriptor()?,
self.compartment,
)
}

pub fn project(&self) -> Project {
Expand All @@ -886,18 +898,26 @@ impl<'a> TargetModelWithContext<'a> {
self.target
.virtual_track()
.ok_or("virtual track not complete")?
.resolve(self.context)
.resolve(self.context, self.compartment)
.map_err(|_| "particular track couldn't be resolved")
}

// Returns an error if that send (or track) doesn't exist.
pub fn track_route(&self) -> Result<TrackRoute, &'static str> {
get_track_route(self.context, &self.target.track_route_descriptor()?)
get_track_route(
self.context,
&self.target.track_route_descriptor()?,
self.compartment,
)
}

// Returns an error if that param (or FX) doesn't exist.
fn fx_param(&self) -> Result<FxParameter, &'static str> {
get_fx_param(self.context, &self.target.fx_parameter_descriptor()?)
get_fx_param(
self.context,
&self.target.fx_parameter_descriptor()?,
self.compartment,
)
}

fn route_type_label(&self) -> &'static str {
Expand Down Expand Up @@ -928,7 +948,7 @@ impl<'a> TargetModelWithContext<'a> {

fn track_label(&self) -> String {
if let Some(t) = self.target.virtual_track() {
t.with_context(self.context).to_string()
t.with_context(self.context, self.compartment).to_string()
} else {
"<Undefined>".to_owned()
}
Expand Down
4 changes: 1 addition & 3 deletions main/src/domain/conditional_activation.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
use crate::core::eel;
use crate::domain::{
ParameterArray, ParameterSlice, COMPARTMENT_PARAMETER_COUNT, PLUGIN_PARAMETER_COUNT,
};
use crate::domain::{ParameterArray, ParameterSlice, COMPARTMENT_PARAMETER_COUNT};
use std::collections::HashSet;

#[derive(Debug)]
Expand Down
16 changes: 8 additions & 8 deletions main/src/domain/main_processor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ const FEEDBACK_TASK_BULK_SIZE: usize = 64;
const CONTROL_TASK_BULK_SIZE: usize = 32;
const PARAMETER_TASK_BULK_SIZE: usize = 32;

pub const PLUGIN_PARAMETER_COUNT: u32 = 100;
pub const PLUGIN_PARAMETER_COUNT: u32 = 200;
pub const COMPARTMENT_PARAMETER_COUNT: u32 = 100;
pub type ParameterArray = [f32; PLUGIN_PARAMETER_COUNT as usize];
pub type ParameterSlice = [f32];
Expand Down Expand Up @@ -215,10 +215,10 @@ impl<EH: DomainEventHandler> MainProcessor<EH> {
let real_time_mappings = mappings
.iter_mut()
.map(|m| {
m.refresh_all(
ExtendedProcessorContext::new(&self.context, &self.parameters),
m.refresh_all(ExtendedProcessorContext::new(
&self.context,
&self.parameters,
);
));
if m.feedback_is_effectively_on() {
// Mark source as used
unused_sources.remove(&m.qualified_source());
Expand Down Expand Up @@ -314,10 +314,10 @@ impl<EH: DomainEventHandler> MainProcessor<EH> {
mapping.id()
);
// Refresh
mapping.refresh_all(
ExtendedProcessorContext::new(&self.context, &self.parameters),
mapping.refresh_all(ExtendedProcessorContext::new(
&self.context,
&self.parameters,
);
));
// Sync to real-time processor
self.normal_real_time_task_sender
.send(NormalRealTimeTask::UpdateSingleMapping(
Expand Down Expand Up @@ -551,7 +551,7 @@ impl<EH: DomainEventHandler> MainProcessor<EH> {
.handle_event(DomainEvent::UpdatedParameter { index, value });
// Mapping activation is supported for both compartments and target activation
// might change also in non-virtual controller mappings due to dynamic targets.
for compartment in MappingCompartment::enum_iter() {
if let Some(compartment) = MappingCompartment::by_absolute_param_index(index) {
let mut changed_mappings = HashSet::new();
let mut unused_sources =
self.currently_feedback_enabled_sources(compartment, true);
Expand Down
Loading

0 comments on commit c67f81e

Please sign in to comment.