Skip to content

Commit

Permalink
Playtime: Improve error handling within Playtime
Browse files Browse the repository at this point in the history
doesn't look nice in the ReaLearn targets but that's because
ReaLearn's error handling needs an overhaul as well
  • Loading branch information
helgoboss committed Dec 8, 2023
1 parent d1ec722 commit a122ec4
Show file tree
Hide file tree
Showing 15 changed files with 246 additions and 177 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.

5 changes: 3 additions & 2 deletions base/src/tracing_util.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use std::fmt::Display;
#[macro_export]
macro_rules! tracing_debug {
($($tts:tt)*) => {
Expand Down Expand Up @@ -33,11 +34,11 @@ macro_rules! tracing_error {
}
}

pub fn ok_or_log_as_warn<T, E: tracing::Value>(result: Result<T, E>) -> Option<T> {
pub fn ok_or_log_as_warn<T, E: Display>(result: Result<T, E>) -> Option<T> {
match result {
Ok(v) => Some(v),
Err(e) => {
tracing::warn!(e);
tracing::warn!("{e}");
None
}
}
Expand Down
29 changes: 15 additions & 14 deletions main/src/domain/backbone_state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ use crate::domain::{
use enum_iterator::IntoEnumIterator;
use pot::{PotFavorites, PotFilterExcludes};

use anyhow::{anyhow, Context};
use once_cell::sync::Lazy;
use realearn_api::persistence::TargetTouchCause;
use reaper_high::{Fx, Reaper};
Expand Down Expand Up @@ -394,12 +395,12 @@ impl BackboneState {
&self,
instance_state: &SharedInstanceState,
f: impl FnOnce(&playtime_clip_engine::base::Matrix) -> R,
) -> Result<R, &'static str> {
) -> anyhow::Result<R> {
use crate::domain::ClipMatrixRef::*;
let other_instance_id = match instance_state
.borrow()
.clip_matrix_ref()
.ok_or(NO_CLIP_MATRIX_SET)?
.context(NO_CLIP_MATRIX_SET)?
{
Own(m) => return Ok(f(m)),
Foreign(instance_id) => *instance_id,
Expand All @@ -412,22 +413,22 @@ impl BackboneState {
&self,
foreign_instance_id: &InstanceId,
f: impl FnOnce(&playtime_clip_engine::base::Matrix) -> R,
) -> Result<R, &'static str> {
) -> anyhow::Result<R> {
use crate::domain::ClipMatrixRef::*;
let other_instance_state = self
.instance_states
.borrow()
.get(foreign_instance_id)
.ok_or(REFERENCED_INSTANCE_NOT_AVAILABLE)?
.context(REFERENCED_INSTANCE_NOT_AVAILABLE)?
.upgrade()
.ok_or(REFERENCED_INSTANCE_NOT_AVAILABLE)?;
.context(REFERENCED_INSTANCE_NOT_AVAILABLE)?;
let other_instance_state = other_instance_state.borrow();
match other_instance_state
.clip_matrix_ref()
.ok_or(REFERENCED_CLIP_MATRIX_NOT_AVAILABLE)?
.context(REFERENCED_CLIP_MATRIX_NOT_AVAILABLE)?
{
Own(m) => Ok(f(m)),
Foreign(_) => Err(NESTED_CLIP_BORROW_NOT_SUPPORTED),
Foreign(_) => Err(anyhow!(NESTED_CLIP_BORROW_NOT_SUPPORTED)),
}
}

Expand All @@ -438,12 +439,12 @@ impl BackboneState {
&self,
instance_state: &SharedInstanceState,
f: impl FnOnce(&mut playtime_clip_engine::base::Matrix) -> R,
) -> Result<R, &'static str> {
) -> anyhow::Result<R> {
use crate::domain::ClipMatrixRef::*;
let other_instance_id = match instance_state
.borrow_mut()
.clip_matrix_ref_mut()
.ok_or(NO_CLIP_MATRIX_SET)?
.context(NO_CLIP_MATRIX_SET)?
{
Own(m) => return Ok(f(m)),
Foreign(instance_id) => *instance_id,
Expand All @@ -456,22 +457,22 @@ impl BackboneState {
&self,
instance_id: &InstanceId,
f: impl FnOnce(&mut playtime_clip_engine::base::Matrix) -> R,
) -> Result<R, &'static str> {
) -> anyhow::Result<R> {
use crate::domain::ClipMatrixRef::*;
let other_instance_state = self
.instance_states
.borrow()
.get(instance_id)
.ok_or(REFERENCED_INSTANCE_NOT_AVAILABLE)?
.context(REFERENCED_INSTANCE_NOT_AVAILABLE)?
.upgrade()
.ok_or(REFERENCED_INSTANCE_NOT_AVAILABLE)?;
.context(REFERENCED_INSTANCE_NOT_AVAILABLE)?;
let mut other_instance_state = other_instance_state.borrow_mut();
match other_instance_state
.clip_matrix_ref_mut()
.ok_or(REFERENCED_CLIP_MATRIX_NOT_AVAILABLE)?
.context(REFERENCED_CLIP_MATRIX_NOT_AVAILABLE)?
{
Own(m) => Ok(f(m)),
Foreign(_) => Err(NESTED_CLIP_BORROW_NOT_SUPPORTED),
Foreign(_) => Err(anyhow!(NESTED_CLIP_BORROW_NOT_SUPPORTED)),
}
}

Expand Down
27 changes: 15 additions & 12 deletions main/src/domain/targets/clip_column_target.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,20 +54,23 @@ impl RealearnTarget for ClipColumnTarget {
value: ControlValue,
context: MappingControlContext,
) -> Result<HitResponse, &'static str> {
let response = BackboneState::get().with_clip_matrix(
context.control_context.instance_state,
|matrix| -> Result<HitResponse, &'static str> {
match self.action {
ClipColumnAction::Stop => {
if !value.is_on() {
return Ok(HitResponse::ignored());
let response = BackboneState::get()
.with_clip_matrix(
context.control_context.instance_state,
|matrix| -> anyhow::Result<HitResponse> {
match self.action {
ClipColumnAction::Stop => {
if !value.is_on() {
return Ok(HitResponse::ignored());
}
matrix.stop_column(self.column_index, None)?;
}
matrix.stop_column(self.column_index, None)?;
}
}
Ok(HitResponse::processed_with_effect())
},
)??;
Ok(HitResponse::processed_with_effect())
},
)
.map_err(|_| "couldn't acquire matrix")?
.map_err(|_| "couldn't carry out column action")?;
Ok(response)
}

Expand Down
61 changes: 35 additions & 26 deletions main/src/domain/targets/clip_management_target.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,35 +39,11 @@ pub struct ClipManagementTarget {
}

impl ClipManagementTarget {
fn with_matrix<R>(
&self,
context: MappingControlContext,
f: impl FnOnce(&mut playtime_clip_engine::base::Matrix) -> R,
) -> Result<R, &'static str> {
BackboneState::get().with_clip_matrix_mut(context.control_context.instance_state, f)
}
}

impl RealearnTarget for ClipManagementTarget {
fn control_type_and_character(&self, _: ControlContext) -> (ControlType, TargetCharacter) {
use ClipManagementAction as A;
match self.action {
A::ClearSlot
| A::FillSlotWithSelectedItem
| A::CopyOrPasteClip
| A::AdjustClipSectionLength(_) => (
ControlType::AbsoluteContinuousRetriggerable,
TargetCharacter::Trigger,
),
A::EditClip => (ControlType::AbsoluteContinuous, TargetCharacter::Switch),
}
}

fn hit(
fn hit_internal(
&mut self,
value: ControlValue,
context: MappingControlContext,
) -> Result<HitResponse, &'static str> {
) -> anyhow::Result<HitResponse> {
use ClipManagementAction as A;
match &self.action {
A::ClearSlot => {
Expand Down Expand Up @@ -122,6 +98,39 @@ impl RealearnTarget for ClipManagementTarget {
}
}

fn with_matrix<R>(
&self,
context: MappingControlContext,
f: impl FnOnce(&mut playtime_clip_engine::base::Matrix) -> R,
) -> anyhow::Result<R> {
BackboneState::get().with_clip_matrix_mut(context.control_context.instance_state, f)
}
}

impl RealearnTarget for ClipManagementTarget {
fn control_type_and_character(&self, _: ControlContext) -> (ControlType, TargetCharacter) {
use ClipManagementAction as A;
match self.action {
A::ClearSlot
| A::FillSlotWithSelectedItem
| A::CopyOrPasteClip
| A::AdjustClipSectionLength(_) => (
ControlType::AbsoluteContinuousRetriggerable,
TargetCharacter::Trigger,
),
A::EditClip => (ControlType::AbsoluteContinuous, TargetCharacter::Switch),
}
}

fn hit(
&mut self,
value: ControlValue,
context: MappingControlContext,
) -> Result<HitResponse, &'static str> {
self.hit_internal(value, context)
.map_err(|_| "couldn't carry out clip management action")
}

fn reaper_target_type(&self) -> Option<ReaperTargetType> {
Some(ReaperTargetType::ClipManagement)
}
Expand Down
75 changes: 39 additions & 36 deletions main/src/domain/targets/clip_matrix_target.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,44 +48,47 @@ impl RealearnTarget for ClipMatrixTarget {
value: ControlValue,
context: MappingControlContext,
) -> Result<HitResponse, &'static str> {
BackboneState::get().with_clip_matrix_mut(
context.control_context.instance_state,
|matrix| {
if !value.is_on() {
return Ok(HitResponse::ignored());
}
match self.action {
ClipMatrixAction::Stop => {
matrix.stop();
}
ClipMatrixAction::Undo => {
let _ = matrix.undo();
}
ClipMatrixAction::Redo => {
let _ = matrix.redo();
}
ClipMatrixAction::BuildScene => {
matrix.build_scene_in_first_empty_row()?;
}
ClipMatrixAction::SetRecordDurationToOpenEnd => {
matrix.set_record_duration(RecordLength::OpenEnd);
}
ClipMatrixAction::SetRecordDurationToOneBar => {
matrix.set_record_duration(record_duration_in_bars(1));
BackboneState::get()
.with_clip_matrix_mut(
context.control_context.instance_state,
|matrix| -> anyhow::Result<HitResponse> {
if !value.is_on() {
return Ok(HitResponse::ignored());
}
ClipMatrixAction::SetRecordDurationToTwoBars => {
matrix.set_record_duration(record_duration_in_bars(2));
match self.action {
ClipMatrixAction::Stop => {
matrix.stop();
}
ClipMatrixAction::Undo => {
let _ = matrix.undo();
}
ClipMatrixAction::Redo => {
let _ = matrix.redo();
}
ClipMatrixAction::BuildScene => {
matrix.build_scene_in_first_empty_row()?;
}
ClipMatrixAction::SetRecordDurationToOpenEnd => {
matrix.set_record_duration(RecordLength::OpenEnd);
}
ClipMatrixAction::SetRecordDurationToOneBar => {
matrix.set_record_duration(record_duration_in_bars(1));
}
ClipMatrixAction::SetRecordDurationToTwoBars => {
matrix.set_record_duration(record_duration_in_bars(2));
}
ClipMatrixAction::SetRecordDurationToFourBars => {
matrix.set_record_duration(record_duration_in_bars(4));
}
ClipMatrixAction::SetRecordDurationToEightBars => {
matrix.set_record_duration(record_duration_in_bars(8));
}
}
ClipMatrixAction::SetRecordDurationToFourBars => {
matrix.set_record_duration(record_duration_in_bars(4));
}
ClipMatrixAction::SetRecordDurationToEightBars => {
matrix.set_record_duration(record_duration_in_bars(8));
}
}
Ok(HitResponse::processed_with_effect())
},
)?
Ok(HitResponse::processed_with_effect())
},
)
.map_err(|_| "couldn't acquire matrix")?
.map_err(|_| "couldn't carry out matrix action")
}

fn process_change_event(
Expand Down
53 changes: 31 additions & 22 deletions main/src/domain/targets/clip_row_target.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,31 +39,11 @@ pub struct ClipRowTarget {
}

impl ClipRowTarget {
fn with_matrix<R>(
&self,
context: ControlContext,
f: impl FnOnce(&mut playtime_clip_engine::base::Matrix) -> R,
) -> Result<R, &'static str> {
BackboneState::get().with_clip_matrix_mut(context.instance_state, f)
}
}

#[derive(Clone, Debug, PartialEq)]
struct ClipRowTargetBasics {
pub row_index: usize,
pub action: ClipRowAction,
}

impl RealearnTarget for ClipRowTarget {
fn control_type_and_character(&self, _: ControlContext) -> (ControlType, TargetCharacter) {
control_type_and_character(self.basics.action)
}

fn hit(
fn hit_internal(
&mut self,
value: ControlValue,
context: MappingControlContext,
) -> Result<HitResponse, &'static str> {
) -> anyhow::Result<HitResponse> {
match self.basics.action {
ClipRowAction::PlayScene => {
if !value.is_on() {
Expand Down Expand Up @@ -108,6 +88,35 @@ impl RealearnTarget for ClipRowTarget {
}
}

fn with_matrix<R>(
&self,
context: ControlContext,
f: impl FnOnce(&mut playtime_clip_engine::base::Matrix) -> R,
) -> anyhow::Result<R> {
BackboneState::get().with_clip_matrix_mut(context.instance_state, f)
}
}

#[derive(Clone, Debug, PartialEq)]
struct ClipRowTargetBasics {
pub row_index: usize,
pub action: ClipRowAction,
}

impl RealearnTarget for ClipRowTarget {
fn control_type_and_character(&self, _: ControlContext) -> (ControlType, TargetCharacter) {
control_type_and_character(self.basics.action)
}

fn hit(
&mut self,
value: ControlValue,
context: MappingControlContext,
) -> Result<HitResponse, &'static str> {
self.hit_internal(value, context)
.map_err(|_| "couldn't carry out row action")
}

fn reaper_target_type(&self) -> Option<ReaperTargetType> {
Some(ReaperTargetType::ClipRow)
}
Expand Down
Loading

0 comments on commit a122ec4

Please sign in to comment.