Files
Cagire/src/state/playback.rs
Raphaël Forment 11cc925faf
All checks were successful
Deploy Website / deploy (push) Has been skipped
more fixes
2026-03-01 03:33:22 +01:00

140 lines
4.1 KiB
Rust

use crate::engine::PatternChange;
use crate::model::{FollowUp, LaunchQuantization, PatternSpeed, SyncMode};
use std::collections::{HashMap, HashSet};
#[derive(Clone)]
pub struct StagedChange {
pub change: PatternChange,
pub quantization: LaunchQuantization,
pub sync_mode: SyncMode,
}
#[derive(Clone, Copy, PartialEq, Eq, Hash)]
pub enum StagedMuteChange {
ToggleMute { bank: usize, pattern: usize },
ToggleSolo { bank: usize, pattern: usize },
}
pub struct StagedPropChange {
pub name: Option<String>,
pub description: Option<String>,
pub length: Option<usize>,
pub speed: PatternSpeed,
pub quantization: LaunchQuantization,
pub sync_mode: SyncMode,
pub follow_up: FollowUp,
}
pub struct PlaybackState {
pub playing: bool,
pub staged_changes: Vec<StagedChange>,
pub queued_changes: Vec<StagedChange>,
pub staged_mute_changes: HashSet<StagedMuteChange>,
pub staged_prop_changes: HashMap<(usize, usize), StagedPropChange>,
pub muted: HashSet<(usize, usize)>,
pub soloed: HashSet<(usize, usize)>,
}
impl Default for PlaybackState {
fn default() -> Self {
Self {
playing: true,
staged_changes: Vec::new(),
queued_changes: Vec::new(),
staged_mute_changes: HashSet::new(),
staged_prop_changes: HashMap::new(),
muted: HashSet::new(),
soloed: HashSet::new(),
}
}
}
impl PlaybackState {
pub fn toggle(&mut self) {
self.playing = !self.playing;
}
pub fn clear_queues(&mut self) {
self.staged_changes.clear();
self.queued_changes.clear();
self.staged_prop_changes.clear();
}
pub fn has_staged_props(&self, bank: usize, pattern: usize) -> bool {
self.staged_prop_changes.contains_key(&(bank, pattern))
}
pub fn stage_mute(&mut self, bank: usize, pattern: usize) {
let change = StagedMuteChange::ToggleMute { bank, pattern };
if self.staged_mute_changes.contains(&change) {
self.staged_mute_changes.remove(&change);
} else {
self.staged_mute_changes.insert(change);
}
}
pub fn stage_solo(&mut self, bank: usize, pattern: usize) {
let change = StagedMuteChange::ToggleSolo { bank, pattern };
if self.staged_mute_changes.contains(&change) {
self.staged_mute_changes.remove(&change);
} else {
self.staged_mute_changes.insert(change);
}
}
pub fn clear_staged_mutes(&mut self) {
self.staged_mute_changes.retain(|c| !matches!(c, StagedMuteChange::ToggleMute { .. }));
}
pub fn clear_staged_solos(&mut self) {
self.staged_mute_changes.retain(|c| !matches!(c, StagedMuteChange::ToggleSolo { .. }));
}
pub fn clear_mutes(&mut self) {
self.clear_staged_mutes();
self.muted.clear();
}
pub fn clear_solos(&mut self) {
self.clear_staged_solos();
self.soloed.clear();
}
pub fn has_staged_mute(&self, bank: usize, pattern: usize) -> bool {
self.staged_mute_changes.contains(&StagedMuteChange::ToggleMute { bank, pattern })
}
pub fn has_staged_solo(&self, bank: usize, pattern: usize) -> bool {
self.staged_mute_changes.contains(&StagedMuteChange::ToggleSolo { bank, pattern })
}
pub fn toggle_mute(&mut self, bank: usize, pattern: usize) {
let key = (bank, pattern);
if !self.muted.remove(&key) {
self.muted.insert(key);
}
}
pub fn toggle_solo(&mut self, bank: usize, pattern: usize) {
let key = (bank, pattern);
if !self.soloed.remove(&key) {
self.soloed.insert(key);
}
}
pub fn is_muted(&self, bank: usize, pattern: usize) -> bool {
self.muted.contains(&(bank, pattern))
}
pub fn is_soloed(&self, bank: usize, pattern: usize) -> bool {
self.soloed.contains(&(bank, pattern))
}
pub fn is_effectively_muted(&self, bank: usize, pattern: usize) -> bool {
if self.muted.contains(&(bank, pattern)) {
return true;
}
!self.soloed.is_empty() && !self.soloed.contains(&(bank, pattern))
}
}