mirror of
https://github.com/storytold/gridcraft.git
synced 2026-10-30 05:37:00 -06:00
Engine: a rolled-back group takes what its script runs ran out of the recording too
Taking back the steps a rolled-back group recorded left what a taken-back script or macro run ran (`Recorder::ran`) under its old index, where a later run could pick it up, and left it out of the size count. `cut_back` now drops it with its step, moves a kept run's entry to the step's new index and counts both again. - Test: `a_rolled_back_script_run_takes_what_it_ran_out_of_the_recording`.
This commit is contained in:
@@ -112,15 +112,26 @@ impl Recorder {
|
||||
/// Takes back the steps recorded in the document with uid `doc` since `mark` (an undo group
|
||||
/// on it was rolled back, so playing them back would make edits it no longer has). Steps in
|
||||
/// other documents stay: their edits do too. Steps the buffer dropped stay counted.
|
||||
/// What a step ran ([`Recorder::ran`]) goes with its step, and stays with a kept one under its
|
||||
/// new index.
|
||||
pub(crate) fn cut_back(&mut self, (len, _): (usize, usize), doc: u64) {
|
||||
let before = self.steps.len();
|
||||
let mut i = 0;
|
||||
self.steps.retain(|s| {
|
||||
i += 1;
|
||||
i <= len || s.doc != doc
|
||||
});
|
||||
if self.steps.len() != before {
|
||||
self.bytes = self.steps.iter().map(|s| serde_json::to_vec(s).map_or(0, |v| v.len())).sum();
|
||||
if !self.steps.iter().skip(len).any(|s| s.doc == doc) {
|
||||
return;
|
||||
}
|
||||
let mut ran = std::mem::take(&mut self.ran);
|
||||
let mut steps = Vec::with_capacity(self.steps.len());
|
||||
for (i, step) in std::mem::take(&mut self.steps).into_iter().enumerate() {
|
||||
if i >= len && step.doc == doc {
|
||||
continue;
|
||||
}
|
||||
if let Some(r) = ran.remove(&i) {
|
||||
self.ran.insert(steps.len(), r);
|
||||
}
|
||||
steps.push(step);
|
||||
}
|
||||
self.steps = steps;
|
||||
let size = |v: Result<Vec<u8>, serde_json::Error>| v.map_or(0, |v| v.len());
|
||||
self.bytes = self.steps.iter().map(|s| size(serde_json::to_vec(s))).sum::<usize>()
|
||||
+ self.ran.values().map(|r| size(serde_json::to_vec(r))).sum::<usize>();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2164,6 +2164,26 @@ fn a_script_step_that_only_opened_a_dialog_is_left_out_of_the_recording() {
|
||||
assert!(recorded(&mut s, "Without").is_empty());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn a_rolled_back_script_run_takes_what_it_ran_out_of_the_recording() {
|
||||
// What a recorded script run ran goes with its step when a group rollback takes the step
|
||||
// back, and a kept run keeps what it ran under its new place.
|
||||
let mut s = s();
|
||||
s.execute("automate.newScript", json!({"name": "Mark", "commands": [{"command": "cell.set", "params": {"cell": "A1", "input": "m"}}]})).unwrap();
|
||||
s.execute("macro.record", json!({"relative": false})).unwrap();
|
||||
s.execute("automate.runScript", json!({"name": "Mark"})).unwrap();
|
||||
let _left = s.group_begin("Left open").unwrap();
|
||||
set(&mut s, "B1", "gone");
|
||||
s.execute("automate.runScript", json!({"name": "Mark"})).unwrap();
|
||||
s.execute("automate.stopAction", json!({})).unwrap();
|
||||
let rec = s.recorder.as_ref().unwrap();
|
||||
assert_eq!((rec.steps.len(), rec.ran.keys().copied().collect::<Vec<_>>()), (1, vec![0]));
|
||||
s.execute("automate.runScript", json!({"name": "Mark"})).unwrap();
|
||||
s.execute("macro.record", json!({"stop": true, "name": "Rec"})).unwrap();
|
||||
let a1 = "cell.set {\"cell\":\"A1\",\"input\":\"m\"}";
|
||||
assert_eq!(recorded(&mut s, "Rec"), [a1, a1]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn a_script_run_records_the_state_its_toggles_set() {
|
||||
let mut s = s();
|
||||
|
||||
Reference in New Issue
Block a user