diff --git a/Cargo.lock b/Cargo.lock index 7495cc3ca..12d08d68a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4337,6 +4337,7 @@ version = "0.1.0" [[package]] name = "reaper-high" version = "0.1.0" +source = "git+https://github.com/helgoboss/reaper-rs.git?branch=master#2f2dc42336040843edc91dba6148575b454b47cf" dependencies = [ "backtrace", "base64 0.13.0", @@ -4366,6 +4367,7 @@ dependencies = [ [[package]] name = "reaper-low" version = "0.1.0" +source = "git+https://github.com/helgoboss/reaper-rs.git?branch=master#2f2dc42336040843edc91dba6148575b454b47cf" dependencies = [ "c_str_macro", "cc 1.0.79", @@ -4379,6 +4381,7 @@ dependencies = [ [[package]] name = "reaper-macros" version = "0.1.0" +source = "git+https://github.com/helgoboss/reaper-rs.git?branch=master#2f2dc42336040843edc91dba6148575b454b47cf" dependencies = [ "darling 0.10.2", "quote 1.0.28", @@ -4388,6 +4391,7 @@ dependencies = [ [[package]] name = "reaper-medium" version = "0.1.0" +source = "git+https://github.com/helgoboss/reaper-rs.git?branch=master#2f2dc42336040843edc91dba6148575b454b47cf" dependencies = [ "c_str_macro", "derive_more", @@ -4405,6 +4409,7 @@ dependencies = [ [[package]] name = "reaper-rx" version = "0.1.0" +source = "git+https://github.com/helgoboss/reaper-rs.git?branch=master#2f2dc42336040843edc91dba6148575b454b47cf" dependencies = [ "crossbeam-channel", "helgoboss-midi", @@ -4577,6 +4582,7 @@ dependencies = [ [[package]] name = "rppxml-parser" version = "0.1.0" +source = "git+https://github.com/helgoboss/reaper-rs.git?branch=master#2f2dc42336040843edc91dba6148575b454b47cf" dependencies = [ "splitty", ] diff --git a/Cargo.toml b/Cargo.toml index 9547369bc..d98f57813 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -121,12 +121,12 @@ vst = { git = "https://github.com/helgoboss/vst-rs.git", branch = "feature/param #vst = { path = "../vst-rs" } # This is for temporary development with local reaper-rs. -[patch.'https://github.com/helgoboss/reaper-rs.git'] -reaper-high = { path = "../reaper-rs/main/high" } -reaper-medium = { path = "../reaper-rs/main/medium" } -reaper-low = { path = "../reaper-rs/main/low" } -reaper-rx = { path = "../reaper-rs/main/rx" } -rppxml-parser = { path = "../reaper-rs/main/rppxml-parser" } +#[patch.'https://github.com/helgoboss/reaper-rs.git'] +#reaper-high = { path = "../reaper-rs/main/high" } +#reaper-medium = { path = "../reaper-rs/main/medium" } +#reaper-low = { path = "../reaper-rs/main/low" } +#reaper-rx = { path = "../reaper-rs/main/rx" } +#rppxml-parser = { path = "../reaper-rs/main/rppxml-parser" } ## This is for temporary development with local egui-baseview. #[patch.'https://github.com/helgoboss/egui-baseview.git'] diff --git a/api/Cargo.toml b/api/Cargo.toml index 60cbe5692..87235cb74 100644 --- a/api/Cargo.toml +++ b/api/Cargo.toml @@ -4,12 +4,16 @@ version = "0.1.0" authors = ["Benjamin Klum "] edition = "2021" +[features] +default = [] +playtime = ["playtime-api"] + [dependencies] serde.workspace = true semver.workspace = true schemars.workspace = true serde_json.workspace = true -playtime-api.workspace = true +playtime-api = { workspace = true, optional = true } derive_more.workspace = true enum-iterator.workspace = true num_enum.workspace = true diff --git a/api/src/persistence/mod.rs b/api/src/persistence/mod.rs index 54fedfc78..60e3a14ac 100644 --- a/api/src/persistence/mod.rs +++ b/api/src/persistence/mod.rs @@ -18,7 +18,6 @@ pub use session::*; pub use source::*; pub use target::*; -use playtime_api::persistence::Matrix; use semver::Version; use serde::{Deserialize, Serialize}; @@ -38,7 +37,8 @@ impl Envelope { #[derive(Serialize, Deserialize)] #[serde(tag = "kind")] pub enum ApiObject { - ClipMatrix(Envelope>>), + #[cfg(feature = "playtime")] + ClipMatrix(Envelope>>), MainCompartment(Envelope>), ControllerCompartment(Envelope>), Mappings(Envelope>), diff --git a/api/src/persistence/session.rs b/api/src/persistence/session.rs index 559531e36..b66a2953d 100644 --- a/api/src/persistence/session.rs +++ b/api/src/persistence/session.rs @@ -5,7 +5,8 @@ use schemars::JsonSchema; #[derive(JsonSchema)] pub struct Session { _main_compartment: Option, - _clip_matrix: Option, + #[cfg(feature = "playtime")] + _clip_matrix: Option, _mapping_snapshots: Vec, } diff --git a/api/src/persistence/target.rs b/api/src/persistence/target.rs index 84511b448..d8e2d34c8 100644 --- a/api/src/persistence/target.rs +++ b/api/src/persistence/target.rs @@ -5,7 +5,6 @@ use derive_more::Display; use enum_iterator::IntoEnumIterator; use enumset::EnumSet; use num_enum::{IntoPrimitive, TryFromPrimitive}; -use playtime_api::persistence::{ClipPlayStartTiming, ClipPlayStopTiming}; use schemars::JsonSchema; use serde::{Deserialize, Serialize}; use std::collections::HashSet; @@ -143,12 +142,19 @@ pub enum Target { RoutePan(RoutePanTarget), RouteVolume(RouteVolumeTarget), RouteTouchState(RouteTouchStateTarget), + #[cfg(feature = "playtime")] ClipTransportAction(ClipTransportActionTarget), + #[cfg(feature = "playtime")] ClipColumnAction(ClipColumnTarget), + #[cfg(feature = "playtime")] ClipRowAction(ClipRowTarget), + #[cfg(feature = "playtime")] ClipMatrixAction(ClipMatrixTarget), + #[cfg(feature = "playtime")] ClipSeek(ClipSeekTarget), + #[cfg(feature = "playtime")] ClipVolume(ClipVolumeTarget), + #[cfg(feature = "playtime")] ClipManagement(ClipManagementTarget), SendMidi(SendMidiTarget), SendOsc(SendOscTarget), @@ -832,6 +838,7 @@ pub struct RouteTouchStateTarget { pub touched_parameter: TouchedRouteParameter, } +#[cfg(feature = "playtime")] #[derive(Eq, PartialEq, Serialize, Deserialize, JsonSchema)] pub struct ClipTransportActionTarget { #[serde(flatten)] @@ -843,11 +850,12 @@ pub struct ClipTransportActionTarget { #[serde(skip_serializing_if = "Option::is_none")] pub stop_column_if_slot_empty: Option, #[serde(skip_serializing_if = "Option::is_none")] - pub play_start_timing: Option, + pub play_start_timing: Option, #[serde(skip_serializing_if = "Option::is_none")] - pub play_stop_timing: Option, + pub play_stop_timing: Option, } +#[cfg(feature = "playtime")] #[derive(Eq, PartialEq, Serialize, Deserialize, JsonSchema)] pub struct ClipColumnTarget { #[serde(flatten)] @@ -856,6 +864,7 @@ pub struct ClipColumnTarget { pub action: ClipColumnAction, } +#[cfg(feature = "playtime")] #[derive(Eq, PartialEq, Serialize, Deserialize, JsonSchema)] pub struct ClipRowTarget { #[serde(flatten)] @@ -864,6 +873,7 @@ pub struct ClipRowTarget { pub action: ClipRowAction, } +#[cfg(feature = "playtime")] #[derive(Eq, PartialEq, Serialize, Deserialize, JsonSchema)] pub struct ClipMatrixTarget { #[serde(flatten)] @@ -871,6 +881,7 @@ pub struct ClipMatrixTarget { pub action: ClipMatrixAction, } +#[cfg(feature = "playtime")] #[derive(Eq, PartialEq, Serialize, Deserialize, JsonSchema)] pub struct ClipSeekTarget { #[serde(flatten)] @@ -880,6 +891,7 @@ pub struct ClipSeekTarget { pub feedback_resolution: Option, } +#[cfg(feature = "playtime")] #[derive(Eq, PartialEq, Serialize, Deserialize, JsonSchema)] pub struct ClipVolumeTarget { #[serde(flatten)] @@ -887,6 +899,7 @@ pub struct ClipVolumeTarget { pub slot: ClipSlotDescriptor, } +#[cfg(feature = "playtime")] #[derive(PartialEq, Serialize, Deserialize, JsonSchema)] pub struct ClipManagementTarget { #[serde(flatten)] @@ -895,6 +908,7 @@ pub struct ClipManagementTarget { pub action: ClipManagementAction, } +#[cfg(feature = "playtime")] #[derive(Clone, PartialEq, Debug, Serialize, Deserialize, JsonSchema)] #[serde(tag = "kind")] pub enum ClipManagementAction { @@ -905,12 +919,14 @@ pub enum ClipManagementAction { AdjustClipSectionLength(AdjustClipSectionLengthAction), } +#[cfg(feature = "playtime")] impl Default for ClipManagementAction { fn default() -> Self { Self::ClearSlot } } +#[cfg(feature = "playtime")] #[derive(Clone, PartialEq, Debug, Serialize, Deserialize, JsonSchema)] pub struct AdjustClipSectionLengthAction { pub factor: f64, @@ -1606,6 +1622,7 @@ pub enum TrackDescriptor { #[serde(skip_serializing_if = "Option::is_none")] allow_multiple: Option, }, + #[cfg(feature = "playtime")] FromClipColumn { #[serde(flatten)] commons: TrackDescriptorCommons, @@ -1614,12 +1631,14 @@ pub enum TrackDescriptor { }, } +#[cfg(feature = "playtime")] #[derive(Copy, Clone, Eq, PartialEq, Debug, Serialize, Deserialize, JsonSchema)] pub enum ClipColumnTrackContext { Playback, Recording, } +#[cfg(feature = "playtime")] impl Default for ClipColumnTrackContext { fn default() -> Self { Self::Playback @@ -1932,6 +1951,7 @@ impl Default for TrackRouteKind { } } +#[cfg(feature = "playtime")] #[derive(Clone, Eq, PartialEq, Debug, Serialize, Deserialize, JsonSchema)] #[serde(tag = "address")] pub enum ClipSlotDescriptor { @@ -1946,12 +1966,14 @@ pub enum ClipSlotDescriptor { }, } +#[cfg(feature = "playtime")] impl Default for ClipSlotDescriptor { fn default() -> Self { Self::Selected } } +#[cfg(feature = "playtime")] #[derive(Clone, Eq, PartialEq, Debug, Serialize, Deserialize, JsonSchema)] #[serde(tag = "address")] pub enum ClipColumnDescriptor { @@ -1960,12 +1982,14 @@ pub enum ClipColumnDescriptor { Dynamic { expression: String }, } +#[cfg(feature = "playtime")] impl Default for ClipColumnDescriptor { fn default() -> Self { Self::Selected } } +#[cfg(feature = "playtime")] #[derive(Clone, Eq, PartialEq, Debug, Serialize, Deserialize, JsonSchema)] #[serde(tag = "address")] pub enum ClipRowDescriptor { @@ -1974,6 +1998,7 @@ pub enum ClipRowDescriptor { Dynamic { expression: String }, } +#[cfg(feature = "playtime")] impl Default for ClipRowDescriptor { fn default() -> Self { Self::Selected diff --git a/api/src/runtime/root.rs b/api/src/runtime/root.rs index f67ddf093..f0ac8c741 100644 --- a/api/src/runtime/root.rs +++ b/api/src/runtime/root.rs @@ -3,5 +3,6 @@ use schemars::JsonSchema; /// Only used for JSON schema generation. #[derive(JsonSchema)] pub struct RealearnRuntimeRoot { + #[cfg(feature = "playtime")] _playtime_api: playtime_api::runtime::PlaytimeRuntimeRoot, } diff --git a/main/Cargo.toml b/main/Cargo.toml index 7703308d0..96bcf7b3e 100644 --- a/main/Cargo.toml +++ b/main/Cargo.toml @@ -8,7 +8,8 @@ license = "GPL-3.0" rust-version = "1.68.2" [features] -default = [] +default = ["playtime"] +playtime = ["playtime-clip-engine", "playtime-api", "realearn-api/playtime"] # Regenerate bindings (for dialog resource IDs and EEL functions) generate = [] @@ -22,14 +23,14 @@ reaper-medium.workspace = true reaper-low.workspace = true swell-ui.workspace = true rx-util.workspace = true -playtime-clip-engine.workspace = true pot.workspace = true realearn-api.workspace = true -playtime-api.workspace = true realearn-csi.workspace = true # In future (when helgoboss-learn has matured), this will become a crates.io dependency helgoboss-learn.workspace = true helgoboss-midi.workspace = true +playtime-api = { workspace = true, optional = true } +playtime-clip-engine = { workspace = true, optional = true } # 3rd-party # For being able to (de)serialize using FromStr and Display diff --git a/main/src/application/session.rs b/main/src/application/session.rs index 8d3bc513d..cad1a27b5 100644 --- a/main/src/application/session.rs +++ b/main/src/application/session.rs @@ -16,16 +16,16 @@ use crate::domain::{ LastTouchedTargetFilter, MainMapping, MappingId, MappingKey, MappingMatchedEvent, MessageCaptureEvent, MidiControlInput, NormalMainTask, NormalRealTimeTask, OscFeedbackTask, ParamSetting, PluginParams, ProcessorContext, ProjectionFeedbackValue, QualifiedMappingId, - RealearnClipMatrix, RealearnControlSurfaceMainTask, RealearnTarget, ReaperTarget, - ReaperTargetType, SharedInstanceState, StayActiveWhenProjectInBackground, Tag, - TargetControlEvent, TargetTouchEvent, TargetValueChangedEvent, VirtualControlElementId, - VirtualFx, VirtualSource, VirtualSourceValue, + RealearnControlSurfaceMainTask, RealearnTarget, ReaperTarget, ReaperTargetType, + SharedInstanceState, StayActiveWhenProjectInBackground, Tag, TargetControlEvent, + TargetTouchEvent, TargetValueChangedEvent, VirtualControlElementId, VirtualFx, VirtualSource, + VirtualSourceValue, }; use base::{Global, NamedChannelSender, SenderToNormalThread, SenderToRealTimeThread}; use derivative::Derivative; use enum_map::EnumMap; -use reaper_high::{ChangeEvent, Reaper}; +use reaper_high::Reaper; use rx_util::Notifier; use rxrust::prelude::*; use slog::{debug, trace}; @@ -54,18 +54,20 @@ pub trait SessionUi { fn celebrate_success(&self); fn conditions_changed(&self); fn send_projection_feedback(&self, session: &Session, value: ProjectionFeedbackValue); + #[cfg(feature = "playtime")] fn clip_matrix_changed( &self, session: &Session, - matrix: &RealearnClipMatrix, + matrix: &playtime_clip_engine::base::Matrix, events: &[playtime_clip_engine::base::ClipMatrixEvent], is_poll: bool, ); + #[cfg(feature = "playtime")] fn process_control_surface_change_event_for_clip_engine( &self, session: &Session, - matrix: &RealearnClipMatrix, - event: &ChangeEvent, + matrix: &playtime_clip_engine::base::Matrix, + event: &reaper_high::ChangeEvent, ); fn mapping_matched(&self, event: MappingMatchedEvent); fn target_controlled(&self, event: TargetControlEvent); @@ -2618,6 +2620,7 @@ impl DomainEventHandler for WeakSession { let s = session.try_borrow()?; s.ui.send_projection_feedback(&s, value); } + #[cfg(feature = "playtime")] ClipMatrixChanged { matrix, events, @@ -2626,6 +2629,7 @@ impl DomainEventHandler for WeakSession { let s = session.try_borrow()?; s.ui.clip_matrix_changed(&s, matrix, events, is_poll); } + #[cfg(feature = "playtime")] ControlSurfaceChangeEventForClipEngine(matrix, event) => { let s = session.try_borrow()?; s.ui.process_control_surface_change_event_for_clip_engine(&s, matrix, event); diff --git a/main/src/application/target_model.rs b/main/src/application/target_model.rs index 1f2845e11..27f0919a1 100644 --- a/main/src/application/target_model.rs +++ b/main/src/application/target_model.rs @@ -20,52 +20,47 @@ use crate::application::{ use crate::domain::{ find_bookmark, get_fx_name, get_fx_params, get_non_present_virtual_route_label, get_non_present_virtual_track_label, get_track_routes, ActionInvocationType, AnyOnParameter, - ClipTransportOptions, Compartment, CompoundMappingTarget, Exclusivity, ExpressionEvaluator, - ExtendedProcessorContext, FeedbackResolution, FxDescriptor, FxDisplayType, - FxParameterDescriptor, GroupId, MappingId, MappingKey, MappingRef, MappingSnapshotId, - MouseActionType, OscDeviceId, PotFilterItemsTargetSettings, ProcessorContext, - QualifiedMappingId, RealearnTarget, ReaperTarget, ReaperTargetType, SeekOptions, - SendMidiDestination, SoloBehavior, Tag, TagScope, TouchedRouteParameterType, - TouchedTrackParameterType, TrackDescriptor, TrackExclusivity, TrackGangBehavior, - TrackRouteDescriptor, TrackRouteSelector, TrackRouteType, TransportAction, + Compartment, CompoundMappingTarget, Exclusivity, ExpressionEvaluator, ExtendedProcessorContext, + FeedbackResolution, FxDescriptor, FxDisplayType, FxParameterDescriptor, GroupId, MappingId, + MappingKey, MappingRef, MappingSnapshotId, MouseActionType, OscDeviceId, + PotFilterItemsTargetSettings, ProcessorContext, QualifiedMappingId, RealearnTarget, + ReaperTarget, ReaperTargetType, SeekOptions, SendMidiDestination, SoloBehavior, Tag, TagScope, + TouchedRouteParameterType, TouchedTrackParameterType, TrackDescriptor, TrackExclusivity, + TrackGangBehavior, TrackRouteDescriptor, TrackRouteSelector, TrackRouteType, TransportAction, UnresolvedActionTarget, UnresolvedAllTrackFxEnableTarget, UnresolvedAnyOnTarget, UnresolvedAutomationModeOverrideTarget, UnresolvedBrowseFxsTarget, UnresolvedBrowseGroupTarget, UnresolvedBrowsePotFilterItemsTarget, UnresolvedBrowsePotPresetsTarget, - UnresolvedBrowseTracksTarget, UnresolvedClipColumnTarget, UnresolvedClipManagementTarget, - UnresolvedClipMatrixTarget, UnresolvedClipRowTarget, UnresolvedClipSeekTarget, - UnresolvedClipTransportTarget, UnresolvedClipVolumeTarget, UnresolvedCompoundMappingTarget, - UnresolvedDummyTarget, UnresolvedEnableInstancesTarget, UnresolvedEnableMappingsTarget, - UnresolvedFxEnableTarget, UnresolvedFxOnlineTarget, UnresolvedFxOpenTarget, - UnresolvedFxParameterTarget, UnresolvedFxParameterTouchStateTarget, UnresolvedFxPresetTarget, - UnresolvedFxToolTarget, UnresolvedGoToBookmarkTarget, UnresolvedLastTouchedTarget, - UnresolvedLoadFxSnapshotTarget, UnresolvedLoadMappingSnapshotTarget, - UnresolvedLoadPotPresetTarget, UnresolvedMidiSendTarget, UnresolvedModifyMappingTarget, - UnresolvedMouseTarget, UnresolvedOscSendTarget, UnresolvedPlayrateTarget, - UnresolvedPreviewPotPresetTarget, UnresolvedReaperTarget, UnresolvedRouteAutomationModeTarget, - UnresolvedRouteMonoTarget, UnresolvedRouteMuteTarget, UnresolvedRoutePanTarget, - UnresolvedRoutePhaseTarget, UnresolvedRouteTouchStateTarget, UnresolvedRouteVolumeTarget, - UnresolvedSeekTarget, UnresolvedTakeMappingSnapshotTarget, UnresolvedTempoTarget, - UnresolvedTrackArmTarget, UnresolvedTrackAutomationModeTarget, + UnresolvedBrowseTracksTarget, UnresolvedCompoundMappingTarget, UnresolvedDummyTarget, + UnresolvedEnableInstancesTarget, UnresolvedEnableMappingsTarget, UnresolvedFxEnableTarget, + UnresolvedFxOnlineTarget, UnresolvedFxOpenTarget, UnresolvedFxParameterTarget, + UnresolvedFxParameterTouchStateTarget, UnresolvedFxPresetTarget, UnresolvedFxToolTarget, + UnresolvedGoToBookmarkTarget, UnresolvedLastTouchedTarget, UnresolvedLoadFxSnapshotTarget, + UnresolvedLoadMappingSnapshotTarget, UnresolvedLoadPotPresetTarget, UnresolvedMidiSendTarget, + UnresolvedModifyMappingTarget, UnresolvedMouseTarget, UnresolvedOscSendTarget, + UnresolvedPlayrateTarget, UnresolvedPreviewPotPresetTarget, UnresolvedReaperTarget, + UnresolvedRouteAutomationModeTarget, UnresolvedRouteMonoTarget, UnresolvedRouteMuteTarget, + UnresolvedRoutePanTarget, UnresolvedRoutePhaseTarget, UnresolvedRouteTouchStateTarget, + UnresolvedRouteVolumeTarget, UnresolvedSeekTarget, UnresolvedTakeMappingSnapshotTarget, + UnresolvedTempoTarget, UnresolvedTrackArmTarget, UnresolvedTrackAutomationModeTarget, UnresolvedTrackMonitoringModeTarget, UnresolvedTrackMuteTarget, UnresolvedTrackPanTarget, UnresolvedTrackParentSendTarget, UnresolvedTrackPeakTarget, UnresolvedTrackPhaseTarget, UnresolvedTrackSelectionTarget, UnresolvedTrackShowTarget, UnresolvedTrackSoloTarget, UnresolvedTrackToolTarget, UnresolvedTrackTouchStateTarget, UnresolvedTrackVolumeTarget, - UnresolvedTrackWidthTarget, UnresolvedTransportTarget, VirtualChainFx, VirtualClipColumn, - VirtualClipRow, VirtualClipSlot, VirtualControlElement, VirtualControlElementId, VirtualFx, - VirtualFxParameter, VirtualMappingSnapshotIdForLoad, VirtualMappingSnapshotIdForTake, - VirtualTarget, VirtualTrack, VirtualTrackRoute, + UnresolvedTrackWidthTarget, UnresolvedTransportTarget, VirtualChainFx, VirtualControlElement, + VirtualControlElementId, VirtualFx, VirtualFxParameter, VirtualMappingSnapshotIdForLoad, + VirtualMappingSnapshotIdForTake, VirtualTarget, VirtualTrack, VirtualTrackRoute, }; + +#[cfg(feature = "playtime")] +use crate::domain::{VirtualClipColumn, VirtualClipRow, VirtualClipSlot}; use serde_repr::*; use std::borrow::Cow; use std::collections::HashSet; use std::error::Error; use crate::domain::ui_util::format_tags_as_csv; -use playtime_api::persistence::{ClipPlayStartTiming, ClipPlayStopTiming}; use realearn_api::persistence::{ - Axis, BrowseTracksMode, ClipColumnAction, ClipColumnDescriptor, ClipColumnTrackContext, - ClipManagementAction, ClipMatrixAction, ClipRowAction, ClipRowDescriptor, ClipSlotDescriptor, - ClipTransportAction, FxChainDescriptor, FxDescriptorCommons, FxToolAction, + Axis, BrowseTracksMode, FxChainDescriptor, FxDescriptorCommons, FxToolAction, LearnTargetMappingModification, LearnableTargetKind, MappingModification, MappingModificationKind, MappingSnapshotDescForLoad, MappingSnapshotDescForTake, MonitoringMode, MouseAction, MouseButton, PotFilterKind, SeekBehavior, @@ -150,17 +145,29 @@ pub enum TargetCommand { SetMouseActionType(MouseActionType), SetAxis(Axis), SetMouseButton(MouseButton), - SetClipSlot(ClipSlotDescriptor), - SetClipColumn(ClipColumnDescriptor), - SetClipRow(ClipRowDescriptor), - SetClipManagementAction(ClipManagementAction), - SetClipTransportAction(ClipTransportAction), - SetClipMatrixAction(ClipMatrixAction), - SetClipColumnAction(ClipColumnAction), - SetClipRowAction(ClipRowAction), - SetClipPlayStartTiming(Option), - SetClipPlayStopTiming(Option), + #[cfg(feature = "playtime")] + SetClipSlot(realearn_api::persistence::ClipSlotDescriptor), + #[cfg(feature = "playtime")] + SetClipColumn(realearn_api::persistence::ClipColumnDescriptor), + #[cfg(feature = "playtime")] + SetClipRow(realearn_api::persistence::ClipRowDescriptor), + #[cfg(feature = "playtime")] + SetClipManagementAction(realearn_api::persistence::ClipManagementAction), + #[cfg(feature = "playtime")] + SetClipTransportAction(realearn_api::persistence::ClipTransportAction), + #[cfg(feature = "playtime")] + SetClipMatrixAction(realearn_api::persistence::ClipMatrixAction), + #[cfg(feature = "playtime")] + SetClipColumnAction(realearn_api::persistence::ClipColumnAction), + #[cfg(feature = "playtime")] + SetClipRowAction(realearn_api::persistence::ClipRowAction), + #[cfg(feature = "playtime")] + SetClipPlayStartTiming(Option), + #[cfg(feature = "playtime")] + SetClipPlayStopTiming(Option), + #[cfg(feature = "playtime")] SetRecordOnlyIfTrackArmed(bool), + #[cfg(feature = "playtime")] SetStopColumnIfSlotEmpty(bool), SetPollForFeedback(bool), SetTags(Vec), @@ -251,17 +258,29 @@ pub enum TargetProp { MouseActionType, Axis, MouseButton, + #[cfg(feature = "playtime")] ClipSlot, + #[cfg(feature = "playtime")] ClipColumn, + #[cfg(feature = "playtime")] ClipRow, + #[cfg(feature = "playtime")] ClipManagementAction, + #[cfg(feature = "playtime")] ClipTransportAction, + #[cfg(feature = "playtime")] ClipMatrixAction, + #[cfg(feature = "playtime")] ClipColumnAction, + #[cfg(feature = "playtime")] ClipRowAction, + #[cfg(feature = "playtime")] ClipPlayStartTiming, + #[cfg(feature = "playtime")] ClipPlayStopTiming, + #[cfg(feature = "playtime")] RecordOnlyIfTrackArmed, + #[cfg(feature = "playtime")] StopColumnIfSlotEmpty, PollForFeedback, Tags, @@ -599,50 +618,62 @@ impl<'a> Change<'a> for TargetModel { self.mapping_snapshot_default_value = v; One(P::MappingSnapshotDefaultValue) } + #[cfg(feature = "playtime")] C::SetClipSlot(s) => { self.clip_slot = s; One(P::ClipSlot) } + #[cfg(feature = "playtime")] C::SetClipColumn(c) => { self.clip_column = c; One(P::ClipColumn) } + #[cfg(feature = "playtime")] C::SetClipRow(r) => { self.clip_row = r; One(P::ClipRow) } + #[cfg(feature = "playtime")] C::SetClipManagementAction(v) => { self.clip_management_action = v; One(P::ClipManagementAction) } + #[cfg(feature = "playtime")] C::SetClipTransportAction(v) => { self.clip_transport_action = v; One(P::ClipTransportAction) } + #[cfg(feature = "playtime")] C::SetClipMatrixAction(v) => { self.clip_matrix_action = v; One(P::ClipMatrixAction) } + #[cfg(feature = "playtime")] C::SetClipColumnAction(v) => { self.clip_column_action = v; One(P::ClipColumnAction) } + #[cfg(feature = "playtime")] C::SetClipRowAction(v) => { self.clip_row_action = v; One(P::ClipRowAction) } + #[cfg(feature = "playtime")] C::SetClipPlayStartTiming(v) => { self.clip_play_start_timing = v; One(P::ClipPlayStartTiming) } + #[cfg(feature = "playtime")] C::SetClipPlayStopTiming(v) => { self.clip_play_stop_timing = v; One(P::ClipPlayStopTiming) } + #[cfg(feature = "playtime")] C::SetRecordOnlyIfTrackArmed(v) => { self.record_only_if_track_armed = v; One(P::RecordOnlyIfTrackArmed) } + #[cfg(feature = "playtime")] C::SetStopColumnIfSlotEmpty(v) => { self.stop_column_if_slot_empty = v; One(P::StopColumnIfSlotEmpty) @@ -696,7 +727,8 @@ pub struct TargetModel { track_index: u32, track_expression: String, enable_only_if_track_selected: bool, - clip_column_track_context: ClipColumnTrackContext, + #[cfg(feature = "playtime")] + clip_column_track_context: realearn_api::persistence::ClipColumnTrackContext, track_tool_action: TrackToolAction, gang_behavior: TrackGangBehavior, browse_tracks_mode: BrowseTracksMode, @@ -777,18 +809,30 @@ pub struct TargetModel { axis: Axis, mouse_button: MouseButton, // # For clip targets - clip_slot: ClipSlotDescriptor, - clip_column: ClipColumnDescriptor, - clip_row: ClipRowDescriptor, - clip_management_action: ClipManagementAction, - clip_transport_action: ClipTransportAction, - clip_matrix_action: ClipMatrixAction, - clip_column_action: ClipColumnAction, - clip_row_action: ClipRowAction, + #[cfg(feature = "playtime")] + clip_slot: realearn_api::persistence::ClipSlotDescriptor, + #[cfg(feature = "playtime")] + clip_column: realearn_api::persistence::ClipColumnDescriptor, + #[cfg(feature = "playtime")] + clip_row: realearn_api::persistence::ClipRowDescriptor, + #[cfg(feature = "playtime")] + clip_management_action: realearn_api::persistence::ClipManagementAction, + #[cfg(feature = "playtime")] + clip_transport_action: realearn_api::persistence::ClipTransportAction, + #[cfg(feature = "playtime")] + clip_matrix_action: realearn_api::persistence::ClipMatrixAction, + #[cfg(feature = "playtime")] + clip_column_action: realearn_api::persistence::ClipColumnAction, + #[cfg(feature = "playtime")] + clip_row_action: realearn_api::persistence::ClipRowAction, + #[cfg(feature = "playtime")] record_only_if_track_armed: bool, + #[cfg(feature = "playtime")] stop_column_if_slot_empty: bool, - clip_play_start_timing: Option, - clip_play_stop_timing: Option, + #[cfg(feature = "playtime")] + clip_play_start_timing: Option, + #[cfg(feature = "playtime")] + clip_play_stop_timing: Option, // # For targets that might have to be polled in order to get automatic feedback in all cases. poll_for_feedback: bool, tags: Vec, @@ -932,18 +976,31 @@ impl Default for TargetModel { exclusivity: Default::default(), group_id: Default::default(), active_mappings_only: false, + #[cfg(feature = "playtime")] clip_slot: Default::default(), + #[cfg(feature = "playtime")] clip_column: Default::default(), + #[cfg(feature = "playtime")] clip_row: Default::default(), + #[cfg(feature = "playtime")] clip_management_action: Default::default(), + #[cfg(feature = "playtime")] clip_transport_action: Default::default(), + #[cfg(feature = "playtime")] clip_column_action: Default::default(), + #[cfg(feature = "playtime")] clip_matrix_action: Default::default(), + #[cfg(feature = "playtime")] record_only_if_track_armed: false, + #[cfg(feature = "playtime")] stop_column_if_slot_empty: false, + #[cfg(feature = "playtime")] clip_play_start_timing: None, + #[cfg(feature = "playtime")] clip_column_track_context: Default::default(), + #[cfg(feature = "playtime")] clip_row_action: Default::default(), + #[cfg(feature = "playtime")] clip_play_stop_timing: None, track_tool_action: Default::default(), fx_tool_action: Default::default(), @@ -1243,7 +1300,8 @@ impl TargetModel { self.osc_dev_id } - pub fn clip_management_action(&self) -> &ClipManagementAction { + #[cfg(feature = "playtime")] + pub fn clip_management_action(&self) -> &realearn_api::persistence::ClipManagementAction { &self.clip_management_action } @@ -1500,6 +1558,7 @@ impl TargetModel { self.track_id = track.id; self.track_name = track.name; } + #[cfg(feature = "playtime")] FromClipColumn => { self.clip_column = track.clip_column; self.clip_column_track_context = track.clip_column_track_context; @@ -1830,6 +1889,7 @@ impl TargetModel { scope: self.track_type.virtual_track_scope().unwrap_or_default(), } } + #[cfg(feature = "playtime")] FromClipColumn => VirtualTrack::FromClipColumn { column: self.virtual_clip_column().ok()?, context: self.clip_column_track_context, @@ -1845,7 +1905,9 @@ impl TargetModel { name: self.track_name.clone(), expression: self.track_expression.clone(), index: self.track_index, + #[cfg(feature = "playtime")] clip_column: self.clip_column.clone(), + #[cfg(feature = "playtime")] clip_column_track_context: self.clip_column_track_context, } } @@ -2058,6 +2120,7 @@ impl TargetModel { expression: self.track_expression.clone(), scope: self.track_type.virtual_track_scope(), }, + #[cfg(feature = "playtime")] FromClipColumn => TrackDescriptor::FromClipColumn { commons, column: self.clip_column.clone(), @@ -2114,8 +2177,9 @@ impl TargetModel { } } + #[cfg(feature = "playtime")] fn virtual_clip_slot(&self) -> Result { - use ClipSlotDescriptor::*; + use realearn_api::persistence::ClipSlotDescriptor::*; let slot = match &self.clip_slot { Selected => VirtualClipSlot::Selected, ByIndex { @@ -2142,12 +2206,14 @@ impl TargetModel { Ok(slot) } + #[cfg(feature = "playtime")] fn virtual_clip_column(&self) -> Result { VirtualClipColumn::from_descriptor(&self.clip_column) } + #[cfg(feature = "playtime")] fn virtual_clip_row(&self) -> Result { - use ClipRowDescriptor::*; + use realearn_api::persistence::ClipRowDescriptor::*; let row = match &self.clip_row { Selected => VirtualClipRow::Selected, ByIndex { index } => VirtualClipRow::ByIndex(*index), @@ -2473,37 +2539,54 @@ impl TargetModel { arg_descriptor: self.osc_arg_descriptor(), device_id: self.osc_dev_id, }), - ClipTransport => { - UnresolvedReaperTarget::ClipTransport(UnresolvedClipTransportTarget { + #[cfg(feature = "playtime")] + ClipTransport => UnresolvedReaperTarget::ClipTransport( + crate::domain::UnresolvedClipTransportTarget { slot: self.virtual_clip_slot()?, action: self.clip_transport_action, options: self.clip_transport_options(), + }, + ), + #[cfg(feature = "playtime")] + ClipColumn => UnresolvedReaperTarget::ClipColumn( + crate::domain::UnresolvedClipColumnTarget { + column: self.virtual_clip_column()?, + action: self.clip_column_action, + }, + ), + #[cfg(feature = "playtime")] + ClipRow => { + UnresolvedReaperTarget::ClipRow(crate::domain::UnresolvedClipRowTarget { + row: self.virtual_clip_row()?, + action: self.clip_row_action, }) } - ClipColumn => UnresolvedReaperTarget::ClipColumn(UnresolvedClipColumnTarget { - column: self.virtual_clip_column()?, - action: self.clip_column_action, - }), - ClipRow => UnresolvedReaperTarget::ClipRow(UnresolvedClipRowTarget { - row: self.virtual_clip_row()?, - action: self.clip_row_action, - }), - ClipSeek => UnresolvedReaperTarget::ClipSeek(UnresolvedClipSeekTarget { - slot: self.virtual_clip_slot()?, - feedback_resolution: self.feedback_resolution, - }), - ClipVolume => UnresolvedReaperTarget::ClipVolume(UnresolvedClipVolumeTarget { - slot: self.virtual_clip_slot()?, - }), - ClipManagement => { - UnresolvedReaperTarget::ClipManagement(UnresolvedClipManagementTarget { + #[cfg(feature = "playtime")] + ClipSeek => { + UnresolvedReaperTarget::ClipSeek(crate::domain::UnresolvedClipSeekTarget { slot: self.virtual_clip_slot()?, - action: self.clip_management_action.clone(), + feedback_resolution: self.feedback_resolution, }) } - ClipMatrix => UnresolvedReaperTarget::ClipMatrix(UnresolvedClipMatrixTarget { - action: self.clip_matrix_action, - }), + #[cfg(feature = "playtime")] + ClipVolume => UnresolvedReaperTarget::ClipVolume( + crate::domain::UnresolvedClipVolumeTarget { + slot: self.virtual_clip_slot()?, + }, + ), + #[cfg(feature = "playtime")] + ClipManagement => UnresolvedReaperTarget::ClipManagement( + crate::domain::UnresolvedClipManagementTarget { + slot: self.virtual_clip_slot()?, + action: self.clip_management_action.clone(), + }, + ), + #[cfg(feature = "playtime")] + ClipMatrix => UnresolvedReaperTarget::ClipMatrix( + crate::domain::UnresolvedClipMatrixTarget { + action: self.clip_matrix_action, + }, + ), LoadMappingSnapshot => UnresolvedReaperTarget::LoadMappingSnapshot( UnresolvedLoadMappingSnapshotTarget { compartment, @@ -2601,27 +2684,33 @@ impl TargetModel { } } - pub fn clip_slot(&self) -> &ClipSlotDescriptor { + #[cfg(feature = "playtime")] + pub fn clip_slot(&self) -> &realearn_api::persistence::ClipSlotDescriptor { &self.clip_slot } - pub fn clip_column(&self) -> &ClipColumnDescriptor { + #[cfg(feature = "playtime")] + pub fn clip_column(&self) -> &realearn_api::persistence::ClipColumnDescriptor { &self.clip_column } - pub fn clip_row(&self) -> &ClipRowDescriptor { + #[cfg(feature = "playtime")] + pub fn clip_row(&self) -> &realearn_api::persistence::ClipRowDescriptor { &self.clip_row } - pub fn clip_transport_action(&self) -> ClipTransportAction { + #[cfg(feature = "playtime")] + pub fn clip_transport_action(&self) -> realearn_api::persistence::ClipTransportAction { self.clip_transport_action } - pub fn clip_matrix_action(&self) -> ClipMatrixAction { + #[cfg(feature = "playtime")] + pub fn clip_matrix_action(&self) -> realearn_api::persistence::ClipMatrixAction { self.clip_matrix_action } - pub fn clip_column_action(&self) -> ClipColumnAction { + #[cfg(feature = "playtime")] + pub fn clip_column_action(&self) -> realearn_api::persistence::ClipColumnAction { self.clip_column_action } @@ -2631,28 +2720,34 @@ impl TargetModel { } } - pub fn clip_row_action(&self) -> ClipRowAction { + #[cfg(feature = "playtime")] + pub fn clip_row_action(&self) -> realearn_api::persistence::ClipRowAction { self.clip_row_action } + #[cfg(feature = "playtime")] pub fn record_only_if_track_armed(&self) -> bool { self.record_only_if_track_armed } + #[cfg(feature = "playtime")] pub fn stop_column_if_slot_empty(&self) -> bool { self.stop_column_if_slot_empty } - pub fn clip_play_start_timing(&self) -> Option { + #[cfg(feature = "playtime")] + pub fn clip_play_start_timing(&self) -> Option { self.clip_play_start_timing } - pub fn clip_play_stop_timing(&self) -> Option { + #[cfg(feature = "playtime")] + pub fn clip_play_stop_timing(&self) -> Option { self.clip_play_stop_timing } - pub fn clip_transport_options(&self) -> ClipTransportOptions { - ClipTransportOptions { + #[cfg(feature = "playtime")] + pub fn clip_transport_options(&self) -> crate::domain::ClipTransportOptions { + crate::domain::ClipTransportOptions { record_only_if_track_armed: self.record_only_if_track_armed, stop_column_if_slot_empty: self.stop_column_if_slot_empty, play_start_timing: self.clip_play_start_timing, @@ -2813,6 +2908,7 @@ impl TargetModel { /// It makes sense then to present the "Track must be selected" checkbox then. fn uses_track_apart_from_type(&self) -> bool { match self.r#type { + #[cfg(feature = "playtime")] ReaperTargetType::ClipTransport => { use TransportAction::*; matches!(self.transport_action, PlayStop | PlayPause) @@ -3146,6 +3242,7 @@ impl<'a> Display for TargetModelFormatMultiLine<'a> { use ReaperTargetType::*; let tt = self.target.r#type; match tt { + #[cfg(feature = "playtime")] ClipTransport | ClipSeek | ClipVolume => { write!(f, "{tt}") } @@ -3650,6 +3747,7 @@ pub enum VirtualTrackType { ByIndexMcp, #[display(fmt = "By ID or name (legacy)")] ByIdOrName, + #[cfg(feature = "playtime")] #[display(fmt = "From clip column")] FromClipColumn, } @@ -3776,6 +3874,7 @@ impl VirtualTrackType { TrackScope::TracksVisibleInTcp => Self::ByIndexTcp, TrackScope::TracksVisibleInMcp => Self::ByIndexMcp, }, + #[cfg(feature = "playtime")] FromClipColumn { .. } => Self::FromClipColumn, } } @@ -4069,8 +4168,10 @@ pub struct TrackPropValues { pub name: String, pub expression: String, pub index: u32, - pub clip_column: ClipColumnDescriptor, - pub clip_column_track_context: ClipColumnTrackContext, + #[cfg(feature = "playtime")] + pub clip_column: realearn_api::persistence::ClipColumnDescriptor, + #[cfg(feature = "playtime")] + pub clip_column_track_context: realearn_api::persistence::ClipColumnTrackContext, } impl TrackPropValues { @@ -4080,14 +4181,19 @@ impl TrackPropValues { id: track.id(), name: track.name().unwrap_or_default(), index: track.index().unwrap_or_default(), - clip_column: match track.clip_column().unwrap_or(&Default::default()) { - VirtualClipColumn::Selected => ClipColumnDescriptor::Selected, - VirtualClipColumn::ByIndex(i) => ClipColumnDescriptor::ByIndex { index: *i }, - VirtualClipColumn::Dynamic(_) => ClipColumnDescriptor::Dynamic { - expression: Default::default(), - }, + #[cfg(feature = "playtime")] + clip_column: { + use realearn_api::persistence::ClipColumnDescriptor; + match track.clip_column().unwrap_or(&Default::default()) { + VirtualClipColumn::Selected => ClipColumnDescriptor::Selected, + VirtualClipColumn::ByIndex(i) => ClipColumnDescriptor::ByIndex { index: *i }, + VirtualClipColumn::Dynamic(_) => ClipColumnDescriptor::Dynamic { + expression: Default::default(), + }, + } }, expression: Default::default(), + #[cfg(feature = "playtime")] clip_column_track_context: track.clip_column_track_context().unwrap_or_default(), } } diff --git a/main/src/domain/audio_hook.rs b/main/src/domain/audio_hook.rs index 1e1db3277..3f94be728 100644 --- a/main/src/domain/audio_hook.rs +++ b/main/src/domain/audio_hook.rs @@ -7,7 +7,6 @@ use assert_no_alloc::*; use base::non_blocking_lock; use helgoboss_learn::{AbstractTimestamp, MidiSourceValue, RawMidiEvents}; use helgoboss_midi::{DataEntryByteOrder, RawShortMessage}; -use playtime_clip_engine::rt::audio_hook::{ClipEngineAudioHook, HardwareInputClipRecordTask}; use reaper_high::{MidiInputDevice, MidiOutputDevice, Reaper}; use reaper_medium::{ MidiInputDeviceId, MidiOutputDeviceId, OnAudioBuffer, OnAudioBufferArgs, SendMidiTime, @@ -40,7 +39,8 @@ pub enum NormalAudioHookTask { RemoveRealTimeProcessor(InstanceId), StartCapturingMidi(MidiCaptureSender), StopCapturingMidi, - StartClipRecording(HardwareInputClipRecordTask), + #[cfg(feature = "playtime")] + StartClipRecording(playtime_clip_engine::rt::audio_hook::HardwareInputClipRecordTask), } /// A global feedback task (which is potentially sent very frequently). @@ -62,7 +62,8 @@ pub struct RealearnAudioHook { time_of_last_run: Option, garbage_bin: GarbageBin, initialized: bool, - clip_engine_audio_hook: ClipEngineAudioHook, + #[cfg(feature = "playtime")] + clip_engine_audio_hook: playtime_clip_engine::rt::audio_hook::ClipEngineAudioHook, } #[derive(Debug)] @@ -90,7 +91,9 @@ impl RealearnAudioHook { time_of_last_run: None, garbage_bin, initialized: false, - clip_engine_audio_hook: ClipEngineAudioHook::new(), + #[cfg(feature = "playtime")] + clip_engine_audio_hook: playtime_clip_engine::rt::audio_hook::ClipEngineAudioHook::new( + ), } } @@ -298,6 +301,7 @@ impl RealearnAudioHook { self.garbage_bin.dispose(Garbage::MidiCaptureSender(sender)); } } + #[cfg(feature = "playtime")] StartClipRecording(task) => { self.clip_engine_audio_hook.start_clip_recording(task); } @@ -331,6 +335,7 @@ impl OnAudioBuffer for RealearnAudioHook { assert_no_alloc(|| { let block_props = AudioBlockProps::from_on_audio_buffer_args(&args); if !args.is_post { + #[cfg(feature = "playtime")] self.clip_engine_audio_hook .poll_advance_timeline(block_props.to_playtime()); let current_time = Instant::now(); @@ -343,6 +348,7 @@ impl OnAudioBuffer for RealearnAudioHook { self.process_feedback_tasks(); self.call_real_time_processors(block_props, might_be_rebirth); } + #[cfg(feature = "playtime")] self.clip_engine_audio_hook.poll_process_clip_record_tasks( args.is_post, block_props.to_playtime(), diff --git a/main/src/domain/backbone_state.rs b/main/src/domain/backbone_state.rs index c863d2a86..468e27d9b 100644 --- a/main/src/domain/backbone_state.rs +++ b/main/src/domain/backbone_state.rs @@ -1,12 +1,10 @@ use base::{ - make_available_globally_in_main_thread_on_demand, tracing_debug, NamedChannelSender, - SenderToNormalThread, SenderToRealTimeThread, + make_available_globally_in_main_thread_on_demand, NamedChannelSender, SenderToNormalThread, }; use crate::domain::{ - AdditionalFeedbackEvent, ClipMatrixRef, ControlInput, DeviceControlInput, DeviceFeedbackOutput, - FeedbackOutput, InstanceId, InstanceState, InstanceStateChanged, NormalAudioHookTask, - NormalRealTimeTask, ProcessorContext, QualifiedClipMatrixEvent, RealearnClipMatrix, + AdditionalFeedbackEvent, ControlInput, DeviceControlInput, DeviceFeedbackOutput, + FeedbackOutput, InstanceId, InstanceState, InstanceStateChanged, ProcessorContext, RealearnSourceState, RealearnTargetState, ReaperTarget, ReaperTargetType, SafeLua, SharedInstanceState, WeakInstanceState, }; @@ -14,7 +12,6 @@ use enum_iterator::IntoEnumIterator; use pot::{PotFavorites, PotFilterExcludes}; use once_cell::sync::Lazy; -use playtime_clip_engine::rt::WeakRtMatrix; use realearn_api::persistence::TargetTouchCause; use reaper_high::{Fx, Reaper}; use std::cell::{Cell, Ref, RefCell, RefMut}; @@ -254,16 +251,25 @@ impl BackboneState { id: InstanceId, processor_context: ProcessorContext, instance_feedback_event_sender: SenderToNormalThread, - clip_matrix_event_sender: SenderToNormalThread, - audio_hook_task_sender: SenderToRealTimeThread, - real_time_processor_sender: SenderToRealTimeThread, + #[cfg(feature = "playtime")] clip_matrix_event_sender: SenderToNormalThread< + crate::domain::QualifiedClipMatrixEvent, + >, + #[cfg(feature = "playtime")] audio_hook_task_sender: base::SenderToRealTimeThread< + crate::domain::NormalAudioHookTask, + >, + #[cfg(feature = "playtime")] real_time_processor_sender: base::SenderToRealTimeThread< + crate::domain::NormalRealTimeTask, + >, ) -> SharedInstanceState { let instance_state = InstanceState::new( id, processor_context, instance_feedback_event_sender, + #[cfg(feature = "playtime")] clip_matrix_event_sender, + #[cfg(feature = "playtime")] audio_hook_task_sender, + #[cfg(feature = "playtime")] real_time_processor_sender, ); let shared_instance_state = Rc::new(RefCell::new(instance_state)); @@ -277,7 +283,7 @@ impl BackboneState { // /// // /// If this instance already contains an owned clip matrix, returns it. If not, creates // /// and installs one, removing a possibly existing foreign matrix reference. - // pub fn get_or_insert_owned_clip_matrix(&mut self) -> &mut RealearnClipMatrix { + // pub fn get_or_insert_owned_clip_matrix(&mut self) -> &mut playtime_clip_engine::base::Matrix { // self.create_and_install_owned_clip_matrix_if_necessary(); // self.owned_clip_matrix_mut().unwrap() // } @@ -289,6 +295,7 @@ impl BackboneState { /// /// Also takes care of clearing all real-time matrices in other ReaLearn instances that refer /// to this one. + #[cfg(feature = "playtime")] pub fn clear_clip_matrix_from_instance_state(&self, instance_state: &mut InstanceState) { instance_state.set_clip_matrix_ref(None); self.update_rt_clip_matrix_of_referencing_instances(instance_state.instance_id(), None); @@ -301,10 +308,11 @@ impl BackboneState { /// /// Also takes care of updating all real-time matrices in other ReaLearn instances that refer /// to this one. + #[cfg(feature = "playtime")] pub fn get_or_insert_owned_clip_matrix_from_instance_state<'a>( &self, instance_state: &'a mut InstanceState, - ) -> &'a mut RealearnClipMatrix { + ) -> &'a mut playtime_clip_engine::base::Matrix { let instance_id = instance_state.instance_id(); let created = instance_state.create_and_install_owned_clip_matrix_if_necessary(); let matrix = instance_state.owned_clip_matrix_mut().unwrap(); @@ -317,10 +325,11 @@ impl BackboneState { matrix } + #[cfg(feature = "playtime")] fn update_rt_clip_matrix_of_referencing_instances( &self, this_instance_id: InstanceId, - real_time_matrix: Option, + real_time_matrix: Option, ) { for (id, is) in self.instance_states.borrow().iter() { if *id == this_instance_id { @@ -332,7 +341,9 @@ impl BackboneState { }; let is = is.borrow(); match is.clip_matrix_ref() { - Some(ClipMatrixRef::Foreign(foreign_id)) if *foreign_id == this_instance_id => { + Some(crate::domain::ClipMatrixRef::Foreign(foreign_id)) + if *foreign_id == this_instance_id => + { is.update_real_time_clip_matrix(real_time_matrix.clone(), false); } _ => continue, @@ -348,13 +359,14 @@ impl BackboneState { /// # Panics /// /// Panics if the foreign instance's instance state is currently mutably borrowed. + #[cfg(feature = "playtime")] pub fn set_instance_clip_matrix_to_foreign_matrix( &self, instance_state: &mut InstanceState, foreign_instance_id: InstanceId, ) { // Set the reference - let matrix_ref = ClipMatrixRef::Foreign(foreign_instance_id); + let matrix_ref = crate::domain::ClipMatrixRef::Foreign(foreign_instance_id); instance_state.set_clip_matrix_ref(Some(matrix_ref)); // Get a real-time matrix from the foreign instance and send it to the real-time processor // of *this* instance. @@ -362,7 +374,7 @@ impl BackboneState { instance_state.update_real_time_clip_matrix(Some(matrix.real_time_matrix()), false); }); if let Err(e) = result { - tracing_debug!("waiting for foreign clip matrix instance ({e})"); + base::tracing_debug!("waiting for foreign clip matrix instance ({e})"); } } @@ -377,12 +389,13 @@ impl BackboneState { /// - The given instance doesn't have any clip matrix defined. /// - The referenced instance doesn't exist. /// - The referenced instance exists but has no clip matrix defined. + #[cfg(feature = "playtime")] pub fn with_clip_matrix( &self, instance_state: &SharedInstanceState, - f: impl FnOnce(&RealearnClipMatrix) -> R, + f: impl FnOnce(&playtime_clip_engine::base::Matrix) -> R, ) -> Result { - use ClipMatrixRef::*; + use crate::domain::ClipMatrixRef::*; let other_instance_id = match instance_state .borrow() .clip_matrix_ref() @@ -394,12 +407,13 @@ impl BackboneState { self.with_owned_clip_matrix_from_instance(&other_instance_id, f) } + #[cfg(feature = "playtime")] fn with_owned_clip_matrix_from_instance( &self, foreign_instance_id: &InstanceId, - f: impl FnOnce(&RealearnClipMatrix) -> R, + f: impl FnOnce(&playtime_clip_engine::base::Matrix) -> R, ) -> Result { - use ClipMatrixRef::*; + use crate::domain::ClipMatrixRef::*; let other_instance_state = self .instance_states .borrow() @@ -419,12 +433,13 @@ impl BackboneState { /// Grants mutable access to the clip matrix defined for the given ReaLearn instance, /// if one is defined. + #[cfg(feature = "playtime")] pub fn with_clip_matrix_mut( &self, instance_state: &SharedInstanceState, - f: impl FnOnce(&mut RealearnClipMatrix) -> R, + f: impl FnOnce(&mut playtime_clip_engine::base::Matrix) -> R, ) -> Result { - use ClipMatrixRef::*; + use crate::domain::ClipMatrixRef::*; let other_instance_id = match instance_state .borrow_mut() .clip_matrix_ref_mut() @@ -436,12 +451,13 @@ impl BackboneState { self.with_owned_clip_matrix_from_instance_mut(&other_instance_id, f) } + #[cfg(feature = "playtime")] fn with_owned_clip_matrix_from_instance_mut( &self, instance_id: &InstanceId, - f: impl FnOnce(&mut RealearnClipMatrix) -> R, + f: impl FnOnce(&mut playtime_clip_engine::base::Matrix) -> R, ) -> Result { - use ClipMatrixRef::*; + use crate::domain::ClipMatrixRef::*; let other_instance_state = self .instance_states .borrow() @@ -597,9 +613,13 @@ fn update_io_usage( device != previously_used_device } +#[cfg(feature = "playtime")] const NO_CLIP_MATRIX_SET: &str = "no clip matrix set for this instance"; +#[cfg(feature = "playtime")] const REFERENCED_INSTANCE_NOT_AVAILABLE: &str = "other instance not available"; +#[cfg(feature = "playtime")] const REFERENCED_CLIP_MATRIX_NOT_AVAILABLE: &str = "clip matrix of other instance not available"; +#[cfg(feature = "playtime")] const NESTED_CLIP_BORROW_NOT_SUPPORTED: &str = "clip matrix of other instance also borrows"; #[derive(Clone, Debug)] diff --git a/main/src/domain/control_surface.rs b/main/src/domain/control_surface.rs index 92c037c42..97243be0a 100644 --- a/main/src/domain/control_surface.rs +++ b/main/src/domain/control_surface.rs @@ -4,9 +4,9 @@ use crate::domain::{ EelTransformation, FeedbackOutput, FeedbackRealTimeTask, FinalSourceFeedbackValue, InstanceId, InstanceStateChanged, LifecycleMidiData, LuaFeedbackScript, MainProcessor, MidiCaptureSender, MidiDeviceChangePayload, MonitoringFxChainChangeDetector, NormalRealTimeTask, OscDeviceId, - OscInputDevice, OscScanResult, QualifiedClipMatrixEvent, RealTimeCompoundMappingTarget, - RealTimeMapping, RealTimeMappingUpdate, RealTimeTargetUpdate, ReaperConfigChangeDetector, - ReaperMessage, ReaperTarget, SharedMainProcessors, SharedRealTimeProcessor, TargetTouchEvent, + OscInputDevice, OscScanResult, RealTimeCompoundMappingTarget, RealTimeMapping, + RealTimeMappingUpdate, RealTimeTargetUpdate, ReaperConfigChangeDetector, ReaperMessage, + ReaperTarget, SharedMainProcessors, SharedRealTimeProcessor, TargetTouchEvent, TouchedTrackParameterType, }; use base::{metrics_util, Global, NamedChannelSender, SenderToNormalThread}; @@ -22,7 +22,6 @@ use std::cell::RefCell; use base::metrics_util::measure_time; use itertools::{EitherOrBoth, Itertools}; -use playtime_clip_engine::rt::WeakRtMatrix; use reaper_medium::{ CommandId, ExtSupportsExtendedTouchArgs, GetFocusedFx2Result, GetTouchStateArgs, MediaTrack, MidiInputDeviceId, MidiOutputDeviceId, PositionInSeconds, ReaProject, @@ -39,6 +38,7 @@ type TargetCaptureSender = async_channel::Sender; const CONTROL_SURFACE_MAIN_TASK_BULK_SIZE: usize = 10; const ADDITIONAL_FEEDBACK_EVENT_BULK_SIZE: usize = 30; +#[cfg(feature = "playtime")] const CLIP_MATRIX_EVENT_BULK_SIZE: usize = 30; const INSTANCE_ORCHESTRATION_EVENT_BULK_SIZE: usize = 30; const OSC_INCOMING_BULK_SIZE: usize = 32; @@ -53,7 +53,8 @@ pub struct RealearnControlSurfaceMiddleware { rx_middleware: ControlSurfaceRxMiddleware, main_processors: SharedMainProcessors, main_task_receiver: Receiver>, - clip_matrix_event_receiver: Receiver, + #[cfg(feature = "playtime")] + clip_matrix_event_receiver: Receiver, additional_feedback_event_receiver: Receiver, instance_orchestration_event_receiver: Receiver, main_task_middleware: MainTaskMiddleware, @@ -71,6 +72,7 @@ pub struct RealearnControlSurfaceMiddleware { control_surface_event_receiver: crossbeam_channel::Receiver>, } +#[allow(clippy::large_enum_variant)] pub enum Garbage { RawMidiEvents(RawMidiEvents), RealTimeProcessor(SharedRealTimeProcessor), @@ -85,7 +87,8 @@ pub enum Garbage { NormalRealTimeTask(NormalRealTimeTask), FeedbackRealTimeTask(FeedbackRealTimeTask), MidiCaptureSender(MidiCaptureSender), - ClipMatrix(WeakRtMatrix), + #[cfg(feature = "playtime")] + ClipMatrix(playtime_clip_engine::rt::WeakRtMatrix), } pub enum RealearnControlSurfaceMainTask { @@ -199,7 +202,9 @@ impl RealearnControlSurfaceMiddleware { pub fn new( parent_logger: &slog::Logger, main_task_receiver: Receiver>, - clip_matrix_event_receiver: Receiver, + #[cfg(feature = "playtime")] clip_matrix_event_receiver: Receiver< + crate::domain::QualifiedClipMatrixEvent, + >, additional_feedback_event_receiver: Receiver, instance_orchestration_event_receiver: Receiver, garbage_receiver: crossbeam_channel::Receiver, @@ -220,6 +225,7 @@ impl RealearnControlSurfaceMiddleware { rx_middleware: ControlSurfaceRxMiddleware::new(Global::control_surface_rx().clone()), main_processors, main_task_receiver, + #[cfg(feature = "playtime")] clip_matrix_event_receiver, additional_feedback_event_receiver, instance_orchestration_event_receiver, @@ -279,8 +285,11 @@ impl RealearnControlSurfaceMiddleware { self.emit_device_changes_as_reaper_source_messages(timestamp); self.process_incoming_osc_messages(timestamp); // Drive clip matrix - self.poll_clip_matrixes(); - self.process_incoming_clip_matrix_events(); + #[cfg(feature = "playtime")] + { + self.poll_clip_matrixes(); + self.process_incoming_clip_matrix_events(); + } // Finally let the ReaLearn main processors do their regular job (the instances) self.run_main_processors(timestamp); // Free memory that has been used in real-time thread @@ -432,6 +441,7 @@ impl RealearnControlSurfaceMiddleware { } } + #[cfg(feature = "playtime")] fn poll_clip_matrixes(&mut self) { for processor in &*self.main_processors.borrow() { let events = processor.poll_owned_clip_matrix(); @@ -473,6 +483,7 @@ impl RealearnControlSurfaceMiddleware { } } + #[cfg(feature = "playtime")] fn process_incoming_clip_matrix_events(&mut self) { for event in self .clip_matrix_event_receiver diff --git a/main/src/domain/eventing.rs b/main/src/domain/eventing.rs index 169204f3e..88224f3e7 100644 --- a/main/src/domain/eventing.rs +++ b/main/src/domain/eventing.rs @@ -1,12 +1,10 @@ use crate::domain::{ Compartment, CompoundMappingTarget, ControlLogContext, ControlLogEntry, MappingId, MessageCaptureResult, PluginParamIndex, PluginParams, ProjectionFeedbackValue, - QualifiedMappingId, RawParamValue, RealearnClipMatrix, + QualifiedMappingId, RawParamValue, }; use helgoboss_learn::{AbsoluteValue, ControlValue}; -use playtime_clip_engine::base::ClipMatrixEvent; use realearn_api::persistence::MappingModification; -use reaper_high::ChangeEvent; use std::collections::HashSet; use std::error::Error; use std::fmt::Debug; @@ -32,12 +30,17 @@ pub enum DomainEvent<'a> { MappingEnabledChangeRequested(MappingEnabledChangeRequestedEvent), MappingModificationRequested(MappingModificationRequestedEvent), /// Only emitted for the instance owning the matrix. + #[cfg(feature = "playtime")] ClipMatrixChanged { - matrix: &'a RealearnClipMatrix, - events: &'a [ClipMatrixEvent], + matrix: &'a playtime_clip_engine::base::Matrix, + events: &'a [playtime_clip_engine::base::ClipMatrixEvent], is_poll: bool, }, - ControlSurfaceChangeEventForClipEngine(&'a RealearnClipMatrix, &'a ChangeEvent), + #[cfg(feature = "playtime")] + ControlSurfaceChangeEventForClipEngine( + &'a playtime_clip_engine::base::Matrix, + &'a reaper_high::ChangeEvent, + ), TimeForCelebratingSuccess, ConditionsChanged, } diff --git a/main/src/domain/instance_state.rs b/main/src/domain/instance_state.rs index ec1bed9c8..e2793d593 100644 --- a/main/src/domain/instance_state.rs +++ b/main/src/domain/instance_state.rs @@ -11,14 +11,10 @@ use crate::base::Prop; use crate::domain::{ AnyThreadBackboneState, BackboneState, Compartment, FxDescriptor, GlobalControlAndFeedbackState, GroupId, InstanceId, MappingId, MappingSnapshotContainer, - NormalAudioHookTask, NormalRealTimeTask, ProcessorContext, QualifiedMappingId, Tag, TagScope, - TrackDescriptor, VirtualMappingSnapshotIdForLoad, + ProcessorContext, QualifiedMappingId, Tag, TagScope, TrackDescriptor, + VirtualMappingSnapshotIdForLoad, }; -use base::{tracing_debug, NamedChannelSender, SenderToNormalThread, SenderToRealTimeThread}; -use playtime_clip_engine::base::{ - ClipMatrixEvent, ClipMatrixHandler, ClipRecordTask, Matrix, SpecificClipRecordTask, -}; -use playtime_clip_engine::rt::WeakRtMatrix; +use base::{NamedChannelSender, SenderToNormalThread}; use pot::{CurrentPreset, OptFilter, PotFavorites, PotFilterExcludes, PotIntegration}; use pot::{PotUnit, PresetId, SharedRuntimePotUnit}; use realearn_api::persistence::PotFilterKind; @@ -26,8 +22,6 @@ use realearn_api::persistence::PotFilterKind; pub type SharedInstanceState = Rc>; pub type WeakInstanceState = Weak>; -pub type RealearnClipMatrix = Matrix; - /// State connected to the instance which also needs to be accessible from layers *above* the /// processing layer (otherwise it could reside in the main processor). /// @@ -45,11 +39,15 @@ pub struct InstanceState { /// Owned clip matrix or reference to a clip matrix owned by another instance. /// /// Persistent. + #[cfg(feature = "playtime")] clip_matrix_ref: Option, instance_feedback_event_sender: SenderToNormalThread, + #[cfg(feature = "playtime")] clip_matrix_event_sender: SenderToNormalThread, - audio_hook_task_sender: SenderToRealTimeThread, - real_time_processor_sender: SenderToRealTimeThread, + #[cfg(feature = "playtime")] + audio_hook_task_sender: base::SenderToRealTimeThread, + #[cfg(feature = "playtime")] + real_time_processor_sender: base::SenderToRealTimeThread, /// Which mappings are in which group. /// /// - Not persistent @@ -130,32 +128,36 @@ pub struct InstanceState { mapping_which_learns_target: Prop>, } +#[cfg(feature = "playtime")] #[derive(Debug)] pub enum ClipMatrixRef { - Own(Box), + Own(Box), Foreign(InstanceId), } +#[cfg(feature = "playtime")] #[derive(Debug)] -pub struct RealearnClipMatrixHandler { +pub struct MatrixHandler { instance_id: InstanceId, - audio_hook_task_sender: SenderToRealTimeThread, - real_time_processor_sender: SenderToRealTimeThread, - event_sender: SenderToNormalThread, + audio_hook_task_sender: base::SenderToRealTimeThread, + real_time_processor_sender: base::SenderToRealTimeThread, + event_sender: base::SenderToNormalThread, } +#[cfg(feature = "playtime")] #[derive(Debug)] pub struct QualifiedClipMatrixEvent { pub instance_id: InstanceId, - pub event: ClipMatrixEvent, + pub event: playtime_clip_engine::base::ClipMatrixEvent, } -impl RealearnClipMatrixHandler { +#[cfg(feature = "playtime")] +impl MatrixHandler { fn new( instance_id: InstanceId, - audio_hook_task_sender: SenderToRealTimeThread, - real_time_processor_sender: SenderToRealTimeThread, - event_sender: SenderToNormalThread, + audio_hook_task_sender: base::SenderToRealTimeThread, + real_time_processor_sender: base::SenderToRealTimeThread, + event_sender: base::SenderToNormalThread, ) -> Self { Self { instance_id, @@ -166,21 +168,22 @@ impl RealearnClipMatrixHandler { } } -impl ClipMatrixHandler for RealearnClipMatrixHandler { - fn request_recording_input(&self, task: ClipRecordTask) { +#[cfg(feature = "playtime")] +impl playtime_clip_engine::base::ClipMatrixHandler for MatrixHandler { + fn request_recording_input(&self, task: playtime_clip_engine::base::ClipRecordTask) { match task.create_specific_task() { - SpecificClipRecordTask::HardwareInput(t) => { + playtime_clip_engine::base::SpecificClipRecordTask::HardwareInput(t) => { self.audio_hook_task_sender - .send_complaining(NormalAudioHookTask::StartClipRecording(t)); + .send_complaining(crate::domain::NormalAudioHookTask::StartClipRecording(t)); } - SpecificClipRecordTask::FxInput(t) => { + playtime_clip_engine::base::SpecificClipRecordTask::FxInput(t) => { self.real_time_processor_sender - .send_complaining(NormalRealTimeTask::StartClipRecording(t)); + .send_complaining(crate::domain::NormalRealTimeTask::StartClipRecording(t)); } } } - fn emit_event(&self, event: ClipMatrixEvent) { + fn emit_event(&self, event: playtime_clip_engine::base::ClipMatrixEvent) { let event = QualifiedClipMatrixEvent { instance_id: self.instance_id, event, @@ -199,17 +202,27 @@ impl InstanceState { instance_id: InstanceId, processor_context: ProcessorContext, instance_feedback_event_sender: SenderToNormalThread, - clip_matrix_event_sender: SenderToNormalThread, - audio_hook_task_sender: SenderToRealTimeThread, - real_time_processor_sender: SenderToRealTimeThread, + #[cfg(feature = "playtime")] clip_matrix_event_sender: SenderToNormalThread< + QualifiedClipMatrixEvent, + >, + #[cfg(feature = "playtime")] audio_hook_task_sender: base::SenderToRealTimeThread< + crate::domain::NormalAudioHookTask, + >, + #[cfg(feature = "playtime")] real_time_processor_sender: base::SenderToRealTimeThread< + crate::domain::NormalRealTimeTask, + >, ) -> Self { Self { instance_id, processor_context, + #[cfg(feature = "playtime")] clip_matrix_ref: None, instance_feedback_event_sender, + #[cfg(feature = "playtime")] clip_matrix_event_sender, + #[cfg(feature = "playtime")] audio_hook_task_sender, + #[cfg(feature = "playtime")] real_time_processor_sender, mappings_by_group: Default::default(), active_mapping_by_group: Default::default(), @@ -357,6 +370,7 @@ impl InstanceState { self.instance_id } + #[cfg(feature = "playtime")] pub fn clip_matrix_relevance(&self, instance_id: InstanceId) -> Option { match self.clip_matrix_ref.as_ref()? { ClipMatrixRef::Own(m) if instance_id == self.instance_id => { @@ -367,31 +381,36 @@ impl InstanceState { } } - pub fn owned_clip_matrix(&self) -> Option<&RealearnClipMatrix> { - use ClipMatrixRef::*; + #[cfg(feature = "playtime")] + pub fn owned_clip_matrix(&self) -> Option<&playtime_clip_engine::base::Matrix> { + use crate::domain::ClipMatrixRef::*; match self.clip_matrix_ref.as_ref()? { Own(m) => Some(m), Foreign(_) => None, } } - pub fn owned_clip_matrix_mut(&mut self) -> Option<&mut RealearnClipMatrix> { - use ClipMatrixRef::*; + #[cfg(feature = "playtime")] + pub fn owned_clip_matrix_mut(&mut self) -> Option<&mut playtime_clip_engine::base::Matrix> { + use crate::domain::ClipMatrixRef::*; match self.clip_matrix_ref.as_mut()? { Own(m) => Some(m), Foreign(_) => None, } } + #[cfg(feature = "playtime")] pub fn clip_matrix_ref(&self) -> Option<&ClipMatrixRef> { self.clip_matrix_ref.as_ref() } + #[cfg(feature = "playtime")] pub fn clip_matrix_ref_mut(&mut self) -> Option<&mut ClipMatrixRef> { self.clip_matrix_ref.as_mut() } /// Returns `true` if it installed a clip matrix. + #[cfg(feature = "playtime")] pub(super) fn create_and_install_owned_clip_matrix_if_necessary(&mut self) -> bool { if matches!(self.clip_matrix_ref.as_ref(), Some(ClipMatrixRef::Own(_))) { return false; @@ -402,33 +421,36 @@ impl InstanceState { true } - fn create_owned_clip_matrix(&self) -> RealearnClipMatrix { - let clip_matrix_handler = RealearnClipMatrixHandler::new( + #[cfg(feature = "playtime")] + fn create_owned_clip_matrix(&self) -> playtime_clip_engine::base::Matrix { + let clip_matrix_handler = MatrixHandler::new( self.instance_id, self.audio_hook_task_sender.clone(), self.real_time_processor_sender.clone(), self.clip_matrix_event_sender.clone(), ); - Matrix::new( + playtime_clip_engine::base::Matrix::new( Box::new(clip_matrix_handler), self.processor_context.track().cloned(), ) } + #[cfg(feature = "playtime")] pub(super) fn set_clip_matrix_ref(&mut self, matrix_ref: Option) { if self.clip_matrix_ref.is_some() { - tracing_debug!("Shutdown existing clip matrix or remove reference to clip matrix of other instance"); + base::tracing_debug!("Shutdown existing clip matrix or remove reference to clip matrix of other instance"); self.update_real_time_clip_matrix(None, false); } self.clip_matrix_ref = matrix_ref; } + #[cfg(feature = "playtime")] pub(super) fn update_real_time_clip_matrix( &self, - real_time_matrix: Option, + real_time_matrix: Option, is_owned: bool, ) { - let rt_task = NormalRealTimeTask::SetClipMatrix { + let rt_task = crate::domain::NormalRealTimeTask::SetClipMatrix { is_owned, matrix: real_time_matrix, }; @@ -698,9 +720,10 @@ pub enum PotStateChangedEvent { PresetLoaded, } +#[cfg(feature = "playtime")] pub enum ClipMatrixRelevance<'a> { /// This instance owns the clip matrix with the given ID. - Owns(&'a RealearnClipMatrix), + Owns(&'a playtime_clip_engine::base::Matrix), /// This instance borrows the clip matrix with the given ID. Borrows, } diff --git a/main/src/domain/main_processor.rs b/main/src/domain/main_processor.rs index cf9b4ac9e..ed00e9466 100644 --- a/main/src/domain/main_processor.rs +++ b/main/src/domain/main_processor.rs @@ -1,20 +1,19 @@ use crate::domain::{ aggregate_target_values, get_project_options, say, AdditionalFeedbackEvent, BackboneState, - ClipMatrixRelevance, Compartment, CompoundChangeEvent, CompoundFeedbackValue, - CompoundMappingSource, CompoundMappingSourceAddress, CompoundMappingTarget, ControlContext, - ControlEvent, ControlEventTimestamp, ControlInput, ControlLogContext, ControlLogEntry, - ControlLogEntryKind, ControlMode, ControlOutcome, DeviceFeedbackOutput, DomainEvent, - DomainEventHandler, ExtendedProcessorContext, FeedbackAudioHookTask, FeedbackCollector, - FeedbackDestinations, FeedbackOutput, FeedbackRealTimeTask, FeedbackResolution, - FeedbackSendBehavior, FinalRealFeedbackValue, FinalSourceFeedbackValue, - GlobalControlAndFeedbackState, GroupId, HitInstructionContext, HitInstructionResponse, - InstanceContainer, InstanceOrchestrationEvent, InstanceStateChanged, IoUpdatedEvent, - KeyMessage, MainMapping, MainSourceMessage, MappingActivationEffect, MappingControlResult, - MappingId, MappingInfo, MessageCaptureEvent, MessageCaptureResult, MidiControlInput, - MidiDestination, MidiScanResult, NormalRealTimeTask, OrderedMappingIdSet, OrderedMappingMap, - OscDeviceId, OscFeedbackTask, PluginParamIndex, PluginParams, ProcessorContext, ProjectOptions, - ProjectionFeedbackValue, QualifiedClipMatrixEvent, QualifiedMappingId, QualifiedSource, - RawParamValue, RealTimeMappingUpdate, RealTimeTargetUpdate, + Compartment, CompoundChangeEvent, CompoundFeedbackValue, CompoundMappingSource, + CompoundMappingSourceAddress, CompoundMappingTarget, ControlContext, ControlEvent, + ControlEventTimestamp, ControlInput, ControlLogContext, ControlLogEntry, ControlLogEntryKind, + ControlMode, ControlOutcome, DeviceFeedbackOutput, DomainEvent, DomainEventHandler, + ExtendedProcessorContext, FeedbackAudioHookTask, FeedbackCollector, FeedbackDestinations, + FeedbackOutput, FeedbackRealTimeTask, FeedbackResolution, FeedbackSendBehavior, + FinalRealFeedbackValue, FinalSourceFeedbackValue, GlobalControlAndFeedbackState, GroupId, + HitInstructionContext, HitInstructionResponse, InstanceContainer, InstanceOrchestrationEvent, + InstanceStateChanged, IoUpdatedEvent, KeyMessage, MainMapping, MainSourceMessage, + MappingActivationEffect, MappingControlResult, MappingId, MappingInfo, MessageCaptureEvent, + MessageCaptureResult, MidiControlInput, MidiDestination, MidiScanResult, NormalRealTimeTask, + OrderedMappingIdSet, OrderedMappingMap, OscDeviceId, OscFeedbackTask, PluginParamIndex, + PluginParams, ProcessorContext, ProjectOptions, ProjectionFeedbackValue, QualifiedMappingId, + QualifiedSource, RawParamValue, RealTimeMappingUpdate, RealTimeTargetUpdate, RealearnMonitoringFxParameterValueChangedEvent, RealearnParameterChangePayload, ReaperConfigChange, ReaperMessage, ReaperSourceFeedbackValue, ReaperTarget, SharedInstanceState, SourceReleasedEvent, SpecificCompoundFeedbackValue, TargetControlEvent, @@ -42,18 +41,16 @@ use base::{ }; use helgoboss_midi::{ControlChange14BitMessage, ParameterNumberMessage, RawShortMessage}; use indexmap::IndexSet; -use playtime_clip_engine::base::ClipMatrixEvent; -use playtime_clip_engine::rt::{QualifiedSlotChangeEvent, SlotChangeEvent}; use reaper_high::{ChangeEvent, Reaper}; use reaper_medium::ReaperNormalizedFxParamValue; use rosc::{OscMessage, OscPacket, OscType}; use slog::{debug, trace}; use std::collections::hash_map::Entry; use std::collections::{HashMap, HashSet}; +use std::fmt; use std::fmt::Display; use std::hash::{Hash, Hasher}; use std::rc::Rc; -use std::{fmt, slice}; // This can be come pretty big when multiple track volumes are adjusted at once. const FEEDBACK_TASK_QUEUE_SIZE: usize = 20_000; @@ -769,7 +766,8 @@ impl MainProcessor { /// Polls the clip matrix of this ReaLearn instance, if existing and only if it's an owned one /// (not borrowed from another instance). - pub fn poll_owned_clip_matrix(&self) -> Vec { + #[cfg(feature = "playtime")] + pub fn poll_owned_clip_matrix(&self) -> Vec { let mut instance_state = self.basics.instance_state.borrow_mut(); let matrix = match instance_state.owned_clip_matrix_mut() { Some(m) => m, @@ -779,16 +777,17 @@ impl MainProcessor { } /// Processes the given clip matrix events if they are relevant to this instance. + #[cfg(feature = "playtime")] pub fn process_polled_clip_matrix_events( &self, instance_id: InstanceId, - events: &[ClipMatrixEvent], + events: &[playtime_clip_engine::base::ClipMatrixEvent], ) { let instance_state = self.basics.instance_state.borrow(); let Some(relevance) = instance_state.clip_matrix_relevance(instance_id) else { return; }; - if let ClipMatrixRelevance::Owns(matrix) = relevance { + if let crate::domain::ClipMatrixRelevance::Owns(matrix) = relevance { self.basics .event_handler .handle_event_ignoring_error(DomainEvent::ClipMatrixChanged { @@ -803,30 +802,40 @@ impl MainProcessor { } /// Processes the given clip matrix event if it's relevant to this instance. - pub fn process_non_polled_clip_matrix_event(&self, event: &QualifiedClipMatrixEvent) { + #[cfg(feature = "playtime")] + pub fn process_non_polled_clip_matrix_event( + &self, + event: &crate::domain::QualifiedClipMatrixEvent, + ) { let instance_state = self.basics.instance_state.borrow(); let Some(relevance) = instance_state.clip_matrix_relevance(event.instance_id) else { return; }; - if let ClipMatrixRelevance::Owns(matrix) = relevance { + if let crate::domain::ClipMatrixRelevance::Owns(matrix) = relevance { self.basics .event_handler .handle_event_ignoring_error(DomainEvent::ClipMatrixChanged { matrix, - events: slice::from_ref(&event.event), + events: std::slice::from_ref(&event.event), is_poll: false, }); } self.process_clip_matrix_event_for_feedback(&event.event) } - fn process_clip_matrix_event_for_feedback(&self, event: &ClipMatrixEvent) { + #[cfg(feature = "playtime")] + fn process_clip_matrix_event_for_feedback( + &self, + event: &playtime_clip_engine::base::ClipMatrixEvent, + ) { let is_position_change = matches!( event, - ClipMatrixEvent::SlotChanged(QualifiedSlotChangeEvent { - event: SlotChangeEvent::Continuous { .. }, - .. - }) + playtime_clip_engine::base::ClipMatrixEvent::SlotChanged( + playtime_clip_engine::rt::QualifiedSlotChangeEvent { + event: playtime_clip_engine::rt::SlotChangeEvent::Continuous { .. }, + .. + } + ) ); if is_position_change { // Position changed. This happens very frequently when a clip is playing. @@ -1724,15 +1733,18 @@ impl MainProcessor { }); } // Process for clip engine - let mut instance_state = self.basics.instance_state.borrow_mut(); - if let Some(matrix) = instance_state.owned_clip_matrix_mut() { - // Let matrix react to track changes etc. - matrix.process_reaper_change_events(events); - // Process for GUI - for event in events { - self.basics.event_handler.handle_event_ignoring_error( - DomainEvent::ControlSurfaceChangeEventForClipEngine(matrix, event), - ); + #[cfg(feature = "playtime")] + { + let mut instance_state = self.basics.instance_state.borrow_mut(); + if let Some(matrix) = instance_state.owned_clip_matrix_mut() { + // Let matrix react to track changes etc. + matrix.process_reaper_change_events(events); + // Process for GUI + for event in events { + self.basics.event_handler.handle_event_ignoring_error( + DomainEvent::ControlSurfaceChangeEventForClipEngine(matrix, event), + ); + } } } } diff --git a/main/src/domain/real_time_processor.rs b/main/src/domain/real_time_processor.rs index 3d033bc63..9a50c31db 100644 --- a/main/src/domain/real_time_processor.rs +++ b/main/src/domain/real_time_processor.rs @@ -24,11 +24,7 @@ use slog::{debug, trace}; use assert_no_alloc::permit_alloc; use base::{Global, NamedChannelSender, SenderToNormalThread, SenderToRealTimeThread}; use enum_map::{enum_map, EnumMap}; -use playtime_clip_engine::rt::audio_hook::FxInputClipRecordTask; -use playtime_clip_engine::rt::fx_hook::{ChannelInputs, ClipEngineFxHook}; -use playtime_clip_engine::rt::WeakRtMatrix; use std::convert::TryInto; -use std::mem; use std::ptr::null_mut; use std::time::Duration; use vst::api::{EventType, Events, SysExEvent}; @@ -69,9 +65,12 @@ pub struct RealTimeProcessor { // For MIDI timing clock calculations midi_clock_calculator: MidiClockCalculator, sample_rate: Hz, - clip_matrix: Option, + #[cfg(feature = "playtime")] + clip_matrix: Option, + #[cfg(feature = "playtime")] clip_matrix_is_owned: bool, - clip_engine_fx_hook: ClipEngineFxHook, + #[cfg(feature = "playtime")] + clip_engine_fx_hook: playtime_clip_engine::rt::fx_hook::ClipEngineFxHook, } impl RealTimeProcessor { @@ -109,9 +108,12 @@ impl RealTimeProcessor { feedback_is_globally_enabled: false, garbage_bin, sample_rate: Hz::new(1.0), + #[cfg(feature = "playtime")] clip_matrix: None, + #[cfg(feature = "playtime")] clip_matrix_is_owned: false, - clip_engine_fx_hook: ClipEngineFxHook::new(), + #[cfg(feature = "playtime")] + clip_engine_fx_hook: playtime_clip_engine::rt::fx_hook::ClipEngineFxHook::new(), } } @@ -146,13 +148,16 @@ impl RealTimeProcessor { pub fn run_from_vst( &mut self, - buffer: &mut vst::buffer::AudioBuffer, - block_props: AudioBlockProps, + #[cfg(feature = "playtime")] buffer: &mut vst::buffer::AudioBuffer, + #[cfg(feature = "playtime")] block_props: AudioBlockProps, host: &HostCallback, ) { - let inputs = VstChannelInputs(buffer.split().0); - self.clip_engine_fx_hook - .process_clip_record_task(&inputs, block_props.to_playtime()); + #[cfg(feature = "playtime")] + { + let inputs = VstChannelInputs(buffer.split().0); + self.clip_engine_fx_hook + .process_clip_record_task(&inputs, block_props.to_playtime()); + } self.process_feedback_tasks(Caller::Vst(host)); } @@ -234,11 +239,14 @@ impl RealTimeProcessor { block_props: AudioBlockProps, might_be_rebirth: bool, ) { - // Poll if this is the clip matrix of this instance. If we would do polling for a foreign - // clip matrix as well, it would be polled more than once, which is unnecessary. - if self.clip_matrix_is_owned { - if let Some(clip_matrix) = self.clip_matrix.as_ref().and_then(|m| m.upgrade()) { - clip_matrix.lock().poll(block_props.to_playtime()); + #[cfg(feature = "playtime")] + { + // Poll if this is the clip matrix of this instance. If we would do polling for a foreign + // clip matrix as well, it would be polled more than once, which is unnecessary. + if self.clip_matrix_is_owned { + if let Some(clip_matrix) = self.clip_matrix.as_ref().and_then(|m| m.upgrade()) { + clip_matrix.lock().poll(block_props.to_playtime()); + } } } // Increase MIDI clock calculator's sample counter @@ -469,12 +477,14 @@ impl RealTimeProcessor { self.garbage_bin .dispose(Garbage::MappingUpdates(mapping_updates)); } + #[cfg(feature = "playtime")] SetClipMatrix { is_owned, matrix } => { self.clip_matrix_is_owned = is_owned; - if let Some(matrix) = mem::replace(&mut self.clip_matrix, matrix) { + if let Some(matrix) = std::mem::replace(&mut self.clip_matrix, matrix) { self.garbage_bin.dispose(Garbage::ClipMatrix(matrix)); } } + #[cfg(feature = "playtime")] StartClipRecording(task) => { self.clip_engine_fx_hook.start_clip_recording(task); } @@ -965,6 +975,7 @@ impl RealTimeProcessor { caller, self.settings.midi_destination(), LogOptions::from_basic_settings(&self.settings), + #[cfg(feature = "playtime")] self.clip_matrix.as_ref(), is_rendering, ) @@ -1006,6 +1017,7 @@ impl RealTimeProcessor { caller, self.settings.midi_destination(), LogOptions::from_basic_settings(&self.settings), + #[cfg(feature = "playtime")] self.clip_matrix.as_ref(), is_rendering, ); @@ -1234,9 +1246,10 @@ impl<'a> Caller<'a> { /// A task which is sent from time to time. #[derive(Debug)] pub enum NormalRealTimeTask { + #[cfg(feature = "playtime")] SetClipMatrix { is_owned: bool, - matrix: Option, + matrix: Option, }, UpdateAllMappings(Compartment, Vec), UpdateSingleMapping(Compartment, Box>), @@ -1263,7 +1276,8 @@ pub enum NormalRealTimeTask { ReturnToControlMode, UpdateControlIsGloballyEnabled(bool), UpdateFeedbackIsGloballyEnabled(bool), - StartClipRecording(FxInputClipRecordTask), + #[cfg(feature = "playtime")] + StartClipRecording(playtime_clip_engine::rt::audio_hook::FxInputClipRecordTask), } #[derive(Copy, Clone, Debug)] @@ -1371,7 +1385,7 @@ fn control_controller_mappings_midi( caller: Caller, midi_feedback_output: Option, log_options: LogOptions, - matrix: Option<&WeakRtMatrix>, + #[cfg(feature = "playtime")] matrix: Option<&playtime_clip_engine::rt::WeakRtMatrix>, is_rendering: bool, ) -> MatchOutcome { let mut match_outcome = MatchOutcome::Unmatched; @@ -1411,6 +1425,7 @@ fn control_controller_mappings_midi( caller, midi_feedback_output, log_options, + #[cfg(feature = "playtime")] matrix, is_rendering, ); @@ -1440,6 +1455,7 @@ fn control_controller_mappings_midi( caller, midi_feedback_output, log_options, + #[cfg(feature = "playtime")] matrix, is_rendering, ); @@ -1465,7 +1481,7 @@ fn process_real_mapping( caller: Caller, midi_feedback_output: Option, log_options: LogOptions, - clip_matrix: Option<&WeakRtMatrix>, + #[cfg(feature = "playtime")] clip_matrix: Option<&playtime_clip_engine::rt::WeakRtMatrix>, is_rendering: bool, ) { let pure_control_event = flatten_control_midi_event(value_event); @@ -1476,7 +1492,11 @@ fn process_real_mapping( if reaper_target.wants_real_time_control(caller, is_rendering) { // Try to process directly here in real-time. mapping.core.increase_invocation_count(); - let control_context = RealTimeControlContext { clip_matrix }; + let control_context = RealTimeControlContext { + #[cfg(feature = "playtime")] + clip_matrix, + _p: &(), + }; let mode_control_result = mapping.core.mode.control_with_options( pure_control_event, reaper_target, @@ -1504,13 +1524,17 @@ fn process_real_mapping( rt_feedback_sender, value_event.payload(), ), + #[cfg(feature = "playtime")] RealTimeReaperTarget::ClipTransport(t) => { t.hit(control_value, control_context) } + #[cfg(feature = "playtime")] RealTimeReaperTarget::ClipColumn(t) => { t.hit(control_value, control_context) } + #[cfg(feature = "playtime")] RealTimeReaperTarget::ClipRow(t) => t.hit(control_value, control_context), + #[cfg(feature = "playtime")] RealTimeReaperTarget::ClipMatrix(t) => { t.hit(control_value, control_context) } @@ -1669,7 +1693,7 @@ fn control_main_mappings_virtual( caller: Caller, midi_feedback_output: Option, log_options: LogOptions, - matrix: Option<&WeakRtMatrix>, + #[cfg(feature = "playtime")] matrix: Option<&playtime_clip_engine::rt::WeakRtMatrix>, is_rendering: bool, ) -> MatchOutcome { // Controller mappings can't have virtual sources, so for now we only need to check @@ -1695,6 +1719,7 @@ fn control_main_mappings_virtual( caller, midi_feedback_output, log_options, + #[cfg(feature = "playtime")] matrix, is_rendering, ); @@ -1820,6 +1845,7 @@ pub struct AudioBlockProps { } impl AudioBlockProps { + #[cfg(feature = "playtime")] pub fn from_vst(buffer: &vst::buffer::AudioBuffer, sample_rate: Hz) -> Self { Self { block_length: buffer.samples(), @@ -1834,6 +1860,7 @@ impl AudioBlockProps { } } + #[cfg(feature = "playtime")] pub fn to_playtime(self) -> playtime_clip_engine::rt::BasicAudioRequestProps { playtime_clip_engine::rt::BasicAudioRequestProps { block_length: self.block_length, @@ -1885,9 +1912,11 @@ fn is_rendering() -> bool { .is_some() } +#[cfg(feature = "playtime")] struct VstChannelInputs<'a>(vst::buffer::Inputs<'a, f64>); -impl<'a> ChannelInputs for VstChannelInputs<'a> { +#[cfg(feature = "playtime")] +impl<'a> playtime_clip_engine::rt::fx_hook::ChannelInputs for VstChannelInputs<'a> { fn channel_count(&self) -> usize { self.0.len() } diff --git a/main/src/domain/realearn_target.rs b/main/src/domain/realearn_target.rs index 6fdaa7aa8..cd35ae2e1 100644 --- a/main/src/domain/realearn_target.rs +++ b/main/src/domain/realearn_target.rs @@ -12,21 +12,19 @@ use crate::domain::{ ReaperTarget, SharedInstanceState, Tag, TagScope, TargetCharacter, TrackExclusivity, ACTION_TARGET, ALL_TRACK_FX_ENABLE_TARGET, ANY_ON_TARGET, AUTOMATION_MODE_OVERRIDE_TARGET, BROWSE_FXS_TARGET, BROWSE_GROUP_MAPPINGS_TARGET, BROWSE_POT_FILTER_ITEMS_TARGET, - BROWSE_POT_PRESETS_TARGET, CLIP_COLUMN_TARGET, CLIP_MANAGEMENT_TARGET, CLIP_MATRIX_TARGET, - CLIP_ROW_TARGET, CLIP_SEEK_TARGET, CLIP_TRANSPORT_TARGET, CLIP_VOLUME_TARGET, DUMMY_TARGET, - ENABLE_INSTANCES_TARGET, ENABLE_MAPPINGS_TARGET, FX_ENABLE_TARGET, FX_ONLINE_TARGET, - FX_OPEN_TARGET, FX_PARAMETER_TARGET, FX_PARAMETER_TOUCH_STATE_TARGET, FX_PRESET_TARGET, - FX_TOOL_TARGET, GO_TO_BOOKMARK_TARGET, LAST_TOUCHED_TARGET, LEARN_MAPPING_TARGET, - LOAD_FX_SNAPSHOT_TARGET, LOAD_MAPPING_SNAPSHOT_TARGET, LOAD_POT_PRESET_TARGET, - MIDI_SEND_TARGET, MOUSE_TARGET, OSC_SEND_TARGET, PLAYRATE_TARGET, PREVIEW_POT_PRESET_TARGET, - ROUTE_AUTOMATION_MODE_TARGET, ROUTE_MONO_TARGET, ROUTE_MUTE_TARGET, ROUTE_PAN_TARGET, - ROUTE_PHASE_TARGET, ROUTE_TOUCH_STATE_TARGET, ROUTE_VOLUME_TARGET, - SAVE_MAPPING_SNAPSHOT_TARGET, SEEK_TARGET, SELECTED_TRACK_TARGET, TEMPO_TARGET, - TRACK_ARM_TARGET, TRACK_AUTOMATION_MODE_TARGET, TRACK_MONITORING_MODE_TARGET, - TRACK_MUTE_TARGET, TRACK_PAN_TARGET, TRACK_PARENT_SEND_TARGET, TRACK_PEAK_TARGET, - TRACK_PHASE_TARGET, TRACK_SELECTION_TARGET, TRACK_SHOW_TARGET, TRACK_SOLO_TARGET, - TRACK_TOOL_TARGET, TRACK_TOUCH_STATE_TARGET, TRACK_VOLUME_TARGET, TRACK_WIDTH_TARGET, - TRANSPORT_TARGET, + BROWSE_POT_PRESETS_TARGET, DUMMY_TARGET, ENABLE_INSTANCES_TARGET, ENABLE_MAPPINGS_TARGET, + FX_ENABLE_TARGET, FX_ONLINE_TARGET, FX_OPEN_TARGET, FX_PARAMETER_TARGET, + FX_PARAMETER_TOUCH_STATE_TARGET, FX_PRESET_TARGET, FX_TOOL_TARGET, GO_TO_BOOKMARK_TARGET, + LAST_TOUCHED_TARGET, LEARN_MAPPING_TARGET, LOAD_FX_SNAPSHOT_TARGET, + LOAD_MAPPING_SNAPSHOT_TARGET, LOAD_POT_PRESET_TARGET, MIDI_SEND_TARGET, MOUSE_TARGET, + OSC_SEND_TARGET, PLAYRATE_TARGET, PREVIEW_POT_PRESET_TARGET, ROUTE_AUTOMATION_MODE_TARGET, + ROUTE_MONO_TARGET, ROUTE_MUTE_TARGET, ROUTE_PAN_TARGET, ROUTE_PHASE_TARGET, + ROUTE_TOUCH_STATE_TARGET, ROUTE_VOLUME_TARGET, SAVE_MAPPING_SNAPSHOT_TARGET, SEEK_TARGET, + SELECTED_TRACK_TARGET, TEMPO_TARGET, TRACK_ARM_TARGET, TRACK_AUTOMATION_MODE_TARGET, + TRACK_MONITORING_MODE_TARGET, TRACK_MUTE_TARGET, TRACK_PAN_TARGET, TRACK_PARENT_SEND_TARGET, + TRACK_PEAK_TARGET, TRACK_PHASE_TARGET, TRACK_SELECTION_TARGET, TRACK_SHOW_TARGET, + TRACK_SOLO_TARGET, TRACK_TOOL_TARGET, TRACK_TOUCH_STATE_TARGET, TRACK_VOLUME_TARGET, + TRACK_WIDTH_TARGET, TRANSPORT_TARGET, }; use base::{SenderToNormalThread, SenderToRealTimeThread}; use enum_dispatch::enum_dispatch; @@ -36,9 +34,6 @@ use helgoboss_learn::{ SourceContext, TransformationInputProvider, UnitValue, }; use num_enum::{IntoPrimitive, TryFromPrimitive}; -use playtime_clip_engine::base::ClipMatrixEvent; -use playtime_clip_engine::rt; -use playtime_clip_engine::rt::WeakRtMatrix; use realearn_api::persistence::{LearnableTargetKind, TrackScope}; use reaper_high::{ChangeEvent, Fx, Guid, Project, Reaper, Track, TrackRoute}; use reaper_medium::CommandId; @@ -335,7 +330,8 @@ pub enum CompoundChangeEvent<'a> { Reaper(&'a ChangeEvent), Additional(&'a AdditionalFeedbackEvent), Instance(&'a InstanceStateChanged), - ClipMatrix(&'a ClipMatrixEvent), + #[cfg(feature = "playtime")] + ClipMatrix(&'a playtime_clip_engine::base::ClipMatrixEvent), } pub fn get_track_name(t: &Track, scope: TrackScope) -> String { @@ -422,11 +418,14 @@ pub struct ControlContext<'a> { #[derive(Copy, Clone, Debug)] pub struct RealTimeControlContext<'a> { - pub clip_matrix: Option<&'a WeakRtMatrix>, + #[cfg(feature = "playtime")] + pub clip_matrix: Option<&'a playtime_clip_engine::rt::WeakRtMatrix>, + pub _p: &'a (), } impl<'a> RealTimeControlContext<'a> { - pub fn clip_matrix(&self) -> Result { + #[cfg(feature = "playtime")] + pub fn clip_matrix(&self) -> Result { let weak_matrix = self .clip_matrix .ok_or("real-time clip matrix not yet initialized")?; @@ -662,18 +661,25 @@ pub enum ReaperTargetType { RouteVolume = 3, // Clip targets + #[cfg(feature = "playtime")] ClipManagement = 46, + #[cfg(feature = "playtime")] ClipTransport = 31, + #[cfg(feature = "playtime")] ClipSeek = 32, + #[cfg(feature = "playtime")] ClipVolume = 33, // Clip column targets + #[cfg(feature = "playtime")] ClipColumn = 50, // Clip row targets + #[cfg(feature = "playtime")] ClipRow = 52, // Clip matrix + #[cfg(feature = "playtime")] ClipMatrix = 51, // Misc @@ -742,7 +748,12 @@ impl ReaperTargetType { pub fn supports_feedback_resolution(self) -> bool { use ReaperTargetType::*; - matches!(self, Seek | ClipSeek) + match self { + #[cfg(feature = "playtime")] + ClipSeek => true, + Seek => true, + _ => false, + } } pub fn supports_poll_for_feedback(self) -> bool { @@ -795,13 +806,20 @@ impl ReaperTargetType { RoutePan => &ROUTE_PAN_TARGET, RouteVolume => &ROUTE_VOLUME_TARGET, RouteTouchState => &ROUTE_TOUCH_STATE_TARGET, - ClipTransport => &CLIP_TRANSPORT_TARGET, - ClipColumn => &CLIP_COLUMN_TARGET, - ClipRow => &CLIP_ROW_TARGET, - ClipSeek => &CLIP_SEEK_TARGET, - ClipVolume => &CLIP_VOLUME_TARGET, - ClipManagement => &CLIP_MANAGEMENT_TARGET, - ClipMatrix => &CLIP_MATRIX_TARGET, + #[cfg(feature = "playtime")] + ClipTransport => &crate::domain::CLIP_TRANSPORT_TARGET, + #[cfg(feature = "playtime")] + ClipColumn => &crate::domain::CLIP_COLUMN_TARGET, + #[cfg(feature = "playtime")] + ClipRow => &crate::domain::CLIP_ROW_TARGET, + #[cfg(feature = "playtime")] + ClipSeek => &crate::domain::CLIP_SEEK_TARGET, + #[cfg(feature = "playtime")] + ClipVolume => &crate::domain::CLIP_VOLUME_TARGET, + #[cfg(feature = "playtime")] + ClipManagement => &crate::domain::CLIP_MANAGEMENT_TARGET, + #[cfg(feature = "playtime")] + ClipMatrix => &crate::domain::CLIP_MATRIX_TARGET, SendMidi => &MIDI_SEND_TARGET, SendOsc => &OSC_SEND_TARGET, Dummy => &DUMMY_TARGET, diff --git a/main/src/domain/reaper_target.rs b/main/src/domain/reaper_target.rs index 2ab7325b8..ccc1aca7a 100644 --- a/main/src/domain/reaper_target.rs +++ b/main/src/domain/reaper_target.rs @@ -21,28 +21,23 @@ use serde_repr::{Deserialize_repr, Serialize_repr}; use helgoboss_learn::{ AbsoluteValue, ControlType, ControlValue, NumericValue, PropValue, Target, UnitValue, }; -use playtime_api::runtime::ClipPlayState; -use playtime_clip_engine::rt::InternalClipPlayState; -use realearn_api::persistence::{ClipTransportAction, SeekBehavior, TrackScope}; +use realearn_api::persistence::{SeekBehavior, TrackScope}; use crate::domain::ui_util::convert_bool_to_unit_value; use crate::domain::{ get_reaper_track_area_of_scope, handle_exclusivity, ActionTarget, AdditionalFeedbackEvent, AllTrackFxEnableTarget, AutomationModeOverrideTarget, BrowseFxsTarget, - BrowsePotFilterItemsTarget, BrowsePotPresetsTarget, BrowseTracksTarget, Caller, - ClipColumnTarget, ClipManagementTarget, ClipMatrixTarget, ClipRowTarget, ClipSeekTarget, - ClipTransportTarget, ClipVolumeTarget, ControlContext, DummyTarget, EnigoMouseTarget, - FxEnableTarget, FxOnlineTarget, FxOpenTarget, FxParameterTarget, FxParameterTouchStateTarget, - FxPresetTarget, FxToolTarget, GoToBookmarkTarget, HierarchyEntry, HierarchyEntryProvider, - LoadFxSnapshotTarget, LoadPotPresetTarget, MappingControlContext, MidiSendTarget, - ModifyMappingTarget, OscSendTarget, PlayrateTarget, PreviewPotPresetTarget, - RealTimeClipColumnTarget, RealTimeClipMatrixTarget, RealTimeClipRowTarget, - RealTimeClipTransportTarget, RealTimeControlContext, RealTimeFxParameterTarget, - RouteMuteTarget, RoutePanTarget, RouteTouchStateTarget, RouteVolumeTarget, SeekTarget, - TakeMappingSnapshotTarget, TargetTypeDef, TempoTarget, TrackArmTarget, - TrackAutomationModeTarget, TrackMonitoringModeTarget, TrackMuteTarget, TrackPanTarget, - TrackParentSendTarget, TrackPeakTarget, TrackSelectionTarget, TrackShowTarget, TrackSoloTarget, - TrackTouchStateTarget, TrackVolumeTarget, TrackWidthTarget, TransportTarget, + BrowsePotFilterItemsTarget, BrowsePotPresetsTarget, BrowseTracksTarget, Caller, ControlContext, + DummyTarget, EnigoMouseTarget, FxEnableTarget, FxOnlineTarget, FxOpenTarget, FxParameterTarget, + FxParameterTouchStateTarget, FxPresetTarget, FxToolTarget, GoToBookmarkTarget, HierarchyEntry, + HierarchyEntryProvider, LoadFxSnapshotTarget, LoadPotPresetTarget, MappingControlContext, + MidiSendTarget, ModifyMappingTarget, OscSendTarget, PlayrateTarget, PreviewPotPresetTarget, + RealTimeControlContext, RealTimeFxParameterTarget, RouteMuteTarget, RoutePanTarget, + RouteTouchStateTarget, RouteVolumeTarget, SeekTarget, TakeMappingSnapshotTarget, TargetTypeDef, + TempoTarget, TrackArmTarget, TrackAutomationModeTarget, TrackMonitoringModeTarget, + TrackMuteTarget, TrackPanTarget, TrackParentSendTarget, TrackPeakTarget, TrackSelectionTarget, + TrackShowTarget, TrackSoloTarget, TrackTouchStateTarget, TrackVolumeTarget, TrackWidthTarget, + TransportTarget, }; use crate::domain::{ AnyOnTarget, BrowseGroupMappingsTarget, CompoundChangeEvent, EnableInstancesTarget, @@ -143,13 +138,20 @@ pub enum ReaperTarget { SendMidi(MidiSendTarget), SendOsc(OscSendTarget), Dummy(DummyTarget), - ClipMatrix(ClipMatrixTarget), - ClipTransport(ClipTransportTarget), - ClipColumn(ClipColumnTarget), - ClipRow(ClipRowTarget), - ClipSeek(ClipSeekTarget), - ClipVolume(ClipVolumeTarget), - ClipManagement(ClipManagementTarget), + #[cfg(feature = "playtime")] + ClipMatrix(crate::domain::ClipMatrixTarget), + #[cfg(feature = "playtime")] + ClipTransport(crate::domain::ClipTransportTarget), + #[cfg(feature = "playtime")] + ClipColumn(crate::domain::ClipColumnTarget), + #[cfg(feature = "playtime")] + ClipRow(crate::domain::ClipRowTarget), + #[cfg(feature = "playtime")] + ClipSeek(crate::domain::ClipSeekTarget), + #[cfg(feature = "playtime")] + ClipVolume(crate::domain::ClipVolumeTarget), + #[cfg(feature = "playtime")] + ClipManagement(crate::domain::ClipManagementTarget), LoadMappingSnapshot(LoadMappingSnapshotTarget), TakeMappingSnapshot(TakeMappingSnapshotTarget), EnableMappings(EnableMappingsTarget), @@ -315,7 +317,9 @@ impl ReaperTarget { | MappedFxParametersChanged ) } - CompoundChangeEvent::Instance(_) | CompoundChangeEvent::ClipMatrix(_) => false, + CompoundChangeEvent::Instance(_) => false, + #[cfg(feature = "playtime")] + CompoundChangeEvent::ClipMatrix(_) => false, } } @@ -655,12 +659,19 @@ impl<'a> Target<'a> for ReaperTarget { TrackAutomationTouchState(t) => t.current_value(context), GoToBookmark(t) => t.current_value(context), Seek(t) => t.current_value(context), + #[cfg(feature = "playtime")] ClipTransport(t) => t.current_value(context), + #[cfg(feature = "playtime")] ClipColumn(t) => t.current_value(context), + #[cfg(feature = "playtime")] ClipRow(t) => t.current_value(context), + #[cfg(feature = "playtime")] ClipSeek(t) => t.current_value(context), + #[cfg(feature = "playtime")] ClipVolume(t) => t.current_value(context), + #[cfg(feature = "playtime")] ClipManagement(t) => t.current_value(context), + #[cfg(feature = "playtime")] ClipMatrix(t) => t.current_value(context), LoadMappingSnapshot(t) => t.current_value(context), TakeMappingSnapshot(t) => t.current_value(context), @@ -693,9 +704,13 @@ impl<'a> Target<'a> for RealTimeReaperTarget { // need to support that one day, we can alternatively use senders. The downside is that // we have fire-and-forget then. We can't query the current value (at least not without // more complex logic). So the target itself should support toggle play/stop etc. + #[cfg(feature = "playtime")] ClipTransport(t) => t.current_value(ctx), + #[cfg(feature = "playtime")] ClipColumn(t) => t.current_value(ctx), + #[cfg(feature = "playtime")] ClipRow(t) => t.current_value(ctx), + #[cfg(feature = "playtime")] ClipMatrix(t) => t.current_value(ctx), FxParameter(t) => t.current_value(ctx), } @@ -705,9 +720,13 @@ impl<'a> Target<'a> for RealTimeReaperTarget { use RealTimeReaperTarget::*; match self { SendMidi(t) => t.control_type(()), + #[cfg(feature = "playtime")] ClipTransport(t) => t.control_type(ctx), + #[cfg(feature = "playtime")] ClipColumn(t) => t.control_type(ctx), + #[cfg(feature = "playtime")] ClipRow(t) => t.control_type(ctx), + #[cfg(feature = "playtime")] ClipMatrix(t) => t.control_type(ctx), FxParameter(t) => t.control_type(ctx), Dummy(t) => t.control_type(()), @@ -716,11 +735,13 @@ impl<'a> Target<'a> for RealTimeReaperTarget { } // Panics if called with repeat or record. +#[cfg(feature = "playtime")] pub(crate) fn clip_play_state_unit_value( - action: ClipTransportAction, - play_state: InternalClipPlayState, + action: realearn_api::persistence::ClipTransportAction, + play_state: playtime_clip_engine::rt::InternalClipPlayState, ) -> UnitValue { - use ClipTransportAction::*; + use playtime_api::runtime::ClipPlayState; + use realearn_api::persistence::ClipTransportAction::*; match action { PlayStop | PlayPause | RecordPlayStop => play_state.feedback_value(), Stop => transport_is_enabled_unit_value(play_state.get() == ClipPlayState::Stopped), @@ -1433,10 +1454,14 @@ pub fn change_track_prop( #[derive(Clone, Debug, PartialEq)] pub enum RealTimeReaperTarget { SendMidi(MidiSendTarget), - ClipTransport(RealTimeClipTransportTarget), - ClipColumn(RealTimeClipColumnTarget), - ClipRow(RealTimeClipRowTarget), - ClipMatrix(RealTimeClipMatrixTarget), + #[cfg(feature = "playtime")] + ClipTransport(crate::domain::RealTimeClipTransportTarget), + #[cfg(feature = "playtime")] + ClipColumn(crate::domain::RealTimeClipColumnTarget), + #[cfg(feature = "playtime")] + ClipRow(crate::domain::RealTimeClipRowTarget), + #[cfg(feature = "playtime")] + ClipMatrix(crate::domain::RealTimeClipMatrixTarget), FxParameter(RealTimeFxParameterTarget), Dummy(DummyTarget), } diff --git a/main/src/domain/targets/clip_management_target.rs b/main/src/domain/targets/clip_management_target.rs index 9d10e9ad8..47fd0b118 100644 --- a/main/src/domain/targets/clip_management_target.rs +++ b/main/src/domain/targets/clip_management_target.rs @@ -1,8 +1,8 @@ use crate::domain::ui_util::convert_bool_to_unit_value; use crate::domain::{ BackboneState, Compartment, ControlContext, ExtendedProcessorContext, HitResponse, - MappingControlContext, RealearnClipMatrix, RealearnTarget, ReaperTarget, ReaperTargetType, - TargetCharacter, TargetTypeDef, UnresolvedReaperTargetDef, VirtualClipSlot, DEFAULT_TARGET, + MappingControlContext, RealearnTarget, ReaperTarget, ReaperTargetType, TargetCharacter, + TargetTypeDef, UnresolvedReaperTargetDef, VirtualClipSlot, DEFAULT_TARGET, }; use helgoboss_learn::{AbsoluteValue, ControlType, ControlValue, PropValue, Target}; use playtime_clip_engine::base::{ClipAddress, ClipSlotAddress}; @@ -42,7 +42,7 @@ impl ClipManagementTarget { fn with_matrix( &self, context: MappingControlContext, - f: impl FnOnce(&mut RealearnClipMatrix) -> R, + f: impl FnOnce(&mut playtime_clip_engine::base::Matrix) -> R, ) -> Result { BackboneState::get().with_clip_matrix_mut(context.control_context.instance_state, f) } diff --git a/main/src/domain/targets/clip_row_target.rs b/main/src/domain/targets/clip_row_target.rs index 474cbea81..03865ffa2 100644 --- a/main/src/domain/targets/clip_row_target.rs +++ b/main/src/domain/targets/clip_row_target.rs @@ -1,8 +1,8 @@ use crate::domain::{ BackboneState, Compartment, ControlContext, ExtendedProcessorContext, HitResponse, - MappingControlContext, RealTimeControlContext, RealTimeReaperTarget, RealearnClipMatrix, - RealearnTarget, ReaperTarget, ReaperTargetType, TargetCharacter, TargetTypeDef, - UnresolvedReaperTargetDef, VirtualClipRow, DEFAULT_TARGET, + MappingControlContext, RealTimeControlContext, RealTimeReaperTarget, RealearnTarget, + ReaperTarget, ReaperTargetType, TargetCharacter, TargetTypeDef, UnresolvedReaperTargetDef, + VirtualClipRow, DEFAULT_TARGET, }; use helgoboss_learn::{AbsoluteValue, ControlType, ControlValue, Target}; use realearn_api::persistence::ClipRowAction; @@ -42,7 +42,7 @@ impl ClipRowTarget { fn with_matrix( &self, context: ControlContext, - f: impl FnOnce(&mut RealearnClipMatrix) -> R, + f: impl FnOnce(&mut playtime_clip_engine::base::Matrix) -> R, ) -> Result { BackboneState::get().with_clip_matrix_mut(context.instance_state, f) } diff --git a/main/src/domain/targets/clip_transport_target.rs b/main/src/domain/targets/clip_transport_target.rs index e0e245ac8..7ba6d17c5 100644 --- a/main/src/domain/targets/clip_transport_target.rs +++ b/main/src/domain/targets/clip_transport_target.rs @@ -2,9 +2,8 @@ use crate::domain::{ clip_play_state_unit_value, format_value_as_on_off, interpret_current_clip_slot_value, transport_is_enabled_unit_value, BackboneState, Compartment, CompoundChangeEvent, ControlContext, ExtendedProcessorContext, HitResponse, MappingControlContext, - RealTimeControlContext, RealTimeReaperTarget, RealearnClipMatrix, RealearnTarget, ReaperTarget, - ReaperTargetType, TargetCharacter, TargetTypeDef, UnresolvedReaperTargetDef, VirtualClipSlot, - DEFAULT_TARGET, + RealTimeControlContext, RealTimeReaperTarget, RealearnTarget, ReaperTarget, ReaperTargetType, + TargetCharacter, TargetTypeDef, UnresolvedReaperTargetDef, VirtualClipSlot, DEFAULT_TARGET, }; use helgoboss_learn::{AbsoluteValue, ControlType, ControlValue, PropValue, Target, UnitValue}; use playtime_api::persistence::{ClipPlayStartTiming, ClipPlayStopTiming}; @@ -64,7 +63,10 @@ pub struct ClipTransportTarget { } impl ClipTransportTarget { - pub fn clip_play_state(&self, matrix: &RealearnClipMatrix) -> Option { + pub fn clip_play_state( + &self, + matrix: &playtime_clip_engine::base::Matrix, + ) -> Option { let play_state = matrix.find_slot(self.basics.slot_coordinates)?.play_state(); Some(play_state) } diff --git a/main/src/domain/targets/mod.rs b/main/src/domain/targets/mod.rs index 259044b9a..66e400bb6 100644 --- a/main/src/domain/targets/mod.rs +++ b/main/src/domain/targets/mod.rs @@ -10,25 +10,39 @@ pub use dummy_target::*; mod mouse_target; pub use mouse_target::*; +#[cfg(feature = "playtime")] mod clip_transport_target; +#[cfg(feature = "playtime")] pub use clip_transport_target::*; +#[cfg(feature = "playtime")] mod clip_column_target; +#[cfg(feature = "playtime")] pub use clip_column_target::*; +#[cfg(feature = "playtime")] mod clip_row_target; +#[cfg(feature = "playtime")] pub use clip_row_target::*; +#[cfg(feature = "playtime")] mod clip_matrix_target; +#[cfg(feature = "playtime")] pub use clip_matrix_target::*; +#[cfg(feature = "playtime")] mod clip_seek_target; +#[cfg(feature = "playtime")] pub use clip_seek_target::*; +#[cfg(feature = "playtime")] mod clip_volume_target; +#[cfg(feature = "playtime")] pub use clip_volume_target::*; +#[cfg(feature = "playtime")] mod clip_management_target; +#[cfg(feature = "playtime")] pub use clip_management_target::*; mod track_peak_target; diff --git a/main/src/domain/ui_util.rs b/main/src/domain/ui_util.rs index 8bce870c6..113a1c307 100644 --- a/main/src/domain/ui_util.rs +++ b/main/src/domain/ui_util.rs @@ -61,6 +61,7 @@ pub fn format_volume_as_db_without_unit(volume: Volume) -> String { } } +#[cfg(feature = "playtime")] pub fn db_unit_value(volume: Db) -> UnitValue { volume_unit_value(Volume::from_db(volume)) } diff --git a/main/src/domain/unresolved_reaper_target.rs b/main/src/domain/unresolved_reaper_target.rs index 84c0c8ca8..c04a53ddd 100644 --- a/main/src/domain/unresolved_reaper_target.rs +++ b/main/src/domain/unresolved_reaper_target.rs @@ -6,13 +6,11 @@ use crate::domain::{ UnresolvedAllTrackFxEnableTarget, UnresolvedAnyOnTarget, UnresolvedAutomationModeOverrideTarget, UnresolvedBrowseFxsTarget, UnresolvedBrowseGroupTarget, UnresolvedBrowsePotFilterItemsTarget, UnresolvedBrowsePotPresetsTarget, - UnresolvedBrowseTracksTarget, UnresolvedClipColumnTarget, UnresolvedClipManagementTarget, - UnresolvedClipMatrixTarget, UnresolvedClipRowTarget, UnresolvedClipSeekTarget, - UnresolvedClipTransportTarget, UnresolvedClipVolumeTarget, UnresolvedDummyTarget, - UnresolvedEnableInstancesTarget, UnresolvedEnableMappingsTarget, UnresolvedFxEnableTarget, - UnresolvedFxOnlineTarget, UnresolvedFxOpenTarget, UnresolvedFxParameterTarget, - UnresolvedFxParameterTouchStateTarget, UnresolvedFxPresetTarget, UnresolvedFxToolTarget, - UnresolvedGoToBookmarkTarget, UnresolvedLastTouchedTarget, UnresolvedLoadFxSnapshotTarget, + UnresolvedBrowseTracksTarget, UnresolvedDummyTarget, UnresolvedEnableInstancesTarget, + UnresolvedEnableMappingsTarget, UnresolvedFxEnableTarget, UnresolvedFxOnlineTarget, + UnresolvedFxOpenTarget, UnresolvedFxParameterTarget, UnresolvedFxParameterTouchStateTarget, + UnresolvedFxPresetTarget, UnresolvedFxToolTarget, UnresolvedGoToBookmarkTarget, + UnresolvedLastTouchedTarget, UnresolvedLoadFxSnapshotTarget, UnresolvedLoadMappingSnapshotTarget, UnresolvedLoadPotPresetTarget, UnresolvedMidiSendTarget, UnresolvedModifyMappingTarget, UnresolvedMouseTarget, UnresolvedOscSendTarget, UnresolvedPlayrateTarget, UnresolvedPreviewPotPresetTarget, @@ -31,11 +29,9 @@ use enum_dispatch::enum_dispatch; use enum_iterator::IntoEnumIterator; use fasteval::{Compiler, Evaler, Instruction, Slab}; use num_enum::{IntoPrimitive, TryFromPrimitive}; -use playtime_clip_engine::base::ClipSlotAddress; use realearn_api::persistence::{ - ClipColumnDescriptor, ClipColumnTrackContext, FxChainDescriptor, FxDescriptorCommons, - TrackDescriptorCommons, TrackScope, + FxChainDescriptor, FxDescriptorCommons, TrackDescriptorCommons, TrackScope, }; use reaper_high::{ BookmarkType, FindBookmarkResult, Fx, FxChain, FxParameter, Guid, Project, Reaper, @@ -99,13 +95,20 @@ pub enum UnresolvedReaperTarget { SendMidi(UnresolvedMidiSendTarget), SendOsc(UnresolvedOscSendTarget), Dummy(UnresolvedDummyTarget), - ClipTransport(UnresolvedClipTransportTarget), - ClipColumn(UnresolvedClipColumnTarget), - ClipRow(UnresolvedClipRowTarget), - ClipSeek(UnresolvedClipSeekTarget), - ClipVolume(UnresolvedClipVolumeTarget), - ClipManagement(UnresolvedClipManagementTarget), - ClipMatrix(UnresolvedClipMatrixTarget), + #[cfg(feature = "playtime")] + ClipTransport(crate::domain::UnresolvedClipTransportTarget), + #[cfg(feature = "playtime")] + ClipColumn(crate::domain::UnresolvedClipColumnTarget), + #[cfg(feature = "playtime")] + ClipRow(crate::domain::UnresolvedClipRowTarget), + #[cfg(feature = "playtime")] + ClipSeek(crate::domain::UnresolvedClipSeekTarget), + #[cfg(feature = "playtime")] + ClipVolume(crate::domain::UnresolvedClipVolumeTarget), + #[cfg(feature = "playtime")] + ClipManagement(crate::domain::UnresolvedClipManagementTarget), + #[cfg(feature = "playtime")] + ClipMatrix(crate::domain::UnresolvedClipMatrixTarget), LoadMappingSnapshot(UnresolvedLoadMappingSnapshotTarget), TakeMappingSnapshot(UnresolvedTakeMappingSnapshotTarget), EnableMappings(UnresolvedEnableMappingsTarget), @@ -175,16 +178,19 @@ impl UnresolvedReaperTarget { return true; } } + #[cfg(feature = "playtime")] if let Some(slot) = descriptors.clip_slot { if slot.can_be_affected_by_parameters() { return true; } } + #[cfg(feature = "playtime")] if let Some(col) = descriptors.clip_column { if col.can_be_affected_by_parameters() { return true; } } + #[cfg(feature = "playtime")] if let Some(row) = descriptors.clip_row { if row.can_be_affected_by_parameters() { return true; @@ -222,18 +228,21 @@ impl UnresolvedReaperTarget { ..Default::default() }; } + #[cfg(feature = "playtime")] if let Some(d) = self.clip_slot_descriptor() { return Descriptors { clip_slot: Some(d), ..Default::default() }; } + #[cfg(feature = "playtime")] if let Some(d) = self.clip_column_descriptor() { return Descriptors { clip_column: Some(d), ..Default::default() }; } + #[cfg(feature = "playtime")] if let Some(d) = self.clip_row_descriptor() { return Descriptors { clip_row: Some(d), @@ -337,6 +346,7 @@ impl TrackDescriptor { }, TrackDescriptorCommons::default(), ), + #[cfg(feature = "playtime")] FromClipColumn { column, context, @@ -743,6 +753,7 @@ impl Default for TrackRouteType { } } +#[cfg(feature = "playtime")] #[derive(Debug)] pub enum VirtualClipSlot { Selected, @@ -756,19 +767,20 @@ pub enum VirtualClipSlot { }, } +#[cfg(feature = "playtime")] impl VirtualClipSlot { pub fn resolve( &self, context: ExtendedProcessorContext, compartment: Compartment, - ) -> Result { + ) -> Result { use VirtualClipSlot::*; let coordinates = match self { Selected => return Err("the concept of a selected slot is not yet supported"), ByIndex { column_index, row_index, - } => ClipSlotAddress::new(*column_index, *row_index), + } => playtime_clip_engine::base::ClipSlotAddress::new(*column_index, *row_index), Dynamic { column_evaluator, row_evaluator, @@ -778,7 +790,7 @@ impl VirtualClipSlot { to_slot_coordinate(column_evaluator.evaluate_with_params(compartment_params))?; let row_index = to_slot_coordinate(row_evaluator.evaluate_with_params(compartment_params))?; - ClipSlotAddress::new(column_index, row_index) + playtime_clip_engine::base::ClipSlotAddress::new(column_index, row_index) } }; // let slot_exists = BackboneState::get() @@ -796,6 +808,7 @@ impl VirtualClipSlot { } } +#[cfg(feature = "playtime")] #[derive(Debug)] pub enum VirtualClipColumn { Selected, @@ -803,17 +816,19 @@ pub enum VirtualClipColumn { Dynamic(Box), } +#[cfg(feature = "playtime")] impl Default for VirtualClipColumn { fn default() -> Self { Self::Selected } } +#[cfg(feature = "playtime")] impl VirtualClipColumn { pub fn from_descriptor( - descriptor: &ClipColumnDescriptor, + descriptor: &realearn_api::persistence::ClipColumnDescriptor, ) -> Result { - use ClipColumnDescriptor::*; + use realearn_api::persistence::ClipColumnDescriptor::*; let column = match descriptor { Selected => VirtualClipColumn::Selected, ByIndex { index } => VirtualClipColumn::ByIndex(*index), @@ -857,6 +872,7 @@ impl VirtualClipColumn { } } +#[cfg(feature = "playtime")] #[derive(Debug)] pub enum VirtualClipRow { Selected, @@ -864,12 +880,14 @@ pub enum VirtualClipRow { Dynamic(Box), } +#[cfg(feature = "playtime")] impl Default for VirtualClipRow { fn default() -> Self { Self::Selected } } +#[cfg(feature = "playtime")] impl VirtualClipRow { pub fn resolve( &self, @@ -905,10 +923,12 @@ impl VirtualClipRow { /// have a clip, which is a valid state and should return *something*. The contract of the target /// `current_value()` is that if it returns `None`, it means it can't get a value at the moment, /// probably just temporarily. In that case, the feedback is simply not updated. +#[cfg(feature = "playtime")] pub fn interpret_current_clip_slot_value(value: Option) -> Option { Some(value.unwrap_or_default()) } +#[cfg(feature = "playtime")] fn to_slot_coordinate(eval_result: Result) -> Result { let res = eval_result.map_err(|_| "couldn't evaluate clip slot coordinate")?; if res < 0.0 { @@ -943,9 +963,10 @@ pub enum VirtualTrack { /// compatibility. ByIdOrName(Guid, WildMatch), /// Uses the track from the given clip column. + #[cfg(feature = "playtime")] FromClipColumn { column: VirtualClipColumn, - context: ClipColumnTrackContext, + context: realearn_api::persistence::ClipColumnTrackContext, }, /// Instance track Instance, @@ -1223,6 +1244,7 @@ impl fmt::Display for VirtualTrack { }; write!(f, "#{}{}", index + 1, suffix) } + #[cfg(feature = "playtime")] FromClipColumn { .. } => f.write_str("From a clip column"), } } @@ -1405,6 +1427,7 @@ impl VirtualTrack { let single = resolve_track_by_index(project, *index as i32, *scope)?; vec![single] } + #[cfg(feature = "playtime")] FromClipColumn { column, context: track_context, @@ -1422,8 +1445,12 @@ impl VirtualTrack { .with_clip_matrix(context.control_context.instance_state, |matrix| { let column = matrix.get_column(clip_column_index)?; match track_context { - ClipColumnTrackContext::Playback => column.playback_track().cloned(), - ClipColumnTrackContext::Recording => column.effective_recording_track(), + realearn_api::persistence::ClipColumnTrackContext::Playback => { + column.playback_track().cloned() + } + realearn_api::persistence::ClipColumnTrackContext::Recording => { + column.effective_recording_track() + } } }) .map_err(|_| generic_error())? @@ -1438,6 +1465,7 @@ impl VirtualTrack { pub fn can_be_affected_by_parameters(&self) -> bool { match self { VirtualTrack::Dynamic { .. } => true, + #[cfg(feature = "playtime")] VirtualTrack::FromClipColumn { column: VirtualClipColumn::Dynamic(_), .. @@ -1578,6 +1606,7 @@ impl VirtualTrack { } } + #[cfg(feature = "playtime")] pub fn clip_column(&self) -> Option<&VirtualClipColumn> { if let VirtualTrack::FromClipColumn { column, .. } = self { Some(column) @@ -1586,7 +1615,10 @@ impl VirtualTrack { } } - pub fn clip_column_track_context(&self) -> Option { + #[cfg(feature = "playtime")] + pub fn clip_column_track_context( + &self, + ) -> Option { if let VirtualTrack::FromClipColumn { context, .. } = self { Some(*context) } else { @@ -2113,8 +2145,11 @@ struct Descriptors<'a> { fx: Option<&'a FxDescriptor>, route: Option<&'a TrackRouteDescriptor>, fx_param: Option<&'a FxParameterDescriptor>, + #[cfg(feature = "playtime")] clip_slot: Option<&'a VirtualClipSlot>, + #[cfg(feature = "playtime")] clip_column: Option<&'a VirtualClipColumn>, + #[cfg(feature = "playtime")] clip_row: Option<&'a VirtualClipRow>, } @@ -2163,14 +2198,17 @@ pub trait UnresolvedReaperTargetDef { None } + #[cfg(feature = "playtime")] fn clip_slot_descriptor(&self) -> Option<&VirtualClipSlot> { None } + #[cfg(feature = "playtime")] fn clip_column_descriptor(&self) -> Option<&VirtualClipColumn> { None } + #[cfg(feature = "playtime")] fn clip_row_descriptor(&self) -> Option<&VirtualClipRow> { None } diff --git a/main/src/infrastructure/api/convert/defaults.rs b/main/src/infrastructure/api/convert/defaults.rs index b21ca2f39..5be87f390 100644 --- a/main/src/infrastructure/api/convert/defaults.rs +++ b/main/src/infrastructure/api/convert/defaults.rs @@ -45,7 +45,9 @@ pub const TARGET_SEEK_MOVE_VIEW: bool = true; pub const TARGET_SEEK_SEEK_PLAY: bool = true; pub const TARGET_LOAD_MAPPING_SNAPSHOT_ACTIVE_MAPPINGS_ONLY: bool = false; pub const TARGET_SAVE_MAPPING_SNAPSHOT_ACTIVE_MAPPINGS_ONLY: bool = false; +#[cfg(feature = "playtime")] pub const TARGET_RECORD_ONLY_IF_TRACK_ARMED: bool = false; +#[cfg(feature = "playtime")] pub const TARGET_STOP_COLUMN_IF_SLOT_EMPTY: bool = false; pub const TARGET_USE_SELECTION_GANGING: bool = false; pub const TARGET_USE_TRACK_GROUPING: bool = false; diff --git a/main/src/infrastructure/api/convert/from_data/target.rs b/main/src/infrastructure/api/convert/from_data/target.rs index d4fe7c522..5d245540d 100644 --- a/main/src/infrastructure/api/convert/from_data/target.rs +++ b/main/src/infrastructure/api/convert/from_data/target.rs @@ -15,17 +15,15 @@ use crate::infrastructure::api::convert::from_data::{ use crate::infrastructure::api::convert::{defaults, ConversionResult}; use crate::infrastructure::data::{ deserialize_fx, deserialize_fx_parameter, deserialize_track, deserialize_track_route, - MigrationDescriptor, TargetModelData, TrackData, + MigrationDescriptor, TargetModelData, TrackData, TrackDeserializationInput, }; use realearn_api::persistence; use realearn_api::persistence::{ AllTrackFxOnOffStateTarget, AnyOnTarget, AutomationModeOverrideTarget, BackwardCompatibleMappingSnapshotDescForTake, BookmarkDescriptor, BookmarkRef, BrowseFxChainTarget, BrowseFxPresetsTarget, BrowseGroupMappingsTarget, - BrowsePotFilterItemsTarget, BrowsePotPresetsTarget, BrowseTracksTarget, ClipColumnDescriptor, - ClipColumnTarget, ClipManagementTarget, ClipMatrixTarget, ClipRowTarget, ClipSeekTarget, - ClipTransportActionTarget, ClipVolumeTarget, DummyTarget, EnableInstancesTarget, - EnableMappingsTarget, FxOnOffStateTarget, FxOnlineOfflineStateTarget, + BrowsePotFilterItemsTarget, BrowsePotPresetsTarget, BrowseTracksTarget, DummyTarget, + EnableInstancesTarget, EnableMappingsTarget, FxOnOffStateTarget, FxOnlineOfflineStateTarget, FxParameterAutomationTouchStateTarget, FxParameterValueTarget, FxToolTarget, FxVisibilityTarget, GoToBookmarkTarget, LastTouchedTarget, LearnTargetMappingModification, LoadFxSnapshotTarget, LoadMappingSnapshotTarget, LoadPotPresetTarget, MappingModification, @@ -107,6 +105,7 @@ fn convert_real_target( convert_track_descriptor( data.track_data, data.enable_only_if_track_is_selected, + #[cfg(feature = "playtime")] &data.clip_column, style, ) @@ -154,6 +153,7 @@ fn convert_real_target( track: convert_track_descriptor( data.track_data, data.enable_only_if_track_is_selected, + #[cfg(feature = "playtime")] &data.clip_column, style, ), @@ -165,6 +165,7 @@ fn convert_real_target( track: convert_track_descriptor( data.track_data, data.enable_only_if_track_is_selected, + #[cfg(feature = "playtime")] &data.clip_column, style, ), @@ -180,6 +181,7 @@ fn convert_real_target( track: convert_track_descriptor( data.track_data, data.enable_only_if_track_is_selected, + #[cfg(feature = "playtime")] &data.clip_column, style, ), @@ -199,6 +201,7 @@ fn convert_real_target( track: convert_track_descriptor( data.track_data, data.enable_only_if_track_is_selected, + #[cfg(feature = "playtime")] &data.clip_column, style, ), @@ -282,36 +285,43 @@ fn convert_real_target( }, route: convert_route_descriptor(data, style), }), - ClipTransport => T::ClipTransportAction(ClipTransportActionTarget { - commons, - slot: data.clip_slot.unwrap_or_default(), - action: data.clip_transport_action.unwrap_or_default(), - record_only_if_track_armed: style.required_value_with_default( - data.record_only_if_track_armed, - defaults::TARGET_RECORD_ONLY_IF_TRACK_ARMED, - ), - stop_column_if_slot_empty: style.required_value_with_default( - data.stop_column_if_slot_empty, - defaults::TARGET_STOP_COLUMN_IF_SLOT_EMPTY, - ), - play_start_timing: data.clip_play_start_timing, - play_stop_timing: data.clip_play_stop_timing, - }), - ClipColumn => T::ClipColumnAction(ClipColumnTarget { + #[cfg(feature = "playtime")] + ClipTransport => { + T::ClipTransportAction(realearn_api::persistence::ClipTransportActionTarget { + commons, + slot: data.clip_slot.unwrap_or_default(), + action: data.clip_transport_action.unwrap_or_default(), + record_only_if_track_armed: style.required_value_with_default( + data.record_only_if_track_armed, + defaults::TARGET_RECORD_ONLY_IF_TRACK_ARMED, + ), + stop_column_if_slot_empty: style.required_value_with_default( + data.stop_column_if_slot_empty, + defaults::TARGET_STOP_COLUMN_IF_SLOT_EMPTY, + ), + play_start_timing: data.clip_play_start_timing, + play_stop_timing: data.clip_play_stop_timing, + }) + } + #[cfg(feature = "playtime")] + ClipColumn => T::ClipColumnAction(realearn_api::persistence::ClipColumnTarget { commons, column: data.clip_column, action: data.clip_column_action, }), - ClipRow => T::ClipRowAction(ClipRowTarget { + #[cfg(feature = "playtime")] + ClipRow => T::ClipRowAction(realearn_api::persistence::ClipRowTarget { commons, row: data.clip_row, action: data.clip_row_action, }), - ClipMatrix => T::ClipMatrixAction(ClipMatrixTarget { + #[cfg(feature = "playtime")] + ClipMatrix => T::ClipMatrixAction(realearn_api::persistence::ClipMatrixTarget { commons, action: data.clip_matrix_action, }), - ClipSeek => T::ClipSeek(ClipSeekTarget { + #[cfg(feature = "playtime")] + ClipSeek => T::ClipSeek(realearn_api::persistence::ClipSeekTarget { commons, slot: data.clip_slot.unwrap_or_default(), feedback_resolution: convert_feedback_resolution( @@ -319,11 +329,13 @@ fn convert_real_target( style, ), }), - ClipVolume => T::ClipVolume(ClipVolumeTarget { + #[cfg(feature = "playtime")] + ClipVolume => T::ClipVolume(realearn_api::persistence::ClipVolumeTarget { commons, slot: data.clip_slot.unwrap_or_default(), }), - ClipManagement => T::ClipManagement(ClipManagementTarget { + #[cfg(feature = "playtime")] + ClipManagement => T::ClipManagement(realearn_api::persistence::ClipManagementTarget { commons, slot: data.clip_slot.unwrap_or_default(), action: data.clip_management_action, @@ -393,6 +405,7 @@ fn convert_real_target( track: convert_track_descriptor( data.track_data, data.enable_only_if_track_is_selected, + #[cfg(feature = "playtime")] &data.clip_column, style, ), @@ -411,6 +424,7 @@ fn convert_real_target( track: convert_track_descriptor( data.track_data, data.enable_only_if_track_is_selected, + #[cfg(feature = "playtime")] &data.clip_column, style, ), @@ -421,6 +435,7 @@ fn convert_real_target( track: convert_track_descriptor( data.track_data, data.enable_only_if_track_is_selected, + #[cfg(feature = "playtime")] &data.clip_column, style, ), @@ -435,6 +450,7 @@ fn convert_real_target( track: convert_track_descriptor( data.track_data, data.enable_only_if_track_is_selected, + #[cfg(feature = "playtime")] &data.clip_column, style, ), @@ -453,6 +469,7 @@ fn convert_real_target( track: convert_track_descriptor( data.track_data, data.enable_only_if_track_is_selected, + #[cfg(feature = "playtime")] &data.clip_column, style, ), @@ -462,6 +479,7 @@ fn convert_real_target( track: convert_track_descriptor( data.track_data, data.enable_only_if_track_is_selected, + #[cfg(feature = "playtime")] &data.clip_column, style, ), @@ -484,6 +502,7 @@ fn convert_real_target( track: convert_track_descriptor( data.track_data, data.enable_only_if_track_is_selected, + #[cfg(feature = "playtime")] &data.clip_column, style, ), @@ -502,6 +521,7 @@ fn convert_real_target( track: convert_track_descriptor( data.track_data, data.enable_only_if_track_is_selected, + #[cfg(feature = "playtime")] &data.clip_column, style, ), @@ -519,6 +539,7 @@ fn convert_real_target( track: convert_track_descriptor( data.track_data, data.enable_only_if_track_is_selected, + #[cfg(feature = "playtime")] &data.clip_column, style, ), @@ -536,6 +557,7 @@ fn convert_real_target( track: convert_track_descriptor( data.track_data, data.enable_only_if_track_is_selected, + #[cfg(feature = "playtime")] &data.clip_column, style, ), @@ -553,6 +575,7 @@ fn convert_real_target( track: convert_track_descriptor( data.track_data, data.enable_only_if_track_is_selected, + #[cfg(feature = "playtime")] &data.clip_column, style, ), @@ -564,6 +587,7 @@ fn convert_real_target( track: convert_track_descriptor( data.track_data, data.enable_only_if_track_is_selected, + #[cfg(feature = "playtime")] &data.clip_column, style, ), @@ -839,10 +863,15 @@ fn convert_virtual_target(data: TargetModelData, style: ConversionStyle) -> pers fn convert_track_descriptor( data: TrackData, only_if_track_selected: bool, - clip_column: &ClipColumnDescriptor, + #[cfg(feature = "playtime")] clip_column: &realearn_api::persistence::ClipColumnDescriptor, style: ConversionStyle, ) -> Option { - let props = deserialize_track(&data, clip_column); + let input = TrackDeserializationInput { + track_data: &data, + #[cfg(feature = "playtime")] + clip_column, + }; + let props = deserialize_track(input); use persistence::TrackDescriptor as T; use VirtualTrackType::*; let commons = persistence::TrackDescriptorCommons { @@ -883,6 +912,7 @@ fn convert_track_descriptor( index: props.index, scope: style.optional_value(props.r#type.virtual_track_scope()), }, + #[cfg(feature = "playtime")] FromClipColumn => T::FromClipColumn { commons, column: props.clip_column, @@ -900,6 +930,7 @@ fn convert_fx_chain_descriptor( track: convert_track_descriptor( data.track_data, data.enable_only_if_track_is_selected, + #[cfg(feature = "playtime")] &data.clip_column, style, ), @@ -957,6 +988,7 @@ fn convert_route_descriptor( track: convert_track_descriptor( data.track_data, data.enable_only_if_track_is_selected, + #[cfg(feature = "playtime")] &data.clip_column, style, ), diff --git a/main/src/infrastructure/api/convert/to_data/target.rs b/main/src/infrastructure/api/convert/to_data/target.rs index 1d161f527..e4caef5a6 100644 --- a/main/src/infrastructure/api/convert/to_data/target.rs +++ b/main/src/infrastructure/api/convert/to_data/target.rs @@ -58,6 +58,7 @@ pub fn convert_target(t: Target) -> ConversionResult { ..init(d.commons) } } + #[allow(unused_mut)] Target::ReaperAction(d) => { let mut track_desc = if let Some(td) = d.track { Some(convert_track_desc(td)?) @@ -86,6 +87,7 @@ pub fn convert_target(t: Target) -> ConversionResult { .as_ref() .map(|d| d.track_must_be_selected) .unwrap_or(defaults::TARGET_TRACK_MUST_BE_SELECTED), + #[cfg(feature = "playtime")] clip_column: track_desc .as_mut() .and_then(|d| d.clip_column.take()) @@ -192,6 +194,7 @@ pub fn convert_target(t: Target) -> ConversionResult { r#type: ReaperTargetType::TrackArm, track_data: track_desc.track_data, enable_only_if_track_is_selected: track_desc.track_must_be_selected, + #[cfg(feature = "playtime")] clip_column: track_desc.clip_column.unwrap_or_default(), track_exclusivity: convert_track_exclusivity(d.exclusivity), use_track_grouping: Some( @@ -212,6 +215,7 @@ pub fn convert_target(t: Target) -> ConversionResult { r#type: ReaperTargetType::TrackParentSend, track_data: track_desc.track_data, enable_only_if_track_is_selected: track_desc.track_must_be_selected, + #[cfg(feature = "playtime")] clip_column: track_desc.clip_column.unwrap_or_default(), track_exclusivity: convert_track_exclusivity(d.exclusivity), ..init(d.commons) @@ -224,6 +228,7 @@ pub fn convert_target(t: Target) -> ConversionResult { r#type: ReaperTargetType::AllTrackFxEnable, track_data: track_desc.track_data, enable_only_if_track_is_selected: track_desc.track_must_be_selected, + #[cfg(feature = "playtime")] clip_column: track_desc.clip_column.unwrap_or_default(), track_exclusivity: convert_track_exclusivity(d.exclusivity), poll_for_feedback: d @@ -239,6 +244,7 @@ pub fn convert_target(t: Target) -> ConversionResult { r#type: ReaperTargetType::TrackMute, track_data: track_desc.track_data, enable_only_if_track_is_selected: track_desc.track_must_be_selected, + #[cfg(feature = "playtime")] clip_column: track_desc.clip_column.unwrap_or_default(), track_exclusivity: convert_track_exclusivity(d.exclusivity), use_track_grouping: Some( @@ -259,6 +265,7 @@ pub fn convert_target(t: Target) -> ConversionResult { r#type: ReaperTargetType::TrackPeak, track_data: track_desc.track_data, enable_only_if_track_is_selected: track_desc.track_must_be_selected, + #[cfg(feature = "playtime")] clip_column: track_desc.clip_column.unwrap_or_default(), ..init(d.commons) } @@ -270,6 +277,7 @@ pub fn convert_target(t: Target) -> ConversionResult { r#type: ReaperTargetType::TrackPhase, track_data: track_desc.track_data, enable_only_if_track_is_selected: track_desc.track_must_be_selected, + #[cfg(feature = "playtime")] clip_column: track_desc.clip_column.unwrap_or_default(), track_exclusivity: convert_track_exclusivity(d.exclusivity), use_track_grouping: Some( @@ -293,6 +301,7 @@ pub fn convert_target(t: Target) -> ConversionResult { r#type: ReaperTargetType::TrackSelection, track_data: track_desc.track_data, enable_only_if_track_is_selected: track_desc.track_must_be_selected, + #[cfg(feature = "playtime")] clip_column: track_desc.clip_column.unwrap_or_default(), track_exclusivity: convert_track_exclusivity(d.exclusivity), scroll_arrange_view: d @@ -311,6 +320,7 @@ pub fn convert_target(t: Target) -> ConversionResult { r#type: ReaperTargetType::TrackAutomationMode, track_data: track_desc.track_data, enable_only_if_track_is_selected: track_desc.track_must_be_selected, + #[cfg(feature = "playtime")] clip_column: track_desc.clip_column.unwrap_or_default(), track_exclusivity: convert_track_exclusivity(d.exclusivity), track_automation_mode: convert_automation_mode(d.mode), @@ -324,6 +334,7 @@ pub fn convert_target(t: Target) -> ConversionResult { r#type: ReaperTargetType::TrackMonitoringMode, track_data: track_desc.track_data, enable_only_if_track_is_selected: track_desc.track_must_be_selected, + #[cfg(feature = "playtime")] clip_column: track_desc.clip_column.unwrap_or_default(), track_exclusivity: convert_track_exclusivity(d.exclusivity), track_monitoring_mode: d.mode, @@ -341,6 +352,7 @@ pub fn convert_target(t: Target) -> ConversionResult { r#type: ReaperTargetType::TrackTouchState, track_data: track_desc.track_data, enable_only_if_track_is_selected: track_desc.track_must_be_selected, + #[cfg(feature = "playtime")] clip_column: track_desc.clip_column.unwrap_or_default(), track_exclusivity: convert_track_exclusivity(d.exclusivity), touched_parameter_type: { @@ -362,6 +374,7 @@ pub fn convert_target(t: Target) -> ConversionResult { r#type: ReaperTargetType::TrackPan, track_data: track_desc.track_data, enable_only_if_track_is_selected: track_desc.track_must_be_selected, + #[cfg(feature = "playtime")] clip_column: track_desc.clip_column.unwrap_or_default(), use_track_grouping: Some( d.use_track_grouping @@ -381,6 +394,7 @@ pub fn convert_target(t: Target) -> ConversionResult { r#type: ReaperTargetType::TrackWidth, track_data: track_desc.track_data, enable_only_if_track_is_selected: track_desc.track_must_be_selected, + #[cfg(feature = "playtime")] clip_column: track_desc.clip_column.unwrap_or_default(), use_track_grouping: Some( d.use_track_grouping @@ -400,6 +414,7 @@ pub fn convert_target(t: Target) -> ConversionResult { r#type: ReaperTargetType::TrackVolume, track_data: track_desc.track_data, enable_only_if_track_is_selected: track_desc.track_must_be_selected, + #[cfg(feature = "playtime")] clip_column: track_desc.clip_column.unwrap_or_default(), use_track_grouping: Some( d.use_track_grouping @@ -419,6 +434,7 @@ pub fn convert_target(t: Target) -> ConversionResult { r#type: ReaperTargetType::TrackTool, track_data: track_desc.track_data, enable_only_if_track_is_selected: track_desc.track_must_be_selected, + #[cfg(feature = "playtime")] clip_column: track_desc.clip_column.unwrap_or_default(), track_tool_action: d.action.unwrap_or_default(), tags: convert_tags(d.instance_tags.unwrap_or_default())?, @@ -432,6 +448,7 @@ pub fn convert_target(t: Target) -> ConversionResult { r#type: ReaperTargetType::TrackShow, track_data: track_desc.track_data, enable_only_if_track_is_selected: track_desc.track_must_be_selected, + #[cfg(feature = "playtime")] clip_column: track_desc.clip_column.unwrap_or_default(), track_exclusivity: convert_track_exclusivity(d.exclusivity), track_area: { @@ -450,6 +467,7 @@ pub fn convert_target(t: Target) -> ConversionResult { r#type: ReaperTargetType::TrackSolo, track_data: track_desc.track_data, enable_only_if_track_is_selected: track_desc.track_must_be_selected, + #[cfg(feature = "playtime")] clip_column: track_desc.clip_column.unwrap_or_default(), track_exclusivity: convert_track_exclusivity(d.exclusivity), solo_behavior: { @@ -482,6 +500,7 @@ pub fn convert_target(t: Target) -> ConversionResult { fx_display_type: convert_fx_display_kind(d.display_kind.unwrap_or_default()), track_data: track_desc.track_data, enable_only_if_track_is_selected: track_desc.track_must_be_selected, + #[cfg(feature = "playtime")] clip_column: track_desc.clip_column.unwrap_or_default(), fx_data: FxData { is_input_fx: chain_desc.is_input_fx, @@ -498,6 +517,7 @@ pub fn convert_target(t: Target) -> ConversionResult { r#type: ReaperTargetType::FxTool, track_data: track_desc.track_data, enable_only_if_track_is_selected: track_desc.track_must_be_selected, + #[cfg(feature = "playtime")] clip_column: track_desc.clip_column.unwrap_or_default(), fx_data: fx_desc.fx_data, enable_only_if_fx_has_focus: fx_desc.fx_must_have_focus, @@ -514,6 +534,7 @@ pub fn convert_target(t: Target) -> ConversionResult { r#type: ReaperTargetType::FxEnable, track_data: track_desc.track_data, enable_only_if_track_is_selected: track_desc.track_must_be_selected, + #[cfg(feature = "playtime")] clip_column: track_desc.clip_column.unwrap_or_default(), fx_data: fx_desc.fx_data, enable_only_if_fx_has_focus: fx_desc.fx_must_have_focus, @@ -528,6 +549,7 @@ pub fn convert_target(t: Target) -> ConversionResult { r#type: ReaperTargetType::FxOnline, track_data: track_desc.track_data, enable_only_if_track_is_selected: track_desc.track_must_be_selected, + #[cfg(feature = "playtime")] clip_column: track_desc.clip_column.unwrap_or_default(), fx_data: fx_desc.fx_data, enable_only_if_fx_has_focus: fx_desc.fx_must_have_focus, @@ -542,6 +564,7 @@ pub fn convert_target(t: Target) -> ConversionResult { r#type: ReaperTargetType::LoadFxSnapshot, track_data: track_desc.track_data, enable_only_if_track_is_selected: track_desc.track_must_be_selected, + #[cfg(feature = "playtime")] clip_column: track_desc.clip_column.unwrap_or_default(), fx_data: fx_desc.fx_data, enable_only_if_fx_has_focus: fx_desc.fx_must_have_focus, @@ -564,6 +587,7 @@ pub fn convert_target(t: Target) -> ConversionResult { r#type: ReaperTargetType::FxPreset, track_data: track_desc.track_data, enable_only_if_track_is_selected: track_desc.track_must_be_selected, + #[cfg(feature = "playtime")] clip_column: track_desc.clip_column.unwrap_or_default(), fx_data: fx_desc.fx_data, enable_only_if_fx_has_focus: fx_desc.fx_must_have_focus, @@ -578,6 +602,7 @@ pub fn convert_target(t: Target) -> ConversionResult { r#type: ReaperTargetType::FxOpen, track_data: track_desc.track_data, enable_only_if_track_is_selected: track_desc.track_must_be_selected, + #[cfg(feature = "playtime")] clip_column: track_desc.clip_column.unwrap_or_default(), fx_data: fx_desc.fx_data, enable_only_if_fx_has_focus: fx_desc.fx_must_have_focus, @@ -594,6 +619,7 @@ pub fn convert_target(t: Target) -> ConversionResult { r#type: ReaperTargetType::FxParameterValue, track_data: track_desc.track_data, enable_only_if_track_is_selected: track_desc.track_must_be_selected, + #[cfg(feature = "playtime")] clip_column: track_desc.clip_column.unwrap_or_default(), fx_data: fx_desc.fx_data, enable_only_if_fx_has_focus: fx_desc.fx_must_have_focus, @@ -614,6 +640,7 @@ pub fn convert_target(t: Target) -> ConversionResult { r#type: ReaperTargetType::FxParameterTouchState, track_data: track_desc.track_data, enable_only_if_track_is_selected: track_desc.track_must_be_selected, + #[cfg(feature = "playtime")] clip_column: track_desc.clip_column.unwrap_or_default(), fx_data: fx_desc.fx_data, enable_only_if_fx_has_focus: fx_desc.fx_must_have_focus, @@ -629,6 +656,7 @@ pub fn convert_target(t: Target) -> ConversionResult { r#type: ReaperTargetType::RouteAutomationMode, track_data: track_desc.track_data, enable_only_if_track_is_selected: track_desc.track_must_be_selected, + #[cfg(feature = "playtime")] clip_column: track_desc.clip_column.unwrap_or_default(), track_route_data: route_desc.track_route_data, poll_for_feedback: d @@ -646,6 +674,7 @@ pub fn convert_target(t: Target) -> ConversionResult { r#type: ReaperTargetType::RouteMono, track_data: track_desc.track_data, enable_only_if_track_is_selected: track_desc.track_must_be_selected, + #[cfg(feature = "playtime")] clip_column: track_desc.clip_column.unwrap_or_default(), track_route_data: route_desc.track_route_data, poll_for_feedback: d @@ -662,6 +691,7 @@ pub fn convert_target(t: Target) -> ConversionResult { r#type: ReaperTargetType::RouteMute, track_data: track_desc.track_data, enable_only_if_track_is_selected: track_desc.track_must_be_selected, + #[cfg(feature = "playtime")] clip_column: track_desc.clip_column.unwrap_or_default(), track_route_data: route_desc.track_route_data, poll_for_feedback: d @@ -678,6 +708,7 @@ pub fn convert_target(t: Target) -> ConversionResult { r#type: ReaperTargetType::RoutePhase, track_data: track_desc.track_data, enable_only_if_track_is_selected: track_desc.track_must_be_selected, + #[cfg(feature = "playtime")] clip_column: track_desc.clip_column.unwrap_or_default(), track_route_data: route_desc.track_route_data, poll_for_feedback: d @@ -694,6 +725,7 @@ pub fn convert_target(t: Target) -> ConversionResult { r#type: ReaperTargetType::RoutePan, track_data: track_desc.track_data, enable_only_if_track_is_selected: track_desc.track_must_be_selected, + #[cfg(feature = "playtime")] clip_column: track_desc.clip_column.unwrap_or_default(), track_route_data: route_desc.track_route_data, ..init(d.commons) @@ -707,6 +739,7 @@ pub fn convert_target(t: Target) -> ConversionResult { r#type: ReaperTargetType::RouteVolume, track_data: track_desc.track_data, enable_only_if_track_is_selected: track_desc.track_must_be_selected, + #[cfg(feature = "playtime")] clip_column: track_desc.clip_column.unwrap_or_default(), track_route_data: route_desc.track_route_data, ..init(d.commons) @@ -720,6 +753,7 @@ pub fn convert_target(t: Target) -> ConversionResult { r#type: ReaperTargetType::RouteTouchState, track_data: track_desc.track_data, enable_only_if_track_is_selected: track_desc.track_must_be_selected, + #[cfg(feature = "playtime")] clip_column: track_desc.clip_column.unwrap_or_default(), track_route_data: route_desc.track_route_data, touched_route_parameter_type: match d.touched_parameter { @@ -729,6 +763,7 @@ pub fn convert_target(t: Target) -> ConversionResult { ..init(d.commons) } } + #[cfg(feature = "playtime")] Target::ClipTransportAction(d) => TargetModelData { category: TargetCategory::Reaper, r#type: ReaperTargetType::ClipTransport, @@ -744,6 +779,7 @@ pub fn convert_target(t: Target) -> ConversionResult { clip_play_stop_timing: d.play_stop_timing, ..init(d.commons) }, + #[cfg(feature = "playtime")] Target::ClipColumnAction(d) => TargetModelData { category: TargetCategory::Reaper, r#type: ReaperTargetType::ClipColumn, @@ -751,6 +787,7 @@ pub fn convert_target(t: Target) -> ConversionResult { clip_column_action: d.action, ..init(d.commons) }, + #[cfg(feature = "playtime")] Target::ClipRowAction(d) => TargetModelData { category: TargetCategory::Reaper, r#type: ReaperTargetType::ClipRow, @@ -758,6 +795,7 @@ pub fn convert_target(t: Target) -> ConversionResult { clip_row_action: d.action, ..init(d.commons) }, + #[cfg(feature = "playtime")] Target::ClipSeek(d) => TargetModelData { category: TargetCategory::Reaper, r#type: ReaperTargetType::ClipSeek, @@ -770,12 +808,14 @@ pub fn convert_target(t: Target) -> ConversionResult { }, ..init(d.commons) }, + #[cfg(feature = "playtime")] Target::ClipVolume(d) => TargetModelData { category: TargetCategory::Reaper, r#type: ReaperTargetType::ClipVolume, clip_slot: Some(d.slot), ..init(d.commons) }, + #[cfg(feature = "playtime")] Target::ClipManagement(d) => TargetModelData { category: TargetCategory::Reaper, r#type: ReaperTargetType::ClipManagement, @@ -783,6 +823,7 @@ pub fn convert_target(t: Target) -> ConversionResult { clip_management_action: d.action, ..init(d.commons) }, + #[cfg(feature = "playtime")] Target::ClipMatrixAction(d) => TargetModelData { category: TargetCategory::Reaper, r#type: ReaperTargetType::ClipMatrix, @@ -941,6 +982,7 @@ pub fn convert_target(t: Target) -> ConversionResult { r#type: ReaperTargetType::LoadPotPreset, track_data: track_desc.track_data, enable_only_if_track_is_selected: track_desc.track_must_be_selected, + #[cfg(feature = "playtime")] clip_column: track_desc.clip_column.unwrap_or_default(), fx_data: fx_desc.fx_data, enable_only_if_fx_has_focus: fx_desc.fx_must_have_focus, @@ -988,6 +1030,7 @@ fn convert_automation_mode(mode: AutomationMode) -> RealearnAutomationMode { struct TrackDesc { track_data: TrackData, track_must_be_selected: bool, + #[cfg(feature = "playtime")] clip_column: Option, } @@ -1126,6 +1169,7 @@ fn convert_track_desc(t: TrackDescriptor) -> ConversionResult { .track_must_be_selected .unwrap_or(defaults::TARGET_TRACK_MUST_BE_SELECTED), ), + #[cfg(feature = "playtime")] FromClipColumn { commons, column, @@ -1142,11 +1186,12 @@ fn convert_track_desc(t: TrackDescriptor) -> ConversionResult { .unwrap_or(defaults::TARGET_TRACK_MUST_BE_SELECTED), ), }; - let (track_data, clip_column) = serialize_track(props); + let output = serialize_track(props); let desc = TrackDesc { - track_data, + track_data: output.track_data, track_must_be_selected, - clip_column, + #[cfg(feature = "playtime")] + clip_column: output.clip_column, }; Ok(desc) } diff --git a/main/src/infrastructure/data/clip_legacy.rs b/main/src/infrastructure/data/clip_legacy.rs index e8144cfd1..74a2f3ca5 100644 --- a/main/src/infrastructure/data/clip_legacy.rs +++ b/main/src/infrastructure/data/clip_legacy.rs @@ -1,7 +1,7 @@ use crate::application::{TargetCategory, VirtualTrackType}; use crate::base::notification; use crate::domain::{ReaperTargetType, TransportAction}; -use crate::infrastructure::data::{deserialize_track, MappingModelData}; +use crate::infrastructure::data::{deserialize_track, MappingModelData, TrackDeserializationInput}; use base::default_util::is_default; use playtime_api::persistence::SourceOrigin; use reaper_high::{Guid, Track}; @@ -94,7 +94,11 @@ fn determine_legacy_clip_track( && matches!(m.target.transport_action, TransportAction::PlayPause | TransportAction::PlayStop) && m.target.slot_index == slot_index { - let prop_values = deserialize_track(&m.target.track_data, &m.target.clip_column); + let input = TrackDeserializationInput { + track_data: &m.target.track_data, + clip_column: &m.target.clip_column, + }; + let prop_values = deserialize_track(input); use VirtualTrackType::*; let t = match prop_values.r#type { This => LegacyClipOutput::ThisTrack, diff --git a/main/src/infrastructure/data/mod.rs b/main/src/infrastructure/data/mod.rs index 070d9f547..a847867d1 100644 --- a/main/src/infrastructure/data/mod.rs +++ b/main/src/infrastructure/data/mod.rs @@ -52,6 +52,7 @@ pub use osc_device_management::*; mod virtual_control; pub use virtual_control::*; +#[cfg(feature = "playtime")] mod clip_legacy; mod common; diff --git a/main/src/infrastructure/data/session_data.rs b/main/src/infrastructure/data/session_data.rs index 3d3b1ee17..ba7c3e7e8 100644 --- a/main/src/infrastructure/data/session_data.rs +++ b/main/src/infrastructure/data/session_data.rs @@ -3,10 +3,10 @@ use crate::application::{ FxPresetLinkConfig, GroupModel, MainPresetAutoLoadMode, Session, SessionCommand, }; use crate::domain::{ - compartment_param_index_iter, BackboneState, ClipMatrixRef, Compartment, CompartmentParamIndex, - CompartmentParams, ControlInput, FeedbackOutput, GroupId, GroupKey, InstanceId, InstanceState, - MappingId, MappingKey, MappingSnapshotContainer, MappingSnapshotId, MidiControlInput, - MidiDestination, OscDeviceId, Param, PluginParams, StayActiveWhenProjectInBackground, Tag, + compartment_param_index_iter, Compartment, CompartmentParamIndex, CompartmentParams, + ControlInput, FeedbackOutput, GroupId, GroupKey, InstanceId, InstanceState, MappingId, + MappingKey, MappingSnapshotContainer, MappingSnapshotId, MidiControlInput, MidiDestination, + OscDeviceId, Param, PluginParams, StayActiveWhenProjectInBackground, Tag, }; use crate::infrastructure::data::{ convert_target_value_to_api, convert_target_value_to_model, @@ -17,10 +17,6 @@ use crate::infrastructure::plugin::App; use base::default_util::{bool_true, deserialize_null_default, is_bool_true, is_default}; use crate::infrastructure::api::convert::to_data::ApiToDataConversionContext; -use crate::infrastructure::data::clip_legacy::{ - create_clip_matrix_from_legacy_slots, QualifiedSlotDescriptor, -}; -use playtime_api::persistence::Matrix; use realearn_api::persistence::{ FxDescriptor, MappingInSnapshot, MappingSnapshot, TrackDescriptor, }; @@ -193,13 +189,15 @@ pub struct SessionData { )] controller_parameters: HashMap, // Legacy (ReaLearn <= 2.12.0-pre.4) + #[cfg(feature = "playtime")] #[serde( default, deserialize_with = "deserialize_null_default", skip_serializing_if = "is_default" )] - clip_slots: Vec, + clip_slots: Vec, // New since 2.12.0-pre.5 + #[cfg(feature = "playtime")] #[serde( default, deserialize_with = "deserialize_null_default", @@ -280,10 +278,11 @@ fn focused_fx_descriptor() -> FxDescriptor { FxDescriptor::Focused } +#[cfg(feature = "playtime")] #[derive(Clone, Debug, PartialEq, Serialize, Deserialize)] #[serde(untagged)] enum ClipMatrixRefData { - Own(Matrix), + Own(playtime_api::persistence::Matrix), Foreign(String), } @@ -376,7 +375,9 @@ impl Default for SessionData { main_preset_auto_load_mode: session_defaults::MAIN_PRESET_AUTO_LOAD_MODE, parameters: Default::default(), controller_parameters: Default::default(), + #[cfg(feature = "playtime")] clip_slots: vec![], + #[cfg(feature = "playtime")] clip_matrix: None, tags: vec![], controller: Default::default(), @@ -482,13 +483,17 @@ impl SessionData { main_preset_auto_load_mode, parameters: get_parameter_data_map(plugin_params, Compartment::Main), controller_parameters: get_parameter_data_map(plugin_params, Compartment::Controller), + #[cfg(feature = "playtime")] clip_slots: vec![], + #[cfg(feature = "playtime")] clip_matrix: { instance_state .clip_matrix_ref() .and_then(|matrix_ref| match matrix_ref { - ClipMatrixRef::Own(m) => Some(ClipMatrixRefData::Own(m.save())), - ClipMatrixRef::Foreign(instance_id) => { + crate::domain::ClipMatrixRef::Own(m) => { + Some(ClipMatrixRefData::Own(m.save())) + } + crate::domain::ClipMatrixRef::Foreign(instance_id) => { let foreign_session = App::get() .find_session_by_instance_id_ignoring_borrowed_ones(*instance_id)?; let foreign_id = foreign_session.borrow().id().to_owned(); @@ -764,49 +769,54 @@ impl SessionData { { let instance_state = session.instance_state().clone(); let mut instance_state = instance_state.borrow_mut(); - if let Some(matrix_ref) = &self.clip_matrix { - use ClipMatrixRefData::*; - match matrix_ref { - Own(m) => { - BackboneState::get() - .get_or_insert_owned_clip_matrix_from_instance_state( - &mut instance_state, - ) - .load(m.clone())?; - } - Foreign(session_id) => { - // Check if a session with that ID already exists. - let foreign_instance_id = App::get() - .find_session_by_id_ignoring_borrowed_ones(session_id) - .and_then(|session| { - session.try_borrow().map(|s| *s.instance_id()).ok() - }); - if let Some(id) = foreign_instance_id { - // Referenced ReaLearn instance exists already. - BackboneState::get().set_instance_clip_matrix_to_foreign_matrix( - &mut instance_state, - id, - ); - } else { - // Referenced ReaLearn instance doesn't exist yet. - session.memorize_unresolved_foreign_clip_matrix_session_id( - session_id.clone(), - ); + #[cfg(feature = "playtime")] + { + use crate::domain::BackboneState; + if let Some(matrix_ref) = &self.clip_matrix { + use ClipMatrixRefData::*; + match matrix_ref { + Own(m) => { + BackboneState::get() + .get_or_insert_owned_clip_matrix_from_instance_state( + &mut instance_state, + ) + .load(m.clone())?; } - } - }; - } else if !self.clip_slots.is_empty() { - let matrix = create_clip_matrix_from_legacy_slots( - &self.clip_slots, - &self.mappings, - &self.controller_mappings, - session.processor_context().track(), - )?; - BackboneState::get() - .get_or_insert_owned_clip_matrix_from_instance_state(&mut instance_state) - .load(matrix)?; - } else { - BackboneState::get().clear_clip_matrix_from_instance_state(&mut instance_state); + Foreign(session_id) => { + // Check if a session with that ID already exists. + let foreign_instance_id = App::get() + .find_session_by_id_ignoring_borrowed_ones(session_id) + .and_then(|session| { + session.try_borrow().map(|s| *s.instance_id()).ok() + }); + if let Some(id) = foreign_instance_id { + // Referenced ReaLearn instance exists already. + BackboneState::get().set_instance_clip_matrix_to_foreign_matrix( + &mut instance_state, + id, + ); + } else { + // Referenced ReaLearn instance doesn't exist yet. + session.memorize_unresolved_foreign_clip_matrix_session_id( + session_id.clone(), + ); + } + } + }; + } else if !self.clip_slots.is_empty() { + let matrix = + crate::infrastructure::data::clip_legacy::create_clip_matrix_from_legacy_slots( + &self.clip_slots, + &self.mappings, + &self.controller_mappings, + session.processor_context().track(), + )?; + BackboneState::get() + .get_or_insert_owned_clip_matrix_from_instance_state(&mut instance_state) + .load(matrix)?; + } else { + BackboneState::get().clear_clip_matrix_from_instance_state(&mut instance_state); + } } instance_state .set_active_instance_tags_without_notification(self.active_instance_tags.clone()); @@ -839,7 +849,9 @@ impl SessionData { } // Check if some other instances waited for the clip matrix of this instance. // (important to do after instance state released). + #[cfg(feature = "playtime")] App::get().with_weak_sessions(|sessions| { + use crate::domain::BackboneState; // Gather other sessions that have a foreign clip matrix ID set. let relevant_other_sessions = sessions.iter().filter_map(|other_session| { let other_session = other_session.upgrade()?; diff --git a/main/src/infrastructure/data/target_model_data.rs b/main/src/infrastructure/data/target_model_data.rs index bef12dddf..1e581e3c3 100644 --- a/main/src/infrastructure/data/target_model_data.rs +++ b/main/src/infrastructure/data/target_model_data.rs @@ -28,14 +28,17 @@ use base::default_util::{ bool_true, deserialize_null_default, is_bool_true, is_default, is_none_or_some_default, }; use helgoboss_learn::{AbsoluteValue, Fraction, OscTypeTag, UnitValue}; -use playtime_api::persistence::{ClipPlayStartTiming, ClipPlayStopTiming}; use realearn_api::persistence::{ - BrowseTracksMode, ClipColumnAction, ClipColumnDescriptor, ClipColumnTrackContext, - ClipManagementAction, ClipMatrixAction, ClipRowAction, ClipRowDescriptor, ClipSlotDescriptor, - ClipTransportAction, FxToolAction, LearnableTargetKind, MappingModificationKind, + BrowseTracksMode, FxToolAction, LearnableTargetKind, MappingModificationKind, MappingSnapshotDescForLoad, MappingSnapshotDescForTake, MonitoringMode, MouseAction, PotFilterKind, SeekBehavior, TargetTouchCause, TargetValue, TrackScope, TrackToolAction, }; + +#[cfg(feature = "playtime")] +use realearn_api::persistence::{ + ClipColumnAction, ClipColumnDescriptor, ClipColumnTrackContext, ClipManagementAction, + ClipMatrixAction, ClipRowAction, ClipRowDescriptor, ClipSlotDescriptor, ClipTransportAction, +}; use semver::Version; use serde::{Deserialize, Serialize}; use std::convert::TryInto; @@ -373,6 +376,7 @@ pub struct TargetModelData { skip_serializing_if = "is_default" )] pub slot_index: usize, + #[cfg(feature = "playtime")] #[serde( default, deserialize_with = "deserialize_null_default", @@ -394,6 +398,7 @@ pub struct TargetModelData { )] pub buffered: bool, /// New since ReaLearn v2.12.0-pre.5 + #[cfg(feature = "playtime")] #[serde( default, deserialize_with = "deserialize_null_default", @@ -407,6 +412,7 @@ pub struct TargetModelData { /// For clip column targets, this contains the clip column to which we want to refer. /// /// New since ReaLearn v2.13.0-pre.4 + #[cfg(feature = "playtime")] #[serde( default, deserialize_with = "deserialize_null_default", @@ -414,6 +420,7 @@ pub struct TargetModelData { )] pub clip_column: ClipColumnDescriptor, /// New since ReaLearn v2.13.0-pre.4 + #[cfg(feature = "playtime")] #[serde( default, deserialize_with = "deserialize_null_default", @@ -423,6 +430,7 @@ pub struct TargetModelData { /// New since ReaLearn v2.13.0-pre.4. /// /// Migrated from `transport_action` if not given. + #[cfg(feature = "playtime")] #[serde( default, deserialize_with = "deserialize_null_default", @@ -430,6 +438,7 @@ pub struct TargetModelData { )] pub clip_transport_action: Option, /// New since ReaLearn v2.13.0-pre.4. + #[cfg(feature = "playtime")] #[serde( default, deserialize_with = "deserialize_null_default", @@ -437,6 +446,7 @@ pub struct TargetModelData { )] pub clip_column_action: ClipColumnAction, /// New since ReaLearn v2.13.0-pre.4. + #[cfg(feature = "playtime")] #[serde( default, deserialize_with = "deserialize_null_default", @@ -444,6 +454,7 @@ pub struct TargetModelData { )] pub clip_row_action: ClipRowAction, /// New since ReaLearn v2.13.0-pre.4. + #[cfg(feature = "playtime")] #[serde( default, deserialize_with = "deserialize_null_default", @@ -451,6 +462,7 @@ pub struct TargetModelData { )] pub clip_matrix_action: ClipMatrixAction, /// New since ReaLearn v2.13.0-pre.4 + #[cfg(feature = "playtime")] #[serde( default, deserialize_with = "deserialize_null_default", @@ -458,6 +470,7 @@ pub struct TargetModelData { )] pub record_only_if_track_armed: bool, /// New since ReaLearn v2.13.0-pre.4 + #[cfg(feature = "playtime")] #[serde( default, deserialize_with = "deserialize_null_default", @@ -465,19 +478,21 @@ pub struct TargetModelData { )] pub stop_column_if_slot_empty: bool, /// New since ReaLearn v2.13.0-pre.4 + #[cfg(feature = "playtime")] #[serde( default, deserialize_with = "deserialize_null_default", skip_serializing_if = "is_default" )] - pub clip_play_start_timing: Option, + pub clip_play_start_timing: Option, /// New since ReaLearn v2.13.0-pre.4 + #[cfg(feature = "playtime")] #[serde( default, deserialize_with = "deserialize_null_default", skip_serializing_if = "is_default" )] - pub clip_play_stop_timing: Option, + pub clip_play_stop_timing: Option, /// New since ReaLearn v2.13.0-pre.4 #[serde( default, @@ -530,7 +545,8 @@ impl TargetModelData { model: &TargetModel, conversion_context: &impl ModelToDataConversionContext, ) -> Self { - let (track_data, track_selector_clip_column) = serialize_track(model.track()); + let output = serialize_track(model.track()); + let track_data = output.track_data; let (session_id, mapping_key) = match model.mapping_ref() { MappingRefModel::OwnMapping { mapping_id } => { let mapping_key = @@ -602,6 +618,7 @@ impl TargetModelData { osc_arg_value_range: OscValueRange::from_interval(model.osc_arg_value_range()), osc_dev_id: model.osc_dev_id(), slot_index: 0, + #[cfg(feature = "playtime")] clip_management_action: model.clip_management_action().clone(), next_bar: false, buffered: false, @@ -618,24 +635,37 @@ impl TargetModelData { .group_key_by_id(model.group_id()) .unwrap_or_default(), active_mappings_only: model.active_mappings_only(), + #[cfg(feature = "playtime")] clip_slot: if model.target_type().supports_clip_slot() { Some(model.clip_slot().clone()) } else { None }, - clip_column: track_selector_clip_column.unwrap_or_else(|| model.clip_column().clone()), + #[cfg(feature = "playtime")] + clip_column: output + .clip_column + .unwrap_or_else(|| model.clip_column().clone()), + #[cfg(feature = "playtime")] clip_row: model.clip_row().clone(), + #[cfg(feature = "playtime")] clip_transport_action: if model.target_type() == ReaperTargetType::ClipTransport { Some(model.clip_transport_action()) } else { None }, + #[cfg(feature = "playtime")] clip_column_action: model.clip_column_action(), + #[cfg(feature = "playtime")] clip_row_action: model.clip_row_action(), + #[cfg(feature = "playtime")] clip_matrix_action: model.clip_matrix_action(), + #[cfg(feature = "playtime")] record_only_if_track_armed: model.record_only_if_track_armed(), + #[cfg(feature = "playtime")] stop_column_if_slot_empty: model.stop_column_if_slot_empty(), + #[cfg(feature = "playtime")] clip_play_start_timing: model.clip_play_start_timing(), + #[cfg(feature = "playtime")] clip_play_stop_timing: model.clip_play_stop_timing(), mouse_action: model.mouse_action(), pot_filter_item_kind: model.pot_filter_item_kind(), @@ -727,7 +757,12 @@ impl TargetModelData { self.invocation_type }; model.change(C::SetActionInvocationType(invocation_type)); - let track_prop_values = deserialize_track(&self.track_data, &self.clip_column); + let track_des_input = TrackDeserializationInput { + track_data: &self.track_data, + #[cfg(feature = "playtime")] + clip_column: &self.clip_column, + }; + let track_prop_values = deserialize_track(track_des_input); let _ = model.set_track_from_prop_values( track_prop_values, false, @@ -873,41 +908,44 @@ impl TargetModelData { .unwrap_or_default(); model.change(C::SetGroupId(group_id)); model.change(C::SetActiveMappingsOnly(self.active_mappings_only)); - let slot_descriptor = self - .clip_slot - .clone() - .unwrap_or(ClipSlotDescriptor::ByIndex { - column_index: self.slot_index, - row_index: 0, + #[cfg(feature = "playtime")] + { + let slot_descriptor = self + .clip_slot + .clone() + .unwrap_or(ClipSlotDescriptor::ByIndex { + column_index: self.slot_index, + row_index: 0, + }); + model.change(C::SetClipSlot(slot_descriptor)); + model.change(C::SetClipColumn(self.clip_column.clone())); + model.change(C::SetClipRow(self.clip_row.clone())); + model.change(C::SetClipManagementAction( + self.clip_management_action.clone(), + )); + let clip_transport_action = self.clip_transport_action.unwrap_or_else(|| { + use ClipTransportAction as T; + use TransportAction::*; + match self.transport_action { + PlayStop => T::PlayStop, + PlayPause => T::PlayPause, + Stop => T::Stop, + Pause => T::Pause, + RecordStop => T::RecordStop, + Repeat => T::Looped, + } }); - model.change(C::SetClipSlot(slot_descriptor)); - model.change(C::SetClipColumn(self.clip_column.clone())); - model.change(C::SetClipRow(self.clip_row.clone())); - model.change(C::SetClipManagementAction( - self.clip_management_action.clone(), - )); - let clip_transport_action = self.clip_transport_action.unwrap_or_else(|| { - use ClipTransportAction as T; - use TransportAction::*; - match self.transport_action { - PlayStop => T::PlayStop, - PlayPause => T::PlayPause, - Stop => T::Stop, - Pause => T::Pause, - RecordStop => T::RecordStop, - Repeat => T::Looped, - } - }); - model.change(C::SetClipTransportAction(clip_transport_action)); - model.change(C::SetClipColumnAction(self.clip_column_action)); - model.change(C::SetClipRowAction(self.clip_row_action)); - model.change(C::SetClipMatrixAction(self.clip_matrix_action)); - model.change(C::SetClipPlayStartTiming(self.clip_play_start_timing)); - model.change(C::SetClipPlayStopTiming(self.clip_play_stop_timing)); - model.change(C::SetRecordOnlyIfTrackArmed( - self.record_only_if_track_armed, - )); - model.change(C::SetStopColumnIfSlotEmpty(self.stop_column_if_slot_empty)); + model.change(C::SetClipTransportAction(clip_transport_action)); + model.change(C::SetClipColumnAction(self.clip_column_action)); + model.change(C::SetClipRowAction(self.clip_row_action)); + model.change(C::SetClipMatrixAction(self.clip_matrix_action)); + model.change(C::SetClipPlayStartTiming(self.clip_play_start_timing)); + model.change(C::SetClipPlayStopTiming(self.clip_play_stop_timing)); + model.change(C::SetRecordOnlyIfTrackArmed( + self.record_only_if_track_armed, + )); + model.change(C::SetStopColumnIfSlotEmpty(self.stop_column_if_slot_empty)); + } model.change(C::SetTrackToolAction(self.track_tool_action)); model.change(C::SetFxToolAction(self.fx_tool_action)); // "Load mapping snapshot" stuff @@ -1005,125 +1043,97 @@ impl TargetModelData { } } +pub struct TrackSerializationOutput { + pub track_data: TrackData, + #[cfg(feature = "playtime")] + pub clip_column: Option, +} + /// This function is so annoying because of backward compatibility. Once made the bad decision /// to not introduce an explicit track type. -pub fn serialize_track(track: TrackPropValues) -> (TrackData, Option) { +pub fn serialize_track(track: TrackPropValues) -> TrackSerializationOutput { use VirtualTrackType::*; - match track.r#type { - This => (TrackData::default(), None), - Selected => ( - TrackData { - guid: Some("selected".to_string()), - ..Default::default() - }, - None, - ), - AllSelected => ( - TrackData { - guid: Some("selected*".to_string()), - ..Default::default() - }, - None, - ), - Master => ( - TrackData { - guid: Some("master".to_string()), - ..Default::default() - }, - None, - ), - Instance => ( - TrackData { - guid: Some("instance".to_string()), - ..Default::default() - }, - None, - ), - ByIdOrName => ( - TrackData { - guid: track.id.map(|id| id.to_string_without_braces()), - name: Some(track.name), - ..Default::default() - }, - None, - ), - ById => ( - TrackData { - guid: track.id.map(|id| id.to_string_without_braces()), - ..Default::default() - }, - None, - ), - ByName => ( - TrackData { - name: Some(track.name), - ..Default::default() - }, - None, - ), - AllByName => ( - TrackData { - guid: Some("name*".to_string()), - name: Some(track.name), - ..Default::default() - }, - None, - ), - ByIndex => ( - TrackData { - index: Some(track.index), - ..Default::default() - }, - None, - ), - ByIndexTcp => ( - TrackData { - guid: Some("index_tcp".to_string()), - index: Some(track.index), - ..Default::default() - }, - None, - ), - ByIndexMcp => ( - TrackData { - guid: Some("index_mcp".to_string()), - index: Some(track.index), - ..Default::default() - }, - None, - ), - Dynamic => ( - TrackData { - expression: Some(track.expression), - ..Default::default() - }, - None, - ), - DynamicTcp => ( - TrackData { - guid: Some("dynamic_tcp".to_string()), - expression: Some(track.expression), - ..Default::default() - }, - None, - ), - DynamicMcp => ( - TrackData { - guid: Some("dynamic_mcp".to_string()), - expression: Some(track.expression), - ..Default::default() - }, - None, - ), - FromClipColumn => ( + #[cfg(feature = "playtime")] + let mut clip_column = None; + let track_data = match track.r#type { + This => TrackData::default(), + Selected => TrackData { + guid: Some("selected".to_string()), + ..Default::default() + }, + AllSelected => TrackData { + guid: Some("selected*".to_string()), + ..Default::default() + }, + Master => TrackData { + guid: Some("master".to_string()), + ..Default::default() + }, + Instance => TrackData { + guid: Some("instance".to_string()), + ..Default::default() + }, + ByIdOrName => TrackData { + guid: track.id.map(|id| id.to_string_without_braces()), + name: Some(track.name), + ..Default::default() + }, + ById => TrackData { + guid: track.id.map(|id| id.to_string_without_braces()), + ..Default::default() + }, + ByName => TrackData { + name: Some(track.name), + ..Default::default() + }, + AllByName => TrackData { + guid: Some("name*".to_string()), + name: Some(track.name), + ..Default::default() + }, + ByIndex => TrackData { + index: Some(track.index), + ..Default::default() + }, + ByIndexTcp => TrackData { + guid: Some("index_tcp".to_string()), + index: Some(track.index), + ..Default::default() + }, + ByIndexMcp => TrackData { + guid: Some("index_mcp".to_string()), + index: Some(track.index), + ..Default::default() + }, + Dynamic => TrackData { + expression: Some(track.expression), + ..Default::default() + }, + DynamicTcp => TrackData { + guid: Some("dynamic_tcp".to_string()), + expression: Some(track.expression), + ..Default::default() + }, + DynamicMcp => TrackData { + guid: Some("dynamic_mcp".to_string()), + expression: Some(track.expression), + ..Default::default() + }, + #[cfg(feature = "playtime")] + FromClipColumn => { + clip_column = Some(track.clip_column); TrackData { guid: Some("from-clip-column".to_string()), expression: Some(track.expression), clip_column_track_context: track.clip_column_track_context, ..Default::default() - }, - Some(track.clip_column), - ), + } + } + }; + TrackSerializationOutput { + track_data, + #[cfg(feature = "playtime")] + clip_column, } } @@ -1448,6 +1458,7 @@ pub struct TrackData { skip_serializing_if = "is_default" )] pub expression: Option, + #[cfg(feature = "playtime")] #[serde( default, deserialize_with = "deserialize_null_default", @@ -1456,13 +1467,16 @@ pub struct TrackData { pub clip_column_track_context: ClipColumnTrackContext, } +pub struct TrackDeserializationInput<'a> { + pub track_data: &'a TrackData, + #[cfg(feature = "playtime")] + pub clip_column: &'a ClipColumnDescriptor, +} + /// This function is so annoying because of backward compatibility. Once made the bad decision /// to not introduce an explicit track type. -pub fn deserialize_track( - track_data: &TrackData, - clip_column: &ClipColumnDescriptor, -) -> TrackPropValues { - match track_data { +pub fn deserialize_track(input: TrackDeserializationInput) -> TrackPropValues { + match input.track_data { TrackData { guid: None, name: None, @@ -1520,13 +1534,14 @@ pub fn deserialize_track( expression: e.clone(), ..Default::default() }, + #[cfg(feature = "playtime")] TrackData { guid: Some(g), clip_column_track_context, .. } if g == "from-clip-column" => TrackPropValues { r#type: VirtualTrackType::FromClipColumn, - clip_column: clip_column.clone(), + clip_column: input.clip_column.clone(), clip_column_track_context: *clip_column_track_context, ..Default::default() }, diff --git a/main/src/infrastructure/plugin/app.rs b/main/src/infrastructure/plugin/app.rs index 0c1db09e3..03542ddea 100644 --- a/main/src/infrastructure/plugin/app.rs +++ b/main/src/infrastructure/plugin/app.rs @@ -10,10 +10,10 @@ use crate::domain::{ InstanceFxChangeRequest, InstanceId, InstanceOrchestrationEvent, InstanceTrackChangeRequest, LastTouchedTargetFilter, MainProcessor, MessageCaptureEvent, MessageCaptureResult, MidiScanResult, NormalAudioHookTask, OscDeviceId, OscFeedbackProcessor, OscFeedbackTask, - OscScanResult, QualifiedClipMatrixEvent, QualifiedMappingId, RealearnAccelerator, - RealearnAudioHook, RealearnClipMatrix, RealearnControlSurfaceMainTask, - RealearnControlSurfaceMiddleware, RealearnTarget, RealearnTargetState, RealearnWindowSnitch, - ReaperTarget, ReaperTargetType, SharedMainProcessors, SharedRealTimeProcessor, Tag, + OscScanResult, QualifiedMappingId, RealearnAccelerator, RealearnAudioHook, + RealearnControlSurfaceMainTask, RealearnControlSurfaceMiddleware, RealearnTarget, + RealearnTargetState, RealearnWindowSnitch, ReaperTarget, ReaperTargetType, + SharedMainProcessors, SharedRealTimeProcessor, Tag, }; use crate::infrastructure::data::{ ExtendedPresetManager, FileBasedControllerPresetManager, FileBasedMainPresetManager, @@ -34,10 +34,8 @@ use base::{ use enum_iterator::IntoEnumIterator; use crate::infrastructure::plugin::tracing_util::setup_tracing; +use crate::infrastructure::server::services::RealearnServices; use once_cell::sync::Lazy; -use playtime_clip_engine::base::Matrix; -use playtime_clip_engine::proto::clip_engine_server::ClipEngine; -use playtime_clip_engine::proto::{ClipEngineHub, MatrixProvider}; use realearn_api::persistence::{ Envelope, FxChainDescriptor, FxDescriptor, TargetTouchCause, TrackDescriptor, TrackFxChain, }; @@ -94,7 +92,8 @@ pub struct App { changed_subject: RefCell>, party_is_over_subject: LocalSubject<'static, (), ()>, control_surface_main_task_sender: RealearnControlSurfaceMainTaskSender, - clip_matrix_event_sender: SenderToNormalThread, + #[cfg(feature = "playtime")] + clip_matrix_event_sender: SenderToNormalThread, osc_feedback_task_sender: SenderToNormalThread, additional_feedback_event_sender: SenderToNormalThread, feedback_audio_hook_task_sender: SenderToRealTimeThread, @@ -104,7 +103,8 @@ pub struct App { sessions_changed_subject: RefCell>, message_panel: SharedView, osc_feedback_processor: Rc>, - clip_engine_hub: ClipEngineHub, + #[cfg(feature = "playtime")] + clip_engine_hub: playtime_clip_engine::proto::ClipEngineHub, } #[derive(Debug)] @@ -137,7 +137,9 @@ enum AppState { struct UninitializedState { control_surface_main_task_receiver: crossbeam_channel::Receiver>, - clip_matrix_event_receiver: crossbeam_channel::Receiver, + #[cfg(feature = "playtime")] + clip_matrix_event_receiver: + crossbeam_channel::Receiver, additional_feedback_event_receiver: crossbeam_channel::Receiver, instance_orchestration_event_receiver: crossbeam_channel::Receiver, normal_audio_hook_task_receiver: crossbeam_channel::Receiver, @@ -208,6 +210,7 @@ impl App { fn new(config: AppConfig) -> App { let (main_sender, main_receiver) = SenderToNormalThread::new_unbounded_channel("control surface main tasks"); + #[cfg(feature = "playtime")] let (clip_matrix_event_sender, clip_matrix_event_receiver) = SenderToNormalThread::new_unbounded_channel("clip matrix events"); let (osc_feedback_task_sender, osc_feedback_task_receiver) = @@ -228,6 +231,7 @@ impl App { ); let uninitialized_state = UninitializedState { control_surface_main_task_receiver: main_receiver, + #[cfg(feature = "playtime")] clip_matrix_event_receiver, additional_feedback_event_receiver, instance_orchestration_event_receiver, @@ -261,6 +265,7 @@ impl App { changed_subject: Default::default(), party_is_over_subject: Default::default(), control_surface_main_task_sender: RealearnControlSurfaceMainTaskSender(main_sender), + #[cfg(feature = "playtime")] clip_matrix_event_sender, osc_feedback_task_sender, additional_feedback_event_sender, @@ -273,7 +278,8 @@ impl App { osc_feedback_processor: Rc::new(RefCell::new(OscFeedbackProcessor::new( osc_feedback_task_receiver, ))), - clip_engine_hub: ClipEngineHub::new(), + #[cfg(feature = "playtime")] + clip_engine_hub: playtime_clip_engine::proto::ClipEngineHub::new(), } } @@ -304,6 +310,7 @@ impl App { /// Executed globally just once as soon as we have access to global REAPER instance. pub fn init(&self) { metrics_util::init_metrics(); + #[cfg(feature = "playtime")] playtime_clip_engine::init(); let prev_state = self.state.replace(AppState::Initializing); let uninit_state = if let AppState::Uninitialized(s) = prev_state { @@ -328,6 +335,7 @@ impl App { let control_surface = MiddlewareControlSurface::new(RealearnControlSurfaceMiddleware::new( App::logger(), uninit_state.control_surface_main_task_receiver, + #[cfg(feature = "playtime")] uninit_state.clip_matrix_event_receiver, uninit_state.additional_feedback_event_receiver, uninit_state.instance_orchestration_event_receiver, @@ -366,8 +374,13 @@ impl App { }); } - fn create_clip_engine_service(&self) -> impl ClipEngine { - self.clip_engine_hub.create_service(AppMatrixProvider) + fn create_services(&self) -> RealearnServices { + RealearnServices { + #[cfg(feature = "playtime")] + playtime_service: server::services::playtime_service::create_playtime_service( + &self.clip_engine_hub, + ), + } } // Executed whenever the first ReaLearn instance is loaded. @@ -381,7 +394,7 @@ impl App { if self.config.borrow().server_is_enabled() { self.server() .borrow_mut() - .start(self.create_clip_engine_service()) + .start(self.create_services()) .unwrap_or_else(warn_about_failed_server_start); } let mut session = Reaper::get().medium_session(); @@ -577,10 +590,14 @@ impl App { &self.feedback_audio_hook_task_sender } - pub fn clip_matrix_event_sender(&self) -> &SenderToNormalThread { + #[cfg(feature = "playtime")] + pub fn clip_matrix_event_sender( + &self, + ) -> &SenderToNormalThread { &self.clip_matrix_event_sender } + #[cfg(feature = "playtime")] pub fn normal_audio_hook_task_sender(&self) -> &SenderToRealTimeThread { &self.audio_hook_task_sender } @@ -605,7 +622,8 @@ impl App { &self.control_surface_main_task_sender } - pub fn clip_engine_hub(&self) -> &ClipEngineHub { + #[cfg(feature = "playtime")] + pub fn clip_engine_hub(&self) -> &playtime_clip_engine::proto::ClipEngineHub { &self.clip_engine_hub } @@ -693,9 +711,7 @@ impl App { } pub fn start_server_persistently(&self) -> Result<(), String> { - self.server - .borrow_mut() - .start(self.create_clip_engine_service())?; + self.server.borrow_mut().start(self.create_services())?; self.change_config(AppConfig::enable_server); Ok(()) } @@ -838,10 +854,11 @@ impl App { }) } + #[cfg(feature = "playtime")] pub fn with_clip_matrix( &self, clip_matrix_id: &str, - f: impl FnOnce(&RealearnClipMatrix) -> R, + f: impl FnOnce(&playtime_clip_engine::base::Matrix) -> R, ) -> Result { let session = self .find_session_by_id(clip_matrix_id) @@ -851,10 +868,11 @@ impl App { BackboneState::get().with_clip_matrix(instance_state, f) } + #[cfg(feature = "playtime")] pub fn with_clip_matrix_mut( &self, clip_matrix_id: &str, - f: impl FnOnce(&mut RealearnClipMatrix) -> R, + f: impl FnOnce(&mut playtime_clip_engine::base::Matrix) -> R, ) -> Result { let session = self .find_session_by_id(clip_matrix_id) @@ -1847,23 +1865,3 @@ impl RealearnWindowSnitch for RealearnSnitch { None } } - -struct AppMatrixProvider; - -impl MatrixProvider for AppMatrixProvider { - fn with_matrix( - &self, - clip_matrix_id: &str, - f: impl FnOnce(&Matrix) -> R, - ) -> Result { - App::get().with_clip_matrix(clip_matrix_id, f) - } - - fn with_matrix_mut( - &self, - clip_matrix_id: &str, - f: impl FnOnce(&mut Matrix) -> R, - ) -> Result { - App::get().with_clip_matrix_mut(clip_matrix_id, f) - } -} diff --git a/main/src/infrastructure/plugin/realearn_plugin.rs b/main/src/infrastructure/plugin/realearn_plugin.rs index 34672f82c..80f48422c 100644 --- a/main/src/infrastructure/plugin/realearn_plugin.rs +++ b/main/src/infrastructure/plugin/realearn_plugin.rs @@ -7,10 +7,10 @@ use vst::plugin::{ use super::RealearnEditor; use crate::domain::{ - AudioBlockProps, BackboneState, ControlEvent, ControlEventTimestamp, ControlMainTask, - FeedbackRealTimeTask, InstanceId, MainProcessor, MidiEvent, NormalMainTask, - NormalRealTimeToMainThreadTask, ParameterMainTask, PluginParamIndex, ProcessorContext, - RealTimeProcessorLocker, SharedRealTimeProcessor, PLUGIN_PARAMETER_COUNT, + BackboneState, ControlEvent, ControlEventTimestamp, ControlMainTask, FeedbackRealTimeTask, + InstanceId, MainProcessor, MidiEvent, NormalMainTask, NormalRealTimeToMainThreadTask, + ParameterMainTask, PluginParamIndex, ProcessorContext, RealTimeProcessorLocker, + SharedRealTimeProcessor, PLUGIN_PARAMETER_COUNT, }; use crate::domain::{NormalRealTimeTask, RealTimeProcessor}; use crate::infrastructure::plugin::realearn_plugin_parameters::RealearnPluginParameters; @@ -303,14 +303,19 @@ impl Plugin for RealearnPlugin { } fn process_f64(&mut self, buffer: &mut AudioBuffer) { + #[cfg(not(feature = "playtime"))] + let _ = buffer; assert_no_alloc(|| { // Get current time information so we can detect changes in play state reliably // (TimeInfoFlags::TRANSPORT_CHANGED doesn't work the way we want it). self.was_playing_in_last_cycle = self.is_now_playing(); - let block_props = AudioBlockProps::from_vst(buffer, self.sample_rate); - self.real_time_processor - .lock_recover() - .run_from_vst(buffer, block_props, &self.host); + self.real_time_processor.lock_recover().run_from_vst( + #[cfg(feature = "playtime")] + buffer, + #[cfg(feature = "playtime")] + crate::domain::AudioBlockProps::from_vst(buffer, self.sample_rate), + &self.host, + ); }); } @@ -418,8 +423,11 @@ impl RealearnPlugin { instance_id, processor_context.clone(), instance_feedback_event_sender, + #[cfg(feature = "playtime")] App::get().clip_matrix_event_sender().clone(), + #[cfg(feature = "playtime")] App::get().normal_audio_hook_task_sender().clone(), + #[cfg(feature = "playtime")] normal_real_time_task_sender.clone(), ); // Session (application - shared) diff --git a/main/src/infrastructure/server/data.rs b/main/src/infrastructure/server/data.rs index f07c3a037..ceadaa5e6 100644 --- a/main/src/infrastructure/server/data.rs +++ b/main/src/infrastructure/server/data.rs @@ -3,7 +3,7 @@ use crate::application::{ ControllerPreset, Preset, PresetManager, Session, SourceCategory, TargetCategory, }; -use crate::domain::{BackboneState, Compartment, MappingKey, ProjectionFeedbackValue}; +use crate::domain::{Compartment, MappingKey, ProjectionFeedbackValue}; use crate::infrastructure::data::{ControllerPresetData, PresetData}; use crate::infrastructure::plugin::App; use helgoboss_learn::UnitValue; @@ -25,7 +25,6 @@ pub enum DataError { OnlyPatchReplaceIsSupported, OnlyCustomDataKeyIsSupportedAsPatchPath, ControllerUpdateFailed, - ClipMatrixNotFound, } pub enum DataErrorCategory { @@ -47,17 +46,15 @@ impl DataError { "only '/customData/{key}' is supported as path" } ControllerUpdateFailed => "couldn't update controller", - ClipMatrixNotFound => "clip matrix not found", } } pub fn category(&self) -> DataErrorCategory { use DataError::*; match self { - SessionNotFound - | SessionHasNoActiveController - | ControllerNotFound - | ClipMatrixNotFound => DataErrorCategory::NotFound, + SessionNotFound | SessionHasNoActiveController | ControllerNotFound => { + DataErrorCategory::NotFound + } OnlyPatchReplaceIsSupported => DataErrorCategory::MethodNotAllowed, OnlyCustomDataKeyIsSupportedAsPatchPath => DataErrorCategory::BadRequest, ControllerUpdateFailed => DataErrorCategory::InternalServerError, @@ -105,18 +102,6 @@ pub fn get_session_data(session_id: String) -> Result Result { - let session = App::get() - .find_session_by_id(session_id) - .ok_or(DataError::SessionNotFound)?; - let session = session.borrow(); - BackboneState::get() - .with_clip_matrix(session.instance_state(), |matrix| matrix.save()) - .map_err(|_| DataError::ClipMatrixNotFound) -} - pub fn get_controller_routing_by_session_id( session_id: String, ) -> Result { diff --git a/main/src/infrastructure/server/grpc/server.rs b/main/src/infrastructure/server/grpc/server.rs index e5a2b9469..6542fab5e 100644 --- a/main/src/infrastructure/server/grpc/server.rs +++ b/main/src/infrastructure/server/grpc/server.rs @@ -1,15 +1,21 @@ -use crate::infrastructure::server::layers::MainThreadLayer; -use playtime_clip_engine::proto::clip_engine_server::{ClipEngine, ClipEngineServer}; +use crate::infrastructure::server::services::RealearnServices; use std::net::SocketAddr; -use tonic::transport::Server; pub async fn start_grpc_server( address: SocketAddr, - service: impl ClipEngine, + services: RealearnServices, ) -> Result<(), tonic::transport::Error> { - Server::builder() - .layer(MainThreadLayer) - .add_service(ClipEngineServer::new(service)) - .serve(address) - .await + #[cfg(feature = "playtime")] + { + tonic::transport::Server::builder() + .layer(crate::infrastructure::server::layers::MainThreadLayer) + .add_service(services.playtime_service) + .serve(address) + .await + } + #[cfg(not(feature = "playtime"))] + { + let _ = (address, services); + Ok(()) + } } diff --git a/main/src/infrastructure/server/http/handlers.rs b/main/src/infrastructure/server/http/handlers.rs index 4036fbd38..6386a5f35 100644 --- a/main/src/infrastructure/server/http/handlers.rs +++ b/main/src/infrastructure/server/http/handlers.rs @@ -1,8 +1,7 @@ use crate::infrastructure::data::ControllerPresetData; use crate::infrastructure::server::data::{ - get_clip_matrix_data, get_controller_preset_data, get_controller_routing_by_session_id, - patch_controller, ControllerRouting, DataError, DataErrorCategory, PatchRequest, - SessionResponseData, Topics, + get_controller_preset_data, get_controller_routing_by_session_id, patch_controller, + ControllerRouting, DataError, DataErrorCategory, PatchRequest, SessionResponseData, Topics, }; use crate::infrastructure::server::http::{send_initial_events, ServerClients, WebSocketClient}; use crate::infrastructure::server::MetricsReporter; @@ -32,14 +31,6 @@ pub async fn session_handler( Ok(Json(session_data)) } -/// Needs to be executed in the main thread! -pub async fn clip_matrix_handler( - Path(session_id): Path, -) -> Result, SimpleResponse> { - let clip_matrix_data = get_clip_matrix_data(&session_id).map_err(translate_data_error)?; - Ok(Json(clip_matrix_data)) -} - /// Needs to be executed in the main thread! pub async fn session_controller_handler( Path(session_id): Path, diff --git a/main/src/infrastructure/server/http/server.rs b/main/src/infrastructure/server/http/server.rs index 809e98cd4..381ce5ef6 100644 --- a/main/src/infrastructure/server/http/server.rs +++ b/main/src/infrastructure/server/http/server.rs @@ -75,10 +75,6 @@ fn create_router( "/realearn/session/:id/controller-routing", get(controller_routing_handler.layer(MainThreadLayer)), ) - .route( - "/realearn/session/:id/clip-matrix", - get(clip_matrix_handler.layer(MainThreadLayer)), - ) .route( "/realearn/controller/:id", patch(patch_controller_handler.layer(MainThreadLayer)), diff --git a/main/src/infrastructure/server/mod.rs b/main/src/infrastructure/server/mod.rs index 60d5fecf3..0cd0110c7 100644 --- a/main/src/infrastructure/server/mod.rs +++ b/main/src/infrastructure/server/mod.rs @@ -19,17 +19,18 @@ use url::Url; use crate::infrastructure::server::grpc::start_grpc_server; use crate::infrastructure::server::http::start_http_server; use crate::infrastructure::server::http::ServerClients; +use crate::infrastructure::server::services::RealearnServices; use derivative::Derivative; -use playtime_clip_engine::proto::clip_engine_server::ClipEngine; use std::thread::JoinHandle; use std::time::Duration; pub type SharedRealearnServer = Rc>; mod data; -pub mod grpc; +mod grpc; pub mod http; mod layers; +pub mod services; #[derive(Debug)] pub struct RealearnServer { @@ -134,7 +135,7 @@ impl RealearnServer { } /// Idempotent - pub fn start(&mut self, clip_engine_service: impl ClipEngine) -> Result<(), String> { + pub fn start(&mut self, services: RealearnServices) -> Result<(), String> { if self.state.is_starting_or_running() { return Ok(()); } @@ -164,7 +165,7 @@ impl RealearnServer { key_and_cert, shutdown_receiver, metrics_reporter, - clip_engine_service, + services, )); runtime.shutdown_timeout(Duration::from_secs(1)); }) @@ -316,7 +317,7 @@ async fn start_servers( (key, cert): (String, String), mut shutdown_receiver: broadcast::Receiver<()>, metrics_reporter: MetricsReporter, - clip_engine_service: impl ClipEngine, + services: RealearnServices, ) { let http_server_future = start_http_server( http_port, @@ -325,10 +326,8 @@ async fn start_servers( (key, cert), metrics_reporter, ); - let grpc_server_future = start_grpc_server( - SocketAddr::from(([127, 0, 0, 1], grpc_port)), - clip_engine_service, - ); + let grpc_server_future = + start_grpc_server(SocketAddr::from(([127, 0, 0, 1], grpc_port)), services); let joined_future = futures::future::join(http_server_future, grpc_server_future); tokio::select! { _ = shutdown_receiver.recv() => { diff --git a/main/src/infrastructure/server/services/mod.rs b/main/src/infrastructure/server/services/mod.rs new file mode 100644 index 000000000..ca237fae1 --- /dev/null +++ b/main/src/infrastructure/server/services/mod.rs @@ -0,0 +1,7 @@ +#[cfg(feature = "playtime")] +pub mod playtime_service; + +pub struct RealearnServices { + #[cfg(feature = "playtime")] + pub playtime_service: playtime_service::PlaytimeService, +} diff --git a/main/src/infrastructure/server/services/playtime_service.rs b/main/src/infrastructure/server/services/playtime_service.rs new file mode 100644 index 000000000..e26c59ab6 --- /dev/null +++ b/main/src/infrastructure/server/services/playtime_service.rs @@ -0,0 +1,30 @@ +use crate::infrastructure::plugin::App; +use playtime_clip_engine::base::Matrix; +use playtime_clip_engine::proto::clip_engine_server::ClipEngineServer; +use playtime_clip_engine::proto::{ClipEngineHub, ClipEngineService, MatrixProvider}; + +pub type PlaytimeService = ClipEngineServer>; + +pub fn create_playtime_service(hub: &ClipEngineHub) -> PlaytimeService { + hub.create_service(AppMatrixProvider) +} + +pub struct AppMatrixProvider; + +impl MatrixProvider for AppMatrixProvider { + fn with_matrix( + &self, + clip_matrix_id: &str, + f: impl FnOnce(&Matrix) -> R, + ) -> Result { + App::get().with_clip_matrix(clip_matrix_id, f) + } + + fn with_matrix_mut( + &self, + clip_matrix_id: &str, + f: impl FnOnce(&mut Matrix) -> R, + ) -> Result { + App::get().with_clip_matrix_mut(clip_matrix_id, f) + } +} diff --git a/main/src/infrastructure/ui/header_panel.rs b/main/src/infrastructure/ui/header_panel.rs index 46e0adff4..ecb8d4c55 100644 --- a/main/src/infrastructure/ui/header_panel.rs +++ b/main/src/infrastructure/ui/header_panel.rs @@ -23,7 +23,7 @@ use crate::application::{ }; use crate::base::{notification, when}; use crate::domain::{ - convert_compartment_param_index_range_to_iter, BackboneState, ClipMatrixRef, Compartment, + convert_compartment_param_index_range_to_iter, BackboneState, Compartment, CompartmentParamIndex, ControlInput, FeedbackOutput, GroupId, MessageCaptureEvent, OscDeviceId, ParamSetting, ReaperTarget, StayActiveWhenProjectInBackground, COMPARTMENT_PARAMETER_COUNT, }; @@ -35,7 +35,6 @@ use crate::infrastructure::data::{ use crate::infrastructure::plugin::{ warn_about_failed_server_start, App, RealearnPluginParameters, }; -use base::Global; use crate::infrastructure::ui::bindings::root; @@ -293,6 +292,7 @@ impl HeaderPanel { !text_from_clipboard.is_empty() && data_object_from_clipboard.is_none(); let session = self.session(); let session = session.borrow(); + #[cfg(feature = "playtime")] let has_clip_matrix = session .instance_state() .borrow() @@ -386,6 +386,7 @@ impl HeaderPanel { }, move || MainMenuAction::DryRunLuaScript(text_from_clipboard_clone), ), + #[cfg(feature = "playtime")] item_with_opts( "Freeze clip matrix", ItemOpts { @@ -690,6 +691,7 @@ impl HeaderPanel { MainMenuAction::EditCompartmentParameter(compartment, range) => { let _ = edit_compartment_parameter(self.session(), compartment, range); } + #[cfg(feature = "playtime")] MainMenuAction::FreezeClipMatrix => { self.freeze_clip_matrix(); } @@ -1172,11 +1174,12 @@ impl HeaderPanel { ); } + #[cfg(feature = "playtime")] // TODO-high-clip-matrix As soon as we implement this, we need to fix the clippy error. #[allow(clippy::await_holding_refcell_ref)] fn freeze_clip_matrix(&self) { let weak_session = self.session.clone(); - Global::future_support().spawn_in_main_thread_from_main_thread(async move { + base::Global::future_support().spawn_in_main_thread_from_main_thread(async move { let shared_session = weak_session.upgrade().expect("session gone"); let shared_instance_state = { shared_session.borrow().instance_state().clone() }; shared_instance_state @@ -2014,14 +2017,15 @@ impl HeaderPanel { plugin_parameters.apply_session_data(&d); } } + #[cfg(feature = "playtime")] Tagged(DataObject::ClipMatrix(Envelope { value, .. })) => { let old_matrix_label = match self.session().borrow().instance_state().borrow().clip_matrix_ref() { None => EMPTY_CLIP_MATRIX_LABEL.to_owned(), Some(r) => match r { - ClipMatrixRef::Own(m) => { + crate::domain::ClipMatrixRef::Own(m) => { get_clip_matrix_label(m.column_count()) } - ClipMatrixRef::Foreign(instance_id) => { + crate::domain::ClipMatrixRef::Foreign(instance_id) => { format!("clip matrix reference (to instance {instance_id})") } }, @@ -2102,6 +2106,7 @@ impl HeaderPanel { enum MenuAction { None, ExportSession(SerializationFormat), + #[cfg(feature = "playtime")] ExportClipMatrix(SerializationFormat), ExportCompartment(SerializationFormat), } @@ -2117,9 +2122,11 @@ impl HeaderPanel { item("Export session as JSON", || { MenuAction::ExportSession(SerializationFormat::JsonDataObject) }), + #[cfg(feature = "playtime")] item("Export clip matrix as JSON", || { MenuAction::ExportClipMatrix(SerializationFormat::JsonDataObject) }), + #[cfg(feature = "playtime")] item("Export clip matrix as Lua", || { MenuAction::ExportClipMatrix(SerializationFormat::LuaApiObject( ConversionStyle::Minimal, @@ -2165,6 +2172,7 @@ impl HeaderPanel { let json = serialize_data_object_to_json(data_object).unwrap(); copy_text_to_clipboard(json); } + #[cfg(feature = "playtime")] MenuAction::ExportClipMatrix(format) => { let matrix = self .session() @@ -2944,8 +2952,10 @@ fn edit_osc_device(mut dev: OscDevice) -> Result { const COMPARTMENT_CHANGES_WARNING_TEXT: &str = "Mapping/group/parameter changes in this compartment will be lost. Consider to save them first. Do you really want to continue?"; +#[cfg(feature = "playtime")] const EMPTY_CLIP_MATRIX_LABEL: &str = "empty clip matrix"; +#[cfg(feature = "playtime")] fn get_clip_matrix_label(column_count: usize) -> String { format!("clip matrix with {column_count} columns") } @@ -2962,6 +2972,7 @@ enum MainMenuAction { PasteReplaceAllInGroup(Envelope>), PasteFromLuaReplaceAllInGroup(Rc), DryRunLuaScript(Rc), + #[cfg(feature = "playtime")] FreezeClipMatrix, ToggleAutoCorrectSettings, ToggleRealInputLogging, diff --git a/main/src/infrastructure/ui/import.rs b/main/src/infrastructure/ui/import.rs index 02ac2f869..c3737fbc2 100644 --- a/main/src/infrastructure/ui/import.rs +++ b/main/src/infrastructure/ui/import.rs @@ -2,7 +2,6 @@ use std::error::Error; use std::fmt::Debug; use std::time::Duration; -use playtime_api::persistence::Matrix; use serde::{Deserialize, Serialize}; use crate::domain::SafeLua; @@ -43,7 +42,8 @@ impl UntaggedDataObject { #[serde(tag = "kind")] pub enum DataObject { Session(Envelope>), - ClipMatrix(Envelope>>), + #[cfg(feature = "playtime")] + ClipMatrix(Envelope>>), MainCompartment(Envelope>), ControllerCompartment(Envelope>), Mappings(Envelope>), @@ -74,6 +74,7 @@ impl DataObject { conversion_context: &impl ApiToDataConversionContext, ) -> Result> { let data_object = match api_object { + #[cfg(feature = "playtime")] ApiObject::ClipMatrix(envelope) => DataObject::ClipMatrix(envelope), ApiObject::MainCompartment(Envelope { value: c, version }) => { let data_compartment = to_data::convert_compartment(*c)?; @@ -117,6 +118,7 @@ impl DataObject { ) -> Result> { let api_object = match self { DataObject::Session(Envelope { .. }) => todo!("session API not yet implemented"), + #[cfg(feature = "playtime")] DataObject::ClipMatrix(envelope) => ApiObject::ClipMatrix(envelope), DataObject::MainCompartment(Envelope { value: c, version }) => { let api_compartment = from_data::convert_compartment(*c, conversion_style)?; @@ -154,6 +156,7 @@ impl DataObject { use DataObject::*; match self { Session(v) => v.version.as_ref(), + #[cfg(feature = "playtime")] ClipMatrix(v) => v.version.as_ref(), MainCompartment(v) => v.version.as_ref(), ControllerCompartment(v) => v.version.as_ref(), diff --git a/main/src/infrastructure/ui/main_panel.rs b/main/src/infrastructure/ui/main_panel.rs index 6b7d10bd3..7800a9e27 100644 --- a/main/src/infrastructure/ui/main_panel.rs +++ b/main/src/infrastructure/ui/main_panel.rs @@ -4,7 +4,7 @@ use crate::infrastructure::ui::{ }; use lazycell::LazyCell; -use reaper_high::{ChangeEvent, Reaper}; +use reaper_high::Reaper; use slog::debug; use std::cell::{Cell, RefCell}; @@ -17,7 +17,7 @@ use crate::base::when; use crate::domain::ui_util::format_tags_as_csv; use crate::domain::{ Compartment, MappingId, MappingMatchedEvent, ProjectionFeedbackValue, QualifiedMappingId, - RealearnClipMatrix, TargetControlEvent, TargetValueChangedEvent, + TargetControlEvent, TargetValueChangedEvent, }; use crate::infrastructure::plugin::{App, RealearnPluginParameters}; use crate::infrastructure::server::http::{ @@ -25,7 +25,6 @@ use crate::infrastructure::server::http::{ }; use crate::infrastructure::ui::util::{header_panel_height, parse_tags_from_csv}; use base::SoundPlayer; -use playtime_clip_engine::base::ClipMatrixEvent; use rxrust::prelude::*; use std::rc::{Rc, Weak}; use std::sync; @@ -502,11 +501,12 @@ impl SessionUi for Weak { let _ = send_projection_feedback_to_subscribed_clients(session.id(), value); } + #[cfg(feature = "playtime")] fn clip_matrix_changed( &self, session: &Session, - matrix: &RealearnClipMatrix, - events: &[ClipMatrixEvent], + matrix: &playtime_clip_engine::base::Matrix, + events: &[playtime_clip_engine::base::ClipMatrixEvent], is_poll: bool, ) { App::get().clip_engine_hub().clip_matrix_changed( @@ -518,11 +518,12 @@ impl SessionUi for Weak { ); } + #[cfg(feature = "playtime")] fn process_control_surface_change_event_for_clip_engine( &self, session: &Session, - matrix: &RealearnClipMatrix, - event: &ChangeEvent, + matrix: &playtime_clip_engine::base::Matrix, + event: &reaper_high::ChangeEvent, ) { App::get() .clip_engine_hub() diff --git a/main/src/infrastructure/ui/mapping_panel.rs b/main/src/infrastructure/ui/mapping_panel.rs index fe89b6477..7caacf8b1 100644 --- a/main/src/infrastructure/ui/mapping_panel.rs +++ b/main/src/infrastructure/ui/mapping_panel.rs @@ -571,6 +571,7 @@ impl MappingPanel { P::ActiveMappingsOnly => { view.invalidate_target_check_box_2(); } + #[cfg(feature = "playtime")] P::ClipPlayStartTiming | P::ClipPlayStopTiming | P::ClipRow | P::ClipRowAction | P::StopColumnIfSlotEmpty | P::ClipSlot | P::ClipColumn | P::ClipManagementAction | P::ClipTransportAction | P::ClipColumnAction | P::RecordOnlyIfTrackArmed | P::ClipMatrixAction => {} P::TouchedRouteParameterType => { view.invalidate_target_line_3_combo_box_2(); diff --git a/playtime-api/src/persistence/mod.rs b/playtime-api/src/persistence/mod.rs index 568b34cb0..4609b7b96 100644 --- a/playtime-api/src/persistence/mod.rs +++ b/playtime-api/src/persistence/mod.rs @@ -1207,6 +1207,9 @@ impl TrackId { pub struct Bpm(f64); impl Bpm { + /// # Safety + /// + /// If you pass a value <= 0.0, you get an invalid Bpm value. pub const unsafe fn new_unchecked(value: f64) -> Self { Self(value) } diff --git a/playtime-clip-engine/src/base/clip_edit_session.rs b/playtime-clip-engine/src/base/clip_edit_session.rs index adb289d44..7701e08ca 100644 --- a/playtime-clip-engine/src/base/clip_edit_session.rs +++ b/playtime-clip-engine/src/base/clip_edit_session.rs @@ -1,7 +1,6 @@ use crate::base::clip_manifestation::ClipOnTrackManifestation; - -use reaper_medium::{Hwnd}; +use reaper_medium::Hwnd; use swell_ui::Window; diff --git a/playtime-clip-engine/src/proto/clip_engine.rs b/playtime-clip-engine/src/proto/clip_engine.rs index 825cabf68..801425e67 100644 --- a/playtime-clip-engine/src/proto/clip_engine.rs +++ b/playtime-clip-engine/src/proto/clip_engine.rs @@ -704,15 +704,9 @@ impl TriggerMatrixAction { "TRIGGER_MATRIX_ACTION_ARRANGEMENT_TOGGLE_PLAY_STOP" } TriggerMatrixAction::StopAllClips => "TRIGGER_MATRIX_ACTION_STOP_ALL_CLIPS", - TriggerMatrixAction::ArrangementPlay => { - "TRIGGER_MATRIX_ACTION_ARRANGEMENT_PLAY" - } - TriggerMatrixAction::ArrangementStop => { - "TRIGGER_MATRIX_ACTION_ARRANGEMENT_STOP" - } - TriggerMatrixAction::ArrangementPause => { - "TRIGGER_MATRIX_ACTION_ARRANGEMENT_PAUSE" - } + TriggerMatrixAction::ArrangementPlay => "TRIGGER_MATRIX_ACTION_ARRANGEMENT_PLAY", + TriggerMatrixAction::ArrangementStop => "TRIGGER_MATRIX_ACTION_ARRANGEMENT_STOP", + TriggerMatrixAction::ArrangementPause => "TRIGGER_MATRIX_ACTION_ARRANGEMENT_PAUSE", TriggerMatrixAction::ArrangementStartRecording => { "TRIGGER_MATRIX_ACTION_ARRANGEMENT_START_RECORDING" } @@ -935,9 +929,7 @@ impl TriggerSlotAction { "TRIGGER_SLOT_ACTION_COPY" => Some(Self::Copy), "TRIGGER_SLOT_ACTION_CUT" => Some(Self::Cut), "TRIGGER_SLOT_ACTION_PASTE" => Some(Self::Paste), - "TRIGGER_SLOT_ACTION_FILL_WITH_SELECTED_ITEM" => { - Some(Self::FillWithSelectedItem) - } + "TRIGGER_SLOT_ACTION_FILL_WITH_SELECTED_ITEM" => Some(Self::FillWithSelectedItem), "TRIGGER_SLOT_ACTION_PANIC" => Some(Self::Panic), _ => None, } @@ -1049,14 +1041,10 @@ impl SlotPlayState { match self { SlotPlayState::Unknown => "SLOT_PLAY_STATE_UNKNOWN", SlotPlayState::Stopped => "SLOT_PLAY_STATE_STOPPED", - SlotPlayState::ScheduledForPlayStart => { - "SLOT_PLAY_STATE_SCHEDULED_FOR_PLAY_START" - } + SlotPlayState::ScheduledForPlayStart => "SLOT_PLAY_STATE_SCHEDULED_FOR_PLAY_START", SlotPlayState::Playing => "SLOT_PLAY_STATE_PLAYING", SlotPlayState::Paused => "SLOT_PLAY_STATE_PAUSED", - SlotPlayState::ScheduledForPlayStop => { - "SLOT_PLAY_STATE_SCHEDULED_FOR_PLAY_STOP" - } + SlotPlayState::ScheduledForPlayStop => "SLOT_PLAY_STATE_SCHEDULED_FOR_PLAY_STOP", SlotPlayState::ScheduledForRecordingStart => { "SLOT_PLAY_STATE_SCHEDULED_FOR_RECORDING_START" } @@ -1071,9 +1059,7 @@ impl SlotPlayState { match value { "SLOT_PLAY_STATE_UNKNOWN" => Some(Self::Unknown), "SLOT_PLAY_STATE_STOPPED" => Some(Self::Stopped), - "SLOT_PLAY_STATE_SCHEDULED_FOR_PLAY_START" => { - Some(Self::ScheduledForPlayStart) - } + "SLOT_PLAY_STATE_SCHEDULED_FOR_PLAY_START" => Some(Self::ScheduledForPlayStart), "SLOT_PLAY_STATE_PLAYING" => Some(Self::Playing), "SLOT_PLAY_STATE_PAUSED" => Some(Self::Paused), "SLOT_PLAY_STATE_SCHEDULED_FOR_PLAY_STOP" => Some(Self::ScheduledForPlayStop), @@ -1081,9 +1067,7 @@ impl SlotPlayState { Some(Self::ScheduledForRecordingStart) } "SLOT_PLAY_STATE_RECORDING" => Some(Self::Recording), - "SLOT_PLAY_STATE_SCHEDULED_FOR_RECORDING_STOP" => { - Some(Self::ScheduledForRecordingStop) - } + "SLOT_PLAY_STATE_SCHEDULED_FOR_RECORDING_STOP" => Some(Self::ScheduledForRecordingStop), _ => None, } } @@ -1108,13 +1092,9 @@ impl ArrangementPlayState { ArrangementPlayState::Unknown => "ARRANGEMENT_PLAY_STATE_UNKNOWN", ArrangementPlayState::Stopped => "ARRANGEMENT_PLAY_STATE_STOPPED", ArrangementPlayState::Playing => "ARRANGEMENT_PLAY_STATE_PLAYING", - ArrangementPlayState::PlayingPaused => { - "ARRANGEMENT_PLAY_STATE_PLAYING_PAUSED" - } + ArrangementPlayState::PlayingPaused => "ARRANGEMENT_PLAY_STATE_PLAYING_PAUSED", ArrangementPlayState::Recording => "ARRANGEMENT_PLAY_STATE_RECORDING", - ArrangementPlayState::RecordingPaused => { - "ARRANGEMENT_PLAY_STATE_RECORDING_PAUSED" - } + ArrangementPlayState::RecordingPaused => "ARRANGEMENT_PLAY_STATE_RECORDING_PAUSED", } } /// Creates an enum from field names used in the ProtoBuf definition. @@ -1235,61 +1215,43 @@ pub mod clip_engine_server { /// Server streaming response type for the GetOccasionalMatrixUpdates method. type GetOccasionalMatrixUpdatesStream: futures_core::Stream< Item = Result, - > - + Send + > + Send + 'static; /// Matrix events async fn get_occasional_matrix_updates( &self, request: tonic::Request, - ) -> Result< - tonic::Response, - tonic::Status, - >; + ) -> Result, tonic::Status>; /// Server streaming response type for the GetContinuousMatrixUpdates method. type GetContinuousMatrixUpdatesStream: futures_core::Stream< Item = Result, - > - + Send + > + Send + 'static; async fn get_continuous_matrix_updates( &self, request: tonic::Request, - ) -> Result< - tonic::Response, - tonic::Status, - >; + ) -> Result, tonic::Status>; /// Server streaming response type for the GetOccasionalColumnUpdates method. type GetOccasionalColumnUpdatesStream: futures_core::Stream< Item = Result, - > - + Send + > + Send + 'static; /// Column events async fn get_occasional_column_updates( &self, request: tonic::Request, - ) -> Result< - tonic::Response, - tonic::Status, - >; + ) -> Result, tonic::Status>; /// Server streaming response type for the GetContinuousColumnUpdates method. type GetContinuousColumnUpdatesStream: futures_core::Stream< Item = Result, - > - + Send + > + Send + 'static; async fn get_continuous_column_updates( &self, request: tonic::Request, - ) -> Result< - tonic::Response, - tonic::Status, - >; + ) -> Result, tonic::Status>; /// Server streaming response type for the GetOccasionalRowUpdates method. - type GetOccasionalRowUpdatesStream: futures_core::Stream< - Item = Result, - > + type GetOccasionalRowUpdatesStream: futures_core::Stream> + Send + 'static; /// Row events @@ -1298,60 +1260,41 @@ pub mod clip_engine_server { request: tonic::Request, ) -> Result, tonic::Status>; /// Server streaming response type for the GetOccasionalSlotUpdates method. - type GetOccasionalSlotUpdatesStream: futures_core::Stream< - Item = Result, - > + type GetOccasionalSlotUpdatesStream: futures_core::Stream> + Send + 'static; /// Slot events async fn get_occasional_slot_updates( &self, request: tonic::Request, - ) -> Result< - tonic::Response, - tonic::Status, - >; + ) -> Result, tonic::Status>; /// Server streaming response type for the GetContinuousSlotUpdates method. - type GetContinuousSlotUpdatesStream: futures_core::Stream< - Item = Result, - > + type GetContinuousSlotUpdatesStream: futures_core::Stream> + Send + 'static; async fn get_continuous_slot_updates( &self, request: tonic::Request, - ) -> Result< - tonic::Response, - tonic::Status, - >; + ) -> Result, tonic::Status>; /// Server streaming response type for the GetOccasionalClipUpdates method. - type GetOccasionalClipUpdatesStream: futures_core::Stream< - Item = Result, - > + type GetOccasionalClipUpdatesStream: futures_core::Stream> + Send + 'static; /// Clip events async fn get_occasional_clip_updates( &self, request: tonic::Request, - ) -> Result< - tonic::Response, - tonic::Status, - >; + ) -> Result, tonic::Status>; /// Server streaming response type for the GetOccasionalTrackUpdates method. type GetOccasionalTrackUpdatesStream: futures_core::Stream< Item = Result, - > - + Send + > + Send + 'static; /// Track events async fn get_occasional_track_updates( &self, request: tonic::Request, - ) -> Result< - tonic::Response, - tonic::Status, - >; + ) -> Result, tonic::Status>; } #[derive(Debug)] pub struct ClipEngineServer { @@ -1372,10 +1315,7 @@ pub mod clip_engine_server { send_compression_encodings: Default::default(), } } - pub fn with_interceptor( - inner: T, - interceptor: F, - ) -> InterceptedService + pub fn with_interceptor(inner: T, interceptor: F) -> InterceptedService where F: tonic::service::Interceptor, { @@ -1403,10 +1343,7 @@ pub mod clip_engine_server { type Response = http::Response; type Error = std::convert::Infallible; type Future = BoxFuture; - fn poll_ready( - &mut self, - _cx: &mut Context<'_>, - ) -> Poll> { + fn poll_ready(&mut self, _cx: &mut Context<'_>) -> Poll> { Poll::Ready(Ok(())) } fn call(&mut self, req: http::Request) -> Self::Future { @@ -1415,23 +1352,15 @@ pub mod clip_engine_server { "/playtime.clip_engine.ClipEngine/GetAllTracks" => { #[allow(non_camel_case_types)] struct GetAllTracksSvc(pub Arc); - impl< - T: ClipEngine, - > tonic::server::UnaryService - for GetAllTracksSvc { + impl tonic::server::UnaryService for GetAllTracksSvc { type Response = super::GetAllTracksReply; - type Future = BoxFuture< - tonic::Response, - tonic::Status, - >; + type Future = BoxFuture, tonic::Status>; fn call( &mut self, request: tonic::Request, ) -> Self::Future { let inner = self.0.clone(); - let fut = async move { - (*inner).get_all_tracks(request).await - }; + let fut = async move { (*inner).get_all_tracks(request).await }; Box::pin(fut) } } @@ -1442,11 +1371,10 @@ pub mod clip_engine_server { let inner = inner.0; let method = GetAllTracksSvc(inner); let codec = tonic::codec::ProstCodec::default(); - let mut grpc = tonic::server::Grpc::new(codec) - .apply_compression_config( - accept_compression_encodings, - send_compression_encodings, - ); + let mut grpc = tonic::server::Grpc::new(codec).apply_compression_config( + accept_compression_encodings, + send_compression_encodings, + ); let res = grpc.unary(method, req).await; Ok(res) }; @@ -1455,23 +1383,17 @@ pub mod clip_engine_server { "/playtime.clip_engine.ClipEngine/TriggerMatrix" => { #[allow(non_camel_case_types)] struct TriggerMatrixSvc(pub Arc); - impl< - T: ClipEngine, - > tonic::server::UnaryService - for TriggerMatrixSvc { + impl tonic::server::UnaryService + for TriggerMatrixSvc + { type Response = super::Empty; - type Future = BoxFuture< - tonic::Response, - tonic::Status, - >; + type Future = BoxFuture, tonic::Status>; fn call( &mut self, request: tonic::Request, ) -> Self::Future { let inner = self.0.clone(); - let fut = async move { - (*inner).trigger_matrix(request).await - }; + let fut = async move { (*inner).trigger_matrix(request).await }; Box::pin(fut) } } @@ -1482,11 +1404,10 @@ pub mod clip_engine_server { let inner = inner.0; let method = TriggerMatrixSvc(inner); let codec = tonic::codec::ProstCodec::default(); - let mut grpc = tonic::server::Grpc::new(codec) - .apply_compression_config( - accept_compression_encodings, - send_compression_encodings, - ); + let mut grpc = tonic::server::Grpc::new(codec).apply_compression_config( + accept_compression_encodings, + send_compression_encodings, + ); let res = grpc.unary(method, req).await; Ok(res) }; @@ -1495,23 +1416,17 @@ pub mod clip_engine_server { "/playtime.clip_engine.ClipEngine/SetMatrixSettings" => { #[allow(non_camel_case_types)] struct SetMatrixSettingsSvc(pub Arc); - impl< - T: ClipEngine, - > tonic::server::UnaryService - for SetMatrixSettingsSvc { + impl tonic::server::UnaryService + for SetMatrixSettingsSvc + { type Response = super::Empty; - type Future = BoxFuture< - tonic::Response, - tonic::Status, - >; + type Future = BoxFuture, tonic::Status>; fn call( &mut self, request: tonic::Request, ) -> Self::Future { let inner = self.0.clone(); - let fut = async move { - (*inner).set_matrix_settings(request).await - }; + let fut = async move { (*inner).set_matrix_settings(request).await }; Box::pin(fut) } } @@ -1522,11 +1437,10 @@ pub mod clip_engine_server { let inner = inner.0; let method = SetMatrixSettingsSvc(inner); let codec = tonic::codec::ProstCodec::default(); - let mut grpc = tonic::server::Grpc::new(codec) - .apply_compression_config( - accept_compression_encodings, - send_compression_encodings, - ); + let mut grpc = tonic::server::Grpc::new(codec).apply_compression_config( + accept_compression_encodings, + send_compression_encodings, + ); let res = grpc.unary(method, req).await; Ok(res) }; @@ -1535,23 +1449,17 @@ pub mod clip_engine_server { "/playtime.clip_engine.ClipEngine/SetMatrixTempo" => { #[allow(non_camel_case_types)] struct SetMatrixTempoSvc(pub Arc); - impl< - T: ClipEngine, - > tonic::server::UnaryService - for SetMatrixTempoSvc { + impl tonic::server::UnaryService + for SetMatrixTempoSvc + { type Response = super::Empty; - type Future = BoxFuture< - tonic::Response, - tonic::Status, - >; + type Future = BoxFuture, tonic::Status>; fn call( &mut self, request: tonic::Request, ) -> Self::Future { let inner = self.0.clone(); - let fut = async move { - (*inner).set_matrix_tempo(request).await - }; + let fut = async move { (*inner).set_matrix_tempo(request).await }; Box::pin(fut) } } @@ -1562,11 +1470,10 @@ pub mod clip_engine_server { let inner = inner.0; let method = SetMatrixTempoSvc(inner); let codec = tonic::codec::ProstCodec::default(); - let mut grpc = tonic::server::Grpc::new(codec) - .apply_compression_config( - accept_compression_encodings, - send_compression_encodings, - ); + let mut grpc = tonic::server::Grpc::new(codec).apply_compression_config( + accept_compression_encodings, + send_compression_encodings, + ); let res = grpc.unary(method, req).await; Ok(res) }; @@ -1575,23 +1482,17 @@ pub mod clip_engine_server { "/playtime.clip_engine.ClipEngine/SetMatrixVolume" => { #[allow(non_camel_case_types)] struct SetMatrixVolumeSvc(pub Arc); - impl< - T: ClipEngine, - > tonic::server::UnaryService - for SetMatrixVolumeSvc { + impl tonic::server::UnaryService + for SetMatrixVolumeSvc + { type Response = super::Empty; - type Future = BoxFuture< - tonic::Response, - tonic::Status, - >; + type Future = BoxFuture, tonic::Status>; fn call( &mut self, request: tonic::Request, ) -> Self::Future { let inner = self.0.clone(); - let fut = async move { - (*inner).set_matrix_volume(request).await - }; + let fut = async move { (*inner).set_matrix_volume(request).await }; Box::pin(fut) } } @@ -1602,11 +1503,10 @@ pub mod clip_engine_server { let inner = inner.0; let method = SetMatrixVolumeSvc(inner); let codec = tonic::codec::ProstCodec::default(); - let mut grpc = tonic::server::Grpc::new(codec) - .apply_compression_config( - accept_compression_encodings, - send_compression_encodings, - ); + let mut grpc = tonic::server::Grpc::new(codec).apply_compression_config( + accept_compression_encodings, + send_compression_encodings, + ); let res = grpc.unary(method, req).await; Ok(res) }; @@ -1615,23 +1515,15 @@ pub mod clip_engine_server { "/playtime.clip_engine.ClipEngine/SetMatrixPan" => { #[allow(non_camel_case_types)] struct SetMatrixPanSvc(pub Arc); - impl< - T: ClipEngine, - > tonic::server::UnaryService - for SetMatrixPanSvc { + impl tonic::server::UnaryService for SetMatrixPanSvc { type Response = super::Empty; - type Future = BoxFuture< - tonic::Response, - tonic::Status, - >; + type Future = BoxFuture, tonic::Status>; fn call( &mut self, request: tonic::Request, ) -> Self::Future { let inner = self.0.clone(); - let fut = async move { - (*inner).set_matrix_pan(request).await - }; + let fut = async move { (*inner).set_matrix_pan(request).await }; Box::pin(fut) } } @@ -1642,11 +1534,10 @@ pub mod clip_engine_server { let inner = inner.0; let method = SetMatrixPanSvc(inner); let codec = tonic::codec::ProstCodec::default(); - let mut grpc = tonic::server::Grpc::new(codec) - .apply_compression_config( - accept_compression_encodings, - send_compression_encodings, - ); + let mut grpc = tonic::server::Grpc::new(codec).apply_compression_config( + accept_compression_encodings, + send_compression_encodings, + ); let res = grpc.unary(method, req).await; Ok(res) }; @@ -1655,23 +1546,17 @@ pub mod clip_engine_server { "/playtime.clip_engine.ClipEngine/TriggerColumn" => { #[allow(non_camel_case_types)] struct TriggerColumnSvc(pub Arc); - impl< - T: ClipEngine, - > tonic::server::UnaryService - for TriggerColumnSvc { + impl tonic::server::UnaryService + for TriggerColumnSvc + { type Response = super::Empty; - type Future = BoxFuture< - tonic::Response, - tonic::Status, - >; + type Future = BoxFuture, tonic::Status>; fn call( &mut self, request: tonic::Request, ) -> Self::Future { let inner = self.0.clone(); - let fut = async move { - (*inner).trigger_column(request).await - }; + let fut = async move { (*inner).trigger_column(request).await }; Box::pin(fut) } } @@ -1682,11 +1567,10 @@ pub mod clip_engine_server { let inner = inner.0; let method = TriggerColumnSvc(inner); let codec = tonic::codec::ProstCodec::default(); - let mut grpc = tonic::server::Grpc::new(codec) - .apply_compression_config( - accept_compression_encodings, - send_compression_encodings, - ); + let mut grpc = tonic::server::Grpc::new(codec).apply_compression_config( + accept_compression_encodings, + send_compression_encodings, + ); let res = grpc.unary(method, req).await; Ok(res) }; @@ -1695,23 +1579,17 @@ pub mod clip_engine_server { "/playtime.clip_engine.ClipEngine/SetColumnSettings" => { #[allow(non_camel_case_types)] struct SetColumnSettingsSvc(pub Arc); - impl< - T: ClipEngine, - > tonic::server::UnaryService - for SetColumnSettingsSvc { + impl tonic::server::UnaryService + for SetColumnSettingsSvc + { type Response = super::Empty; - type Future = BoxFuture< - tonic::Response, - tonic::Status, - >; + type Future = BoxFuture, tonic::Status>; fn call( &mut self, request: tonic::Request, ) -> Self::Future { let inner = self.0.clone(); - let fut = async move { - (*inner).set_column_settings(request).await - }; + let fut = async move { (*inner).set_column_settings(request).await }; Box::pin(fut) } } @@ -1722,11 +1600,10 @@ pub mod clip_engine_server { let inner = inner.0; let method = SetColumnSettingsSvc(inner); let codec = tonic::codec::ProstCodec::default(); - let mut grpc = tonic::server::Grpc::new(codec) - .apply_compression_config( - accept_compression_encodings, - send_compression_encodings, - ); + let mut grpc = tonic::server::Grpc::new(codec).apply_compression_config( + accept_compression_encodings, + send_compression_encodings, + ); let res = grpc.unary(method, req).await; Ok(res) }; @@ -1735,23 +1612,17 @@ pub mod clip_engine_server { "/playtime.clip_engine.ClipEngine/SetColumnName" => { #[allow(non_camel_case_types)] struct SetColumnNameSvc(pub Arc); - impl< - T: ClipEngine, - > tonic::server::UnaryService - for SetColumnNameSvc { + impl tonic::server::UnaryService + for SetColumnNameSvc + { type Response = super::Empty; - type Future = BoxFuture< - tonic::Response, - tonic::Status, - >; + type Future = BoxFuture, tonic::Status>; fn call( &mut self, request: tonic::Request, ) -> Self::Future { let inner = self.0.clone(); - let fut = async move { - (*inner).set_column_name(request).await - }; + let fut = async move { (*inner).set_column_name(request).await }; Box::pin(fut) } } @@ -1762,11 +1633,10 @@ pub mod clip_engine_server { let inner = inner.0; let method = SetColumnNameSvc(inner); let codec = tonic::codec::ProstCodec::default(); - let mut grpc = tonic::server::Grpc::new(codec) - .apply_compression_config( - accept_compression_encodings, - send_compression_encodings, - ); + let mut grpc = tonic::server::Grpc::new(codec).apply_compression_config( + accept_compression_encodings, + send_compression_encodings, + ); let res = grpc.unary(method, req).await; Ok(res) }; @@ -1775,23 +1645,17 @@ pub mod clip_engine_server { "/playtime.clip_engine.ClipEngine/SetColumnVolume" => { #[allow(non_camel_case_types)] struct SetColumnVolumeSvc(pub Arc); - impl< - T: ClipEngine, - > tonic::server::UnaryService - for SetColumnVolumeSvc { + impl tonic::server::UnaryService + for SetColumnVolumeSvc + { type Response = super::Empty; - type Future = BoxFuture< - tonic::Response, - tonic::Status, - >; + type Future = BoxFuture, tonic::Status>; fn call( &mut self, request: tonic::Request, ) -> Self::Future { let inner = self.0.clone(); - let fut = async move { - (*inner).set_column_volume(request).await - }; + let fut = async move { (*inner).set_column_volume(request).await }; Box::pin(fut) } } @@ -1802,11 +1666,10 @@ pub mod clip_engine_server { let inner = inner.0; let method = SetColumnVolumeSvc(inner); let codec = tonic::codec::ProstCodec::default(); - let mut grpc = tonic::server::Grpc::new(codec) - .apply_compression_config( - accept_compression_encodings, - send_compression_encodings, - ); + let mut grpc = tonic::server::Grpc::new(codec).apply_compression_config( + accept_compression_encodings, + send_compression_encodings, + ); let res = grpc.unary(method, req).await; Ok(res) }; @@ -1815,23 +1678,15 @@ pub mod clip_engine_server { "/playtime.clip_engine.ClipEngine/SetColumnPan" => { #[allow(non_camel_case_types)] struct SetColumnPanSvc(pub Arc); - impl< - T: ClipEngine, - > tonic::server::UnaryService - for SetColumnPanSvc { + impl tonic::server::UnaryService for SetColumnPanSvc { type Response = super::Empty; - type Future = BoxFuture< - tonic::Response, - tonic::Status, - >; + type Future = BoxFuture, tonic::Status>; fn call( &mut self, request: tonic::Request, ) -> Self::Future { let inner = self.0.clone(); - let fut = async move { - (*inner).set_column_pan(request).await - }; + let fut = async move { (*inner).set_column_pan(request).await }; Box::pin(fut) } } @@ -1842,11 +1697,10 @@ pub mod clip_engine_server { let inner = inner.0; let method = SetColumnPanSvc(inner); let codec = tonic::codec::ProstCodec::default(); - let mut grpc = tonic::server::Grpc::new(codec) - .apply_compression_config( - accept_compression_encodings, - send_compression_encodings, - ); + let mut grpc = tonic::server::Grpc::new(codec).apply_compression_config( + accept_compression_encodings, + send_compression_encodings, + ); let res = grpc.unary(method, req).await; Ok(res) }; @@ -1855,23 +1709,17 @@ pub mod clip_engine_server { "/playtime.clip_engine.ClipEngine/SetColumnTrack" => { #[allow(non_camel_case_types)] struct SetColumnTrackSvc(pub Arc); - impl< - T: ClipEngine, - > tonic::server::UnaryService - for SetColumnTrackSvc { + impl tonic::server::UnaryService + for SetColumnTrackSvc + { type Response = super::Empty; - type Future = BoxFuture< - tonic::Response, - tonic::Status, - >; + type Future = BoxFuture, tonic::Status>; fn call( &mut self, request: tonic::Request, ) -> Self::Future { let inner = self.0.clone(); - let fut = async move { - (*inner).set_column_track(request).await - }; + let fut = async move { (*inner).set_column_track(request).await }; Box::pin(fut) } } @@ -1882,11 +1730,10 @@ pub mod clip_engine_server { let inner = inner.0; let method = SetColumnTrackSvc(inner); let codec = tonic::codec::ProstCodec::default(); - let mut grpc = tonic::server::Grpc::new(codec) - .apply_compression_config( - accept_compression_encodings, - send_compression_encodings, - ); + let mut grpc = tonic::server::Grpc::new(codec).apply_compression_config( + accept_compression_encodings, + send_compression_encodings, + ); let res = grpc.unary(method, req).await; Ok(res) }; @@ -1895,15 +1742,9 @@ pub mod clip_engine_server { "/playtime.clip_engine.ClipEngine/DragColumn" => { #[allow(non_camel_case_types)] struct DragColumnSvc(pub Arc); - impl< - T: ClipEngine, - > tonic::server::UnaryService - for DragColumnSvc { + impl tonic::server::UnaryService for DragColumnSvc { type Response = super::Empty; - type Future = BoxFuture< - tonic::Response, - tonic::Status, - >; + type Future = BoxFuture, tonic::Status>; fn call( &mut self, request: tonic::Request, @@ -1920,11 +1761,10 @@ pub mod clip_engine_server { let inner = inner.0; let method = DragColumnSvc(inner); let codec = tonic::codec::ProstCodec::default(); - let mut grpc = tonic::server::Grpc::new(codec) - .apply_compression_config( - accept_compression_encodings, - send_compression_encodings, - ); + let mut grpc = tonic::server::Grpc::new(codec).apply_compression_config( + accept_compression_encodings, + send_compression_encodings, + ); let res = grpc.unary(method, req).await; Ok(res) }; @@ -1933,15 +1773,9 @@ pub mod clip_engine_server { "/playtime.clip_engine.ClipEngine/TriggerRow" => { #[allow(non_camel_case_types)] struct TriggerRowSvc(pub Arc); - impl< - T: ClipEngine, - > tonic::server::UnaryService - for TriggerRowSvc { + impl tonic::server::UnaryService for TriggerRowSvc { type Response = super::Empty; - type Future = BoxFuture< - tonic::Response, - tonic::Status, - >; + type Future = BoxFuture, tonic::Status>; fn call( &mut self, request: tonic::Request, @@ -1958,11 +1792,10 @@ pub mod clip_engine_server { let inner = inner.0; let method = TriggerRowSvc(inner); let codec = tonic::codec::ProstCodec::default(); - let mut grpc = tonic::server::Grpc::new(codec) - .apply_compression_config( - accept_compression_encodings, - send_compression_encodings, - ); + let mut grpc = tonic::server::Grpc::new(codec).apply_compression_config( + accept_compression_encodings, + send_compression_encodings, + ); let res = grpc.unary(method, req).await; Ok(res) }; @@ -1971,23 +1804,15 @@ pub mod clip_engine_server { "/playtime.clip_engine.ClipEngine/SetRowData" => { #[allow(non_camel_case_types)] struct SetRowDataSvc(pub Arc); - impl< - T: ClipEngine, - > tonic::server::UnaryService - for SetRowDataSvc { + impl tonic::server::UnaryService for SetRowDataSvc { type Response = super::Empty; - type Future = BoxFuture< - tonic::Response, - tonic::Status, - >; + type Future = BoxFuture, tonic::Status>; fn call( &mut self, request: tonic::Request, ) -> Self::Future { let inner = self.0.clone(); - let fut = async move { - (*inner).set_row_data(request).await - }; + let fut = async move { (*inner).set_row_data(request).await }; Box::pin(fut) } } @@ -1998,11 +1823,10 @@ pub mod clip_engine_server { let inner = inner.0; let method = SetRowDataSvc(inner); let codec = tonic::codec::ProstCodec::default(); - let mut grpc = tonic::server::Grpc::new(codec) - .apply_compression_config( - accept_compression_encodings, - send_compression_encodings, - ); + let mut grpc = tonic::server::Grpc::new(codec).apply_compression_config( + accept_compression_encodings, + send_compression_encodings, + ); let res = grpc.unary(method, req).await; Ok(res) }; @@ -2011,15 +1835,9 @@ pub mod clip_engine_server { "/playtime.clip_engine.ClipEngine/DragRow" => { #[allow(non_camel_case_types)] struct DragRowSvc(pub Arc); - impl< - T: ClipEngine, - > tonic::server::UnaryService - for DragRowSvc { + impl tonic::server::UnaryService for DragRowSvc { type Response = super::Empty; - type Future = BoxFuture< - tonic::Response, - tonic::Status, - >; + type Future = BoxFuture, tonic::Status>; fn call( &mut self, request: tonic::Request, @@ -2036,11 +1854,10 @@ pub mod clip_engine_server { let inner = inner.0; let method = DragRowSvc(inner); let codec = tonic::codec::ProstCodec::default(); - let mut grpc = tonic::server::Grpc::new(codec) - .apply_compression_config( - accept_compression_encodings, - send_compression_encodings, - ); + let mut grpc = tonic::server::Grpc::new(codec).apply_compression_config( + accept_compression_encodings, + send_compression_encodings, + ); let res = grpc.unary(method, req).await; Ok(res) }; @@ -2049,23 +1866,15 @@ pub mod clip_engine_server { "/playtime.clip_engine.ClipEngine/TriggerSlot" => { #[allow(non_camel_case_types)] struct TriggerSlotSvc(pub Arc); - impl< - T: ClipEngine, - > tonic::server::UnaryService - for TriggerSlotSvc { + impl tonic::server::UnaryService for TriggerSlotSvc { type Response = super::Empty; - type Future = BoxFuture< - tonic::Response, - tonic::Status, - >; + type Future = BoxFuture, tonic::Status>; fn call( &mut self, request: tonic::Request, ) -> Self::Future { let inner = self.0.clone(); - let fut = async move { - (*inner).trigger_slot(request).await - }; + let fut = async move { (*inner).trigger_slot(request).await }; Box::pin(fut) } } @@ -2076,11 +1885,10 @@ pub mod clip_engine_server { let inner = inner.0; let method = TriggerSlotSvc(inner); let codec = tonic::codec::ProstCodec::default(); - let mut grpc = tonic::server::Grpc::new(codec) - .apply_compression_config( - accept_compression_encodings, - send_compression_encodings, - ); + let mut grpc = tonic::server::Grpc::new(codec).apply_compression_config( + accept_compression_encodings, + send_compression_encodings, + ); let res = grpc.unary(method, req).await; Ok(res) }; @@ -2089,15 +1897,9 @@ pub mod clip_engine_server { "/playtime.clip_engine.ClipEngine/DragSlot" => { #[allow(non_camel_case_types)] struct DragSlotSvc(pub Arc); - impl< - T: ClipEngine, - > tonic::server::UnaryService - for DragSlotSvc { + impl tonic::server::UnaryService for DragSlotSvc { type Response = super::Empty; - type Future = BoxFuture< - tonic::Response, - tonic::Status, - >; + type Future = BoxFuture, tonic::Status>; fn call( &mut self, request: tonic::Request, @@ -2114,11 +1916,10 @@ pub mod clip_engine_server { let inner = inner.0; let method = DragSlotSvc(inner); let codec = tonic::codec::ProstCodec::default(); - let mut grpc = tonic::server::Grpc::new(codec) - .apply_compression_config( - accept_compression_encodings, - send_compression_encodings, - ); + let mut grpc = tonic::server::Grpc::new(codec).apply_compression_config( + accept_compression_encodings, + send_compression_encodings, + ); let res = grpc.unary(method, req).await; Ok(res) }; @@ -2127,23 +1928,15 @@ pub mod clip_engine_server { "/playtime.clip_engine.ClipEngine/TriggerClip" => { #[allow(non_camel_case_types)] struct TriggerClipSvc(pub Arc); - impl< - T: ClipEngine, - > tonic::server::UnaryService - for TriggerClipSvc { + impl tonic::server::UnaryService for TriggerClipSvc { type Response = super::Empty; - type Future = BoxFuture< - tonic::Response, - tonic::Status, - >; + type Future = BoxFuture, tonic::Status>; fn call( &mut self, request: tonic::Request, ) -> Self::Future { let inner = self.0.clone(); - let fut = async move { - (*inner).trigger_clip(request).await - }; + let fut = async move { (*inner).trigger_clip(request).await }; Box::pin(fut) } } @@ -2154,11 +1947,10 @@ pub mod clip_engine_server { let inner = inner.0; let method = TriggerClipSvc(inner); let codec = tonic::codec::ProstCodec::default(); - let mut grpc = tonic::server::Grpc::new(codec) - .apply_compression_config( - accept_compression_encodings, - send_compression_encodings, - ); + let mut grpc = tonic::server::Grpc::new(codec).apply_compression_config( + accept_compression_encodings, + send_compression_encodings, + ); let res = grpc.unary(method, req).await; Ok(res) }; @@ -2167,23 +1959,15 @@ pub mod clip_engine_server { "/playtime.clip_engine.ClipEngine/SetClipName" => { #[allow(non_camel_case_types)] struct SetClipNameSvc(pub Arc); - impl< - T: ClipEngine, - > tonic::server::UnaryService - for SetClipNameSvc { + impl tonic::server::UnaryService for SetClipNameSvc { type Response = super::Empty; - type Future = BoxFuture< - tonic::Response, - tonic::Status, - >; + type Future = BoxFuture, tonic::Status>; fn call( &mut self, request: tonic::Request, ) -> Self::Future { let inner = self.0.clone(); - let fut = async move { - (*inner).set_clip_name(request).await - }; + let fut = async move { (*inner).set_clip_name(request).await }; Box::pin(fut) } } @@ -2194,11 +1978,10 @@ pub mod clip_engine_server { let inner = inner.0; let method = SetClipNameSvc(inner); let codec = tonic::codec::ProstCodec::default(); - let mut grpc = tonic::server::Grpc::new(codec) - .apply_compression_config( - accept_compression_encodings, - send_compression_encodings, - ); + let mut grpc = tonic::server::Grpc::new(codec).apply_compression_config( + accept_compression_encodings, + send_compression_encodings, + ); let res = grpc.unary(method, req).await; Ok(res) }; @@ -2207,23 +1990,15 @@ pub mod clip_engine_server { "/playtime.clip_engine.ClipEngine/SetClipData" => { #[allow(non_camel_case_types)] struct SetClipDataSvc(pub Arc); - impl< - T: ClipEngine, - > tonic::server::UnaryService - for SetClipDataSvc { + impl tonic::server::UnaryService for SetClipDataSvc { type Response = super::Empty; - type Future = BoxFuture< - tonic::Response, - tonic::Status, - >; + type Future = BoxFuture, tonic::Status>; fn call( &mut self, request: tonic::Request, ) -> Self::Future { let inner = self.0.clone(); - let fut = async move { - (*inner).set_clip_data(request).await - }; + let fut = async move { (*inner).set_clip_data(request).await }; Box::pin(fut) } } @@ -2234,11 +2009,10 @@ pub mod clip_engine_server { let inner = inner.0; let method = SetClipDataSvc(inner); let codec = tonic::codec::ProstCodec::default(); - let mut grpc = tonic::server::Grpc::new(codec) - .apply_compression_config( - accept_compression_encodings, - send_compression_encodings, - ); + let mut grpc = tonic::server::Grpc::new(codec).apply_compression_config( + accept_compression_encodings, + send_compression_encodings, + ); let res = grpc.unary(method, req).await; Ok(res) }; @@ -2247,23 +2021,17 @@ pub mod clip_engine_server { "/playtime.clip_engine.ClipEngine/GetClipDetail" => { #[allow(non_camel_case_types)] struct GetClipDetailSvc(pub Arc); - impl< - T: ClipEngine, - > tonic::server::UnaryService - for GetClipDetailSvc { + impl tonic::server::UnaryService + for GetClipDetailSvc + { type Response = super::GetClipDetailReply; - type Future = BoxFuture< - tonic::Response, - tonic::Status, - >; + type Future = BoxFuture, tonic::Status>; fn call( &mut self, request: tonic::Request, ) -> Self::Future { let inner = self.0.clone(); - let fut = async move { - (*inner).get_clip_detail(request).await - }; + let fut = async move { (*inner).get_clip_detail(request).await }; Box::pin(fut) } } @@ -2274,11 +2042,10 @@ pub mod clip_engine_server { let inner = inner.0; let method = GetClipDetailSvc(inner); let codec = tonic::codec::ProstCodec::default(); - let mut grpc = tonic::server::Grpc::new(codec) - .apply_compression_config( - accept_compression_encodings, - send_compression_encodings, - ); + let mut grpc = tonic::server::Grpc::new(codec).apply_compression_config( + accept_compression_encodings, + send_compression_encodings, + ); let res = grpc.unary(method, req).await; Ok(res) }; @@ -2287,22 +2054,18 @@ pub mod clip_engine_server { "/playtime.clip_engine.ClipEngine/GetOccasionalMatrixUpdates" => { #[allow(non_camel_case_types)] struct GetOccasionalMatrixUpdatesSvc(pub Arc); - impl< - T: ClipEngine, - > tonic::server::ServerStreamingService< - super::GetOccasionalMatrixUpdatesRequest, - > for GetOccasionalMatrixUpdatesSvc { + impl + tonic::server::ServerStreamingService< + super::GetOccasionalMatrixUpdatesRequest, + > for GetOccasionalMatrixUpdatesSvc + { type Response = super::GetOccasionalMatrixUpdatesReply; type ResponseStream = T::GetOccasionalMatrixUpdatesStream; - type Future = BoxFuture< - tonic::Response, - tonic::Status, - >; + type Future = + BoxFuture, tonic::Status>; fn call( &mut self, - request: tonic::Request< - super::GetOccasionalMatrixUpdatesRequest, - >, + request: tonic::Request, ) -> Self::Future { let inner = self.0.clone(); let fut = async move { @@ -2318,11 +2081,10 @@ pub mod clip_engine_server { let inner = inner.0; let method = GetOccasionalMatrixUpdatesSvc(inner); let codec = tonic::codec::ProstCodec::default(); - let mut grpc = tonic::server::Grpc::new(codec) - .apply_compression_config( - accept_compression_encodings, - send_compression_encodings, - ); + let mut grpc = tonic::server::Grpc::new(codec).apply_compression_config( + accept_compression_encodings, + send_compression_encodings, + ); let res = grpc.server_streaming(method, req).await; Ok(res) }; @@ -2331,22 +2093,18 @@ pub mod clip_engine_server { "/playtime.clip_engine.ClipEngine/GetContinuousMatrixUpdates" => { #[allow(non_camel_case_types)] struct GetContinuousMatrixUpdatesSvc(pub Arc); - impl< - T: ClipEngine, - > tonic::server::ServerStreamingService< - super::GetContinuousMatrixUpdatesRequest, - > for GetContinuousMatrixUpdatesSvc { + impl + tonic::server::ServerStreamingService< + super::GetContinuousMatrixUpdatesRequest, + > for GetContinuousMatrixUpdatesSvc + { type Response = super::GetContinuousMatrixUpdatesReply; type ResponseStream = T::GetContinuousMatrixUpdatesStream; - type Future = BoxFuture< - tonic::Response, - tonic::Status, - >; + type Future = + BoxFuture, tonic::Status>; fn call( &mut self, - request: tonic::Request< - super::GetContinuousMatrixUpdatesRequest, - >, + request: tonic::Request, ) -> Self::Future { let inner = self.0.clone(); let fut = async move { @@ -2362,11 +2120,10 @@ pub mod clip_engine_server { let inner = inner.0; let method = GetContinuousMatrixUpdatesSvc(inner); let codec = tonic::codec::ProstCodec::default(); - let mut grpc = tonic::server::Grpc::new(codec) - .apply_compression_config( - accept_compression_encodings, - send_compression_encodings, - ); + let mut grpc = tonic::server::Grpc::new(codec).apply_compression_config( + accept_compression_encodings, + send_compression_encodings, + ); let res = grpc.server_streaming(method, req).await; Ok(res) }; @@ -2375,22 +2132,18 @@ pub mod clip_engine_server { "/playtime.clip_engine.ClipEngine/GetOccasionalColumnUpdates" => { #[allow(non_camel_case_types)] struct GetOccasionalColumnUpdatesSvc(pub Arc); - impl< - T: ClipEngine, - > tonic::server::ServerStreamingService< - super::GetOccasionalColumnUpdatesRequest, - > for GetOccasionalColumnUpdatesSvc { + impl + tonic::server::ServerStreamingService< + super::GetOccasionalColumnUpdatesRequest, + > for GetOccasionalColumnUpdatesSvc + { type Response = super::GetOccasionalColumnUpdatesReply; type ResponseStream = T::GetOccasionalColumnUpdatesStream; - type Future = BoxFuture< - tonic::Response, - tonic::Status, - >; + type Future = + BoxFuture, tonic::Status>; fn call( &mut self, - request: tonic::Request< - super::GetOccasionalColumnUpdatesRequest, - >, + request: tonic::Request, ) -> Self::Future { let inner = self.0.clone(); let fut = async move { @@ -2406,11 +2159,10 @@ pub mod clip_engine_server { let inner = inner.0; let method = GetOccasionalColumnUpdatesSvc(inner); let codec = tonic::codec::ProstCodec::default(); - let mut grpc = tonic::server::Grpc::new(codec) - .apply_compression_config( - accept_compression_encodings, - send_compression_encodings, - ); + let mut grpc = tonic::server::Grpc::new(codec).apply_compression_config( + accept_compression_encodings, + send_compression_encodings, + ); let res = grpc.server_streaming(method, req).await; Ok(res) }; @@ -2419,22 +2171,18 @@ pub mod clip_engine_server { "/playtime.clip_engine.ClipEngine/GetContinuousColumnUpdates" => { #[allow(non_camel_case_types)] struct GetContinuousColumnUpdatesSvc(pub Arc); - impl< - T: ClipEngine, - > tonic::server::ServerStreamingService< - super::GetContinuousColumnUpdatesRequest, - > for GetContinuousColumnUpdatesSvc { + impl + tonic::server::ServerStreamingService< + super::GetContinuousColumnUpdatesRequest, + > for GetContinuousColumnUpdatesSvc + { type Response = super::GetContinuousColumnUpdatesReply; type ResponseStream = T::GetContinuousColumnUpdatesStream; - type Future = BoxFuture< - tonic::Response, - tonic::Status, - >; + type Future = + BoxFuture, tonic::Status>; fn call( &mut self, - request: tonic::Request< - super::GetContinuousColumnUpdatesRequest, - >, + request: tonic::Request, ) -> Self::Future { let inner = self.0.clone(); let fut = async move { @@ -2450,11 +2198,10 @@ pub mod clip_engine_server { let inner = inner.0; let method = GetContinuousColumnUpdatesSvc(inner); let codec = tonic::codec::ProstCodec::default(); - let mut grpc = tonic::server::Grpc::new(codec) - .apply_compression_config( - accept_compression_encodings, - send_compression_encodings, - ); + let mut grpc = tonic::server::Grpc::new(codec).apply_compression_config( + accept_compression_encodings, + send_compression_encodings, + ); let res = grpc.server_streaming(method, req).await; Ok(res) }; @@ -2463,27 +2210,21 @@ pub mod clip_engine_server { "/playtime.clip_engine.ClipEngine/GetOccasionalRowUpdates" => { #[allow(non_camel_case_types)] struct GetOccasionalRowUpdatesSvc(pub Arc); - impl< - T: ClipEngine, - > tonic::server::ServerStreamingService< - super::GetOccasionalRowUpdatesRequest, - > for GetOccasionalRowUpdatesSvc { + impl + tonic::server::ServerStreamingService + for GetOccasionalRowUpdatesSvc + { type Response = super::GetOccasionalRowUpdatesReply; type ResponseStream = T::GetOccasionalRowUpdatesStream; - type Future = BoxFuture< - tonic::Response, - tonic::Status, - >; + type Future = + BoxFuture, tonic::Status>; fn call( &mut self, - request: tonic::Request< - super::GetOccasionalRowUpdatesRequest, - >, + request: tonic::Request, ) -> Self::Future { let inner = self.0.clone(); - let fut = async move { - (*inner).get_occasional_row_updates(request).await - }; + let fut = + async move { (*inner).get_occasional_row_updates(request).await }; Box::pin(fut) } } @@ -2494,11 +2235,10 @@ pub mod clip_engine_server { let inner = inner.0; let method = GetOccasionalRowUpdatesSvc(inner); let codec = tonic::codec::ProstCodec::default(); - let mut grpc = tonic::server::Grpc::new(codec) - .apply_compression_config( - accept_compression_encodings, - send_compression_encodings, - ); + let mut grpc = tonic::server::Grpc::new(codec).apply_compression_config( + accept_compression_encodings, + send_compression_encodings, + ); let res = grpc.server_streaming(method, req).await; Ok(res) }; @@ -2507,27 +2247,22 @@ pub mod clip_engine_server { "/playtime.clip_engine.ClipEngine/GetOccasionalSlotUpdates" => { #[allow(non_camel_case_types)] struct GetOccasionalSlotUpdatesSvc(pub Arc); - impl< - T: ClipEngine, - > tonic::server::ServerStreamingService< - super::GetOccasionalSlotUpdatesRequest, - > for GetOccasionalSlotUpdatesSvc { + impl + tonic::server::ServerStreamingService< + super::GetOccasionalSlotUpdatesRequest, + > for GetOccasionalSlotUpdatesSvc + { type Response = super::GetOccasionalSlotUpdatesReply; type ResponseStream = T::GetOccasionalSlotUpdatesStream; - type Future = BoxFuture< - tonic::Response, - tonic::Status, - >; + type Future = + BoxFuture, tonic::Status>; fn call( &mut self, - request: tonic::Request< - super::GetOccasionalSlotUpdatesRequest, - >, + request: tonic::Request, ) -> Self::Future { let inner = self.0.clone(); - let fut = async move { - (*inner).get_occasional_slot_updates(request).await - }; + let fut = + async move { (*inner).get_occasional_slot_updates(request).await }; Box::pin(fut) } } @@ -2538,11 +2273,10 @@ pub mod clip_engine_server { let inner = inner.0; let method = GetOccasionalSlotUpdatesSvc(inner); let codec = tonic::codec::ProstCodec::default(); - let mut grpc = tonic::server::Grpc::new(codec) - .apply_compression_config( - accept_compression_encodings, - send_compression_encodings, - ); + let mut grpc = tonic::server::Grpc::new(codec).apply_compression_config( + accept_compression_encodings, + send_compression_encodings, + ); let res = grpc.server_streaming(method, req).await; Ok(res) }; @@ -2551,27 +2285,22 @@ pub mod clip_engine_server { "/playtime.clip_engine.ClipEngine/GetContinuousSlotUpdates" => { #[allow(non_camel_case_types)] struct GetContinuousSlotUpdatesSvc(pub Arc); - impl< - T: ClipEngine, - > tonic::server::ServerStreamingService< - super::GetContinuousSlotUpdatesRequest, - > for GetContinuousSlotUpdatesSvc { + impl + tonic::server::ServerStreamingService< + super::GetContinuousSlotUpdatesRequest, + > for GetContinuousSlotUpdatesSvc + { type Response = super::GetContinuousSlotUpdatesReply; type ResponseStream = T::GetContinuousSlotUpdatesStream; - type Future = BoxFuture< - tonic::Response, - tonic::Status, - >; + type Future = + BoxFuture, tonic::Status>; fn call( &mut self, - request: tonic::Request< - super::GetContinuousSlotUpdatesRequest, - >, + request: tonic::Request, ) -> Self::Future { let inner = self.0.clone(); - let fut = async move { - (*inner).get_continuous_slot_updates(request).await - }; + let fut = + async move { (*inner).get_continuous_slot_updates(request).await }; Box::pin(fut) } } @@ -2582,11 +2311,10 @@ pub mod clip_engine_server { let inner = inner.0; let method = GetContinuousSlotUpdatesSvc(inner); let codec = tonic::codec::ProstCodec::default(); - let mut grpc = tonic::server::Grpc::new(codec) - .apply_compression_config( - accept_compression_encodings, - send_compression_encodings, - ); + let mut grpc = tonic::server::Grpc::new(codec).apply_compression_config( + accept_compression_encodings, + send_compression_encodings, + ); let res = grpc.server_streaming(method, req).await; Ok(res) }; @@ -2595,27 +2323,22 @@ pub mod clip_engine_server { "/playtime.clip_engine.ClipEngine/GetOccasionalClipUpdates" => { #[allow(non_camel_case_types)] struct GetOccasionalClipUpdatesSvc(pub Arc); - impl< - T: ClipEngine, - > tonic::server::ServerStreamingService< - super::GetOccasionalClipUpdatesRequest, - > for GetOccasionalClipUpdatesSvc { + impl + tonic::server::ServerStreamingService< + super::GetOccasionalClipUpdatesRequest, + > for GetOccasionalClipUpdatesSvc + { type Response = super::GetOccasionalClipUpdatesReply; type ResponseStream = T::GetOccasionalClipUpdatesStream; - type Future = BoxFuture< - tonic::Response, - tonic::Status, - >; + type Future = + BoxFuture, tonic::Status>; fn call( &mut self, - request: tonic::Request< - super::GetOccasionalClipUpdatesRequest, - >, + request: tonic::Request, ) -> Self::Future { let inner = self.0.clone(); - let fut = async move { - (*inner).get_occasional_clip_updates(request).await - }; + let fut = + async move { (*inner).get_occasional_clip_updates(request).await }; Box::pin(fut) } } @@ -2626,11 +2349,10 @@ pub mod clip_engine_server { let inner = inner.0; let method = GetOccasionalClipUpdatesSvc(inner); let codec = tonic::codec::ProstCodec::default(); - let mut grpc = tonic::server::Grpc::new(codec) - .apply_compression_config( - accept_compression_encodings, - send_compression_encodings, - ); + let mut grpc = tonic::server::Grpc::new(codec).apply_compression_config( + accept_compression_encodings, + send_compression_encodings, + ); let res = grpc.server_streaming(method, req).await; Ok(res) }; @@ -2639,27 +2361,22 @@ pub mod clip_engine_server { "/playtime.clip_engine.ClipEngine/GetOccasionalTrackUpdates" => { #[allow(non_camel_case_types)] struct GetOccasionalTrackUpdatesSvc(pub Arc); - impl< - T: ClipEngine, - > tonic::server::ServerStreamingService< - super::GetOccasionalTrackUpdatesRequest, - > for GetOccasionalTrackUpdatesSvc { + impl + tonic::server::ServerStreamingService< + super::GetOccasionalTrackUpdatesRequest, + > for GetOccasionalTrackUpdatesSvc + { type Response = super::GetOccasionalTrackUpdatesReply; type ResponseStream = T::GetOccasionalTrackUpdatesStream; - type Future = BoxFuture< - tonic::Response, - tonic::Status, - >; + type Future = + BoxFuture, tonic::Status>; fn call( &mut self, - request: tonic::Request< - super::GetOccasionalTrackUpdatesRequest, - >, + request: tonic::Request, ) -> Self::Future { let inner = self.0.clone(); - let fut = async move { - (*inner).get_occasional_track_updates(request).await - }; + let fut = + async move { (*inner).get_occasional_track_updates(request).await }; Box::pin(fut) } } @@ -2670,28 +2387,23 @@ pub mod clip_engine_server { let inner = inner.0; let method = GetOccasionalTrackUpdatesSvc(inner); let codec = tonic::codec::ProstCodec::default(); - let mut grpc = tonic::server::Grpc::new(codec) - .apply_compression_config( - accept_compression_encodings, - send_compression_encodings, - ); + let mut grpc = tonic::server::Grpc::new(codec).apply_compression_config( + accept_compression_encodings, + send_compression_encodings, + ); let res = grpc.server_streaming(method, req).await; Ok(res) }; Box::pin(fut) } - _ => { - Box::pin(async move { - Ok( - http::Response::builder() - .status(200) - .header("grpc-status", "12") - .header("content-type", "application/grpc") - .body(empty_body()) - .unwrap(), - ) - }) - } + _ => Box::pin(async move { + Ok(http::Response::builder() + .status(200) + .header("grpc-status", "12") + .header("content-type", "application/grpc") + .body(empty_body()) + .unwrap()) + }), } } } diff --git a/playtime-clip-engine/src/proto/hub.rs b/playtime-clip-engine/src/proto/hub.rs index b79d094b7..7f1a13343 100644 --- a/playtime-clip-engine/src/proto/hub.rs +++ b/playtime-clip-engine/src/proto/hub.rs @@ -1,4 +1,5 @@ use crate::base::{ClipMatrixEvent, Matrix}; +use crate::proto::clip_engine_server::ClipEngineServer; use crate::proto::senders::{ ClipEngineSenders, ContinuousColumnUpdateBatch, ContinuousMatrixUpdateBatch, ContinuousSlotUpdateBatch, OccasionalClipUpdateBatch, OccasionalColumnUpdateBatch, @@ -30,6 +31,12 @@ pub struct ClipEngineHub { senders: ClipEngineSenders, } +impl Default for ClipEngineHub { + fn default() -> Self { + Self::new() + } +} + impl ClipEngineHub { pub fn new() -> Self { Self { @@ -37,8 +44,14 @@ impl ClipEngineHub { } } - pub fn create_service(&self, matrix_provider: P) -> ClipEngineService

{ - ClipEngineService::new(matrix_provider, self.senders.clone()) + pub fn create_service( + &self, + matrix_provider: P, + ) -> ClipEngineServer> { + ClipEngineServer::new(ClipEngineService::new( + matrix_provider, + self.senders.clone(), + )) } pub fn clip_matrix_changed( diff --git a/playtime-clip-engine/src/rt/audio_hook.rs b/playtime-clip-engine/src/rt/audio_hook.rs index 5fe7fbeb2..16112d48e 100644 --- a/playtime-clip-engine/src/rt/audio_hook.rs +++ b/playtime-clip-engine/src/rt/audio_hook.rs @@ -10,16 +10,14 @@ use reaper_high::{MidiInputDevice, Reaper}; use reaper_medium::{AudioHookRegister, MidiInputDeviceId}; use std::sync::MutexGuard; -#[derive(Debug)] +#[derive(Debug, Default)] pub struct ClipEngineAudioHook { clip_record_task: Option, } impl ClipEngineAudioHook { pub fn new() -> Self { - Self { - clip_record_task: None, - } + Self::default() } } diff --git a/playtime-clip-engine/src/rt/fx_hook.rs b/playtime-clip-engine/src/rt/fx_hook.rs index dbe419c6d..6472565a0 100644 --- a/playtime-clip-engine/src/rt/fx_hook.rs +++ b/playtime-clip-engine/src/rt/fx_hook.rs @@ -2,16 +2,14 @@ use crate::rt::audio_hook::FxInputClipRecordTask; use crate::rt::supplier::WriteAudioRequest; use crate::rt::{AudioBuf, BasicAudioRequestProps}; -#[derive(Debug)] +#[derive(Debug, Default)] pub struct ClipEngineFxHook { clip_record_task: Option, } impl ClipEngineFxHook { pub fn new() -> Self { - Self { - clip_record_task: None, - } + Self::default() } pub fn start_clip_recording(&mut self, task: FxInputClipRecordTask) { diff --git a/playtime-clip-engine/src/rt/rt_clip.rs b/playtime-clip-engine/src/rt/rt_clip.rs index 7103ffd98..527512f84 100644 --- a/playtime-clip-engine/src/rt/rt_clip.rs +++ b/playtime-clip-engine/src/rt/rt_clip.rs @@ -8,11 +8,11 @@ use crate::rt::schedule_util::calc_distance_from_quantized_pos; use crate::rt::supplier::{ AudioSupplier, ChainEquipment, ChainSettings, CompleteRecordingData, KindSpecificRecordingOutcome, MaterialInfo, MidiOverdubOutcome, MidiOverdubSettings, - MidiSequence, MidiSupplier, PollRecordingOutcome, RecordState, Recorder, - RecorderRequest, RecordingArgs, RecordingEquipment, RecordingOutcome, RtClipSource, - StopRecordingOutcome, SupplierChain, SupplyAudioRequest, SupplyMidiRequest, - SupplyRequestGeneralInfo, SupplyRequestInfo, SupplyResponse, SupplyResponseStatus, - WithMaterialInfo, WriteAudioRequest, WriteMidiRequest, MIDI_BASE_BPM, MIDI_FRAME_RATE, + MidiSequence, MidiSupplier, PollRecordingOutcome, RecordState, Recorder, RecorderRequest, + RecordingArgs, RecordingEquipment, RecordingOutcome, RtClipSource, StopRecordingOutcome, + SupplierChain, SupplyAudioRequest, SupplyMidiRequest, SupplyRequestGeneralInfo, + SupplyRequestInfo, SupplyResponse, SupplyResponseStatus, WithMaterialInfo, WriteAudioRequest, + WriteMidiRequest, MIDI_BASE_BPM, MIDI_FRAME_RATE, }; use crate::rt::tempo_util::{calc_tempo_factor, determine_tempo_from_time_base}; use crate::rt::{OverridableMatrixSettings, RtClips, RtColumnEvent, RtColumnSettings}; diff --git a/playtime-clip-engine/src/rt/rt_column.rs b/playtime-clip-engine/src/rt/rt_column.rs index 0b4b6de6d..292ca673e 100644 --- a/playtime-clip-engine/src/rt/rt_column.rs +++ b/playtime-clip-engine/src/rt/rt_column.rs @@ -859,7 +859,7 @@ impl RtColumn { .dispose(RtColumnGarbage::LoadSlotArgs(boxed_args)); } LoadClip(mut boxed_args) => { - self.load_clip(&mut *boxed_args).unwrap(); + self.load_clip(&mut boxed_args).unwrap(); self.event_sender .dispose(RtColumnGarbage::LoadClipArgs(boxed_args)); } diff --git a/playtime-clip-engine/src/rt/supplier/chain.rs b/playtime-clip-engine/src/rt/supplier/chain.rs index 193192438..8ad5ac20c 100644 --- a/playtime-clip-engine/src/rt/supplier/chain.rs +++ b/playtime-clip-engine/src/rt/supplier/chain.rs @@ -6,9 +6,9 @@ use crate::rt::supplier::{ InteractionHandler, LoopBehavior, Looper, MaterialInfo, MidiNoteTracker, MidiOverdubOutcome, MidiOverdubSettings, MidiSequence, PollRecordingOutcome, PositionTranslationSkill, PreBuffer, PreBufferCacheMissBehavior, PreBufferFillRequest, PreBufferOptions, PreBufferRequest, - PreBufferSourceSkill, RecordState, Recorder, RecordingArgs, Resampler, - RtClipSource, Section, SectionBounds, StartEndHandler, StopRecordingOutcome, TimeStretcher, - WithMaterialInfo, WithSupplier, WriteAudioRequest, WriteMidiRequest, + PreBufferSourceSkill, RecordState, Recorder, RecordingArgs, Resampler, RtClipSource, Section, + SectionBounds, StartEndHandler, StopRecordingOutcome, TimeStretcher, WithMaterialInfo, + WithSupplier, WriteAudioRequest, WriteMidiRequest, }; use crate::rt::tempo_util::determine_tempo_from_beat_time_base; use crate::rt::BasicAudioRequestProps; diff --git a/playtime-clip-engine/src/rt/supplier/downbeat.rs b/playtime-clip-engine/src/rt/supplier/downbeat.rs index ebf8f2e98..30731c0ac 100644 --- a/playtime-clip-engine/src/rt/supplier/downbeat.rs +++ b/playtime-clip-engine/src/rt/supplier/downbeat.rs @@ -1,9 +1,10 @@ use crate::conversion_util::convert_duration_in_seconds_to_frames; use crate::rt::buffer::AudioBufMut; use crate::rt::supplier::{ - AudioSupplier, AutoDelegatingMidiSilencer, AutoDelegatingWithMaterialInfo, MaterialInfo, MidiSupplier, PositionTranslationSkill, PreBufferFillRequest, - PreBufferSourceSkill, SupplyAudioRequest, SupplyMidiRequest, SupplyRequest, SupplyRequestInfo, - SupplyResponse, WithMaterialInfo, WithSupplier, + AudioSupplier, AutoDelegatingMidiSilencer, AutoDelegatingWithMaterialInfo, MaterialInfo, + MidiSupplier, PositionTranslationSkill, PreBufferFillRequest, PreBufferSourceSkill, + SupplyAudioRequest, SupplyMidiRequest, SupplyRequest, SupplyRequestInfo, SupplyResponse, + WithMaterialInfo, WithSupplier, }; use playtime_api::persistence::PositiveBeat; diff --git a/playtime-clip-engine/src/rt/supplier/interaction_handler.rs b/playtime-clip-engine/src/rt/supplier/interaction_handler.rs index 0afaf4d5f..76a965faf 100644 --- a/playtime-clip-engine/src/rt/supplier/interaction_handler.rs +++ b/playtime-clip-engine/src/rt/supplier/interaction_handler.rs @@ -5,14 +5,13 @@ use crate::rt::supplier::fade_util::{ use crate::rt::supplier::midi_util::SilenceMidiBlockMode; use crate::rt::supplier::{ midi_util, AudioSupplier, AutoDelegatingPositionTranslationSkill, - AutoDelegatingPreBufferSourceSkill, AutoDelegatingWithMaterialInfo, MidiSilencer, - MidiSupplier, + AutoDelegatingPreBufferSourceSkill, AutoDelegatingWithMaterialInfo, MidiSilencer, MidiSupplier, SupplyAudioRequest, SupplyMidiRequest, SupplyRequestInfo, SupplyResponse, SupplyResponseStatus, WithMaterialInfo, WithSupplier, }; use crate::ClipEngineResult; use playtime_api::persistence::MidiResetMessageRange; -use reaper_medium::{BorrowedMidiEventList}; +use reaper_medium::BorrowedMidiEventList; use std::cmp; use std::fmt::Debug; diff --git a/playtime-clip-engine/src/rt/supplier/looper.rs b/playtime-clip-engine/src/rt/supplier/looper.rs index 58d894793..313804d31 100644 --- a/playtime-clip-engine/src/rt/supplier/looper.rs +++ b/playtime-clip-engine/src/rt/supplier/looper.rs @@ -1,13 +1,14 @@ use crate::rt::buffer::AudioBufMut; use crate::rt::supplier::midi_util::SilenceMidiBlockMode; use crate::rt::supplier::{ - midi_util, AudioSupplier, AutoDelegatingMidiSilencer, AutoDelegatingWithMaterialInfo, MidiSilencer, MidiSupplier, PositionTranslationSkill, SupplyAudioRequest, - SupplyMidiRequest, SupplyRequest, SupplyRequestInfo, SupplyResponse, SupplyResponseStatus, - WithMaterialInfo, WithSupplier, + midi_util, AudioSupplier, AutoDelegatingMidiSilencer, AutoDelegatingWithMaterialInfo, + MidiSilencer, MidiSupplier, PositionTranslationSkill, SupplyAudioRequest, SupplyMidiRequest, + SupplyRequest, SupplyRequestInfo, SupplyResponse, SupplyResponseStatus, WithMaterialInfo, + WithSupplier, }; use crate::ClipEngineResult; use playtime_api::persistence::MidiResetMessageRange; -use reaper_medium::{BorrowedMidiEventList}; +use reaper_medium::BorrowedMidiEventList; #[derive(Debug)] pub struct Looper { diff --git a/playtime-clip-engine/src/rt/supplier/midi_note_tracker.rs b/playtime-clip-engine/src/rt/supplier/midi_note_tracker.rs index 8f4247234..6ad01fd41 100644 --- a/playtime-clip-engine/src/rt/supplier/midi_note_tracker.rs +++ b/playtime-clip-engine/src/rt/supplier/midi_note_tracker.rs @@ -1,23 +1,14 @@ - - - - - - use crate::rt::supplier::{ - AutoDelegatingAudioSupplier, - AutoDelegatingPositionTranslationSkill, AutoDelegatingWithMaterialInfo, MidiSilencer, MidiSupplier, - SupplyMidiRequest, SupplyResponse, WithSupplier, + AutoDelegatingAudioSupplier, AutoDelegatingPositionTranslationSkill, + AutoDelegatingWithMaterialInfo, MidiSilencer, MidiSupplier, SupplyMidiRequest, SupplyResponse, + WithSupplier, }; use helgoboss_midi::{ Channel, KeyNumber, RawShortMessage, ShortMessage, ShortMessageFactory, StructuredShortMessage, U7, }; -use reaper_medium::{ - BorrowedMidiEventList, MidiEvent, - MidiFrameOffset, -}; +use reaper_medium::{BorrowedMidiEventList, MidiEvent, MidiFrameOffset}; use std::fmt::Debug; #[derive(Clone, Debug)] diff --git a/playtime-clip-engine/src/rt/supplier/pre_buffer.rs b/playtime-clip-engine/src/rt/supplier/pre_buffer.rs index 82b2688cf..11ffbabc3 100644 --- a/playtime-clip-engine/src/rt/supplier/pre_buffer.rs +++ b/playtime-clip-engine/src/rt/supplier/pre_buffer.rs @@ -1,8 +1,9 @@ use crate::rt::buffer::{AudioBufMut, OwnedAudioBuffer}; use crate::rt::supplier::{ AudioMaterialInfo, AudioSupplier, AutoDelegatingMidiSilencer, AutoDelegatingMidiSupplier, - AutoDelegatingPositionTranslationSkill, MaterialInfo, PreBufferFillRequest, PreBufferSourceSkill, SupplyAudioRequest, SupplyRequestInfo, SupplyResponse, SupplyResponseStatus, WithMaterialInfo, - WithSupplier, + AutoDelegatingPositionTranslationSkill, MaterialInfo, PreBufferFillRequest, + PreBufferSourceSkill, SupplyAudioRequest, SupplyRequestInfo, SupplyResponse, + SupplyResponseStatus, WithMaterialInfo, WithSupplier, }; use crate::ClipEngineResult; use core::cmp; diff --git a/playtime-clip-engine/src/rt/supplier/resampler.rs b/playtime-clip-engine/src/rt/supplier/resampler.rs index 151279f16..cbf760023 100644 --- a/playtime-clip-engine/src/rt/supplier/resampler.rs +++ b/playtime-clip-engine/src/rt/supplier/resampler.rs @@ -2,12 +2,10 @@ use crate::conversion_util::adjust_proportionally_positive; use crate::rt::buffer::AudioBufMut; use crate::rt::supplier::{ AudioSupplier, AutoDelegatingPositionTranslationSkill, AutoDelegatingPreBufferSourceSkill, - AutoDelegatingWithMaterialInfo, SupplyAudioRequest, - SupplyResponse, SupplyResponseStatus, WithMaterialInfo, WithSupplier, MIDI_FRAME_RATE, -}; -use crate::rt::supplier::{ - MidiSupplier, SupplyMidiRequest, SupplyRequestInfo, + AutoDelegatingWithMaterialInfo, SupplyAudioRequest, SupplyResponse, SupplyResponseStatus, + WithMaterialInfo, WithSupplier, MIDI_FRAME_RATE, }; +use crate::rt::supplier::{MidiSupplier, SupplyMidiRequest, SupplyRequestInfo}; use playtime_api::persistence::VirtualResampleMode; use reaper_high::Reaper; diff --git a/playtime-clip-engine/src/rt/supplier/start_end_handler.rs b/playtime-clip-engine/src/rt/supplier/start_end_handler.rs index d295b671a..d4b0ab42d 100644 --- a/playtime-clip-engine/src/rt/supplier/start_end_handler.rs +++ b/playtime-clip-engine/src/rt/supplier/start_end_handler.rs @@ -5,12 +5,12 @@ use crate::rt::supplier::fade_util::{ use crate::rt::supplier::midi_util::SilenceMidiBlockMode; use crate::rt::supplier::{ midi_util, AudioSupplier, AutoDelegatingMidiSilencer, AutoDelegatingPositionTranslationSkill, - AutoDelegatingWithMaterialInfo, MidiSilencer, MidiSupplier, SupplyAudioRequest, SupplyMidiRequest, SupplyResponse, - WithMaterialInfo, WithSupplier, + AutoDelegatingWithMaterialInfo, MidiSilencer, MidiSupplier, SupplyAudioRequest, + SupplyMidiRequest, SupplyResponse, WithMaterialInfo, WithSupplier, }; use playtime_api::persistence::MidiResetMessageRange; -use reaper_medium::{BorrowedMidiEventList}; +use reaper_medium::BorrowedMidiEventList; #[derive(Debug)] pub struct StartEndHandler { diff --git a/playtime-clip-engine/src/rt/supplier/time_stretcher.rs b/playtime-clip-engine/src/rt/supplier/time_stretcher.rs index c521de049..5d97128d9 100644 --- a/playtime-clip-engine/src/rt/supplier/time_stretcher.rs +++ b/playtime-clip-engine/src/rt/supplier/time_stretcher.rs @@ -1,18 +1,16 @@ use crate::rt::buffer::AudioBufMut; +use crate::rt::supplier::SupplyRequestInfo; use crate::rt::supplier::{ AudioSupplier, AutoDelegatingMidiSilencer, AutoDelegatingMidiSupplier, AutoDelegatingPositionTranslationSkill, AutoDelegatingPreBufferSourceSkill, - AutoDelegatingWithMaterialInfo, - SupplyAudioRequest, SupplyResponse, SupplyResponseStatus, WithMaterialInfo, WithSupplier, -}; -use crate::rt::supplier::{ - SupplyRequestInfo, + AutoDelegatingWithMaterialInfo, SupplyAudioRequest, SupplyResponse, SupplyResponseStatus, + WithMaterialInfo, WithSupplier, }; use playtime_api::persistence::VirtualTimeStretchMode; use reaper_high::Reaper; use reaper_low::raw::REAPER_PITCHSHIFT_API_VER; -use reaper_medium::{OwnedReaperPitchShift}; +use reaper_medium::OwnedReaperPitchShift; #[derive(Debug)] pub struct TimeStretcher {