aura_anim_iced/state/
matcher.rs1use std::{hash::Hash, sync::Arc};
2
3use rustc_hash::FxHashMap;
4
5use crate::{StateTransition, Timeline};
6
7#[derive(Debug, Clone, PartialEq)]
9pub struct StateTransitionSet<S>
10where
11 S: Copy + Eq + Hash,
12{
13 transitions: Vec<StateTransition<S>>,
14 index: FxHashMap<(S, S), usize>,
15 fallback: Option<Arc<Timeline>>,
16}
17
18impl<S> StateTransitionSet<S>
19where
20 S: Copy + Eq + Hash,
21{
22 #[must_use]
24 pub fn new() -> Self {
25 Self {
26 transitions: Vec::new(),
27 index: FxHashMap::default(),
28 fallback: None,
29 }
30 }
31
32 #[must_use]
34 pub fn from_transitions(transitions: impl IntoIterator<Item = StateTransition<S>>) -> Self {
35 let mut set = Self::new();
36
37 for transition in transitions {
38 set.push(transition);
39 }
40
41 set
42 }
43
44 #[must_use]
46 pub fn with_fallback(mut self, fallback: Timeline) -> Self {
47 self.fallback = Some(Arc::new(fallback));
48 self
49 }
50
51 pub fn push(&mut self, transition: StateTransition<S>) {
53 let key = (transition.from(), transition.to());
54 let index = self.transitions.len();
55
56 self.transitions.push(transition);
57 self.index.entry(key).or_insert(index);
58 }
59
60 #[must_use]
62 pub fn transitions(&self) -> &[StateTransition<S>] {
63 &self.transitions
64 }
65
66 #[must_use]
68 pub fn fallback(&self) -> Option<&Timeline> {
69 self.fallback.as_deref()
70 }
71
72 pub(crate) fn fallback_arc(&self) -> Option<Arc<Timeline>> {
73 self.fallback.as_ref().map(Arc::clone)
74 }
75
76 #[must_use]
78 pub fn find(&self, from: S, to: S) -> Option<&StateTransition<S>> {
79 self.index
80 .get(&(from, to))
81 .and_then(|index| self.transitions.get(*index))
82 }
83}
84
85impl<S> Default for StateTransitionSet<S>
86where
87 S: Copy + Eq + Hash,
88{
89 fn default() -> Self {
90 Self::new()
91 }
92}
93
94impl<S> From<Vec<StateTransition<S>>> for StateTransitionSet<S>
95where
96 S: Copy + Eq + Hash,
97{
98 fn from(value: Vec<StateTransition<S>>) -> Self {
99 Self::from_transitions(value)
100 }
101}