Skip to main content

token_value_map/
lib.rs

1//! A time-based data mapping library for animation and interpolation.
2//!
3//! This crate provides types for storing and manipulating data that changes
4//! over time. It supports both uniform (static) and animated (time-varying)
5//! values with automatic interpolation between keyframes.
6//!
7//! # Core Types
8//!
9//! - [`Token`]: A string key type wrapping [`Ustr`](ustr::Ustr) (with `ustr`
10//!   feature) or [`String`] (without) used for lookups.
11//! - [`Value`]: A value that can be either uniform or animated over time.
12//! - [`Data`]: A variant enum containing all supported data types.
13//! - [`AnimatedData`]: Time-indexed data with interpolation support.
14//! - [`TimeDataMap`]: A mapping from time to data values.
15//! - [`TokenValueMap`]: A collection of named values indexed by tokens.
16//!
17//! # Data Types
18//!
19//! The library supports scalar types ([`Boolean`], [`Integer`], [`Real`],
20//! [`String`]), vector types ([`Vector2`], [`Vector3`], [`Color`],
21//! [`Matrix3`]), and collections of these types ([`BooleanVec`],
22//! [`IntegerVec`], etc.).
23//!
24//! # Motion Blur Sampling
25//!
26//! Use the [`Sample`] trait with a [`Shutter`] to generate motion blur samples
27//! for animated values during rendering.
28//!
29//! # Interpolation (Optional Feature)
30//!
31//! When the `interpolation` feature is enabled, [`TimeDataMap`] supports
32//! advanced interpolation modes including bezier curves with tangent control.
33//! This enables integration with professional animation systems like Dopamine.
34//!
35//! # Curve Types (Optional `curves` Feature)
36//!
37//! When the `curves` feature is enabled (on by default), the crate provides
38//! [`RealCurve`] and [`ColorCurve`] types for position-keyed parameter
39//! mappings. These use [`KeyDataMap<Position, T>`](KeyDataMap) under the hood,
40//! where [`Position`] is a normalized \[0, 1\] key type.
41//!
42//! ```rust
43//! use token_value_map::*;
44//!
45//! // Create a falloff curve: ramps linearly from 0 → 1.
46//! let curve = RealCurve::linear();
47//! assert_eq!(curve.evaluate(0.0), 0.0);
48//! assert_eq!(curve.evaluate(1.0), 1.0);
49//!
50//! // Create a black-to-white color gradient.
51//! let gradient = ColorCurve::black_to_white();
52//! let mid = gradient.evaluate(0.5);  // ~[0.5, 0.5, 0.5, 1.0]
53//! assert!(mid[0] > 0.4 && mid[0] < 0.6);
54//! ```
55//!
56//! # Examples
57//!
58//! ```rust
59//! use frame_tick::Tick;
60//! use token_value_map::*;
61//!
62//! // Create a uniform value.
63//! let uniform = Value::uniform(42.0);
64//!
65//! // Create an animated value.
66//! let animated =
67//!     Value::animated(vec![(Tick::new(0), 0.0), (Tick::new(10), 10.0)])
68//!         .unwrap();
69//!
70//! // Sample at a specific time.
71//! let interpolated = animated.interpolate(Tick::new(5));
72//! ```
73
74#[cfg(feature = "facet")]
75use facet::Facet;
76#[cfg(feature = "builtin-types")]
77use function_name::named;
78#[cfg(feature = "rkyv")]
79use rkyv::{Archive, Deserialize as RkyvDeserialize, Serialize as RkyvSerialize};
80#[cfg(feature = "serde")]
81use serde::{Deserialize, Serialize};
82use smallvec::SmallVec;
83use std::fmt::Debug;
84use std::hash::Hash;
85#[cfg(feature = "builtin-types")]
86use std::hash::Hasher;
87
88// Internal macro module.
89#[cfg(feature = "builtin-types")]
90mod macros;
91#[cfg(feature = "builtin-types")]
92use macros::impl_sample_for_value;
93
94// Math backend abstraction.
95#[cfg(feature = "builtin-types")]
96pub mod math;
97
98// Built-in types (feature-gated).
99#[cfg(feature = "builtin-types")]
100mod animated_data;
101#[cfg(feature = "builtin-types")]
102mod data;
103#[cfg(feature = "builtin-types")]
104mod data_types;
105#[cfg(feature = "builtin-types")]
106mod token_value_map;
107#[cfg(feature = "builtin-types")]
108mod value;
109
110// Generic types (always available).
111mod define_data_macro;
112mod generic_token_value_map;
113mod generic_value;
114mod traits;
115
116// Position type for curve domains.
117#[cfg(feature = "curves")]
118mod position;
119
120// Token type.
121mod token;
122
123// Other modules.
124#[cfg(feature = "egui-keyframe")]
125mod egui_keyframe_integration;
126mod error;
127#[cfg(feature = "interpolation")]
128mod interpolation;
129#[cfg(all(feature = "lua", feature = "builtin-types"))]
130mod lua;
131mod shutter;
132mod time_data_map;
133
134// Re-exports: built-in types (feature-gated).
135#[cfg(feature = "builtin-types")]
136pub use animated_data::*;
137#[cfg(feature = "builtin-types")]
138pub use data::*;
139#[cfg(feature = "builtin-types")]
140pub use data_types::*;
141#[cfg(feature = "builtin-types")]
142pub use token_value_map::*;
143#[cfg(feature = "builtin-types")]
144pub use value::*;
145
146// Re-exports: always available.
147pub use error::*;
148pub use generic_token_value_map::*;
149pub use generic_value::*;
150#[cfg(feature = "interpolation")]
151pub use interpolation::*;
152#[cfg(all(feature = "lua", feature = "builtin-types"))]
153pub use lua::*;
154#[cfg(feature = "curves")]
155pub use position::*;
156pub use shutter::*;
157pub use time_data_map::*;
158pub use token::*;
159pub use traits::*;
160
161/// A time value represented as a fixed-point [`Tick`](frame_tick::Tick).
162pub type Time = frame_tick::Tick;
163
164/// Trait for getting data type information.
165///
166/// This trait is only available with the `builtin-types` feature.
167#[cfg(feature = "builtin-types")]
168pub trait DataTypeOps {
169    /// Returns the [`DataType`] variant for this value.
170    fn data_type(&self) -> DataType;
171    /// Returns a string name for this data type.
172    fn type_name(&self) -> &'static str;
173}
174
175#[cfg(feature = "builtin-types")]
176impl DataTypeOps for Value {
177    fn data_type(&self) -> DataType {
178        match self {
179            Value::Uniform(data) => data.data_type(),
180            Value::Animated(animated_data) => animated_data.data_type(),
181        }
182    }
183
184    fn type_name(&self) -> &'static str {
185        match self {
186            Value::Uniform(data) => data.type_name(),
187            Value::Animated(animated_data) => animated_data.type_name(),
188        }
189    }
190}