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}