use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize)]
#[repr(u8)]
pub enum Phase {
Idle = 0,
Approaching = 1,
Snap = 2,
Hold = 3,
}
impl From<u8> for Phase {
fn from(v: u8) -> Self {
match v {
0 => Phase::Idle,
1 => Phase::Approaching,
2 => Phase::Snap,
_ => Phase::Hold,
}
}
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub struct TemporalState {
pub beat_pos: f64,
pub phase: Phase,
pub rhythm_coherence: f64,
}
impl TemporalState {
pub fn new(beat_pos: f64, phase: Phase, rhythm_coherence: f64) -> Self {
Self { beat_pos, phase, rhythm_coherence }
}
pub fn default() -> Self {
Self {
beat_pos: 0.0,
phase: Phase::Idle,
rhythm_coherence: 1.0,
}
}
pub fn check_alignment(&self) -> Vec<String> {
let mut violations = Vec::new();
if !(0.0..=1.0).contains(&self.beat_pos) {
violations.push("temporal.beat_pos must be 0-1".into());
}
if !(0.0..=1.0).contains(&self.rhythm_coherence) {
violations.push("temporal.rhythm_coherence must be 0-1".into());
}
violations
}
pub fn merge(&self, other: &Self) -> Self {
Self {
beat_pos: self.beat_pos.max(other.beat_pos),
phase: std::cmp::max(self.phase, other.phase),
rhythm_coherence: self.rhythm_coherence.max(other.rhythm_coherence),
}
}
}