Skip to main content

concinnity_core/components/
animation_params.rs

1// src/components/animation_params.rs
2
3use alloc::vec::Vec;
4
5use crate::ecs::SkinnedMeshHandle;
6
7/// Runtime-only parameter block for one animation graph target.
8///
9/// `AnimationSystem` publishes one `AnimationParams` per `AnimationGraph` at init,
10/// seeded to the graph's declared parameter defaults. Gameplay systems write
11/// values into it each frame (matching on `target`); `AnimationSystem` reads
12/// it back during its step and evaluates the graph's transitions against the
13/// values. Entries are indexed by the graph's parameter declaration order --
14/// parameter names are compiled away at build time, so nothing resolves them
15/// at runtime.
16///
17/// Not authored in world files: it has no `args`.
18#[derive(Debug, Clone)]
19pub struct AnimationParams {
20    /// The `SkinnedMesh` resource whose graph these parameters drive.
21    pub target: SkinnedMeshHandle,
22    /// One value per graph parameter, in declaration order.
23    pub values: Vec<f32>,
24}
25
26impl AnimationParams {
27    /// A parameter block for `target`, seeded with the graph's defaults.
28    pub fn new(target: SkinnedMeshHandle, values: Vec<f32>) -> Self {
29        Self { target, values }
30    }
31
32    /// Set one parameter by index; out-of-range writes are ignored so a
33    /// stale writer cannot grow the block.
34    pub fn set(&mut self, index: usize, value: f32) {
35        if let Some(slot) = self.values.get_mut(index) {
36            *slot = value;
37        }
38    }
39}
40
41#[cfg(test)]
42mod tests {
43    use super::*;
44    use alloc::vec;
45
46    #[test]
47    fn set_writes_in_range_and_ignores_out_of_range() {
48        let mut p = AnimationParams::new(SkinnedMeshHandle(1), vec![0.0, 1.0]);
49        p.set(0, 3.5);
50        assert_eq!(p.values, vec![3.5, 1.0]);
51        p.set(5, 9.0);
52        assert_eq!(p.values.len(), 2, "out-of-range write must not grow");
53    }
54}