Skip to content

Commit

Permalink
Playtime: Make undo not interrupt playing clips
Browse files Browse the repository at this point in the history
  • Loading branch information
helgoboss committed Jun 9, 2023
1 parent 9d742cc commit e6bc0ab
Show file tree
Hide file tree
Showing 14 changed files with 335 additions and 237 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 3 additions & 1 deletion main/src/infrastructure/data/clip_legacy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ pub(super) fn create_clip_matrix_from_legacy_slots(
let output =
determine_legacy_clip_track(desc.index, main_mappings, controller_mappings);
let api_column = api::Column {
id: Default::default(),
clip_play_settings: api::ColumnClipPlaySettings {
track: output
.resolve_track(containing_track.cloned())?
Expand All @@ -33,7 +34,7 @@ pub(super) fn create_clip_matrix_from_legacy_slots(
clip_record_settings: Default::default(),
slots: {
let api_clip = api::Clip {
id: None,
id: Default::default(),
name: None,
source: match desc.descriptor.content.clone() {
ClipContent::File { file } => {
Expand All @@ -59,6 +60,7 @@ pub(super) fn create_clip_matrix_from_legacy_slots(
midi_settings: Default::default(),
};
let api_slot = api::Slot {
id: Default::default(),
// In the previous clip system, we had only one dimension.
row: 0,
clip_old: None,
Expand Down
2 changes: 1 addition & 1 deletion main/src/infrastructure/ui/main_panel.rs
Original file line number Diff line number Diff line change
Expand Up @@ -931,7 +931,7 @@ fn get_track_peaks(track: &Track) -> Vec<f64> {
// TODO-high-clip-engine CONTINUE Respect solo (same as a recent ReaLearn issue)
(0..channel_count)
.map(|ch| {
let volume = unsafe { reaper.track_get_peak_info(track, ch as u32 + 1024) };
let volume = unsafe { reaper.track_get_peak_info(track, ch as u32) };
volume.get()
})
.collect()
Expand Down
4 changes: 3 additions & 1 deletion playtime-api/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,6 @@ serde.workspace = true
# TODO-medium Actually not necessary anymore because we generate Dart directly now.
schemars.workspace = true
# For being able to use various attributes that can help in Rust-to-Dart code generation
realearn-macros.workspace = true
realearn-macros.workspace = true
# For generating random IDs
nanoid.workspace = true
55 changes: 52 additions & 3 deletions playtime-api/src/persistence/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -520,8 +520,55 @@ impl EvenQuantization {
}
}

#[derive(Clone, Eq, PartialEq, Hash, Debug, Serialize, Deserialize, JsonSchema)]
pub struct ColumnId(String);

impl ColumnId {
pub fn random() -> Self {
Default::default()
}
}

impl Default for ColumnId {
fn default() -> Self {
Self(nanoid::nanoid!())
}
}

#[derive(Clone, Eq, PartialEq, Hash, Debug, Serialize, Deserialize, JsonSchema)]
pub struct SlotId(String);

impl SlotId {
pub fn random() -> Self {
Default::default()
}
}

impl Default for SlotId {
fn default() -> Self {
Self(nanoid::nanoid!())
}
}

#[derive(Clone, Eq, PartialEq, Hash, Debug, Serialize, Deserialize, JsonSchema)]
pub struct ClipId(String);

impl ClipId {
pub fn random() -> Self {
Default::default()
}
}

impl Default for ClipId {
fn default() -> Self {
Self(nanoid::nanoid!())
}
}

#[derive(Clone, PartialEq, Debug, Serialize, Deserialize, JsonSchema)]
pub struct Column {
#[serde(default)]
pub id: ColumnId,
pub clip_play_settings: ColumnClipPlaySettings,
pub clip_record_settings: ColumnClipRecordSettings,
/// Slots in this column.
Expand Down Expand Up @@ -712,7 +759,7 @@ pub struct ReaperPitchShiftMode {
pub sub_mode: u32,
}

#[derive(Clone, Eq, PartialEq, Debug, Serialize, Deserialize, JsonSchema)]
#[derive(Copy, Clone, Eq, PartialEq, Debug, Serialize, Deserialize, JsonSchema)]
#[serde(tag = "kind")]
pub enum RecordOrigin {
/// Records using the hardware input set for the track (MIDI or stereo).
Expand Down Expand Up @@ -751,6 +798,8 @@ impl Default for RecordOrigin {

#[derive(Clone, PartialEq, Debug, Serialize, Deserialize, JsonSchema)]
pub struct Slot {
#[serde(default)]
pub id: SlotId,
/// Slot index within the column (= row), starting at zero.
pub row: usize,
/// Clip which currently lives in this slot.
Expand All @@ -773,8 +822,8 @@ impl Slot {

#[derive(Clone, PartialEq, Debug, Serialize, Deserialize, JsonSchema)]
pub struct Clip {
#[serde(skip_serializing_if = "Option::is_none")]
pub id: Option<String>,
#[serde(default)]
pub id: ClipId,
#[serde(skip_serializing_if = "Option::is_none")]
pub name: Option<String>,
/// Source of the audio/MIDI material of this clip.
Expand Down
46 changes: 8 additions & 38 deletions playtime-clip-engine/src/base/clip.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,20 +10,17 @@ use crate::source_util::{
use crate::{rt, source_util, ClipEngineResult};
use crossbeam_channel::Sender;
use playtime_api::persistence as api;
use playtime_api::persistence::{ClipColor, ClipTimeBase, Db, Section, SourceOrigin};
use playtime_api::persistence::{ClipColor, ClipId, ClipTimeBase, Db, Section, SourceOrigin};
use reaper_high::{Project, Reaper, Track};
use reaper_medium::{Bpm, PeakFileMode};
use std::fmt::{Display, Formatter};
use std::fs;
use std::future::Future;
use std::path::{Path, PathBuf};
use std::str::FromStr;
use std::{fmt, fs};
use ulid::Ulid;

/// Describes a clip.
///
/// Not loaded yet.
#[derive(Clone, Debug)]
#[derive(Clone, PartialEq, Debug)]
pub struct Clip {
id: ClipId,
name: Option<String>,
Expand All @@ -34,38 +31,11 @@ pub struct Clip {
processing_relevant_settings: ProcessingRelevantClipSettings,
}

#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Debug, Hash)]
pub struct ClipId(Ulid);

impl ClipId {
pub fn random() -> Self {
Self(Ulid::new())
}
}

impl Display for ClipId {
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
self.0.fmt(f)
}
}

impl FromStr for ClipId {
type Err = &'static str;

fn from_str(s: &str) -> Result<Self, Self::Err> {
let ulid = Ulid::from_str(s).map_err(|_| "couldn't decode string as ULID")?;
Ok(ClipId(ulid))
}
}

impl Clip {
pub fn load(api_clip: api::Clip) -> Self {
Self {
processing_relevant_settings: ProcessingRelevantClipSettings::from_api(&api_clip),
id: api_clip
.id
.and_then(|s| ClipId::from_str(&s).ok())
.unwrap_or_else(ClipId::random),
id: api_clip.id,
name: api_clip.name,
color: api_clip.color,
source: api_clip.source,
Expand All @@ -91,7 +61,7 @@ impl Clip {
Audio { path, .. } => create_file_api_source(temporary_project, &path),
};
let clip = Self {
id: ClipId::random(),
id: Default::default(),
name: recording_track.name().map(|n| n.into_string()),
color: ClipColor::PlayTrackColor,
source: api_source,
Expand Down Expand Up @@ -122,7 +92,7 @@ impl Clip {
temporary_project: Option<Project>,
) -> ClipEngineResult<api::Clip> {
let clip = api::Clip {
id: Some(self.id.to_string()),
id: self.id.clone(),
name: self.name.clone(),
source: {
if let Some(midi_source) = midi_source {
Expand Down Expand Up @@ -290,8 +260,8 @@ impl Clip {
ClipChangeEvent::Everything
}

pub fn id(&self) -> ClipId {
self.id
pub fn id(&self) -> &ClipId {
&self.id
}

pub fn volume(&self) -> Db {
Expand Down
Loading

0 comments on commit e6bc0ab

Please sign in to comment.