use std::collections::HashMap;
#[derive(Debug, Clone)]
pub struct AnimationDataStore {
values: HashMap<String, StateValue>,
}
#[derive(Debug, Clone, PartialEq)]
pub enum StateValue {
F64(f64),
I32(i32),
I64(i64),
Bool(bool),
String(String),
VecF64(Vec<f64>),
}
impl AnimationDataStore {
pub fn new() -> Self {
Self {
values: HashMap::new(),
}
}
pub fn with_values(values: HashMap<String, StateValue>) -> Self {
Self { values }
}
pub fn set(&mut self, key: &str, value: StateValue) {
self.values.insert(key.to_string(), value);
}
pub fn get(&self, key: &str) -> Option<&StateValue> {
self.values.get(key)
}
pub fn contains_key(&self, key: &str) -> bool {
self.values.contains_key(key)
}
pub fn remove(&mut self, key: &str) -> Option<StateValue> {
self.values.remove(key)
}
pub fn clear(&mut self) {
self.values.clear();
}
pub fn get_f64(&self, key: &str, default: f64) -> f64 {
match self.get(key) {
Some(StateValue::F64(v)) => *v,
_ => default,
}
}
pub fn get_i32(&self, key: &str, default: i32) -> i32 {
match self.get(key) {
Some(StateValue::I32(v)) => *v,
_ => default,
}
}
pub fn get_i64(&self, key: &str, default: i64) -> i64 {
match self.get(key) {
Some(StateValue::I64(v)) => *v,
_ => default,
}
}
pub fn get_bool(&self, key: &str, default: bool) -> bool {
match self.get(key) {
Some(StateValue::Bool(v)) => *v,
_ => default,
}
}
pub fn get_string(&self, key: &str, default: &str) -> String {
match self.get(key) {
Some(StateValue::String(v)) => v.clone(),
_ => default.to_string(),
}
}
pub fn get_vec_f64(&self, key: &str, default: Vec<f64>) -> Vec<f64> {
match self.get(key) {
Some(StateValue::VecF64(v)) => v.clone(),
_ => default,
}
}
pub fn set_f64(&mut self, key: &str, value: f64) {
self.set(key, StateValue::F64(value));
}
pub fn set_i32(&mut self, key: &str, value: i32) {
self.set(key, StateValue::I32(value));
}
pub fn set_i64(&mut self, key: &str, value: i64) {
self.set(key, StateValue::I64(value));
}
pub fn set_bool(&mut self, key: &str, value: bool) {
self.set(key, StateValue::Bool(value));
}
pub fn set_string(&mut self, key: &str, value: &str) {
self.set(key, StateValue::String(value.to_string()));
}
pub fn add_f64(&mut self, key: &str, delta: f64) {
let current = self.get_f64(key, 0.0);
self.set_f64(key, current + delta);
}
pub fn mul_f64(&mut self, key: &str, factor: f64) {
let current = self.get_f64(key, 0.0);
self.set_f64(key, current * factor);
}
pub fn inc_i32(&mut self, key: &str) {
let current = self.get_i32(key, 0);
self.set_i32(key, current + 1);
}
pub fn toggle_bool(&mut self, key: &str) {
let current = self.get_bool(key, false);
self.set_bool(key, !current);
}
pub fn lerp_f64(&self, from_key: &str, to_key: &str, t: f64) -> f64 {
let from = self.get_f64(from_key, 0.0);
let to = self.get_f64(to_key, 0.0);
from + (to - from) * t.clamp(0.0, 1.0)
}
pub fn clamp_f64(&mut self, key: &str, min: f64, max: f64) {
let current = self.get_f64(key, 0.0);
self.set_f64(key, current.clamp(min, max));
}
pub fn in_range_f64(&self, key: &str, min: f64, max: f64) -> bool {
let value = self.get_f64(key, 0.0);
value >= min && value <= max
}
pub fn keys(&self) -> Vec<String> {
self.values.keys().cloned().collect()
}
pub fn len(&self) -> usize {
self.values.len()
}
pub fn is_empty(&self) -> bool {
self.values.is_empty()
}
}
impl Default for AnimationDataStore {
fn default() -> Self {
Self::new()
}
}