mod actions;
mod copy;
mod feedback;
mod modes;
pub(crate) use actions::{
remove_action, remove_rules, set_action, set_mode, set_touch, set_while_held,
};
pub(crate) use copy::{copy_rule, make_mode_switch, relearn_control};
pub(crate) use feedback::{add_feedback, remove_feedback, set_source};
pub(crate) use modes::{add_mode, move_mode, remove_mode, rename_control, rename_mode};
use gled_model::asset::midi_controller::{
MidiControllerMapping, MidiInputAction, MidiOutputBindingKind, MidiValueSource,
};
use super::build::Rule;
use super::controls::{Control, stored};
use super::groups::{Numbering, RuleGroup};
use super::numbers::{
action_numbers, output_numbers, set_action_number, set_output_number, set_source_number,
source_numbers,
};
use super::sentence::Numbers;
#[derive(Debug, Clone, PartialEq, Eq)]
pub(crate) struct Members {
pub(crate) rules: Vec<Rule>,
pub(crate) numbers: Vec<i32>,
}
impl Members {
pub(crate) fn single(rule: Rule) -> Self {
Self {
rules: vec![rule],
numbers: vec![1],
}
}
pub(crate) fn of_group(rules: &[Rule], group: &RuleGroup) -> Self {
Self {
rules: group
.rules
.iter()
.map(|&rule| rules[rule].clone())
.collect(),
numbers: group.numbers.clone(),
}
}
pub(crate) fn keys(&self) -> Vec<(usize, Option<u8>)> {
self.rules
.iter()
.map(|rule| (rule.control, rule.mode))
.collect()
}
fn each(&self) -> impl Iterator<Item = (&Rule, i32)> {
self.rules.iter().zip(self.numbers.iter().copied())
}
}
fn member_value(template: u8, numbering: Numbering, n: i32) -> u8 {
match numbering {
Numbering::Same => template,
Numbering::Counting { offset } => u8::try_from((n + offset - 1).max(0)).unwrap_or(u8::MAX),
}
}
fn member_action(template: &MidiInputAction, numbers: &dyn Numbers, n: i32) -> MidiInputAction {
let mut action = template.clone();
for (slot, value) in action_numbers(template) {
set_action_number(
&mut action,
slot,
member_value(value, numbers.numbering(slot), n),
);
}
action
}
fn member_source(template: &MidiValueSource, numbers: &dyn Numbers, n: i32) -> MidiValueSource {
let mut source = template.clone();
for (slot, value) in source_numbers(template) {
set_source_number(
&mut source,
slot,
member_value(value, numbers.numbering(slot), n),
);
}
source
}
fn member_output(
template: &MidiOutputBindingKind,
numbers: &dyn Numbers,
n: i32,
) -> MidiOutputBindingKind {
let mut output = template.clone();
for (slot, value) in output_numbers(template) {
set_output_number(
&mut output,
slot,
member_value(value, numbers.numbering(slot), n),
);
}
output
}
fn remove_bindings(
mapping: &mut MidiControllerMapping,
mut inputs: Vec<usize>,
mut outputs: Vec<usize>,
) {
inputs.sort_unstable();
inputs.dedup();
for index in inputs.into_iter().rev() {
if index < mapping.input_bindings.len() {
mapping.input_bindings.remove(index);
}
}
outputs.sort_unstable();
outputs.dedup();
for index in outputs.into_iter().rev() {
if index < mapping.output_bindings.len() {
mapping.output_bindings.remove(index);
}
}
}
fn store_controls(mapping: &mut MidiControllerMapping, controls: &[Control]) {
mapping.controls = controls
.iter()
.filter(|control| !control.named_by_message)
.map(stored)
.collect();
}