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 { limit: history_limit, history: History::new(Vec::new(), initial_state, Vec::new()) }
34 }
35
36 pub fn get_present(&self) -> T {
37 self.history.present.clone()
38 }
39
40 pub fn insert(
42 &mut self,
43 state: T,
44 ) {
45 let past = &self.history.past;
46 let length = past.len() + 1;
47
48 let past_sliced = match self.limit {
50 Some(limit) if length >= limit => past[1..].to_vec(),
51 _ => past.clone(),
52 };
53
54 let mut new_past = past_sliced;
56 new_past.push(self.history.latest_unfiltered.clone());
57
58 self.history = History::new(new_past, state, Vec::new());
59 }
60
61 pub fn jump_to_future(
63 &mut self,
64 index: usize,
65 ) {
66 if index >= self.history.future.len() {
67 return;
68 }
69
70 let mut new_past = self.history.past.clone();
71 new_past.push(self.history.latest_unfiltered.clone());
72 new_past.extend_from_slice(&self.history.future[..index]);
73
74 let new_present = self.history.future[index].clone();
75 let new_future = self.history.future[index + 1..].to_vec();
76
77 self.history = History::new(new_past, new_present, new_future);
78 }
79
80 pub fn jump_to_past(
82 &mut self,
83 index: usize,
84 ) {
85 if index >= self.history.past.len() {
86 return;
87 }
88
89 let new_past = self.history.past[..index].to_vec();
90 let mut new_future = self.history.past[index + 1..].to_vec();
91 new_future.push(self.history.latest_unfiltered.clone());
92 new_future.extend_from_slice(&self.history.future);
93
94 let new_present = self.history.past[index].clone();
95
96 self.history = History::new(new_past, new_present, new_future);
97 }
98
99 pub fn jump(
101 &mut self,
102 n: isize,
103 ) {
104 match n.cmp(&0) {
105 std::cmp::Ordering::Less => {
106 let past_len = self.history.past.len() as isize;
107 let target = past_len + n;
108 if target >= 0 {
109 self.jump_to_past(target as usize);
110 }
111 },
112 std::cmp::Ordering::Equal => {},
113 std::cmp::Ordering::Greater => {
114 self.jump_to_future((n - 1) as usize);
115 },
116 }
117 }
118
119 pub fn clear_history(&mut self) {
121 let present = self.history.present.clone();
122 self.history = History::new(Vec::new(), present, Vec::new());
123 }
124}