use super::StatePlay;
use alloc::string::String;
use alloc::vec::Vec;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default, serde::Serialize, serde::Deserialize)]
#[serde(rename_all = "lowercase")]
pub enum CmpOp {
#[default]
Lt,
Le,
Gt,
Ge,
Eq,
Ne,
}
impl CmpOp {
pub fn eval(self, lhs: f32, rhs: f32) -> bool {
match self {
CmpOp::Lt => lhs < rhs,
CmpOp::Le => lhs <= rhs,
CmpOp::Gt => lhs > rhs,
CmpOp::Ge => lhs >= rhs,
CmpOp::Eq => lhs == rhs,
CmpOp::Ne => lhs != rhs,
}
}
}
#[derive(Debug, Clone)]
pub struct CompiledCondition {
pub param: usize,
pub op: CmpOp,
pub value: f32,
}
#[derive(Debug, Clone)]
pub struct CompiledTransition {
pub to: usize,
pub duration_secs: f32,
pub exit_time: Option<f32>,
pub conditions: Vec<CompiledCondition>,
}
#[derive(Debug, Clone)]
pub struct CompiledState {
pub name: String,
pub rate: f32,
pub looping: bool,
pub play: StatePlay,
pub transitions: Vec<CompiledTransition>,
}
#[derive(Debug, Clone)]
pub struct ParamSpec {
pub name: String,
pub default: f32,
}
#[derive(Debug, Clone)]
pub struct CompiledGraph {
pub params: Vec<ParamSpec>,
pub states: Vec<CompiledState>,
pub initial: usize,
}
impl CompiledGraph {
pub fn param_index(&self, name: &str) -> Option<usize> {
self.params.iter().position(|p| p.name == name)
}
pub fn default_params(&self) -> Vec<f32> {
self.params.iter().map(|p| p.default).collect()
}
pub fn refresh_clip_duration(&mut self, clip: usize, duration_secs: f32) {
for state in &mut self.states {
for member in state.play.members_mut() {
if member.clip == clip {
member.duration_secs = duration_secs;
}
}
}
}
}