1use std::ops::{Add, AddAssign};
6
7use undoredo::{Delta, Recorder, UndoRedo};
8
9#[derive(Clone, Copy, Debug, PartialEq)]
12struct Vector2<T> {
13 x: T,
14 y: T,
15}
16
17impl<T: Add<T, Output = T>> Add for Vector2<T> {
18 type Output = Self;
19
20 fn add(self, rhs: Self) -> Self {
21 Self {
22 x: self.x + rhs.x,
23 y: self.y + rhs.y,
24 }
25 }
26}
27
28impl<T: AddAssign<T>> AddAssign for Vector2<T> {
29 fn add_assign(&mut self, rhs: Self) {
30 self.x += rhs.x;
31 self.y += rhs.y;
32 }
33}
34
35#[derive(Delta)]
38#[undoredo(delta = EntitiesDelta)]
43#[undoredo(half_delta = EntitiesHalfDelta)]
48struct Entities<T> {
49 positions: Recorder<Vec<Vector2<T>>>,
50 velocities: Recorder<Vec<Vector2<T>>>,
51 healths: Recorder<Vec<i64>>,
52 turn_counter: Recorder<u64>,
54 #[undoredo(skip)]
59 #[allow(unused)]
60 not_in_delta: String,
61}
62
63impl<T: Add<T, Output = T> + AddAssign<T> + Copy + PartialOrd> Entities<T> {
64 pub fn new_entity(&mut self, position: Vector2<T>, velocity: Vector2<T>, health: i64) -> usize {
65 self.positions.push(position);
66 self.velocities.push(velocity);
67 self.healths.push(health)
68 }
69
70 pub fn update(&mut self) {
71 self.turn_counter.assign(*self.turn_counter.container() + 1);
72
73 for i in 0..self.positions.container().len() {
74 self.update_entity(i);
75 }
76 }
77
78 fn update_entity(&mut self, index: usize) {
79 let velocity = self.velocities[index];
82 self.positions
83 .modify(index, |position| *position += velocity);
84
85 self.healths.set(index, self.healths[index] - 1);
92 }
93}
94
95fn assert_entity(entities: &Entities<f64>, index: usize, pos: Vector2<f64>, health: i64) {
96 assert_eq!(entities.positions[index], pos);
97 assert_eq!(entities.healths[index], health);
98}
99
100fn main() {
101 let mut entities = Entities::<f64> {
102 positions: Recorder::new(Vec::new()),
103 velocities: Recorder::new(Vec::new()),
104 healths: Recorder::new(Vec::new()),
105 turn_counter: Recorder::new(0),
106 not_in_delta: "not_in_delta".to_string(),
107 };
108
109 let mut undoredo: UndoRedo<EntitiesDelta<f64>> = UndoRedo::new();
111
112 entities.new_entity(Vector2 { x: 0.0, y: 0.0 }, Vector2 { x: 1.0, y: 0.0 }, 100);
113 entities.new_entity(Vector2 { x: 0.0, y: 0.0 }, Vector2 { x: 0.0, y: 2.0 }, 100);
114 undoredo.commit(&mut entities);
115
116 entities.new_entity(
117 Vector2 { x: 100.0, y: 100.0 },
118 Vector2 { x: -1.0, y: -1.0 },
119 50,
120 );
121 undoredo.commit(&mut entities);
122
123 assert_eq!(entities.positions.container().len(), 3);
124
125 for _ in 0..3 {
127 entities.update();
128 undoredo.commit(&mut entities);
129 }
130
131 for _ in 0..5 {
133 entities.update();
134 }
135 undoredo.commit(&mut entities);
136
137 assert!(entities.positions.container().len() == 3);
138 assert_entity(&entities, 0, Vector2 { x: 8.0, y: 0.0 }, 92);
139 assert_entity(&entities, 1, Vector2 { x: 0.0, y: 16.0 }, 92);
140 assert_entity(&entities, 2, Vector2 { x: 92.0, y: 92.0 }, 42);
141 assert_eq!(*entities.turn_counter.container(), 8);
142
143 undoredo.undo(&mut entities);
144
145 assert!(entities.positions.container().len() == 3);
146 assert_entity(&entities, 0, Vector2 { x: 3.0, y: 0.0 }, 97);
147 assert_entity(&entities, 1, Vector2 { x: 0.0, y: 6.0 }, 97);
148 assert_entity(&entities, 2, Vector2 { x: 97.0, y: 97.0 }, 47);
149 assert_eq!(*entities.turn_counter.container(), 3);
150
151 undoredo.undo(&mut entities);
152
153 assert!(entities.positions.container().len() == 3);
154 assert_entity(&entities, 0, Vector2 { x: 2.0, y: 0.0 }, 98);
155 assert_entity(&entities, 1, Vector2 { x: 0.0, y: 4.0 }, 98);
156 assert_entity(&entities, 2, Vector2 { x: 98.0, y: 98.0 }, 48);
157
158 undoredo.undo(&mut entities);
159
160 assert!(entities.positions.container().len() == 3);
161 assert_entity(&entities, 0, Vector2 { x: 1.0, y: 0.0 }, 99);
162 assert_entity(&entities, 1, Vector2 { x: 0.0, y: 2.0 }, 99);
163 assert_entity(&entities, 2, Vector2 { x: 99.0, y: 99.0 }, 49);
164
165 undoredo.undo(&mut entities);
166
167 assert!(entities.positions.container().len() == 3);
168 assert_entity(&entities, 0, Vector2 { x: 0.0, y: 0.0 }, 100);
169 assert_entity(&entities, 1, Vector2 { x: 0.0, y: 0.0 }, 100);
170 assert_entity(&entities, 2, Vector2 { x: 100.0, y: 100.0 }, 50);
171 assert_eq!(*entities.turn_counter.container(), 0);
172
173 undoredo.undo(&mut entities);
174
175 assert!(entities.positions.container().len() == 2);
176 assert_entity(&entities, 0, Vector2 { x: 0.0, y: 0.0 }, 100);
177 assert_entity(&entities, 1, Vector2 { x: 0.0, y: 0.0 }, 100);
178
179 undoredo.redo(&mut entities);
180
181 assert!(entities.positions.container().len() == 3);
182 assert_entity(&entities, 0, Vector2 { x: 0.0, y: 0.0 }, 100);
183 assert_entity(&entities, 1, Vector2 { x: 0.0, y: 0.0 }, 100);
184 assert_entity(&entities, 2, Vector2 { x: 100.0, y: 100.0 }, 50);
185
186 undoredo.redo(&mut entities);
187
188 assert_entity(&entities, 0, Vector2 { x: 1.0, y: 0.0 }, 99);
189 assert_entity(&entities, 1, Vector2 { x: 0.0, y: 2.0 }, 99);
190 assert_entity(&entities, 2, Vector2 { x: 99.0, y: 99.0 }, 49);
191
192 undoredo.redo(&mut entities);
193
194 assert_entity(&entities, 0, Vector2 { x: 2.0, y: 0.0 }, 98);
195 assert_entity(&entities, 1, Vector2 { x: 0.0, y: 4.0 }, 98);
196 assert_entity(&entities, 2, Vector2 { x: 98.0, y: 98.0 }, 48);
197
198 undoredo.redo(&mut entities);
199
200 assert_entity(&entities, 0, Vector2 { x: 3.0, y: 0.0 }, 97);
201 assert_entity(&entities, 1, Vector2 { x: 0.0, y: 6.0 }, 97);
202 assert_entity(&entities, 2, Vector2 { x: 97.0, y: 97.0 }, 47);
203
204 undoredo.redo(&mut entities);
205
206 assert!(entities.positions.container().len() == 3);
207 assert_entity(&entities, 0, Vector2 { x: 8.0, y: 0.0 }, 92);
208 assert_entity(&entities, 1, Vector2 { x: 0.0, y: 16.0 }, 92);
209 assert_entity(&entities, 2, Vector2 { x: 92.0, y: 92.0 }, 42);
210 assert_eq!(*entities.turn_counter.container(), 8);
211}
212
213#[test]
214fn test() {
215 main();
216}