onedrop_engine/
history.rs1use std::collections::VecDeque;
4
5#[derive(Debug, Clone)]
7pub struct History<T> {
8 items: VecDeque<T>,
10
11 current_index: Option<usize>,
13
14 max_size: usize,
16}
17
18impl<T: Clone> History<T> {
19 pub fn new(max_size: usize) -> Self {
21 Self {
22 items: VecDeque::with_capacity(max_size),
23 current_index: None,
24 max_size,
25 }
26 }
27
28 pub fn push(&mut self, item: T) {
30 if let Some(idx) = self.current_index {
32 while self.items.len() > idx + 1 {
33 self.items.pop_back();
34 }
35 }
36
37 self.items.push_back(item);
39
40 while self.items.len() > self.max_size {
42 self.items.pop_front();
43 }
44
45 self.current_index = if self.items.is_empty() {
47 None
48 } else {
49 Some(self.items.len() - 1)
50 };
51 }
52
53 pub fn back(&mut self) -> Option<&T> {
55 if self.items.is_empty() {
56 return None;
57 }
58
59 match self.current_index {
60 None => {
61 self.current_index = Some(self.items.len() - 1);
63 self.items.back()
64 }
65 Some(0) => {
66 self.items.front()
68 }
69 Some(idx) => {
70 self.current_index = Some(idx - 1);
72 self.items.get(idx - 1)
73 }
74 }
75 }
76
77 pub fn forward(&mut self) -> Option<&T> {
79 if self.items.is_empty() {
80 return None;
81 }
82
83 match self.current_index {
84 None => None,
85 Some(idx) if idx >= self.items.len() - 1 => {
86 self.items.back()
88 }
89 Some(idx) => {
90 self.current_index = Some(idx + 1);
92 self.items.get(idx + 1)
93 }
94 }
95 }
96
97 pub fn current(&self) -> Option<&T> {
99 self.current_index.and_then(|idx| self.items.get(idx))
100 }
101
102 pub fn can_go_back(&self) -> bool {
104 match self.current_index {
105 None => !self.items.is_empty(),
106 Some(0) => false,
107 Some(_) => true,
108 }
109 }
110
111 pub fn can_go_forward(&self) -> bool {
113 match self.current_index {
114 None => false,
115 Some(idx) => idx < self.items.len() - 1,
116 }
117 }
118
119 pub fn len(&self) -> usize {
121 self.items.len()
122 }
123
124 pub fn is_empty(&self) -> bool {
126 self.items.is_empty()
127 }
128
129 pub fn clear(&mut self) {
131 self.items.clear();
132 self.current_index = None;
133 }
134}
135
136impl<T: Clone> Default for History<T> {
137 fn default() -> Self {
138 Self::new(100) }
140}
141
142#[derive(Debug, Clone, PartialEq)]
144pub struct MashUpState {
145 pub source_presets: Vec<String>,
147
148 pub mash_type: MashUpType,
150
151 pub timestamp: std::time::SystemTime,
153}
154
155#[derive(Debug, Clone, Copy, PartialEq, Eq)]
157pub enum MashUpType {
158 Regular,
160
161 Deep,
163}
164
165#[derive(Debug, Clone, PartialEq)]
167pub struct ColorState {
168 pub colors: Vec<[f32; 3]>,
170
171 pub timestamp: std::time::SystemTime,
173}
174
175#[cfg(test)]
176mod tests {
177 use super::*;
178
179 #[test]
180 fn test_history_push() {
181 let mut history = History::new(5);
182
183 history.push(1);
184 history.push(2);
185 history.push(3);
186
187 assert_eq!(history.len(), 3);
188 assert_eq!(history.current(), Some(&3));
189 }
190
191 #[test]
192 fn test_history_back() {
193 let mut history = History::new(5);
194
195 history.push(1);
196 history.push(2);
197 history.push(3);
198
199 assert_eq!(history.back(), Some(&2));
200 assert_eq!(history.back(), Some(&1));
201 assert_eq!(history.back(), Some(&1)); }
203
204 #[test]
205 fn test_history_forward() {
206 let mut history = History::new(5);
207
208 history.push(1);
209 history.push(2);
210 history.push(3);
211
212 history.back();
213 history.back();
214
215 assert_eq!(history.forward(), Some(&2));
216 assert_eq!(history.forward(), Some(&3));
217 assert_eq!(history.forward(), Some(&3)); }
219
220 #[test]
221 fn test_history_max_size() {
222 let mut history = History::new(3);
223
224 history.push(1);
225 history.push(2);
226 history.push(3);
227 history.push(4);
228 history.push(5);
229
230 assert_eq!(history.len(), 3);
231 assert_eq!(history.items[0], 3);
232 assert_eq!(history.items[1], 4);
233 assert_eq!(history.items[2], 5);
234 }
235
236 #[test]
237 fn test_history_can_navigate() {
238 let mut history = History::new(5);
239
240 history.push(1);
241 history.push(2);
242 history.push(3);
243
244 assert!(!history.can_go_forward());
245 assert!(history.can_go_back());
246
247 history.back();
248
249 assert!(history.can_go_forward());
250 assert!(history.can_go_back());
251
252 history.back();
253
254 assert!(history.can_go_forward());
255 assert!(!history.can_go_back());
256 }
257
258 #[test]
259 fn test_history_clear() {
260 let mut history = History::new(5);
261
262 history.push(1);
263 history.push(2);
264 history.push(3);
265
266 history.clear();
267
268 assert!(history.is_empty());
269 assert_eq!(history.current(), None);
270 }
271}