moduforge_runtime/
history_manager.rs1pub struct History<T: Clone> {
3 past: Vec<T>,
4 present: T,
5 future: Vec<T>,
6 latest_unfiltered: T,
7}
8
9impl<T: Clone> History<T> {
10 fn new(
12 past: Vec<T>,
13 present: T,
14 future: Vec<T>,
15 ) -> Self {
16 let latest_unfiltered = present.clone();
17 History { past, present, future, latest_unfiltered }
18 }
19}
20
21pub struct HistoryManager<T: Clone> {
23 limit: Option<usize>,
24 history: History<T>,
25}
26
27impl<T: Clone> HistoryManager<T> {
28 pub fn new(
30 initial_state: T,
31 history_limit: Option<usize>,
32 ) -> Self {
33 HistoryManager {
34 limit: history_limit,
35 history: History::new(Vec::new(), initial_state, Vec::new()),
36 }
37 }
38
39 pub fn get_present(&self) -> T {
40 self.history.present.clone()
41 }
42
43 pub fn insert(
45 &mut self,
46 state: T,
47 ) {
48 let past = &self.history.past;
49 let length = past.len() + 1;
50
51 let past_sliced = match self.limit {
53 Some(limit) if length >= limit => past[1..].to_vec(),
54 _ => past.clone(),
55 };
56
57 let mut new_past = past_sliced;
59 new_past.push(self.history.latest_unfiltered.clone());
60
61 self.history = History::new(new_past, state, Vec::new());
62 }
63
64 pub fn jump_to_future(
66 &mut self,
67 index: usize,
68 ) {
69 if index >= self.history.future.len() {
70 return;
71 }
72
73 let mut new_past = self.history.past.clone();
74 new_past.push(self.history.latest_unfiltered.clone());
75 new_past.extend_from_slice(&self.history.future[..index]);
76
77 let new_present = self.history.future[index].clone();
78 let new_future = self.history.future[index + 1..].to_vec();
79
80 self.history = History::new(new_past, new_present, new_future);
81 }
82
83 pub fn jump_to_past(
85 &mut self,
86 index: usize,
87 ) {
88 if index >= self.history.past.len() {
89 return;
90 }
91
92 let new_past = self.history.past[..index].to_vec();
93 let mut new_future = self.history.past[index + 1..].to_vec();
94 new_future.push(self.history.latest_unfiltered.clone());
95 new_future.extend_from_slice(&self.history.future);
96
97 let new_present = self.history.past[index].clone();
98
99 self.history = History::new(new_past, new_present, new_future);
100 }
101
102 pub fn jump(
104 &mut self,
105 n: isize,
106 ) {
107 match n.cmp(&0) {
108 std::cmp::Ordering::Less => {
109 let past_len = self.history.past.len() as isize;
110 let target = past_len + n;
111 if target >= 0 {
112 self.jump_to_past(target as usize);
113 }
114 },
115 std::cmp::Ordering::Equal => {},
116 std::cmp::Ordering::Greater => {
117 self.jump_to_future((n - 1) as usize);
118 },
119 }
120 }
121
122 pub fn clear_history(&mut self) {
124 let present = self.history.present.clone();
125 self.history = History::new(Vec::new(), present, Vec::new());
126 }
127}