Reorganize top-level directories with clearer naming convention

app -> app-desktop-macos, presets -> app-presets, server -> remote-server,
daw-config-reaper -> osc-config-daw, plugin-reaper-realearn -> plugin-reaper-relearn.
Updated run.py and presets.py path references accordingly.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
Paul Lipscomb
2026-07-15 17:51:05 -04:00
parent e58f06d9fa
commit 7ecc718f5d
2256 changed files with 11 additions and 5 deletions
@@ -0,0 +1,134 @@
use crate::domain::{
FeedbackOutput, FinalRealFeedbackValue, FinalSourceFeedbackValue, MidiDestination,
PreliminaryRealFeedbackValue, PreliminarySourceFeedbackValue, RealearnSourceState,
};
use base::hash_util::NonCryptoHashSet;
use helgoboss_learn::devices::x_touch::XTouchMackieLcdState;
use helgoboss_learn::{
DisplaySpecAddress, MackieLcdScope, MidiSourceValue, RawFeedbackAddressInfo, RawMidiEvent,
XTouchMackieLcdColorRequest,
};
/// Responsible for collecting non-final feedback values and aggregating them into final ones.
pub struct FeedbackCollector<'a> {
x_touch_mackie_lcd_feedback_collector: Option<XTouchMackieLcdFeedbackCollector<'a>>,
}
struct XTouchMackieLcdFeedbackCollector<'a> {
state: &'a mut XTouchMackieLcdState,
changed_x_touch_mackie_lcd_extenders: NonCryptoHashSet<u8>,
}
impl<'a> FeedbackCollector<'a> {
pub fn new(
global_source_state: &'a mut RealearnSourceState,
feedback_output: Option<FeedbackOutput>,
) -> Self {
let x_touch_mackie_lcd_state = match feedback_output {
Some(FeedbackOutput::Midi(MidiDestination::Device(dev_id))) => {
Some(global_source_state.get_x_touch_mackie_lcd_state_mut(dev_id))
}
// No or no direct MIDI device output. Then we can ignore this because
// the X-Touch!
_ => None,
};
Self {
x_touch_mackie_lcd_feedback_collector: x_touch_mackie_lcd_state.map(|state| {
XTouchMackieLcdFeedbackCollector {
state,
changed_x_touch_mackie_lcd_extenders: Default::default(),
}
}),
}
}
/// Spits the given feedback value immediately out again if it's already final or only has a
/// projection part, but collects it if it's non-final.
pub fn process(
&mut self,
preliminary_feedback_value: PreliminaryRealFeedbackValue,
) -> Option<FinalRealFeedbackValue> {
match preliminary_feedback_value.source {
None => {
// Has projection part only.
FinalRealFeedbackValue::new(preliminary_feedback_value.projection, None)
}
Some(preliminary_source_feedback_value) => match preliminary_source_feedback_value {
PreliminarySourceFeedbackValue::Midi(v) => {
if let Some(req) = v.x_touch_mackie_lcd_color_request {
self.process_x_touch_mackie_lcd_color_request(req);
}
FinalRealFeedbackValue::new(
preliminary_feedback_value.projection,
Some(FinalSourceFeedbackValue::Midi(v.final_value)),
)
}
// Is final OSC value already.
PreliminarySourceFeedbackValue::Osc(v) => FinalRealFeedbackValue::new(
preliminary_feedback_value.projection,
Some(FinalSourceFeedbackValue::Osc(v)),
),
// Is final REAPER source value already.
PreliminarySourceFeedbackValue::Reaper(v) => FinalRealFeedbackValue::new(
preliminary_feedback_value.projection,
Some(FinalSourceFeedbackValue::Reaper(v)),
),
// Is final StreamDeck source value already.
PreliminarySourceFeedbackValue::StreamDeck(v) => FinalRealFeedbackValue::new(
preliminary_feedback_value.projection,
Some(FinalSourceFeedbackValue::StreamDeck(v)),
),
},
}
}
/// Takes the collected and aggregated material and produces the final feedback values.
pub fn generate_final_feedback_values(
self,
) -> impl Iterator<Item = FinalRealFeedbackValue> + 'a {
self.x_touch_mackie_lcd_feedback_collector
.into_iter()
.flat_map(|x_touch_collector| {
x_touch_collector
.changed_x_touch_mackie_lcd_extenders
.into_iter()
.filter_map(|extender_index| {
let sysex = x_touch_collector.state.sysex(extender_index);
let midi_event = RawMidiEvent::try_from_iter(0, sysex).ok()?;
let feedback_address = RawFeedbackAddressInfo::Display {
spec: DisplaySpecAddress::XTouchMackieLcdColors { extender_index },
};
let source_feedback_value = FinalSourceFeedbackValue::Midi(
MidiSourceValue::single_raw(Some(feedback_address), midi_event),
);
FinalRealFeedbackValue::new(None, Some(source_feedback_value))
})
})
}
fn process_x_touch_mackie_lcd_color_request(&mut self, req: XTouchMackieLcdColorRequest) {
let collector = match &mut self.x_touch_mackie_lcd_feedback_collector {
None => return,
Some(c) => c,
};
let channels = match req.channel {
None => 0..MackieLcdScope::CHANNEL_COUNT,
Some(ch) => ch..ch + 1,
};
let mut at_least_one_color_change = false;
for ch in channels {
let changed =
collector
.state
.notify_color_requested(req.extender_index, ch, req.color_index);
if changed {
at_least_one_color_change = true;
}
}
if at_least_one_color_change {
collector
.changed_x_touch_mackie_lcd_extenders
.insert(req.extender_index);
}
}
}