ringkernel_procint/gui/canvas/
token_animation.rs1#[derive(Debug, Clone)]
7pub struct Token {
8 pub id: u64,
10 pub case_id: u64,
12 pub source_activity: u32,
14 pub target_activity: u32,
16 pub progress: f32,
18 pub speed: f32,
20}
21
22impl Token {
23 pub fn new(id: u64, case_id: u64, source: u32, target: u32) -> Self {
25 Self {
26 id,
27 case_id,
28 source_activity: source,
29 target_activity: target,
30 progress: 0.0,
31 speed: 1.0,
32 }
33 }
34
35 pub fn update(&mut self, dt: f32) -> bool {
37 self.progress += dt * self.speed;
38 self.progress >= 1.0
39 }
40}
41
42#[derive(Debug, Default)]
44pub struct TokenAnimation {
45 tokens: Vec<Token>,
47 next_id: u64,
49 max_tokens: usize,
51 base_speed: f32,
53}
54
55impl TokenAnimation {
56 pub fn new() -> Self {
58 Self {
59 tokens: Vec::new(),
60 next_id: 1,
61 max_tokens: 50,
62 base_speed: 0.5,
63 }
64 }
65
66 pub fn with_max_tokens(mut self, max: usize) -> Self {
68 self.max_tokens = max;
69 self
70 }
71
72 pub fn with_base_speed(mut self, speed: f32) -> Self {
74 self.base_speed = speed;
75 self
76 }
77
78 pub fn spawn(&mut self, case_id: u64, source: u32, target: u32) {
80 if self.tokens.len() >= self.max_tokens {
81 self.tokens.remove(0);
83 }
84
85 let mut token = Token::new(self.next_id, case_id, source, target);
86 token.speed = self.base_speed;
87 self.tokens.push(token);
88 self.next_id += 1;
89 }
90
91 pub fn spawn_from_transitions(&mut self, transitions: &[(u64, u32, u32)]) {
93 for &(case_id, source, target) in transitions {
94 self.spawn(case_id, source, target);
95 }
96 }
97
98 pub fn update(&mut self, dt: f32) {
100 self.tokens.retain_mut(|token| !token.update(dt));
102 }
103
104 pub fn active_tokens(&self) -> &[Token] {
106 &self.tokens
107 }
108
109 pub fn count(&self) -> usize {
111 self.tokens.len()
112 }
113
114 pub fn clear(&mut self) {
116 self.tokens.clear();
117 }
118
119 pub fn set_speed(&mut self, speed: f32) {
121 self.base_speed = speed;
122 for token in &mut self.tokens {
123 token.speed = speed;
124 }
125 }
126}
127
128#[cfg(test)]
129mod tests {
130 use super::*;
131
132 #[test]
133 fn test_token_creation() {
134 let token = Token::new(1, 100, 1, 2);
135 assert_eq!(token.progress, 0.0);
136 assert_eq!(token.source_activity, 1);
137 assert_eq!(token.target_activity, 2);
138 }
139
140 #[test]
141 fn test_token_update() {
142 let mut token = Token::new(1, 100, 1, 2);
143 token.speed = 1.0;
144
145 let completed = token.update(0.5);
147 assert!(!completed);
148 assert_eq!(token.progress, 0.5);
149
150 let completed = token.update(0.5);
152 assert!(completed);
153 }
154
155 #[test]
156 fn test_animation_manager() {
157 let mut anim = TokenAnimation::new().with_max_tokens(5);
158 anim.spawn(100, 1, 2);
159 anim.spawn(101, 2, 3);
160
161 assert_eq!(anim.count(), 2);
162
163 anim.update(0.1);
165 assert_eq!(anim.count(), 2);
166
167 for _ in 0..20 {
169 anim.update(0.1);
170 }
171 assert_eq!(anim.count(), 0);
172 }
173}